src/qt3support/sql/q3sqlcursor.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt3Support module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <qplatformdefs.h>
       
    43 #include "q3sqlcursor.h"
       
    44 
       
    45 #ifndef QT_NO_SQL
       
    46 
       
    47 #include "qsqldriver.h"
       
    48 #include "qsqlresult.h"
       
    49 #include "qdatetime.h"
       
    50 #include "qsqldatabase.h"
       
    51 #include "qsql.h"
       
    52 #include "q3sqlrecordinfo.h"
       
    53 #include "q3sqlfieldinfo.h"
       
    54 
       
    55 QT_BEGIN_NAMESPACE
       
    56 
       
    57 class Q3SqlCursorPrivate
       
    58 {
       
    59 public:
       
    60 
       
    61     Q3SqlCursorPrivate(const QString& name, QSqlDatabase sdb)
       
    62         : lastAt(QSql::BeforeFirst), nm(name), srt(name), md(0), db(sdb), q(0)
       
    63     {}
       
    64     ~Q3SqlCursorPrivate()
       
    65     {
       
    66         delete q;
       
    67     }
       
    68 
       
    69     QSqlQuery* query()
       
    70     {
       
    71         if (!q)
       
    72             q = new QSqlQuery(QString(), db);
       
    73         return q;
       
    74     }
       
    75 
       
    76     int lastAt;
       
    77     QString nm;         //name
       
    78     QSqlIndex srt;        //sort
       
    79     QString ftr;        //filter
       
    80     int md;         //mode
       
    81     QSqlIndex priIndx;    //primary index
       
    82     QSqlRecord editBuffer;
       
    83     // the primary index as it was before the user changed the values in editBuffer
       
    84     QString editIndex;
       
    85     Q3SqlRecordInfo infoBuffer;
       
    86     QSqlDatabase db;
       
    87     QSqlQuery *q;
       
    88 };
       
    89 
       
    90 QString qOrderByClause(const QSqlIndex & i, const QString& prefix = QString())
       
    91 {
       
    92     QString str;
       
    93     int k = i.count();
       
    94     if(k == 0)
       
    95         return QString();
       
    96     str = QLatin1String(" order by ") + i.toString(prefix);
       
    97     return str;
       
    98 }
       
    99 
       
   100 QString qWhereClause(const QString& prefix, QSqlField* field, const QSqlDriver* driver)
       
   101 {
       
   102     QString f;
       
   103     if (field && driver) {
       
   104         if (!prefix.isEmpty())
       
   105             f += prefix + QLatin1Char('.');
       
   106         f += field->name();
       
   107         if (field->isNull()) {
       
   108             f += QLatin1String(" IS NULL");
       
   109         } else {
       
   110             f += QLatin1String(" = ") + driver->formatValue(field);
       
   111         }
       
   112     }
       
   113     return f;
       
   114 }
       
   115 
       
   116 QString qWhereClause(QSqlRecord* rec, const QString& prefix, const QString& sep,
       
   117                       const QSqlDriver* driver)
       
   118 {
       
   119     static QString blank(QLatin1Char(' '));
       
   120     QString filter;
       
   121     bool separator = false;
       
   122     for (int j = 0; j < rec->count(); ++j) {
       
   123         QSqlField f = rec->field(j);
       
   124         if (rec->isGenerated(j)) {
       
   125             if (separator)
       
   126                 filter += sep + blank;
       
   127             filter += qWhereClause(prefix, &f, driver);
       
   128             filter += blank;
       
   129             separator = true;
       
   130         }
       
   131     }
       
   132     return filter;
       
   133 }
       
   134 
       
   135 /*!
       
   136     \class Q3SqlCursor
       
   137     \brief The Q3SqlCursor class provides browsing and editing of SQL
       
   138     tables and views.
       
   139 
       
   140     \compat
       
   141 
       
   142     A Q3SqlCursor is a database record (see \l QSqlRecord) that
       
   143     corresponds to a table or view within an SQL database (see \l
       
   144     QSqlDatabase). There are two buffers in a cursor, one used for
       
   145     browsing and one used for editing records. Each buffer contains a
       
   146     list of fields which correspond to the fields in the table or
       
   147     view.
       
   148 
       
   149     When positioned on a valid record, the browse buffer contains the
       
   150     values of the current record's fields from the database. The edit
       
   151     buffer is separate, and is used for editing existing records and
       
   152     inserting new records.
       
   153 
       
   154     For browsing data, a cursor must first select() data from the
       
   155     database. After a successful select() the cursor is active
       
   156     (isActive() returns true), but is initially not positioned on a
       
   157     valid record (isValid() returns false). To position the cursor on
       
   158     a valid record, use one of the navigation functions, next(),
       
   159     previous(), first(), last(), or seek(). Once positioned on a valid
       
   160     record, data can be retrieved from the browse buffer using
       
   161     value(). If a navigation function is not successful, it returns
       
   162     false, the cursor will no longer be positioned on a valid record
       
   163     and the values returned by value() are undefined.
       
   164 
       
   165     For example:
       
   166 
       
   167     \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 0
       
   168 
       
   169     In the above example, a cursor is created specifying a table or
       
   170     view name in the database. Then, select() is called, which can be
       
   171     optionally parameterised to filter and order the records
       
   172     retrieved. Each record in the cursor is retrieved using next().
       
   173     When next() returns false, there are no more records to process,
       
   174     and the loop terminates.
       
   175 
       
   176     For editing records (rows of data), a cursor contains a separate
       
   177     edit buffer which is independent of the fields used when browsing.
       
   178     The functions insert(), update() and del() operate on the edit
       
   179     buffer. This allows the cursor to be repositioned to other
       
   180     records while simultaneously maintaining a separate buffer for
       
   181     edits. You can get a pointer to the edit buffer using
       
   182     editBuffer(). The primeInsert(), primeUpdate() and primeDelete()
       
   183     functions also return a pointer to the edit buffer and prepare it
       
   184     for insert, update and delete respectively. Edit operations only
       
   185     affect a single row at a time. Note that update() and del()
       
   186     require that the table or view contain a primaryIndex() to ensure
       
   187     that edit operations affect a unique record within the database.
       
   188 
       
   189     For example:
       
   190 
       
   191     \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 1
       
   192 
       
   193     To edit an existing database record, first move to the record you
       
   194     wish to update. Call primeUpdate() to get the pointer to the
       
   195     cursor's edit buffer. Then use this pointer to modify the values
       
   196     in the edit buffer. Finally, call update() to save the changes to
       
   197     the database. The values in the edit buffer will be used to
       
   198     locate the appropriate record when updating the database (see
       
   199     primaryIndex()).
       
   200 
       
   201     Similarly, when deleting an existing database record, first move
       
   202     to the record you wish to delete. Then, call primeDelete() to get
       
   203     the pointer to the edit buffer. Finally, call del() to delete the
       
   204     record from the database. Again, the values in the edit buffer
       
   205     will be used to locate and delete the appropriate record.
       
   206 
       
   207     To insert a new record, call primeInsert() to get the pointer to
       
   208     the edit buffer. Use this pointer to populate the edit buffer
       
   209     with new values and then insert() the record into the database.
       
   210 
       
   211     After calling insert(), update() or del(), the cursor is no longer
       
   212     positioned on a valid record and can no longer be navigated
       
   213     (isValid() return false). The reason for this is that any changes
       
   214     made to the database will not be visible until select() is called
       
   215     to refresh the cursor. You can change this behavior by passing
       
   216     false to insert(), update() or del() which will prevent the cursor
       
   217     from becoming invalid. The edits will still not be visible when
       
   218     navigating the cursor until select() is called.
       
   219 
       
   220     Q3SqlCursor contains virtual methods which allow editing behavior
       
   221     to be customized by subclasses. This allows custom cursors to be
       
   222     created that encapsulate the editing behavior of a database table
       
   223     for an entire application. For example, a cursor can be customized
       
   224     to always auto-number primary index fields, or provide fields with
       
   225     suitable default values, when inserting new records. Q3SqlCursor
       
   226     generates SQL statements which are sent to the database engine;
       
   227     you can control which fields are included in these statements
       
   228     using setGenerated().
       
   229 
       
   230     Note that Q3SqlCursor does not inherit from QObject. This means
       
   231     that you are responsible for destroying instances of this class
       
   232     yourself. However if you create a Q3SqlCursor and use it in a
       
   233     \l Q3DataTable, \l Q3DataBrowser or a \l Q3DataView these classes will
       
   234     usually take ownership of the cursor and destroy it when they
       
   235     don't need it anymore. The documentation for Q3DataTable,
       
   236     Q3DataBrowser and Q3DataView explicitly states which calls take
       
   237     ownership of the cursor.
       
   238 */
       
   239 
       
   240 /*!
       
   241     \enum Q3SqlCursor::Mode
       
   242 
       
   243     This enum type describes how Q3SqlCursor operates on records in the
       
   244     database.
       
   245 
       
   246     \value ReadOnly  the cursor can only SELECT records from the
       
   247     database.
       
   248 
       
   249     \value Insert  the cursor can INSERT records into the database.
       
   250 
       
   251     \value Update  the cursor can UPDATE records in the database.
       
   252 
       
   253     \value Delete  the cursor can DELETE records from the database.
       
   254 
       
   255     \value Writable  the cursor can INSERT, UPDATE and DELETE records
       
   256     in the database.
       
   257 */
       
   258 
       
   259 /*!
       
   260     \fn QVariant Q3SqlCursor::value(const QString &name) const
       
   261 
       
   262     \overload
       
   263 
       
   264     Returns the value of the field named \a name.
       
   265 */
       
   266 
       
   267 /*!
       
   268     \fn void Q3SqlCursor::setValue(const QString &name, const QVariant &val)
       
   269 
       
   270     \overload
       
   271 
       
   272     Sets the value for the field named \a name to \a val.
       
   273 */
       
   274 
       
   275 /*!
       
   276     Constructs a cursor on database \a db using table or view \a name.
       
   277 
       
   278     If \a autopopulate is true (the default), the \a name of the
       
   279     cursor must correspond to an existing table or view name in the
       
   280     database so that field information can be automatically created.
       
   281     If the table or view does not exist, the cursor will not be
       
   282     functional.
       
   283 
       
   284     The cursor is created with an initial mode of Q3SqlCursor::Writable
       
   285     (meaning that records can be inserted, updated or deleted using
       
   286     the cursor). If the cursor does not have a unique primary index,
       
   287     update and deletes cannot be performed.
       
   288 
       
   289     Note that \a autopopulate refers to populating the cursor with
       
   290     meta-data, e.g. the names of the table's fields, not with
       
   291     retrieving data. The select() function is used to populate the
       
   292     cursor with data.
       
   293 
       
   294     \sa setName() setMode()
       
   295 */
       
   296 
       
   297 Q3SqlCursor::Q3SqlCursor(const QString & name, bool autopopulate, QSqlDatabase db)
       
   298     : QSqlRecord(), QSqlQuery(QString(), db)
       
   299 {
       
   300     d = new Q3SqlCursorPrivate(name, db);
       
   301     setMode(Writable);
       
   302     if (!d->nm.isEmpty())
       
   303         setName(d->nm, autopopulate);
       
   304 }
       
   305 
       
   306 /*!
       
   307     Constructs a copy of \a other.
       
   308 */
       
   309 
       
   310 Q3SqlCursor::Q3SqlCursor(const Q3SqlCursor & other)
       
   311     : QSqlRecord(other), QSqlQuery(other)
       
   312 {
       
   313     d = new Q3SqlCursorPrivate(other.d->nm, other.d->db);
       
   314     d->lastAt = other.d->lastAt;
       
   315     d->nm = other.d->nm;
       
   316     d->srt = other.d->srt;
       
   317     d->ftr = other.d->ftr;
       
   318     d->priIndx = other.d->priIndx;
       
   319     d->editBuffer = other.d->editBuffer;
       
   320     d->infoBuffer = other.d->infoBuffer;
       
   321     d->q = 0; // do not share queries
       
   322     setMode(other.mode());
       
   323 }
       
   324 
       
   325 /*!
       
   326     Destroys the object and frees any allocated resources.
       
   327 */
       
   328 
       
   329 Q3SqlCursor::~Q3SqlCursor()
       
   330 {
       
   331     delete d;
       
   332 }
       
   333 
       
   334 /*!
       
   335     Sets the cursor equal to \a other.
       
   336 */
       
   337 
       
   338 Q3SqlCursor& Q3SqlCursor::operator=(const Q3SqlCursor& other)
       
   339 {
       
   340     QSqlRecord::operator=(other);
       
   341     QSqlQuery::operator=(other);
       
   342     delete d;
       
   343     d = new Q3SqlCursorPrivate(other.d->nm, other.d->db);
       
   344     d->lastAt = other.d->lastAt;
       
   345     d->nm = other.d->nm;
       
   346     d->srt = other.d->srt;
       
   347     d->ftr = other.d->ftr;
       
   348     d->priIndx = other.d->priIndx;
       
   349     d->editBuffer = other.d->editBuffer;
       
   350     d->infoBuffer = other.d->infoBuffer;
       
   351     d->q = 0; // do not share queries
       
   352     setMode(other.mode());
       
   353     return *this;
       
   354 }
       
   355 
       
   356 /*!
       
   357     Sets the current sort to \a sort. Note that no new records are
       
   358     selected. To select new records, use select(). The \a sort will
       
   359     apply to any subsequent select() calls that do not explicitly
       
   360     specify a sort.
       
   361 */
       
   362 
       
   363 void Q3SqlCursor::setSort(const QSqlIndex& sort)
       
   364 {
       
   365     d->srt = sort;
       
   366 }
       
   367 
       
   368 /*!
       
   369     Returns the current sort, or an empty index if there is no current
       
   370     sort.
       
   371 */
       
   372 QSqlIndex Q3SqlCursor::sort() const
       
   373 {
       
   374     return d->srt;
       
   375 }
       
   376 
       
   377 /*!
       
   378     Sets the current filter to \a filter. Note that no new records are
       
   379     selected. To select new records, use select(). The \a filter will
       
   380     apply to any subsequent select() calls that do not explicitly
       
   381     specify a filter.
       
   382 
       
   383     The filter is a SQL \c WHERE clause without the keyword 'WHERE',
       
   384     e.g. \c{name='Dave'} which will be processed by the DBMS.
       
   385 */
       
   386 void Q3SqlCursor::setFilter(const QString& filter)
       
   387 {
       
   388     d->ftr = filter;
       
   389 }
       
   390 
       
   391 /*!
       
   392     Returns the current filter, or an empty string if there is no
       
   393     current filter.
       
   394 */
       
   395 QString Q3SqlCursor::filter() const
       
   396 {
       
   397     return d->ftr;
       
   398 }
       
   399 
       
   400 /*!
       
   401     Sets the name of the cursor to \a name. If \a autopopulate is true
       
   402     (the default), the \a name must correspond to a valid table or
       
   403     view name in the database. Also, note that all references to the
       
   404     cursor edit buffer become invalidated when fields are
       
   405     auto-populated. See the Q3SqlCursor constructor documentation for
       
   406     more information.
       
   407 */
       
   408 void Q3SqlCursor::setName(const QString& name, bool autopopulate)
       
   409 {
       
   410     d->nm = name;
       
   411     if (autopopulate) {
       
   412         if (driver()) {
       
   413             d->infoBuffer = driver()->record(name);
       
   414             *this = d->infoBuffer.toRecord();
       
   415             d->editBuffer = *this;
       
   416             d->priIndx = driver()->primaryIndex(name);
       
   417         }
       
   418         if (isEmpty())
       
   419             qWarning("Q3SqlCursor::setName: unable to build record, does '%s' exist?", name.latin1());
       
   420     }
       
   421 }
       
   422 
       
   423 /*!
       
   424     Returns the name of the cursor.
       
   425 */
       
   426 
       
   427 QString Q3SqlCursor::name() const
       
   428 {
       
   429     return d->nm;
       
   430 }
       
   431 
       
   432 /*! \internal
       
   433 */
       
   434 
       
   435 QString Q3SqlCursor::toString(const QString& prefix, const QString& sep) const
       
   436 {
       
   437     QString pflist;
       
   438     QString pfix =  prefix.isEmpty() ? prefix : prefix + QLatin1Char('.');
       
   439     bool comma = false;
       
   440 
       
   441     for (int i = 0; i < count(); ++i) {
       
   442         const QString fname = fieldName(i);
       
   443         if (isGenerated(i)) {
       
   444             if(comma)
       
   445                 pflist += sep + QLatin1Char(' ');
       
   446             pflist += pfix + driver()->escapeIdentifier(fname, QSqlDriver::FieldName);
       
   447             comma = true;
       
   448         }
       
   449     }
       
   450     return pflist;
       
   451 }
       
   452 
       
   453 /*!
       
   454   \internal
       
   455 
       
   456   Assigns the record \a list.
       
   457 
       
   458 */
       
   459 QSqlRecord & Q3SqlCursor::operator=(const QSqlRecord & list)
       
   460 {
       
   461     return QSqlRecord::operator=(list);
       
   462 }
       
   463 
       
   464 /*!
       
   465     Append a copy of field \a fieldInfo to the end of the cursor. Note
       
   466     that all references to the cursor edit buffer become invalidated.
       
   467 */
       
   468 
       
   469 void Q3SqlCursor::append(const Q3SqlFieldInfo& fieldInfo)
       
   470 {
       
   471     d->editBuffer.append(fieldInfo.toField());
       
   472     d->infoBuffer.append(fieldInfo);
       
   473     QSqlRecord::append(fieldInfo.toField());
       
   474 }
       
   475 
       
   476 /*!
       
   477     Removes all fields from the cursor. Note that all references to
       
   478     the cursor edit buffer become invalidated.
       
   479 */
       
   480 void Q3SqlCursor::clear()
       
   481 {
       
   482     d->editBuffer.clear();
       
   483     d->infoBuffer.clear();
       
   484     QSqlRecord::clear();
       
   485 }
       
   486 
       
   487 
       
   488 /*!
       
   489     Insert a copy of \a fieldInfo at position \a pos. If a field
       
   490     already exists at \a pos, it is removed. Note that all references
       
   491     to the cursor edit buffer become invalidated.
       
   492 */
       
   493 
       
   494 void  Q3SqlCursor::insert(int pos, const Q3SqlFieldInfo& fieldInfo)
       
   495 {
       
   496     d->editBuffer.replace(pos, fieldInfo.toField());
       
   497     d->infoBuffer[pos] = fieldInfo;
       
   498     QSqlRecord::replace(pos, fieldInfo.toField());
       
   499 }
       
   500 
       
   501 /*!
       
   502     Removes the field at \a pos. If \a pos does not exist, nothing
       
   503     happens. Note that all references to the cursor edit buffer become
       
   504     invalidated.
       
   505 */
       
   506 
       
   507 void Q3SqlCursor::remove(int pos)
       
   508 {
       
   509     d->editBuffer.remove(pos);
       
   510     d->infoBuffer[pos] = Q3SqlFieldInfo();
       
   511     QSqlRecord::remove(pos);
       
   512 }
       
   513 
       
   514 /*!
       
   515     Sets the generated flag for the field \a name to \a generated. If
       
   516     the field does not exist, nothing happens. Only fields that have
       
   517     \a generated set to true are included in the SQL that is
       
   518     generated by insert(), update() or del().
       
   519 */
       
   520 
       
   521 void Q3SqlCursor::setGenerated(const QString& name, bool generated)
       
   522 {
       
   523     int pos = indexOf(name);
       
   524     if (pos == -1)
       
   525         return;
       
   526     QSqlRecord::setGenerated(name, generated);
       
   527     d->editBuffer.setGenerated(name, generated);
       
   528     d->infoBuffer[pos].setGenerated(generated);
       
   529 }
       
   530 
       
   531 /*!
       
   532     \overload
       
   533 
       
   534     Sets the generated flag for the field \a i to \a generated.
       
   535 */
       
   536 void Q3SqlCursor::setGenerated(int i, bool generated)
       
   537 {
       
   538     if (i < 0 || i >= (int)d->infoBuffer.count())
       
   539         return;
       
   540     QSqlRecord::setGenerated(i, generated);
       
   541     d->editBuffer.setGenerated(i, generated);
       
   542     d->infoBuffer[i].setGenerated(generated);
       
   543 }
       
   544 
       
   545 /*!
       
   546     Returns the primary index associated with the cursor as defined in
       
   547     the database, or an empty index if there is no primary index. If
       
   548     \a setFromCursor is true (the default), the index fields are
       
   549     populated with the corresponding values in the cursor's current
       
   550     record.
       
   551 */
       
   552 
       
   553 QSqlIndex Q3SqlCursor::primaryIndex(bool setFromCursor) const
       
   554 {
       
   555     if (setFromCursor) {
       
   556         for (int i = 0; i < d->priIndx.count(); ++i) {
       
   557             const QString fn = d->priIndx.fieldName(i);
       
   558             if (contains(fn))
       
   559                 d->priIndx.setValue(i, QSqlRecord::value(fn));
       
   560         }
       
   561     }
       
   562     return d->priIndx;
       
   563 }
       
   564 
       
   565 /*!
       
   566     Sets the primary index associated with the cursor to the index \a
       
   567     idx. Note that this index must contain a field or set of fields
       
   568     which identify a unique record within the underlying database
       
   569     table or view so that update() and del() will execute as expected.
       
   570 
       
   571     \sa update() del()
       
   572 */
       
   573 
       
   574 void Q3SqlCursor::setPrimaryIndex(const QSqlIndex& idx)
       
   575 {
       
   576     d->priIndx = idx;
       
   577 }
       
   578 
       
   579 
       
   580 /*!
       
   581     Returns an index composed of \a fieldNames, all in ASCending
       
   582     order. Note that all field names must exist in the cursor,
       
   583     otherwise an empty index is returned.
       
   584 
       
   585     \sa QSqlIndex
       
   586 */
       
   587 
       
   588 QSqlIndex Q3SqlCursor::index(const QStringList& fieldNames) const
       
   589 {
       
   590     QSqlIndex idx;
       
   591     for (QStringList::ConstIterator it = fieldNames.begin(); it != fieldNames.end(); ++it) {
       
   592         QSqlField f = field((*it));
       
   593         if (!f.isValid()) { /* all fields must exist */
       
   594             idx.clear();
       
   595             break;
       
   596         }
       
   597         idx.append(f);
       
   598     }
       
   599     return idx;
       
   600 }
       
   601 
       
   602 /*!
       
   603     \overload
       
   604 
       
   605     Returns an index based on \a fieldName.
       
   606 */
       
   607 
       
   608 QSqlIndex Q3SqlCursor::index(const QString& fieldName) const
       
   609 {
       
   610     QStringList fl(fieldName);
       
   611     return index(fl);
       
   612 }
       
   613 
       
   614 /*!
       
   615     Selects all fields in the cursor from the database matching the
       
   616     filter criteria \a filter. The data is returned in the order
       
   617     specified by the index \a sort. Returns true if the data was
       
   618     successfully selected; otherwise returns false.
       
   619 
       
   620     The \a filter is a string containing a SQL \c WHERE clause but
       
   621     without the 'WHERE' keyword. The cursor is initially positioned at
       
   622     an invalid row after this function is called. To move to a valid
       
   623     row, use seek(), first(), last(), previous() or next().
       
   624 
       
   625     Example:
       
   626     \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 2
       
   627 
       
   628     The filter will apply to any subsequent select() calls that do not
       
   629     explicitly specify another filter. Similarly the sort will apply
       
   630     to any subsequent select() calls that do not explicitly specify
       
   631     another sort.
       
   632 
       
   633     \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 3
       
   634 
       
   635 */
       
   636 
       
   637 bool Q3SqlCursor::select(const QString & filter, const QSqlIndex & sort)
       
   638 {
       
   639     QString fieldList(toString(d->nm));
       
   640     if (fieldList.isEmpty())
       
   641         return false;
       
   642     QString str(QLatin1String("select ") + fieldList);
       
   643     str += QLatin1String(" from ") + d->nm;
       
   644     if (!filter.isEmpty()) {
       
   645         d->ftr = filter;
       
   646         str += QLatin1String(" where ") + filter;
       
   647     } else
       
   648         d->ftr.clear();
       
   649     if (sort.count() > 0)
       
   650         str += QLatin1String(" order by ") + sort.toString(d->nm);
       
   651     d->srt = sort;
       
   652     return exec(str);
       
   653 }
       
   654 
       
   655 /*!
       
   656     \overload
       
   657 
       
   658     Selects all fields in the cursor from the database. The rows are
       
   659     returned in the order specified by the last call to setSort() or
       
   660     the last call to select() that specified a sort, whichever is the
       
   661     most recent. If there is no current sort, the order in which the
       
   662     rows are returned is undefined. The records are filtered according
       
   663     to the filter specified by the last call to setFilter() or the
       
   664     last call to select() that specified a filter, whichever is the
       
   665     most recent. If there is no current filter, all records are
       
   666     returned. The cursor is initially positioned at an invalid row. To
       
   667     move to a valid row, use seek(), first(), last(), previous() or
       
   668     next().
       
   669 
       
   670     \sa setSort() setFilter()
       
   671 */
       
   672 
       
   673 bool Q3SqlCursor::select()
       
   674 {
       
   675     return select(filter(), sort());
       
   676 }
       
   677 
       
   678 /*!
       
   679     \overload
       
   680 
       
   681     Selects all fields in the cursor from the database. The data is
       
   682     returned in the order specified by the index \a sort. The records
       
   683     are filtered according to the filter specified by the last call to
       
   684     setFilter() or the last call to select() that specified a filter,
       
   685     whichever is the most recent. The cursor is initially positioned
       
   686     at an invalid row. To move to a valid row, use seek(), first(),
       
   687     last(), previous() or next().
       
   688 */
       
   689 
       
   690 bool Q3SqlCursor::select(const QSqlIndex& sort)
       
   691 {
       
   692     return select(filter(), sort);
       
   693 }
       
   694 
       
   695 /*!
       
   696     \overload
       
   697 
       
   698     Selects all fields in the cursor matching the filter index \a
       
   699     filter. The data is returned in the order specified by the index
       
   700     \a sort. The \a filter index works by constructing a WHERE clause
       
   701     using the names of the fields from the \a filter and their values
       
   702     from the current cursor record. The cursor is initially positioned
       
   703     at an invalid row. To move to a valid row, use seek(), first(),
       
   704     last(), previous() or next(). This function is useful, for example,
       
   705     for retrieving data based upon a table's primary index:
       
   706 
       
   707     \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 4
       
   708 
       
   709     In this example the QSqlIndex, pk, is used for two different
       
   710     purposes. When used as the filter (first) argument, the field
       
   711     names it contains are used to construct the WHERE clause, each set
       
   712     to the current cursor value, \c{WHERE id=10}, in this case. When
       
   713     used as the sort (second) argument the field names it contains are
       
   714     used for the ORDER BY clause, \c{ORDER BY id} in this example.
       
   715 */
       
   716 
       
   717 bool Q3SqlCursor::select(const QSqlIndex & filter, const QSqlIndex & sort)
       
   718 {
       
   719     return select(toString(filter, this, d->nm, QString(QLatin1Char('=')), QLatin1String("and")), sort);
       
   720 }
       
   721 
       
   722 /*!
       
   723     Sets the cursor mode to \a mode. This value can be an OR'ed
       
   724     combination of \l Q3SqlCursor::Mode values. The default mode for a
       
   725     cursor is Q3SqlCursor::Writable.
       
   726 
       
   727     \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 5
       
   728 */
       
   729 
       
   730 void Q3SqlCursor::setMode(int mode)
       
   731 {
       
   732     d->md = mode;
       
   733 }
       
   734 
       
   735 /*!
       
   736     Returns the current cursor mode.
       
   737 
       
   738     \sa setMode()
       
   739 */
       
   740 
       
   741 int Q3SqlCursor::mode() const
       
   742 {
       
   743     return d->md;
       
   744 }
       
   745 
       
   746 /*!
       
   747     Sets field \a name to \a calculated. If the field \a name does not
       
   748     exist, nothing happens. The value of a calculated field is set by
       
   749     the calculateField() virtual function which you must reimplement
       
   750     (or the field value will be an invalid QVariant). Calculated
       
   751     fields do not appear in generated SQL statements sent to the
       
   752     database.
       
   753 
       
   754     \sa calculateField()
       
   755 */
       
   756 
       
   757 void Q3SqlCursor::setCalculated(const QString& name, bool calculated)
       
   758 {
       
   759     int pos = indexOf(name);
       
   760     if (pos < 0)
       
   761         return;
       
   762     d->infoBuffer[pos].setCalculated(calculated);
       
   763     if (calculated)
       
   764         setGenerated(pos, false);
       
   765 }
       
   766 
       
   767 /*!
       
   768     Returns true if the field \a name exists and is calculated;
       
   769     otherwise returns false.
       
   770 
       
   771     \sa setCalculated()
       
   772 */
       
   773 
       
   774 bool Q3SqlCursor::isCalculated(const QString& name) const
       
   775 {
       
   776     int pos = indexOf(name);
       
   777     if (pos < 0)
       
   778         return false;
       
   779     return d->infoBuffer[pos].isCalculated();
       
   780 }
       
   781 
       
   782 /*!
       
   783     Sets field \a{name}'s trimmed status to \a trim. If the field \a
       
   784     name does not exist, nothing happens.
       
   785 
       
   786     When a trimmed field of type string is read from the
       
   787     database any trailing (right-most) spaces are removed.
       
   788 
       
   789     \sa isTrimmed() QVariant
       
   790 */
       
   791 
       
   792 void Q3SqlCursor::setTrimmed(const QString& name, bool trim)
       
   793 {
       
   794     int pos = indexOf(name);
       
   795     if (pos < 0)
       
   796         return;
       
   797     d->infoBuffer[pos].setTrim(trim);
       
   798 }
       
   799 
       
   800 /*!
       
   801     Returns true if the field \a name exists and is trimmed; otherwise
       
   802     returns false.
       
   803 
       
   804     When a trimmed field of type string or cstring is read from the
       
   805     database any trailing (right-most) spaces are removed.
       
   806 
       
   807     \sa setTrimmed()
       
   808 */
       
   809 
       
   810 bool Q3SqlCursor::isTrimmed(const QString& name) const
       
   811 {
       
   812     int pos = indexOf(name);
       
   813     if (pos < 0)
       
   814         return false;
       
   815     return d->infoBuffer[pos].isTrim();
       
   816 }
       
   817 
       
   818 /*!
       
   819     Returns true if the cursor is read-only; otherwise returns false.
       
   820     The default is false. Read-only cursors cannot be edited using
       
   821     insert(), update() or del().
       
   822 
       
   823     \sa setMode()
       
   824 */
       
   825 
       
   826 bool Q3SqlCursor::isReadOnly() const
       
   827 {
       
   828     return d->md == 0;
       
   829 }
       
   830 
       
   831 /*!
       
   832     Returns true if the cursor will perform inserts; otherwise returns
       
   833     false.
       
   834 
       
   835     \sa setMode()
       
   836 */
       
   837 
       
   838 bool Q3SqlCursor::canInsert() const
       
   839 {
       
   840     return ((d->md & Insert) == Insert) ;
       
   841 }
       
   842 
       
   843 
       
   844 /*!
       
   845     Returns true if the cursor will perform updates; otherwise returns
       
   846     false.
       
   847 
       
   848     \sa setMode()
       
   849 */
       
   850 
       
   851 bool Q3SqlCursor::canUpdate() const
       
   852 {
       
   853     return ((d->md & Update) == Update) ;
       
   854 }
       
   855 
       
   856 /*!
       
   857     Returns true if the cursor will perform deletes; otherwise returns
       
   858     false.
       
   859 
       
   860     \sa setMode()
       
   861 */
       
   862 
       
   863 bool Q3SqlCursor::canDelete() const
       
   864 {
       
   865     return ((d->md & Delete) == Delete) ;
       
   866 }
       
   867 
       
   868 /*!
       
   869     \overload
       
   870 
       
   871     Returns a formatted string composed of the \a prefix (e.g. table
       
   872     or view name), ".", the \a field name, the \a fieldSep and the
       
   873     field value. If the \a prefix is empty then the string will begin
       
   874     with the \a field name. This function is useful for generating SQL
       
   875     statements.
       
   876 */
       
   877 
       
   878 QString Q3SqlCursor::toString(const QString& prefix, QSqlField* field, const QString& fieldSep) const
       
   879 {
       
   880     QString f;
       
   881     if (field && driver()) {
       
   882         f = (prefix.length() > 0 ? prefix + QLatin1Char('.') : QString()) + driver()->escapeIdentifier(field->name(), QSqlDriver::FieldName);
       
   883         f += QLatin1Char(' ') + fieldSep + QLatin1Char(' ');
       
   884         if (field->isNull()) {
       
   885             f += QLatin1String("NULL");
       
   886         } else {
       
   887             f += driver()->formatValue(field);
       
   888         }
       
   889     }
       
   890     return f;
       
   891 }
       
   892 
       
   893 /*!
       
   894     Returns a formatted string composed of all the fields in \a rec.
       
   895     Each field is composed of the \a prefix (e.g. table or view name),
       
   896     ".", the field name, the \a fieldSep and the field value. If the
       
   897     \a prefix is empty then each field will begin with the field name.
       
   898     The fields are then joined together separated by \a sep. Fields
       
   899     where isGenerated() returns false are not included. This function
       
   900     is useful for generating SQL statements.
       
   901 */
       
   902 
       
   903 QString Q3SqlCursor::toString(QSqlRecord* rec, const QString& prefix, const QString& fieldSep,
       
   904                               const QString& sep) const
       
   905 {
       
   906     static QString blank(QLatin1Char(' '));
       
   907     QString filter;
       
   908     bool separator = false;
       
   909     for (int j = 0; j < count(); ++j) {
       
   910         QSqlField f = rec->field(j);
       
   911         if (rec->isGenerated(j)) {
       
   912             if (separator)
       
   913                 filter += sep + blank;
       
   914             filter += toString(prefix, &f, fieldSep);
       
   915             filter += blank;
       
   916             separator = true;
       
   917         }
       
   918     }
       
   919     return filter;
       
   920 }
       
   921 
       
   922 /*!
       
   923     \overload
       
   924 
       
   925     Returns a formatted string composed of all the fields in the index
       
   926     \a i. Each field is composed of the \a prefix (e.g. table or view
       
   927     name), ".", the field name, the \a fieldSep and the field value.
       
   928     If the \a prefix is empty then each field will begin with the field
       
   929     name. The field values are taken from \a rec. The fields are then
       
   930     joined together separated by \a sep. Fields where isGenerated()
       
   931     returns false are ignored. This function is useful for generating
       
   932     SQL statements.
       
   933 */
       
   934 
       
   935 QString Q3SqlCursor::toString(const QSqlIndex& i, QSqlRecord* rec, const QString& prefix,
       
   936                                 const QString& fieldSep, const QString& sep) const
       
   937 {
       
   938     QString filter;
       
   939     bool separator = false;
       
   940     for(int j = 0; j < i.count(); ++j){
       
   941         if (rec->isGenerated(j)) {
       
   942             if(separator) {
       
   943                 filter += QLatin1Char(' ') + sep + QLatin1Char(' ') ;
       
   944             }
       
   945             QString fn = i.fieldName(j);
       
   946             QSqlField f = rec->field(fn);
       
   947             filter += toString(prefix, &f, fieldSep);
       
   948             separator = true;
       
   949         }
       
   950     }
       
   951     return filter;
       
   952 }
       
   953 
       
   954 /*!
       
   955     Inserts the current contents of the cursor's edit record buffer
       
   956     into the database, if the cursor allows inserts. Returns the
       
   957     number of rows affected by the insert. For error information, use
       
   958     lastError().
       
   959 
       
   960     If \a invalidate is true (the default), the cursor will no longer
       
   961     be positioned on a valid record and can no longer be navigated. A
       
   962     new select() call must be made before navigating to a valid
       
   963     record.
       
   964 
       
   965     \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 6
       
   966 
       
   967     In the above example, a cursor is created on the 'prices' table
       
   968     and a pointer to the insert buffer is acquired using primeInsert().
       
   969     Each field's value is set to the desired value and then insert()
       
   970     is called to insert the data into the database. Remember: all edit
       
   971     operations (insert(), update() and delete()) operate on the
       
   972     contents of the cursor edit buffer and not on the contents of the
       
   973     cursor itself.
       
   974 
       
   975     \sa setMode() lastError()
       
   976 */
       
   977 
       
   978 int Q3SqlCursor::insert(bool invalidate)
       
   979 {
       
   980     if ((d->md & Insert) != Insert || !driver())
       
   981         return false;
       
   982     int k = d->editBuffer.count();
       
   983     if (k == 0)
       
   984         return 0;
       
   985 
       
   986     QString fList;
       
   987     QString vList;
       
   988     bool comma = false;
       
   989     // use a prepared query if the driver supports it
       
   990     if (driver()->hasFeature(QSqlDriver::PreparedQueries)) {
       
   991         int cnt = 0;
       
   992         bool oraStyle = driver()->hasFeature(QSqlDriver::NamedPlaceholders);
       
   993         for(int j = 0; j < k; ++j) {
       
   994             QSqlField f = d->editBuffer.field(j);
       
   995             if (d->editBuffer.isGenerated(j)) {
       
   996                 if (comma) {
       
   997                     fList += QLatin1Char(',');
       
   998                     vList += QLatin1Char(',');
       
   999                 }
       
  1000                 fList += driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName);
       
  1001                 vList += (oraStyle == true) ? QLatin1String(":f") + QString::number(cnt) : QString(QLatin1Char('?'));
       
  1002                 cnt++;
       
  1003                 comma = true;
       
  1004             }
       
  1005         }
       
  1006         if (!comma) {
       
  1007             return 0;
       
  1008         }
       
  1009         QString str;
       
  1010         str.append(QLatin1String("insert into ")).append(name())
       
  1011            .append(QLatin1String(" (")).append(fList)
       
  1012            .append(QLatin1String(") values (")).append(vList). append(QLatin1Char(')'));
       
  1013 
       
  1014         return applyPrepared(str, invalidate);
       
  1015     } else {
       
  1016         for(int j = 0; j < k; ++j) {
       
  1017             QSqlField f = d->editBuffer.field(j);
       
  1018             if (d->editBuffer.isGenerated(j)) {
       
  1019                 if (comma) {
       
  1020                     fList += QLatin1Char(',');
       
  1021                     vList += QLatin1Char(',');
       
  1022                 }
       
  1023                 fList += driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName);
       
  1024                 vList += driver()->formatValue(&f);
       
  1025                 comma = true;
       
  1026             }
       
  1027         }
       
  1028 
       
  1029         if (!comma) {
       
  1030             // no valid fields found
       
  1031             return 0;
       
  1032         }
       
  1033         QString str;
       
  1034         str.append(QLatin1String("insert into ")).append(name()).append(QLatin1String(" ("))
       
  1035            .append(fList).append(QLatin1String(") values (")).append(vList). append (QLatin1String(")"));
       
  1036         return apply(str, invalidate);
       
  1037     }
       
  1038 }
       
  1039 
       
  1040 /*!
       
  1041     Returns the current internal edit buffer. If \a copy is true (the
       
  1042     default is false), the current cursor field values are first
       
  1043     copied into the edit buffer. The edit buffer is valid as long as
       
  1044     the cursor remains valid. The cursor retains ownership of the
       
  1045     returned pointer, so it must not be deleted or modified.
       
  1046 
       
  1047     \sa primeInsert(), primeUpdate() primeDelete()
       
  1048 */
       
  1049 
       
  1050 QSqlRecord* Q3SqlCursor::editBuffer(bool copy)
       
  1051 {
       
  1052     sync();
       
  1053     if (copy) {
       
  1054         for(int i = 0; i < d->editBuffer.count(); i++) {
       
  1055             if (QSqlRecord::isNull(i)) {
       
  1056                 d->editBuffer.setNull(i);
       
  1057             } else {
       
  1058                 d->editBuffer.setValue(i, value(i));
       
  1059             }
       
  1060         }
       
  1061     }
       
  1062     return &d->editBuffer;
       
  1063 }
       
  1064 
       
  1065 /*!
       
  1066     This function primes the edit buffer's field values for update and
       
  1067     returns the edit buffer. The default implementation copies the
       
  1068     field values from the current cursor record into the edit buffer
       
  1069     (therefore, this function is equivalent to calling editBuffer(
       
  1070     true)). The cursor retains ownership of the returned pointer, so
       
  1071     it must not be deleted or modified.
       
  1072 
       
  1073     \sa editBuffer() update()
       
  1074 */
       
  1075 
       
  1076 QSqlRecord* Q3SqlCursor::primeUpdate()
       
  1077 {
       
  1078     // memorize the primary keys as they were before the user changed the values in editBuffer
       
  1079     QSqlRecord* buf = editBuffer(true);
       
  1080     QSqlIndex idx = primaryIndex(false);
       
  1081     if (!idx.isEmpty())
       
  1082         d->editIndex = toString(idx, buf, d->nm, QString(QLatin1Char('=')), QLatin1String("and"));
       
  1083     else
       
  1084         d->editIndex = qWhereClause(buf, d->nm, QLatin1String("and"), driver());
       
  1085     return buf;
       
  1086 }
       
  1087 
       
  1088 /*!
       
  1089     This function primes the edit buffer's field values for delete and
       
  1090     returns the edit buffer. The default implementation copies the
       
  1091     field values from the current cursor record into the edit buffer
       
  1092     (therefore, this function is equivalent to calling editBuffer(
       
  1093     true)). The cursor retains ownership of the returned pointer, so
       
  1094     it must not be deleted or modified.
       
  1095 
       
  1096     \sa editBuffer() del()
       
  1097 */
       
  1098 
       
  1099 QSqlRecord* Q3SqlCursor::primeDelete()
       
  1100 {
       
  1101     return editBuffer(true);
       
  1102 }
       
  1103 
       
  1104 /*!
       
  1105     This function primes the edit buffer's field values for insert and
       
  1106     returns the edit buffer. The default implementation clears all
       
  1107     field values in the edit buffer. The cursor retains ownership of
       
  1108     the returned pointer, so it must not be deleted or modified.
       
  1109 
       
  1110     \sa editBuffer() insert()
       
  1111 */
       
  1112 
       
  1113 QSqlRecord* Q3SqlCursor::primeInsert()
       
  1114 {
       
  1115     d->editBuffer.clearValues();
       
  1116     return &d->editBuffer;
       
  1117 }
       
  1118 
       
  1119 
       
  1120 /*!
       
  1121     Updates the database with the current contents of the edit buffer.
       
  1122     Returns the number of records which were updated.
       
  1123     For error information, use lastError().
       
  1124 
       
  1125     Only records which meet the filter criteria specified by the
       
  1126     cursor's primary index are updated. If the cursor does not contain
       
  1127     a primary index, no update is performed and 0 is returned.
       
  1128 
       
  1129     If \a invalidate is true (the default), the current cursor can no
       
  1130     longer be navigated. A new select() call must be made before you
       
  1131     can move to a valid record. For example:
       
  1132 
       
  1133     \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 7
       
  1134 
       
  1135     In the above example, a cursor is created on the 'prices' table
       
  1136     and is positioned on the record to be updated. Then a pointer to
       
  1137     the cursor's edit buffer is acquired using primeUpdate(). A new
       
  1138     value is calculated and placed into the edit buffer with the
       
  1139     setValue() call. Finally, an update() call is made on the cursor
       
  1140     which uses the tables's primary index to update the record in the
       
  1141     database with the contents of the cursor's edit buffer. Remember:
       
  1142     all edit operations (insert(), update() and delete()) operate on
       
  1143     the contents of the cursor edit buffer and not on the contents of
       
  1144     the cursor itself.
       
  1145 
       
  1146     Note that if the primary index does not uniquely distinguish
       
  1147     records the database may be changed into an inconsistent state.
       
  1148 
       
  1149     \sa setMode() lastError()
       
  1150 */
       
  1151 
       
  1152 int Q3SqlCursor::update(bool invalidate)
       
  1153 {
       
  1154     if (d->editIndex.isEmpty())
       
  1155         return 0;
       
  1156     return update(d->editIndex, invalidate);
       
  1157 }
       
  1158 
       
  1159 /*!
       
  1160     \overload
       
  1161 
       
  1162     Updates the database with the current contents of the cursor edit
       
  1163     buffer using the specified \a filter. Returns the number of
       
  1164     records which were updated.
       
  1165     For error information, use lastError().
       
  1166 
       
  1167     Only records which meet the filter criteria are updated, otherwise
       
  1168     all records in the table are updated.
       
  1169 
       
  1170     If \a invalidate is true (the default), the cursor can no longer
       
  1171     be navigated. A new select() call must be made before you can move
       
  1172     to a valid record.
       
  1173 
       
  1174     \sa primeUpdate() setMode() lastError()
       
  1175 */
       
  1176 
       
  1177 int Q3SqlCursor::update(const QString & filter, bool invalidate)
       
  1178 {
       
  1179     if ((d->md & Update) != Update) {
       
  1180         return false;
       
  1181     }
       
  1182     int k = count();
       
  1183     if (k == 0) {
       
  1184         return 0;
       
  1185     }
       
  1186     
       
  1187     // use a prepared query if the driver supports it
       
  1188     if (driver()->hasFeature(QSqlDriver::PreparedQueries)) {
       
  1189         QString fList;
       
  1190         bool comma = false;
       
  1191         int cnt = 0;
       
  1192         bool oraStyle = driver()->hasFeature(QSqlDriver::NamedPlaceholders);
       
  1193         for(int j = 0; j < k; ++j) {
       
  1194             QSqlField f = d->editBuffer.field(j);
       
  1195             if (d->editBuffer.isGenerated(j)) {
       
  1196                 if (comma) {
       
  1197                     fList += QLatin1Char(',');
       
  1198                 }
       
  1199                 fList += f.name() + QLatin1String(" = ") + (oraStyle == true ? QLatin1String(":f") + QString::number(cnt) : QString(QLatin1Char('?')));
       
  1200                 cnt++;
       
  1201                 comma = true;
       
  1202             }
       
  1203         }
       
  1204         if (!comma) {
       
  1205             return 0;
       
  1206         }
       
  1207         QString str(QLatin1String("update ") + name() + QLatin1String(" set ") + fList);
       
  1208         if (filter.length()) {
       
  1209             str+= QLatin1String(" where ") + filter;
       
  1210         }
       
  1211         return applyPrepared(str, invalidate);
       
  1212     } else {
       
  1213         QString str = QLatin1String("update ") + name();
       
  1214         str += QLatin1String(" set ") + toString(&d->editBuffer, QString(), QString(QLatin1Char('=')), QString(QLatin1Char(',')));
       
  1215         if (filter.length()) {
       
  1216             str+= QLatin1String(" where ") + filter;
       
  1217         }
       
  1218         return apply(str, invalidate);
       
  1219     }
       
  1220 }
       
  1221 
       
  1222 /*!
       
  1223     Deletes a record from the database using the cursor's primary
       
  1224     index and the contents of the cursor edit buffer. Returns the
       
  1225     number of records which were deleted.
       
  1226     For error information, use lastError().
       
  1227 
       
  1228     Only records which meet the filter criteria specified by the
       
  1229     cursor's primary index are deleted. If the cursor does not contain
       
  1230     a primary index, no delete is performed and 0 is returned. If \a
       
  1231     invalidate is true (the default), the current cursor can no longer
       
  1232     be navigated. A new select() call must be made before you can move
       
  1233     to a valid record. For example:
       
  1234 
       
  1235     \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 8
       
  1236 
       
  1237     In the above example, a cursor is created on the 'prices' table
       
  1238     and positioned to the record to be deleted. First primeDelete() is
       
  1239     called to populate the edit buffer with the current cursor values,
       
  1240     e.g. with an id of 999, and then del() is called to actually
       
  1241     delete the record from the database. Remember: all edit operations
       
  1242     (insert(), update() and delete()) operate on the contents of the
       
  1243     cursor edit buffer and not on the contents of the cursor itself.
       
  1244 
       
  1245     \sa primeDelete() setMode() lastError()
       
  1246 */
       
  1247 
       
  1248 int Q3SqlCursor::del(bool invalidate)
       
  1249 {
       
  1250     QSqlIndex idx = primaryIndex(false);
       
  1251     if (idx.isEmpty())
       
  1252         return del(qWhereClause(&d->editBuffer, d->nm, QLatin1String("and"), driver()), invalidate);
       
  1253     return del(toString(primaryIndex(), &d->editBuffer, d->nm, QString(QLatin1Char('=')), QLatin1String("and")), invalidate);
       
  1254 }
       
  1255 
       
  1256 /*!
       
  1257     \overload
       
  1258 
       
  1259     Deletes the current cursor record from the database using the
       
  1260     filter \a filter. Only records which meet the filter criteria are
       
  1261     deleted. Returns the number of records which were deleted. If \a
       
  1262     invalidate is true (the default), the current cursor can no longer
       
  1263     be navigated. A new select() call must be made before you can move
       
  1264     to a valid record. For error information, use lastError().
       
  1265 
       
  1266     The \a filter is an SQL \c WHERE clause, e.g. \c{id=500}.
       
  1267 
       
  1268     \sa setMode() lastError()
       
  1269 */
       
  1270 
       
  1271 int Q3SqlCursor::del(const QString & filter, bool invalidate)
       
  1272 {
       
  1273     if ((d->md & Delete) != Delete)
       
  1274         return 0;
       
  1275     int k = count();
       
  1276     if(k == 0) return 0;
       
  1277     QString str = QLatin1String("delete from ") + name();
       
  1278     if (filter.length())
       
  1279         str+= QLatin1String(" where ") + filter;
       
  1280     return apply(str, invalidate);
       
  1281 }
       
  1282 
       
  1283 /*
       
  1284   \internal
       
  1285 */
       
  1286 
       
  1287 int Q3SqlCursor::apply(const QString& q, bool invalidate)
       
  1288 {
       
  1289     int ar = 0;
       
  1290     if (invalidate) {
       
  1291         if (exec(q))
       
  1292             ar = numRowsAffected();
       
  1293     } else if (driver()) {
       
  1294         QSqlQuery* sql = d->query();
       
  1295         if (sql && sql->exec(q))
       
  1296             ar = sql->numRowsAffected();
       
  1297     }
       
  1298     return ar;
       
  1299 }
       
  1300 
       
  1301 /*
       
  1302   \internal
       
  1303 */
       
  1304 
       
  1305 int Q3SqlCursor::applyPrepared(const QString& q, bool invalidate)
       
  1306 {
       
  1307     int ar = 0;
       
  1308     QSqlQuery* sql = 0;
       
  1309 
       
  1310     if (invalidate) {
       
  1311         sql = (QSqlQuery*)this;
       
  1312         d->lastAt = QSql::BeforeFirst;
       
  1313     } else {
       
  1314         sql = d->query();
       
  1315     }
       
  1316     if (!sql)
       
  1317         return 0;
       
  1318 
       
  1319     if (invalidate || sql->lastQuery() != q) {
       
  1320         if (!sql->prepare(q))
       
  1321             return 0;
       
  1322     }
       
  1323 
       
  1324     int cnt = 0;
       
  1325     int fieldCount = (int)count();
       
  1326     for (int j = 0; j < fieldCount; ++j) {
       
  1327         const QSqlField f = d->editBuffer.field(j);
       
  1328         if (d->editBuffer.isGenerated(j)) {
       
  1329             if (f.type() == QVariant::ByteArray)
       
  1330                 sql->bindValue(cnt, f.value(), QSql::In | QSql::Binary);
       
  1331             else
       
  1332                 sql->bindValue(cnt, f.value());
       
  1333             cnt++;
       
  1334         }
       
  1335     }
       
  1336     if (sql->exec()) {
       
  1337         ar = sql->numRowsAffected();
       
  1338     }
       
  1339     return ar;
       
  1340 }
       
  1341 
       
  1342 /*!
       
  1343   Executes the SQL query \a sql. Returns true of the cursor is
       
  1344   active, otherwise returns false.
       
  1345 */
       
  1346 bool Q3SqlCursor::exec(const QString & sql)
       
  1347 {
       
  1348     d->lastAt = QSql::BeforeFirst;
       
  1349     QSqlQuery::exec(sql);
       
  1350     return isActive();
       
  1351 }
       
  1352 
       
  1353 /*!
       
  1354     Protected virtual function which is called whenever a field needs
       
  1355     to be calculated. If calculated fields are being used, derived
       
  1356     classes must reimplement this function and return the appropriate
       
  1357     value for field \a name. The default implementation returns an
       
  1358     invalid QVariant.
       
  1359 
       
  1360     \sa setCalculated()
       
  1361 */
       
  1362 
       
  1363 QVariant Q3SqlCursor::calculateField(const QString&)
       
  1364 {
       
  1365     return QVariant();
       
  1366 }
       
  1367 
       
  1368 /*! \internal
       
  1369    Ensure fieldlist is synced with query.
       
  1370 
       
  1371 */
       
  1372 
       
  1373 static QString qTrim(const QString& s)
       
  1374 {
       
  1375     QString result = s;
       
  1376     int end = result.length() - 1;
       
  1377     while (end >= 0 && result[end].isSpace()) // skip white space from end
       
  1378         end--;
       
  1379     result.truncate(end + 1);
       
  1380     return result;
       
  1381 }
       
  1382 
       
  1383 /*! \internal
       
  1384  */
       
  1385 
       
  1386 void Q3SqlCursor::sync()
       
  1387 {
       
  1388     if (isActive() && isValid() && d->lastAt != at()) {
       
  1389         d->lastAt = at();
       
  1390         int i = 0;
       
  1391         int j = 0;
       
  1392         bool haveCalculatedFields = false;
       
  1393         for (; i < count(); ++i) {
       
  1394             if (!haveCalculatedFields && d->infoBuffer[i].isCalculated()) {
       
  1395                 haveCalculatedFields = true;
       
  1396             }
       
  1397             if (QSqlRecord::isGenerated(i)) {
       
  1398                 QVariant v = QSqlQuery::value(j);
       
  1399                 if ((v.type() == QVariant::String) &&
       
  1400                         d->infoBuffer[i].isTrim()) {
       
  1401                     v = qTrim(v.toString());
       
  1402                 }
       
  1403                 QSqlRecord::setValue(i, v);
       
  1404                 if (QSqlQuery::isNull(j))
       
  1405                     QSqlRecord::field(i).clear();
       
  1406                 j++;
       
  1407             }
       
  1408         }
       
  1409         if (haveCalculatedFields) {
       
  1410             for (i = 0; i < count(); ++i) {
       
  1411                 if (d->infoBuffer[i].isCalculated())
       
  1412                     QSqlRecord::setValue(i, calculateField(fieldName(i)));
       
  1413             }
       
  1414         }
       
  1415     }
       
  1416 }
       
  1417 
       
  1418 /*!
       
  1419     Returns the value of field number \a i.
       
  1420 */
       
  1421 
       
  1422 QVariant Q3SqlCursor::value(int i) const
       
  1423 {
       
  1424     const_cast<Q3SqlCursor *>(this)->sync();
       
  1425     return QSqlRecord::value(i);
       
  1426 }
       
  1427 
       
  1428 /*! \internal
       
  1429   cursors should be filled with Q3SqlFieldInfos...
       
  1430 */
       
  1431 void Q3SqlCursor::append(const QSqlField& field)
       
  1432 {
       
  1433     append(Q3SqlFieldInfo(field));
       
  1434 }
       
  1435 
       
  1436 /*!
       
  1437     Returns true if the field \a i is NULL or if there is no field at
       
  1438     position \a i; otherwise returns false.
       
  1439 
       
  1440     This is the same as calling QSqlRecord::isNull(\a i)
       
  1441 */
       
  1442 bool Q3SqlCursor::isNull(int i) const
       
  1443 {
       
  1444     const_cast<Q3SqlCursor *>(this)->sync();
       
  1445     return QSqlRecord::isNull(i);
       
  1446 }
       
  1447 /*!
       
  1448     \overload
       
  1449 
       
  1450     Returns true if the field called \a name is NULL or if there is no
       
  1451     field called \a name; otherwise returns false.
       
  1452 
       
  1453     This is the same as calling QSqlRecord::isNull(\a name)
       
  1454 */
       
  1455 bool Q3SqlCursor::isNull(const QString& name) const
       
  1456 {
       
  1457     const_cast<Q3SqlCursor *>(this)->sync();
       
  1458     return QSqlRecord::isNull(name);
       
  1459 }
       
  1460 
       
  1461 /*! \internal */
       
  1462 void Q3SqlCursor::setValue(int i, const QVariant& val)
       
  1463 {
       
  1464     sync();
       
  1465 #ifdef QT_DEBUG
       
  1466     qDebug("Q3SqlCursor::setValue(): This will not affect actual database values. Use primeInsert(), primeUpdate() or primeDelete().");
       
  1467 #endif
       
  1468     QSqlRecord::setValue(i, val);
       
  1469 }
       
  1470 
       
  1471 /*! \internal */
       
  1472 bool Q3SqlCursor::seek(int i, bool relative)
       
  1473 {
       
  1474     bool res = QSqlQuery::seek(i, relative);
       
  1475     sync();
       
  1476     return res;
       
  1477 }
       
  1478 
       
  1479 /*! \internal */
       
  1480 bool Q3SqlCursor::next()
       
  1481 {
       
  1482     bool res = QSqlQuery::next();
       
  1483     sync();
       
  1484     return res;
       
  1485 }
       
  1486 
       
  1487 /*!
       
  1488     \fn Q3SqlCursor::previous()
       
  1489 
       
  1490     \internal
       
  1491 */
       
  1492 
       
  1493 /*! \internal */
       
  1494 bool Q3SqlCursor::prev()
       
  1495 {
       
  1496     bool res = QSqlQuery::previous();
       
  1497     sync();
       
  1498     return res;
       
  1499 }
       
  1500 
       
  1501 /*! \internal */
       
  1502 bool Q3SqlCursor::first()
       
  1503 {
       
  1504     bool res = QSqlQuery::first();
       
  1505     sync();
       
  1506     return res;
       
  1507 }
       
  1508 
       
  1509 /*! \internal */
       
  1510 bool Q3SqlCursor::last()
       
  1511 {
       
  1512     bool res = QSqlQuery::last();
       
  1513     sync();
       
  1514     return res;
       
  1515 }
       
  1516 
       
  1517 QT_END_NAMESPACE
       
  1518 
       
  1519 #endif