Update some documentation about what happens with select()/setQuery().
[qt:qt.git] / src / sql / models / qsqltablemodel.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 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 QtSql 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 "qsqltablemodel.h"
43
44 #include "qsqldriver.h"
45 #include "qsqlerror.h"
46 #include "qsqlfield.h"
47 #include "qsqlindex.h"
48 #include "qsqlquery.h"
49 #include "qsqlrecord.h"
50 #include "qsqlresult.h"
51
52 #include "qsqltablemodel_p.h"
53
54 #include <qdebug.h>
55
56 QT_BEGIN_NAMESPACE
57
58 /*! \internal
59     Populates our record with values.
60 */
61 QSqlRecord QSqlTableModelPrivate::record(const QVector<QVariant> &values) const
62 {
63     QSqlRecord r = rec;
64     for (int i = 0; i < r.count() && i < values.count(); ++i)
65         r.setValue(i, values.at(i));
66     return r;
67 }
68
69 /*! \internal
70     Set a record for OnFieldChange and OnRowChange.
71 */
72 bool QSqlTableModelPrivate::setRecord(int row, const QSqlRecord &record)
73 {
74     Q_Q(QSqlTableModel);
75     bool isOk = true;
76
77     QSqlTableModel::EditStrategy oldStrategy = strategy;
78
79     // FieldChange strategy makes no sense when setting an entire row
80     if (strategy == QSqlTableModel::OnFieldChange)
81         strategy = QSqlTableModel::OnRowChange;
82     for (int i = 0; i < record.count(); ++i) {
83         int idx = nameToIndex(record.fieldName(i));
84         if (idx == -1)
85             continue;
86         QModelIndex cIndex = q->createIndex(row, idx);
87         QVariant value = record.value(i);
88         QVariant oldValue = q->data(cIndex);
89         if (oldValue.isNull() || oldValue != value)
90             isOk &= q->setData(cIndex, value, Qt::EditRole);
91     }
92     if (isOk && oldStrategy == QSqlTableModel::OnFieldChange)
93         q->submitAll();
94     strategy = oldStrategy;
95
96     return isOk;
97 }
98
99 int QSqlTableModelPrivate::nameToIndex(const QString &name) const
100 {
101     QString fieldname = name;
102     if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName))
103         fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName);
104     return rec.indexOf(fieldname);
105 }
106
107 void QSqlTableModelPrivate::initRecordAndPrimaryIndex()
108 {
109     rec = db.record(tableName);
110     primaryIndex = db.primaryIndex(tableName);
111 }
112
113 void QSqlTableModelPrivate::clear()
114 {
115     editIndex = -1;
116     sortColumn = -1;
117     sortOrder = Qt::AscendingOrder;
118     tableName.clear();
119     editQuery.clear();
120     editBuffer.clear();
121     cache.clear();
122     primaryIndex.clear();
123     rec.clear();
124     filter.clear();
125 }
126
127 void QSqlTableModelPrivate::revertInsertedRow()
128 {
129     Q_Q(QSqlTableModel);
130     if (insertIndex == -1)
131         return;
132
133     q->beginRemoveRows(QModelIndex(), insertIndex, insertIndex);
134     insertIndex = -1;
135     q->endRemoveRows();
136 }
137
138 void QSqlTableModelPrivate::clearEditBuffer()
139 {
140     editBuffer = rec;
141 }
142
143 void QSqlTableModelPrivate::clearCache()
144 {
145     cache.clear();
146 }
147
148 void QSqlTableModelPrivate::revertCachedRow(int row)
149 {
150     Q_Q(QSqlTableModel);
151     ModifiedRow r = cache.value(row);
152     switch (r.op) {
153     case QSqlTableModelPrivate::None:
154         Q_ASSERT_X(false, "QSqlTableModelPrivate::revertCachedRow()", "Invalid entry in cache map");
155         return;
156     case QSqlTableModelPrivate::Update:
157     case QSqlTableModelPrivate::Delete:
158         cache.remove(row);
159         emit q->dataChanged(q->createIndex(row, 0),
160                             q->createIndex(row, q->columnCount() - 1));
161         break;
162     case QSqlTableModelPrivate::Insert: {
163             QMap<int, QSqlTableModelPrivate::ModifiedRow>::Iterator it = cache.find(row);
164             if (it == cache.end())
165                 return;
166             q->beginRemoveRows(QModelIndex(), row, row);
167             it = cache.erase(it);
168             while (it != cache.end()) {
169                 int oldKey = it.key();
170                 const QSqlTableModelPrivate::ModifiedRow oldValue = it.value();
171                 cache.erase(it);
172                 it = cache.insert(oldKey - 1, oldValue);
173                 ++it;
174             }
175             q->endRemoveRows();
176         break; }
177     }
178 }
179
180 bool QSqlTableModelPrivate::exec(const QString &stmt, bool prepStatement,
181                                  const QSqlRecord &rec, const QSqlRecord &whereValues)
182 {
183     if (stmt.isEmpty())
184         return false;
185
186     // lazy initialization of editQuery
187     if (editQuery.driver() != db.driver())
188         editQuery = QSqlQuery(db);
189
190     // workaround for In-Process databases - remove all read locks
191     // from the table to make sure the editQuery succeeds
192     if (db.driver()->hasFeature(QSqlDriver::SimpleLocking))
193         const_cast<QSqlResult *>(query.result())->detachFromResultSet();
194
195     if (prepStatement) {
196         if (editQuery.lastQuery() != stmt) {
197             if (!editQuery.prepare(stmt)) {
198                 error = editQuery.lastError();
199                 return false;
200             }
201         }
202         int i;
203         for (i = 0; i < rec.count(); ++i) {
204             if (rec.isGenerated(i) && rec.value(i).type() != QVariant::Invalid)
205                 editQuery.addBindValue(rec.value(i));
206         }
207         for (i = 0; i < whereValues.count(); ++i) {
208             if (whereValues.isGenerated(i) && !whereValues.isNull(i))
209                 editQuery.addBindValue(whereValues.value(i));
210         }
211
212         if (!editQuery.exec()) {
213             error = editQuery.lastError();
214             return false;
215         }
216     } else {
217         if (!editQuery.exec(stmt)) {
218             error = editQuery.lastError();
219             return false;
220         }
221     }
222     return true;
223 }
224
225 QSqlRecord QSqlTableModelPrivate::primaryValues(int row)
226 {
227     QSqlRecord record;
228     if (!query.seek(row)) {
229         error = query.lastError();
230         return record;
231     }
232     if (primaryIndex.isEmpty()) {
233         record = rec;
234         for (int i = 0; i < record.count(); ++i)
235             record.setValue(i, query.value(i));
236     } else {
237         record = primaryIndex;
238         for (int i = 0; i < record.count(); ++i)
239             record.setValue(i, query.value(rec.indexOf(record.fieldName(i))));
240     }
241     return record;
242 }
243
244 /*!
245     \class QSqlTableModel
246     \brief The QSqlTableModel class provides an editable data model
247     for a single database table.
248
249     \ingroup database
250     \inmodule QtSql
251
252     QSqlTableModel is a high-level interface for reading and writing
253     database records from a single table. It is build on top of the
254     lower-level QSqlQuery and can be used to provide data to view
255     classes such as QTableView. For example:
256
257     \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 24
258
259     We set the SQL table's name and the edit strategy, then we set up
260     the labels displayed in the view header. The edit strategy
261     dictates when the changes done by the user in the view are
262     actually applied to the database. The possible values are \l
263     OnFieldChange, \l OnRowChange, and \l OnManualSubmit.
264
265     QSqlTableModel can also be used to access a database
266     programmatically, without binding it to a view:
267
268     \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 21
269
270     The code snippet above extracts the \c salary field from record 4 in
271     the result set of the query \c{SELECT * from employee}.
272
273     It is possible to set filters using setFilter(), or modify the
274     sort order using setSort(). At the end, you must call select() to
275     populate the model with data.
276
277     The \l{sql/tablemodel} example illustrates how to use
278     QSqlTableModel as the data source for a QTableView.
279
280     QSqlTableModel provides no direct support for foreign keys. Use
281     the QSqlRelationalTableModel and QSqlRelationalDelegate if you
282     want to resolve foreign keys.
283
284     \sa QSqlRelationalTableModel, QSqlQuery, {Model/View Programming},
285         {Table Model Example}, {Cached Table Example}
286 */
287
288 /*!
289     \fn QSqlTableModel::beforeDelete(int row)
290
291     This signal is emitted by deleteRowFromTable() before the \a row
292     is deleted from the currently active database table.
293 */
294
295 /*!
296     \fn void QSqlTableModel::primeInsert(int row, QSqlRecord &record)
297
298     This signal is emitted by insertRows(), when an insertion is
299     initiated in the given \a row of the currently active database
300     table. The \a record parameter can be written to (since it is a
301     reference), for example to populate some fields with default
302     values.
303 */
304
305 /*!
306     \fn QSqlTableModel::beforeInsert(QSqlRecord &record)
307
308     This signal is emitted by insertRowIntoTable() before a new row is
309     inserted into the currently active database table. The values that
310     are about to be inserted are stored in \a record and can be
311     modified before they will be inserted.
312 */
313
314 /*!
315     \fn QSqlTableModel::beforeUpdate(int row, QSqlRecord &record)
316
317     This signal is emitted by updateRowInTable() before the \a row is
318     updated in the currently active database table with the values
319     from \a record.
320
321     Note that only values that are marked as generated will be updated.
322     The generated flag can be set with \l QSqlRecord::setGenerated()
323     and checked with \l QSqlRecord::isGenerated().
324
325     \sa QSqlRecord::isGenerated()
326 */
327
328 /*!
329     Creates an empty QSqlTableModel and sets the parent to \a parent
330     and the database connection to \a db. If \a db is not valid, the
331     default database connection will be used.
332
333     The default edit strategy is \l OnRowChange.
334 */
335 QSqlTableModel::QSqlTableModel(QObject *parent, QSqlDatabase db)
336     : QSqlQueryModel(*new QSqlTableModelPrivate, parent)
337 {
338     Q_D(QSqlTableModel);
339     d->db = db.isValid() ? db : QSqlDatabase::database();
340 }
341
342 /*!  \internal
343 */
344 QSqlTableModel::QSqlTableModel(QSqlTableModelPrivate &dd, QObject *parent, QSqlDatabase db)
345     : QSqlQueryModel(dd, parent)
346 {
347     Q_D(QSqlTableModel);
348     d->db = db.isValid() ? db : QSqlDatabase::database();
349 }
350
351 /*!
352     Destroys the object and frees any allocated resources.
353 */
354 QSqlTableModel::~QSqlTableModel()
355 {
356 }
357
358 /*!
359     Sets the database table on which the model operates to \a
360     tableName. Does not select data from the table, but fetches its
361     field information.
362
363     To populate the model with the table's data, call select().
364
365     Error information can be retrieved with \l lastError().
366
367     \sa select(), setFilter(), lastError()
368 */
369 void QSqlTableModel::setTable(const QString &tableName)
370 {
371     Q_D(QSqlTableModel);
372     clear();
373     d->tableName = tableName;
374     d->initRecordAndPrimaryIndex();
375     d->initColOffsets(d->rec.count());
376
377     if (d->rec.count() == 0)
378         d->error = QSqlError(QLatin1String("Unable to find table ") + d->tableName, QString(),
379                              QSqlError::StatementError);
380 }
381
382 /*!
383     Returns the name of the currently selected table.
384 */
385 QString QSqlTableModel::tableName() const
386 {
387     Q_D(const QSqlTableModel);
388     return d->tableName;
389 }
390
391 /*!
392     Populates the model with data from the table that was set via setTable(), using the
393     specified filter and sort condition, and returns true if successful; otherwise
394     returns false.
395
396     \note Calling select() will revert any unsubmitted changes and remove any inserted columns.
397
398     \sa setTable(), setFilter(), selectStatement()
399 */
400 bool QSqlTableModel::select()
401 {
402     Q_D(QSqlTableModel);
403     QString query = selectStatement();
404     if (query.isEmpty())
405         return false;
406
407     revertAll();
408     QSqlQuery qu(query, d->db);
409     setQuery(qu);
410
411     if (!qu.isActive() || lastError().isValid()) {
412         // something went wrong - revert to non-select state
413         d->initRecordAndPrimaryIndex();
414         return false;
415     }
416     return true;
417 }
418
419 /*!
420     \reimp
421 */
422 QVariant QSqlTableModel::data(const QModelIndex &index, int role) const
423 {
424     Q_D(const QSqlTableModel);
425     if (!index.isValid() || (role != Qt::DisplayRole && role != Qt::EditRole))
426         return QVariant();
427
428     QModelIndex item = indexInQuery(index);
429
430     switch (d->strategy) {
431     case OnFieldChange:
432     case OnRowChange:
433         if (index.row() == d->insertIndex) {
434             QVariant val;
435             if (item.column() < 0 || item.column() >= d->rec.count())
436                 return val;
437             val = d->editBuffer.value(index.column());
438             if (val.type() == QVariant::Invalid)
439                 val = QVariant(d->rec.field(item.column()).type());
440             return val;
441         }
442         if (d->editIndex == item.row()) {
443             QVariant var = d->editBuffer.value(item.column());
444             if (var.isValid())
445                 return var;
446         }
447         break;
448     case OnManualSubmit: {
449         const QSqlTableModelPrivate::ModifiedRow row = d->cache.value(index.row());
450         const QVariant var = row.rec.value(item.column());
451         if (var.isValid() || row.op == QSqlTableModelPrivate::Insert)
452             return var;
453         break; }
454     }
455     return QSqlQueryModel::data(item, role);
456 }
457
458 /*!
459     \reimp
460 */
461 QVariant QSqlTableModel::headerData(int section, Qt::Orientation orientation, int role) const
462 {
463     Q_D(const QSqlTableModel);
464     if (orientation == Qt::Vertical && role == Qt::DisplayRole) {
465         switch (d->strategy) {
466         case OnFieldChange:
467         case OnRowChange:
468             if (d->insertIndex == section)
469                 return QLatin1String("*");
470             break;
471         case OnManualSubmit:
472             QSqlTableModelPrivate::Op op = d->cache.value(section).op;
473             if (op == QSqlTableModelPrivate::Insert)
474                 return QLatin1String("*");
475             else if (op == QSqlTableModelPrivate::Delete)
476                 return QLatin1String("!");
477             break;
478         }
479     }
480     return QSqlQueryModel::headerData(section, orientation, role);
481 }
482
483 /*!
484     Returns true if the value at the index \a index is dirty, otherwise false.
485     Dirty values are values that were modified in the model
486     but not yet written into the database.
487
488     If \a index is invalid or points to a non-existing row, false is returned.
489 */
490 bool QSqlTableModel::isDirty(const QModelIndex &index) const
491 {
492     Q_D(const QSqlTableModel);
493     if (!index.isValid())
494         return false;
495
496     switch (d->strategy) {
497         case OnFieldChange:
498             return false;
499         case OnRowChange:
500             return index.row() == d->editIndex && d->editBuffer.value(index.column()).isValid();
501         case OnManualSubmit: {
502             const QSqlTableModelPrivate::ModifiedRow row = d->cache.value(index.row());
503             return row.op == QSqlTableModelPrivate::Insert
504                    || row.op == QSqlTableModelPrivate::Delete
505                    || (row.op == QSqlTableModelPrivate::Update
506                        && row.rec.value(index.column()).isValid());
507         }
508     }
509     return false;
510 }
511
512 /*!
513     Sets the data for the item \a index for the role \a role to \a
514     value. Depending on the edit strategy, the value might be applied
515     to the database at once or cached in the model.
516
517     Returns true if the value could be set or false on error, for
518     example if \a index is out of bounds.
519
520     \sa editStrategy(), data(), submit(), submitAll(), revertRow()
521 */
522 bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
523 {
524     Q_D(QSqlTableModel);
525     if (role != Qt::EditRole)
526         return QSqlQueryModel::setData(index, value, role);
527
528     if (!index.isValid() || index.column() >= d->rec.count() || index.row() >= rowCount())
529         return false;
530
531     bool isOk = true;
532     switch (d->strategy) {
533     case OnFieldChange: {
534         if (index.row() == d->insertIndex) {
535             d->editBuffer.setValue(index.column(), value);
536             return true;
537         }
538         d->clearEditBuffer();
539         d->editBuffer.setValue(index.column(), value);
540         isOk = updateRowInTable(index.row(), d->editBuffer);
541         if (isOk)
542             select();
543         emit dataChanged(index, index);
544         break; }
545     case OnRowChange:
546         if (index.row() == d->insertIndex) {
547             d->editBuffer.setValue(index.column(), value);
548             return true;
549         }
550         if (d->editIndex != index.row()) {
551             if (d->editIndex != -1)
552                 submit();
553             d->clearEditBuffer();
554         }
555         d->editBuffer.setValue(index.column(), value);
556         d->editIndex = index.row();
557         emit dataChanged(index, index);
558         break;
559     case OnManualSubmit: {
560         QSqlTableModelPrivate::ModifiedRow &row = d->cache[index.row()];
561         if (row.op == QSqlTableModelPrivate::None) {
562             row.op = QSqlTableModelPrivate::Update;
563             row.rec = d->rec;
564             row.primaryValues = d->primaryValues(indexInQuery(index).row());
565         }
566         row.rec.setValue(index.column(), value);
567         emit dataChanged(index, index);
568         break; }
569     }
570     return isOk;
571 }
572
573 /*!
574     This function simply calls QSqlQueryModel::setQuery(\a query).
575     You should normally not call it on a QSqlTableModel. Instead, use
576     setTable(), setSort(), setFilter(), etc., to set up the query.
577
578     \sa selectStatement()
579 */
580 void QSqlTableModel::setQuery(const QSqlQuery &query)
581 {
582     QSqlQueryModel::setQuery(query);
583 }
584
585 /*!
586     Updates the given \a row in the currently active database table
587     with the specified \a values. Returns true if successful; otherwise
588     returns false.
589
590     This is a low-level method that operates directly on the database
591     and should not be called directly. Use setData() to update values.
592     The model will decide depending on its edit strategy when to modify
593     the database.
594
595     Note that only values that have the generated-flag set are updated.
596     The generated-flag can be set with QSqlRecord::setGenerated() and
597     tested with QSqlRecord::isGenerated().
598
599     \sa QSqlRecord::isGenerated(), setData()
600 */
601 bool QSqlTableModel::updateRowInTable(int row, const QSqlRecord &values)
602 {
603     Q_D(QSqlTableModel);
604     QSqlRecord rec(values);
605     emit beforeUpdate(row, rec);
606
607     const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues : d->primaryValues(row);
608     bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries);
609     QString stmt = d->db.driver()->sqlStatement(QSqlDriver::UpdateStatement, d->tableName,
610                                                 rec, prepStatement);
611     QString where = d->db.driver()->sqlStatement(QSqlDriver::WhereStatement, d->tableName,
612                                                  whereValues, prepStatement);
613
614     if (stmt.isEmpty() || where.isEmpty() || row < 0 || row >= rowCount()) {
615         d->error = QSqlError(QLatin1String("No Fields to update"), QString(),
616                                  QSqlError::StatementError);
617         return false;
618     }
619     stmt.append(QLatin1Char(' ')).append(where);
620
621     return d->exec(stmt, prepStatement, rec, whereValues);
622 }
623
624
625 /*!
626     Inserts the values \a values into the currently active database table.
627
628     This is a low-level method that operates directly on the database
629     and should not be called directly. Use insertRow() and setData()
630     to insert values. The model will decide depending on its edit strategy
631     when to modify the database.
632
633     Returns true if the values could be inserted, otherwise false.
634     Error information can be retrieved with \l lastError().
635
636     \sa lastError(), insertRow(), insertRows()
637 */
638 bool QSqlTableModel::insertRowIntoTable(const QSqlRecord &values)
639 {
640     Q_D(QSqlTableModel);
641     QSqlRecord rec = values;
642     emit beforeInsert(rec);
643
644     bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries);
645     QString stmt = d->db.driver()->sqlStatement(QSqlDriver::InsertStatement, d->tableName,
646                                                 rec, prepStatement);
647
648     if (stmt.isEmpty()) {
649         d->error = QSqlError(QLatin1String("No Fields to update"), QString(),
650                                  QSqlError::StatementError);
651         return false;
652     }
653
654     return d->exec(stmt, prepStatement, rec);
655 }
656
657 /*!
658     Deletes the given \a row from the currently active database table.
659
660     This is a low-level method that operates directly on the database
661     and should not be called directly. Use removeRow() or removeRows()
662     to delete values. The model will decide depending on its edit strategy
663     when to modify the database.
664
665     Returns true if the row was deleted; otherwise returns false.
666
667     \sa removeRow(), removeRows()
668 */
669 bool QSqlTableModel::deleteRowFromTable(int row)
670 {
671     Q_D(QSqlTableModel);
672     emit beforeDelete(row);
673
674     const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues : d->primaryValues(row);
675     bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries);
676     QString stmt = d->db.driver()->sqlStatement(QSqlDriver::DeleteStatement,
677                                                 d->tableName,
678                                                 QSqlRecord(),
679                                                 prepStatement);
680     QString where = d->db.driver()->sqlStatement(QSqlDriver::WhereStatement,
681                                                  d->tableName,
682                                                  whereValues,
683                                                  prepStatement);
684
685     if (stmt.isEmpty() || where.isEmpty()) {
686         d->error = QSqlError(QLatin1String("Unable to delete row"), QString(),
687                              QSqlError::StatementError);
688         return false;
689     }
690     stmt.append(QLatin1Char(' ')).append(where);
691
692     return d->exec(stmt, prepStatement, whereValues);
693 }
694
695 /*!
696     Submits all pending changes and returns true on success.
697     Returns false on error, detailed error information can be
698     obtained with lastError().
699
700     On success the model will be repopulated. Any views 
701     presenting it will lose their selections.
702
703     Note: In OnManualSubmit mode, already submitted changes won't
704     be cleared from the cache when submitAll() fails. This allows
705     transactions to be rolled back and resubmitted again without
706     losing data.
707
708     \sa revertAll(), lastError()
709 */
710 bool QSqlTableModel::submitAll()
711 {
712     Q_D(QSqlTableModel);
713
714     switch (d->strategy) {
715     case OnFieldChange:
716         if (d->insertIndex == -1)
717             return true;
718         // else fall through
719     case OnRowChange:
720         if (d->editBuffer.isEmpty())
721             return true;
722         if (d->insertIndex != -1) {
723             if (!insertRowIntoTable(d->editBuffer))
724                 return false;
725             d->bottom = d->bottom.sibling(d->bottom.row() + 1, d->bottom.column());
726         } else {
727             if (!updateRowInTable(d->editIndex, d->editBuffer))
728                 return false;
729         }
730         d->clearEditBuffer();
731         d->editIndex = -1;
732         d->insertIndex = -1;
733         return select();
734     case OnManualSubmit:
735         for (QSqlTableModelPrivate::CacheMap::ConstIterator it = d->cache.constBegin();
736              it != d->cache.constEnd(); ++it) {
737             switch (it.value().op) {
738             case QSqlTableModelPrivate::Insert:
739                 if (!insertRowIntoTable(it.value().rec))
740                     return false;
741                 d->bottom = d->bottom.sibling(d->bottom.row() + 1, d->bottom.column());
742                 break;
743             case QSqlTableModelPrivate::Update:
744                 if (!updateRowInTable(it.key(), it.value().rec))
745                     return false;
746                 break;
747             case QSqlTableModelPrivate::Delete:
748                 if (!deleteRowFromTable(it.key()))
749                     return false;
750                 break;
751             case QSqlTableModelPrivate::None:
752                 Q_ASSERT_X(false, "QSqlTableModel::submitAll()", "Invalid cache operation");
753                 break;
754             }
755         }
756         d->clearCache();
757         return select();
758     }
759     return false;
760 }
761
762 /*!
763     This reimplemented slot is called by the item delegates when the
764     user stopped editing the current row.
765
766     Submits the currently edited row if the model's strategy is set
767     to OnRowChange or OnFieldChange. Does nothing for the OnManualSubmit
768     strategy.
769
770     Use submitAll() to submit all pending changes for the
771     OnManualSubmit strategy.
772
773     Returns true on success; otherwise returns false. Use lastError()
774     to query detailed error information.
775
776     On success the model will be repopulated. Any views 
777     presenting it will lose their selections.
778
779     \sa revert(), revertRow(), submitAll(), revertAll(), lastError()
780 */
781 bool QSqlTableModel::submit()
782 {
783     Q_D(QSqlTableModel);
784     if (d->strategy == OnRowChange || d->strategy == OnFieldChange)
785         return submitAll();
786     return true;
787 }
788
789 /*!
790     This reimplemented slot is called by the item delegates when the
791     user canceled editing the current row.
792
793     Reverts the changes if the model's strategy is set to
794     OnRowChange. Does nothing for the other edit strategies.
795
796     Use revertAll() to revert all pending changes for the
797     OnManualSubmit strategy or revertRow() to revert a specific row.
798
799     \sa submit(), submitAll(), revertRow(), revertAll()
800 */
801 void QSqlTableModel::revert()
802 {
803     Q_D(QSqlTableModel);
804     if (d->strategy == OnRowChange)
805         revertAll();
806 }
807
808 /*!
809     \enum QSqlTableModel::EditStrategy
810
811     This enum type describes which strategy to choose when editing values in the database.
812
813     \value OnFieldChange  All changes to the model will be applied immediately to the database.
814     \value OnRowChange  Changes to a row will be applied when the user selects a different row.
815     \value OnManualSubmit  All changes will be cached in the model until either submitAll()
816                            or revertAll() is called.
817
818     Note: To prevent inserting only partly initialized rows into the database,
819     \c OnFieldChange will behave like \c OnRowChange for newly inserted rows.
820
821     \sa setEditStrategy()
822 */
823
824
825 /*!
826     Sets the strategy for editing values in the database to \a
827     strategy.
828
829     This will revert any pending changes.
830
831     \sa editStrategy(), revertAll()
832 */
833 void QSqlTableModel::setEditStrategy(EditStrategy strategy)
834 {
835     Q_D(QSqlTableModel);
836     revertAll();
837     d->strategy = strategy;
838 }
839
840 /*!
841     Returns the current edit strategy.
842
843     \sa setEditStrategy()
844 */
845 QSqlTableModel::EditStrategy QSqlTableModel::editStrategy() const
846 {
847     Q_D(const QSqlTableModel);
848     return d->strategy;
849 }
850
851 /*!
852     Reverts all pending changes.
853
854     \sa revert(), revertRow(), submitAll()
855 */
856 void QSqlTableModel::revertAll()
857 {
858     Q_D(QSqlTableModel);
859     switch (d->strategy) {
860     case OnFieldChange:
861         break;
862     case OnRowChange:
863         if (d->editIndex != -1)
864             revertRow(d->editIndex);
865         else if (d->insertIndex != -1)
866             revertRow(d->insertIndex);
867         break;
868     case OnManualSubmit:
869         while (!d->cache.isEmpty())
870             revertRow(d->cache.constBegin().key());
871         break;
872     }
873 }
874
875 /*!
876     Reverts all changes for the specified \a row.
877
878     \sa revert(), revertAll(), submit(), submitAll()
879 */
880 void QSqlTableModel::revertRow(int row)
881 {
882     if (row < 0)
883         return;
884
885     Q_D(QSqlTableModel);
886     switch (d->strategy) {
887     case OnFieldChange:
888         break;
889     case OnRowChange: {
890         if (d->editIndex == row) {
891             d->editBuffer.clear();
892             int oldIndex = d->editIndex;
893             d->editIndex = -1;
894             emit dataChanged(createIndex(oldIndex, 0), createIndex(oldIndex, columnCount()));
895         } else if (d->insertIndex == row) {
896             d->revertInsertedRow();
897         }
898         break; }
899     case OnManualSubmit:
900         d->revertCachedRow(row);
901         break;
902     }
903 }
904
905 /*!
906     Returns the primary key for the current table, or an empty
907     QSqlIndex if the table is not set or has no primary key.
908
909     \sa setTable(), setPrimaryKey(), QSqlDatabase::primaryIndex()
910 */
911 QSqlIndex QSqlTableModel::primaryKey() const
912 {
913     Q_D(const QSqlTableModel);
914     return d->primaryIndex;
915 }
916
917 /*!
918     Protected method that allows subclasses to set the primary key to
919     \a key.
920
921     Normally, the primary index is set automatically whenever you
922     call setTable().
923
924     \sa primaryKey(), QSqlDatabase::primaryIndex()
925 */
926 void QSqlTableModel::setPrimaryKey(const QSqlIndex &key)
927 {
928     Q_D(QSqlTableModel);
929     d->primaryIndex = key;
930 }
931
932 /*!
933     Returns a pointer to the used QSqlDatabase or 0 if no database was set.
934 */
935 QSqlDatabase QSqlTableModel::database() const
936 {
937     Q_D(const QSqlTableModel);
938      return d->db;
939 }
940
941 /*!
942     Sorts the data by \a column with the sort order \a order.
943     This will immediately select data, use setSort()
944     to set a sort order without populating the model with data.
945
946     \sa setSort(), select(), orderByClause()
947 */
948 void QSqlTableModel::sort(int column, Qt::SortOrder order)
949 {
950     setSort(column, order);
951     select();
952 }
953
954 /*!
955     Sets the sort order for \a column to \a order. This does not
956     affect the current data, to refresh the data using the new
957     sort order, call select().
958
959     \sa select(), orderByClause()
960 */
961 void QSqlTableModel::setSort(int column, Qt::SortOrder order)
962 {
963     Q_D(QSqlTableModel);
964     d->sortColumn = column;
965     d->sortOrder = order;
966 }
967
968 /*!
969     Returns an SQL \c{ORDER BY} clause based on the currently set
970     sort order.
971
972     \sa setSort(), selectStatement()
973 */
974 QString QSqlTableModel::orderByClause() const
975 {
976     Q_D(const QSqlTableModel);
977     QString s;
978     QSqlField f = d->rec.field(d->sortColumn);
979     if (!f.isValid())
980         return s;
981         
982     QString table = d->tableName;
983     //we can safely escape the field because it would have been obtained from the database
984     //and have the correct case
985     QString field = d->db.driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName);
986     s.append(QLatin1String("ORDER BY ")).append(table).append(QLatin1Char('.')).append(field);
987     s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC");
988
989     return s;
990 }
991
992 /*!
993     Returns the index of the field \a fieldName.
994 */
995 int QSqlTableModel::fieldIndex(const QString &fieldName) const
996 {
997     Q_D(const QSqlTableModel);
998     return d->rec.indexOf(fieldName);
999 }
1000
1001 /*!
1002     Returns the SQL \c SELECT statement used internally to populate
1003     the model. The statement includes the filter and the \c{ORDER BY}
1004     clause.
1005
1006     \sa filter(), orderByClause()
1007 */
1008 QString QSqlTableModel::selectStatement() const
1009 {
1010     Q_D(const QSqlTableModel);
1011     QString query;
1012     if (d->tableName.isEmpty()) {
1013         d->error = QSqlError(QLatin1String("No table name given"), QString(),
1014                              QSqlError::StatementError);
1015         return query;
1016     }
1017     if (d->rec.isEmpty()) {
1018         d->error = QSqlError(QLatin1String("Unable to find table ") + d->tableName, QString(),
1019                              QSqlError::StatementError);
1020         return query;
1021     }
1022
1023     query = d->db.driver()->sqlStatement(QSqlDriver::SelectStatement,
1024                                          d->tableName,
1025                                          d->rec,
1026                                          false);
1027     if (query.isEmpty()) {
1028         d->error = QSqlError(QLatin1String("Unable to select fields from table ") + d->tableName,
1029                              QString(), QSqlError::StatementError);
1030         return query;
1031     }
1032     if (!d->filter.isEmpty())
1033         query.append(QLatin1String(" WHERE ")).append(d->filter);
1034     QString orderBy(orderByClause());
1035     if (!orderBy.isEmpty())
1036         query.append(QLatin1Char(' ')).append(orderBy);
1037
1038     return query;
1039 }
1040
1041 /*!
1042     Removes \a count columns from the \a parent model, starting at
1043     index \a column.
1044
1045     Returns if the columns were successfully removed; otherwise
1046     returns false.
1047
1048     \sa removeRows()
1049 */
1050 bool QSqlTableModel::removeColumns(int column, int count, const QModelIndex &parent)
1051 {
1052     Q_D(QSqlTableModel);
1053     if (parent.isValid() || column < 0 || column + count > d->rec.count())
1054         return false;
1055     for (int i = 0; i < count; ++i)
1056         d->rec.remove(column);
1057     if (d->query.isActive())
1058         return select();
1059     return true;
1060 }
1061
1062 /*!
1063     Removes \a count rows starting at \a row. Since this model
1064     does not support hierarchical structures, \a parent must be
1065     an invalid model index.
1066
1067     Emits the beforeDelete() signal before a row is deleted. When
1068     the edit strategy is OnManualSubmit signal emission is delayed
1069     until submitAll() is called.
1070
1071     Returns true if all rows could be removed; otherwise returns
1072     false. Detailed error information can be retrieved using
1073     lastError().
1074
1075     \sa removeColumns(), insertRows()
1076 */
1077 bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent)
1078 {
1079     Q_D(QSqlTableModel);
1080     if (parent.isValid() || row < 0 || count <= 0)
1081         return false;
1082
1083     int i;
1084     switch (d->strategy) {
1085     case OnFieldChange:
1086     case OnRowChange:
1087         for (i = 0; i < count; ++i) {
1088             if (row + i == d->insertIndex)
1089                 d->revertInsertedRow();
1090             else if (!deleteRowFromTable(row + i))
1091                 return false;
1092         }
1093         select();
1094         break;
1095     case OnManualSubmit:
1096         for (i = 0; i < count; ++i) {
1097             int idx = row + i;
1098             if (idx >= rowCount())
1099                 return false;
1100             if (d->cache.value(idx).op == QSqlTableModelPrivate::Insert)
1101                 revertRow(idx);
1102             else {
1103                 d->cache[idx].op = QSqlTableModelPrivate::Delete;
1104                 d->cache[idx].primaryValues = d->primaryValues(indexInQuery(createIndex(idx, 0)).row());
1105                 emit headerDataChanged(Qt::Vertical, idx, idx);
1106             }
1107         }
1108         break;
1109     }
1110     return true;
1111 }
1112
1113 /*!
1114     Inserts \a count empty rows at position \a row. Note that \a
1115     parent must be invalid, since this model does not support
1116     parent-child relations.
1117
1118     Only one row at a time can be inserted when using the
1119     OnFieldChange or OnRowChange update strategies.
1120
1121     The primeInsert() signal will be emitted for each new row.
1122     Connect to it if you want to initialize the new row with default
1123     values.
1124
1125     Returns false if the parameters are out of bounds; otherwise
1126     returns true.
1127
1128     \sa primeInsert(), insertRecord()
1129 */
1130 bool QSqlTableModel::insertRows(int row, int count, const QModelIndex &parent)
1131 {
1132     Q_D(QSqlTableModel);
1133     if (row < 0 || count <= 0 || row > rowCount() || parent.isValid())
1134         return false;
1135
1136     switch (d->strategy) {
1137     case OnFieldChange:
1138     case OnRowChange:
1139         if (count != 1)
1140             return false;
1141         beginInsertRows(parent, row, row);
1142         d->insertIndex = row;
1143         // ### apply dangling changes...
1144         d->clearEditBuffer();
1145         emit primeInsert(row, d->editBuffer);
1146         break;
1147     case OnManualSubmit:
1148         beginInsertRows(parent, row, row + count - 1);
1149         if (!d->cache.isEmpty()) {
1150             QMap<int, QSqlTableModelPrivate::ModifiedRow>::Iterator it = d->cache.end();
1151             while (it != d->cache.begin() && (--it).key() >= row) {
1152                 int oldKey = it.key();
1153                 const QSqlTableModelPrivate::ModifiedRow oldValue = it.value();
1154                 d->cache.erase(it);
1155                 it = d->cache.insert(oldKey + count, oldValue);
1156             }
1157         }
1158
1159         for (int i = 0; i < count; ++i) {
1160             d->cache[row + i] = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Insert,
1161                                                                    d->rec);
1162             emit primeInsert(row + i, d->cache[row + i].rec);
1163         }
1164         break;
1165     }
1166     endInsertRows();
1167     return true;
1168 }
1169
1170 /*!
1171     Inserts the \a record after \a row. If \a row is negative, the
1172     record will be appended to the end. Calls insertRows() and
1173     setRecord() internally.
1174
1175     Returns true if the row could be inserted, otherwise false.
1176
1177     \sa insertRows(), removeRows()
1178 */
1179 bool QSqlTableModel::insertRecord(int row, const QSqlRecord &record)
1180 {
1181     Q_D(QSqlTableModel);
1182     if (row < 0)
1183         row = rowCount();
1184     if (!insertRow(row, QModelIndex()))
1185         return false;
1186     if (!setRecord(row, record))
1187         return false;
1188     if (d->strategy == OnFieldChange || d->strategy == OnRowChange)
1189         return submit();
1190     return true;
1191 }
1192
1193 /*! \reimp
1194 */
1195 int QSqlTableModel::rowCount(const QModelIndex &parent) const
1196 {
1197     Q_D(const QSqlTableModel);
1198
1199     if (parent.isValid())
1200         return 0;
1201
1202     int rc = QSqlQueryModel::rowCount();
1203     if (d->strategy == OnManualSubmit) {
1204         for (QSqlTableModelPrivate::CacheMap::ConstIterator it = d->cache.constBegin();
1205              it != d->cache.constEnd(); ++it) {
1206              if (it.value().op == QSqlTableModelPrivate::Insert)
1207                  ++rc;
1208         }
1209     } else if (d->insertIndex >= 0) {
1210         ++rc;
1211     }
1212     return rc;
1213 }
1214
1215 /*!
1216     Returns the index of the value in the database result set for the
1217     given \a item in the model.
1218
1219     The return value is identical to \a item if no columns or rows
1220     have been inserted, removed, or moved around.
1221
1222     Returns an invalid model index if \a item is out of bounds or if
1223     \a item does not point to a value in the result set.
1224
1225     \sa QSqlQueryModel::indexInQuery()
1226 */
1227 QModelIndex QSqlTableModel::indexInQuery(const QModelIndex &item) const
1228 {
1229     Q_D(const QSqlTableModel);
1230     const QModelIndex it = QSqlQueryModel::indexInQuery(item);
1231     if (d->strategy == OnManualSubmit) {
1232         int rowOffset = 0;
1233         QSqlTableModelPrivate::CacheMap::ConstIterator i = d->cache.constBegin();
1234         while (i != d->cache.constEnd() && i.key() <= it.row()) {
1235             if (i.value().op == QSqlTableModelPrivate::Insert)
1236                 ++rowOffset;
1237             ++i;
1238         }
1239         return createIndex(it.row() - rowOffset, it.column(), it.internalPointer());
1240     } else {
1241         if (d->insertIndex >= 0 && it.row() >= d->insertIndex)
1242             return createIndex(it.row() - 1, it.column(), it.internalPointer());
1243     }
1244     return it;
1245 }
1246
1247 /*!
1248     Returns the currently set filter.
1249
1250     \sa setFilter(), select()
1251 */
1252 QString QSqlTableModel::filter() const
1253 {
1254     Q_D(const QSqlTableModel);
1255     return d->filter;
1256 }
1257
1258 /*!
1259     Sets the current filter to \a filter.
1260
1261     The filter is a SQL \c WHERE clause without the keyword \c WHERE
1262     (for example, \c{name='Josephine')}.
1263
1264     If the model is already populated with data from a database,
1265     the model re-selects it with the new filter. Otherwise, the filter
1266     will be applied the next time select() is called.
1267
1268     \sa filter(), select(), selectStatement(), orderByClause()
1269 */
1270 void QSqlTableModel::setFilter(const QString &filter)
1271 {
1272     Q_D(QSqlTableModel);
1273     d->filter = filter;
1274     if (d->query.isActive())
1275         select();
1276 }
1277
1278 /*! \reimp
1279 */
1280 void QSqlTableModel::clear()
1281 {
1282     Q_D(QSqlTableModel);
1283     d->clear();
1284     QSqlQueryModel::clear();
1285 }
1286
1287 /*! \reimp
1288 */
1289 Qt::ItemFlags QSqlTableModel::flags(const QModelIndex &index) const
1290 {
1291     Q_D(const QSqlTableModel);
1292     if (index.internalPointer() || index.column() < 0 || index.column() >= d->rec.count()
1293         || index.row() < 0)
1294         return 0;
1295     if (d->rec.field(index.column()).isReadOnly())
1296         return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
1297     return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
1298 }
1299
1300 /*!
1301     Sets the values at the specified \a row to the values of \a
1302     record. Returns true if all the values could be set; otherwise
1303     returns false.
1304
1305     \sa record()
1306 */
1307 bool QSqlTableModel::setRecord(int row, const QSqlRecord &record)
1308 {
1309     Q_D(QSqlTableModel);
1310     Q_ASSERT_X(row >= 0, "QSqlTableModel::setRecord()", "Cannot set a record to a row less than 0");
1311     if (row >= rowCount())
1312         return false;
1313
1314     bool isOk = true;
1315     switch (d->strategy) {
1316     case OnFieldChange:
1317     case OnRowChange:
1318         return d->setRecord(row, record);
1319     case OnManualSubmit: {
1320         QSqlTableModelPrivate::ModifiedRow &mrow = d->cache[row];
1321         if (mrow.op == QSqlTableModelPrivate::None) {
1322             mrow.op = QSqlTableModelPrivate::Update;
1323             mrow.rec = d->rec;
1324             mrow.primaryValues = d->primaryValues(indexInQuery(createIndex(row, 0)).row());
1325         }
1326         QString fieldName;
1327         for (int i = 0; i < record.count(); ++i) {
1328             fieldName = record.fieldName(i);
1329             if (d->db.driver()->isIdentifierEscaped(fieldName, QSqlDriver::FieldName))
1330                 fieldName = d->db.driver()->stripDelimiters(fieldName, QSqlDriver::FieldName);
1331             int idx = mrow.rec.indexOf(fieldName);
1332             if (idx == -1)
1333                 isOk = false;
1334             else
1335                 mrow.rec.setValue(idx, record.value(i));
1336         }
1337
1338         if (isOk)
1339             emit dataChanged(createIndex(row, 0), createIndex(row, columnCount() - 1));
1340         return isOk; }
1341     }
1342     return false;
1343 }
1344
1345 QT_END_NAMESPACE