QSqlTableModel: record(row) must use virtual data()
authorMark Brand <mabrand@mabrand.nl>
Fri, 28 Sep 2012 14:27:45 +0000 (16:27 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 5 Oct 2012 01:16:22 +0000 (03:16 +0200)
Commit fbf010a26617b3986e9a76bd9c004403aebfcdc2 introduced a version
of record(row) that includes the generated flags, but it neglected to
populate the values using virtual data() as QSqlQueryModel correctly
does.

Test included lest we forget again.

Change-Id: I49d0f8f87cd0c5078aa6a0e8373b2cffc01f2387
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: David Faure <david.faure@kdab.com>
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
src/sql/models/qsqltablemodel.cpp
tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp

index a3fdd06..29e9367 100644 (file)
@@ -1311,10 +1311,18 @@ QSqlRecord QSqlTableModel::record(int row) const
 {
     Q_D(const QSqlTableModel);
 
-    if (d->cache.contains(row))
-        return d->cache.value(row).rec();
+    // the query gets the values from virtual data()
+    QSqlRecord rec = QSqlQueryModel::record(row);
+
+    // get generated flags from the cache
+    const QSqlTableModelPrivate::ModifiedRow mrow = d->cache.value(row);
+    if (mrow.op() != QSqlTableModelPrivate::None) {
+        const QSqlRecord crec = mrow.rec();
+        for (int i = 0, cnt = rec.count(); i < cnt; ++i)
+            rec.setGenerated(i, crec.isGenerated(i));
+    }
 
-    return QSqlQueryModel::record(row);
+    return rec;
 }
 
 /*!
index d3407de..bd9e458 100644 (file)
@@ -87,6 +87,8 @@ private slots:
     void setRecord();
     void setRecordReimpl_data()  { generic_data(); }
     void setRecordReimpl();
+    void recordReimpl_data()  { generic_data(); }
+    void recordReimpl();
     void insertRow_data() { generic_data_with_strategies(); }
     void insertRow();
     void insertRowFailure_data() { generic_data_with_strategies(); }
@@ -574,6 +576,45 @@ void tst_QSqlTableModel::setRecordReimpl()
     QCOMPARE(rec.value(2).toString(), QString("Qt"));
 }
 
+class RecordReimplModel: public QSqlTableModel
+{
+    Q_OBJECT
+public:
+    RecordReimplModel(QObject *parent, QSqlDatabase db):QSqlTableModel(parent, db) {}
+    QVariant data(const QModelIndex &index, int role = Qt::EditRole) const
+    {
+        if (role == Qt::EditRole)
+            return QString("Qt");
+        else
+            return QSqlTableModel::data(index, role);
+    }
+};
+
+void tst_QSqlTableModel::recordReimpl()
+{
+    QFETCH(QString, dbName);
+    QSqlDatabase db = QSqlDatabase::database(dbName);
+    CHECK_DATABASE(db);
+    RecordReimplModel model(0, db);
+    model.setEditStrategy(QSqlTableModel::OnManualSubmit);
+    model.setTable(test3);
+    model.setSort(0, Qt::AscendingOrder);
+    QVERIFY_SQL(model, select());
+
+    // make sure reimplemented data() affects record(row)
+    QSqlRecord rec = model.record(0);
+    QCOMPARE(rec.value(1).toString(), QString("Qt"));
+    QCOMPARE(rec.value(2).toString(), QString("Qt"));
+
+    // and also when the record is in the cache
+    QVERIFY_SQL(model, setData(model.index(0, 1), QString("not Qt")));
+    QVERIFY_SQL(model, setData(model.index(0, 2), QString("not Qt")));
+
+    rec = model.record(0);
+    QCOMPARE(rec.value(1).toString(), QString("Qt"));
+    QCOMPARE(rec.value(2).toString(), QString("Qt"));
+}
+
 void tst_QSqlTableModel::insertRow()
 {
     QFETCH(QString, dbName);