From 244eeae406b83227f08ea01f9417c07ecc3cf133 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Fri, 28 Sep 2012 12:22:55 +0200 Subject: [PATCH] QSqlTableModel::selectRow(): don't expand cache if there is no change Test added. Change-Id: Ibd72ef2aeee482abbd22991573460e55dc577457 Reviewed-by: Marc Mutz Reviewed-by: David Faure (fixes for KDE) --- src/sql/models/qsqltablemodel.cpp | 30 +++++++++++++++++++--- .../sql/models/qsqltablemodel/qsqltablemodel.pro | 2 +- .../models/qsqltablemodel/tst_qsqltablemodel.cpp | 21 ++++++++++++++- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 29e9367..5feb308 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -439,18 +439,40 @@ bool QSqlTableModel::selectRow(int row) if (stmt.isEmpty()) return false; + bool exists; + QSqlRecord newValues; + { QSqlQuery q(d->db); q.setForwardOnly(true); if (!q.exec(stmt)) return false; - bool exists = q.next(); - d->cache[row].refresh(exists, q.record()); + exists = q.next(); + newValues = q.record(); + } + + bool needsAddingToCache = !exists || d->cache.contains(row); + + if (!needsAddingToCache) { + const QSqlRecord curValues = record(row); + needsAddingToCache = curValues.count() != newValues.count(); + if (!needsAddingToCache) { + // Look for changed values. Primary key fields are customarily first + // and probably change less often than other fields, so start at the end. + for (int f = curValues.count() - 1; f >= 0; --f) { + if (curValues.value(f) != newValues.value(f)) + needsAddingToCache = true; + break; + } + } } - emit headerDataChanged(Qt::Vertical, row, row); - emit dataChanged(createIndex(row, 0), createIndex(row, columnCount() - 1)); + if (needsAddingToCache) { + d->cache[row].refresh(exists, newValues); + emit headerDataChanged(Qt::Vertical, row, row); + emit dataChanged(createIndex(row, 0), createIndex(row, columnCount() - 1)); + } return true; } diff --git a/tests/auto/sql/models/qsqltablemodel/qsqltablemodel.pro b/tests/auto/sql/models/qsqltablemodel/qsqltablemodel.pro index e1b150a..3ad44d6 100644 --- a/tests/auto/sql/models/qsqltablemodel/qsqltablemodel.pro +++ b/tests/auto/sql/models/qsqltablemodel/qsqltablemodel.pro @@ -2,7 +2,7 @@ CONFIG += testcase TARGET = tst_qsqltablemodel SOURCES += tst_qsqltablemodel.cpp -QT = core sql testlib +QT = core core-private sql sql-private testlib wince*: { plugFiles.files = ../../../plugins/sqldrivers diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp index bd9e458..843ef7b 100644 --- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp @@ -43,6 +43,7 @@ #include #include "../../kernel/qsqldatabase/tst_databases.h" #include +#include const QString test(qTableName("test", __FILE__)), test2(qTableName("test2", __FILE__)), @@ -319,6 +320,19 @@ void tst_QSqlTableModel::select() QCOMPARE(model.data(model.index(3, 3)), QVariant()); } +class SelectRowModel: public QSqlTableModel +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QSqlTableModel) +public: + SelectRowModel(QObject *parent, QSqlDatabase db): QSqlTableModel(parent, db) {} + bool cacheEmpty() const + { + Q_D(const QSqlTableModel); + return d->cache.isEmpty(); + } +}; + void tst_QSqlTableModel::selectRow() { QFETCH(QString, dbName); @@ -332,7 +346,7 @@ void tst_QSqlTableModel::selectRow() q.exec("INSERT INTO " + tbl + " (id, a) VALUES (1, 'b')"); q.exec("INSERT INTO " + tbl + " (id, a) VALUES (2, 'c')"); - QSqlTableModel model(0, db); + SelectRowModel model(0, db); model.setEditStrategy(QSqlTableModel::OnFieldChange); model.setTable(tbl); model.setSort(0, Qt::AscendingOrder); @@ -343,6 +357,11 @@ void tst_QSqlTableModel::selectRow() QModelIndex idx = model.index(1, 1); + // selectRow should not make the cache grow if there is no change. + model.selectRow(1); + QCOMPARE(model.data(idx).toString(), QString("b")); + QVERIFY_SQL(model, cacheEmpty()); + // Check if selectRow() refreshes an unchanged row. // Row is not in cache yet. q.exec("UPDATE " + tbl + " SET a = 'Qt' WHERE id = 1"); -- 2.7.4