summaryrefslogtreecommitdiffstats
path: root/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp')
-rw-r--r--tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp228
1 files changed, 228 insertions, 0 deletions
diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
index 92356e6707..df89ba3cf8 100644
--- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -83,6 +83,8 @@ private slots:
void insertColumns();
void submitAll_data() { generic_data(); }
void submitAll();
+ void setData_data() { generic_data(); }
+ void setData();
void setRecord_data() { generic_data(); }
void setRecord();
void setRecordReimpl_data() { generic_data(); }
@@ -97,6 +99,8 @@ private slots:
void insertRecord();
void insertMultiRecords_data() { generic_data(); }
void insertMultiRecords();
+ void insertWithAutoColumn_data() { generic_data_with_strategies("QSQLITE"); }
+ void insertWithAutoColumn();
void removeRow_data() { generic_data(); }
void removeRow();
void removeRows_data() { generic_data(); }
@@ -105,6 +109,8 @@ private slots:
void removeInsertedRow();
void removeInsertedRows_data() { generic_data(); }
void removeInsertedRows();
+ void revert_data() { generic_data_with_strategies("QSQLITE"); }
+ void revert();
void isDirty_data() { generic_data_with_strategies(); }
void isDirty();
void setFilter_data() { generic_data(); }
@@ -501,6 +507,77 @@ void tst_QSqlTableModel::insertColumns()
QCOMPARE(model.data(model.index(3, 5)), QVariant());
}
+void tst_QSqlTableModel::setData()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlTableModel model(0, db);
+ model.setEditStrategy(QSqlTableModel::OnManualSubmit);
+ model.setTable(test);
+ model.setSort(0, Qt::AscendingOrder);
+ QVERIFY_SQL(model, select());
+
+ // initial state
+ QModelIndex idx = model.index(0, 0);
+ QVariant val = model.data(idx);
+ QVERIFY(val == int(1));
+ QVERIFY(!val.isNull());
+ QFAIL_SQL(model, isDirty());
+
+ // change 1 to 0
+ idx = model.index(0, 0);
+ QVERIFY_SQL(model, setData(idx, int(0)));
+ val = model.data(idx);
+ QVERIFY(val == int(0));
+ QVERIFY(!val.isNull());
+ QVERIFY_SQL(model, isDirty(idx));
+ QVERIFY_SQL(model, submitAll());
+
+ // change 0 to NULL
+ idx = model.index(0, 0);
+ QVERIFY_SQL(model, setData(idx, QVariant(QVariant::Int)));
+ val = model.data(idx);
+ QVERIFY(val == QVariant(QVariant::Int));
+ QVERIFY(val.isNull());
+ QVERIFY_SQL(model, isDirty(idx));
+ QVERIFY_SQL(model, submitAll());
+
+ // change NULL to 0
+ idx = model.index(0, 0);
+ QVERIFY_SQL(model, setData(idx, int(0)));
+ val = model.data(idx);
+ QVERIFY(val == int(0));
+ QVERIFY(!val.isNull());
+ QVERIFY_SQL(model, isDirty(idx));
+ QVERIFY_SQL(model, submitAll());
+
+ // ignore unchanged 0 to 0
+ idx = model.index(0, 0);
+ QVERIFY_SQL(model, setData(idx, int(0)));
+ val = model.data(idx);
+ QVERIFY(val == int(0));
+ QVERIFY(!val.isNull());
+ QFAIL_SQL(model, isDirty(idx));
+
+ // pending INSERT
+ QVERIFY_SQL(model, insertRow(0));
+ // initial state
+ idx = model.index(0, 0);
+ QSqlRecord rec = model.record(0);
+ QVERIFY(rec.value(0) == QVariant(QVariant::Int));
+ QVERIFY(rec.isNull(0));
+ QVERIFY(!rec.isGenerated(0));
+ // unchanged value, but causes column to be included in INSERT
+ QVERIFY_SQL(model, setData(idx, QVariant(QVariant::Int)));
+ rec = model.record(0);
+ QVERIFY(rec.value(0) == QVariant(QVariant::Int));
+ QVERIFY(rec.isNull(0));
+ QVERIFY(rec.isGenerated(0));
+ QVERIFY_SQL(model, submitAll());
+}
+
void tst_QSqlTableModel::setRecord()
{
QFETCH(QString, dbName);
@@ -890,6 +967,72 @@ void tst_QSqlTableModel::insertMultiRecords()
QCOMPARE(model.data(model.index(5, 2)).toInt(), 1);
}
+void tst_QSqlTableModel::insertWithAutoColumn()
+{
+ QFETCH(QString, dbName);
+ QFETCH(int, submitpolicy_i);
+ QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QString tbl = qTableName("autoColumnTest", __FILE__);
+ QSqlQuery q(db);
+ q.exec("DROP TABLE " + tbl);
+ QVERIFY_SQL(q, exec("CREATE TABLE " + tbl + "(id INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)"));
+
+ QSqlTableModel model(0, db);
+ model.setTable(tbl);
+ model.setSort(0, Qt::AscendingOrder);
+ model.setEditStrategy(submitpolicy);
+
+ QVERIFY_SQL(model, select());
+ QCOMPARE(model.rowCount(), 0);
+
+ // For insertRow/insertRows, we have to touch at least one column
+ // or else the generated flag won't be set, which would lead to
+ // an empty column list in the INSERT statement, which generally
+ // does not work.
+ if (submitpolicy != QSqlTableModel::OnManualSubmit) {
+ for (int id = 1; id <= 2; ++id) {
+ QVERIFY_SQL(model, insertRow(0));
+ QVERIFY_SQL(model, setData(model.index(0, 1), QString("foo")));
+ QVERIFY_SQL(model, submit());
+ QCOMPARE(model.data(model.index(0, 0)).toInt(), id);
+ }
+ } else {
+ QVERIFY_SQL(model, insertRows(0, 2));
+ QVERIFY_SQL(model, setData(model.index(0, 1), QString("foo")));
+ QVERIFY_SQL(model, setData(model.index(1, 1), QString("foo")));
+ }
+
+ QCOMPARE(model.rowCount(), 2);
+
+ QSqlRecord rec = db.record(tbl);
+ QVERIFY(rec.field(0).isAutoValue());
+ rec.setGenerated(0, false);
+
+ QVERIFY_SQL(model, insertRecord(0, rec));
+ if (submitpolicy != QSqlTableModel::OnManualSubmit)
+ QCOMPARE(model.data(model.index(0, 0)).toInt(), 3);
+
+ QCOMPARE(model.rowCount(), 3);
+
+ if (submitpolicy != QSqlTableModel::OnManualSubmit) {
+ // Rows updated in original positions after previous submits.
+ QCOMPARE(model.data(model.index(0, 0)).toInt(), 3);
+ QCOMPARE(model.data(model.index(1, 0)).toInt(), 2);
+ QCOMPARE(model.data(model.index(2, 0)).toInt(), 1);
+ } else {
+ // Manual submit is followed by requery.
+ QVERIFY_SQL(model, submitAll());
+ QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
+ QCOMPARE(model.data(model.index(1, 0)).toInt(), 2);
+ QCOMPARE(model.data(model.index(2, 0)).toInt(), 3);
+ }
+
+ QVERIFY_SQL(q, exec("DROP TABLE " + tbl));
+}
+
void tst_QSqlTableModel::submitAll()
{
QFETCH(QString, dbName);
@@ -1227,6 +1370,83 @@ void tst_QSqlTableModel::removeInsertedRows()
QCOMPARE(model.data(model.index(1, 1)).toString(), QString("vohi"));
}
+void tst_QSqlTableModel::revert()
+{
+ QFETCH(QString, dbName);
+ QFETCH(int, submitpolicy_i);
+ QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QString tblA = qTableName("revertATest", __FILE__);
+ QString tblB = qTableName("revertBTest", __FILE__);
+ QSqlQuery q(db);
+ q.exec("PRAGMA foreign_keys = ON;");
+ q.exec("DROP TABLE " + tblB);
+ q.exec("DROP TABLE " + tblA);
+ QVERIFY_SQL(q, exec("CREATE TABLE " + tblA + "(a INT PRIMARY KEY)"));
+ QVERIFY_SQL(q, exec("CREATE TABLE " + tblB + "(b INT PRIMARY KEY, FOREIGN KEY (b) REFERENCES " + tblA + " (a))"));
+ QVERIFY_SQL(q, exec("INSERT INTO " + tblA + "(a) VALUES (1)"));
+ QVERIFY_SQL(q, exec("INSERT INTO " + tblB + "(b) VALUES (1)"));
+ if (q.exec("UPDATE " + tblA + " SET a = -1"))
+ QSKIP("database does not enforce foreign key constraints, skipping test");
+
+ QSqlTableModel model(0, db);
+ model.setTable(tblA);
+ model.setSort(0, Qt::AscendingOrder);
+ model.setEditStrategy(submitpolicy);
+
+ QVERIFY_SQL(model, select());
+ QCOMPARE(model.rowCount(), 1);
+ QFAIL_SQL(model, isDirty());
+
+ // don't crash if there is no change
+ model.revert();
+
+ // UPDATE
+ // invalid value makes submit fail leaving pending update in cache
+ const QModelIndex idx = model.index(0, 0);
+ if (submitpolicy == QSqlTableModel::OnFieldChange)
+ QFAIL_SQL(model, setData(idx, int(-1)));
+ else
+ QVERIFY_SQL(model, setData(idx, int(-1)));
+ QVERIFY_SQL(model, isDirty(idx));
+ model.revert();
+ if (submitpolicy != QSqlTableModel::OnManualSubmit)
+ QFAIL_SQL(model, isDirty(idx));
+ else
+ QVERIFY_SQL(model, isDirty(idx));
+
+ // INSERT
+ QVERIFY_SQL(model, select());
+ // insertRow() does not submit leaving pending insert in cache
+ QVERIFY_SQL(model, insertRow(0));
+ QCOMPARE(model.rowCount(), 2);
+ QVERIFY_SQL(model, isDirty());
+ model.revert();
+ if (submitpolicy != QSqlTableModel::OnManualSubmit)
+ QFAIL_SQL(model, isDirty());
+ else
+ QVERIFY_SQL(model, isDirty());
+
+ // DELETE
+ QVERIFY_SQL(model, select());
+ // foreign key makes submit fail leaving pending delete in cache
+ if (submitpolicy == QSqlTableModel::OnManualSubmit)
+ QVERIFY_SQL(model, removeRow(0));
+ else
+ QFAIL_SQL(model, removeRow(0));
+ QVERIFY_SQL(model, isDirty());
+ model.revert();
+ if (submitpolicy != QSqlTableModel::OnManualSubmit)
+ QFAIL_SQL(model, isDirty());
+ else
+ QVERIFY_SQL(model, isDirty());
+
+ q.exec("DROP TABLE " + tblB);
+ q.exec("DROP TABLE " + tblA);
+}
+
void tst_QSqlTableModel::isDirty()
{
QFETCH(QString, dbName);
@@ -1433,6 +1653,14 @@ void tst_QSqlTableModel::emptyTable()
QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.columnCount(), 1);
+
+ // QTBUG-29108: check correct horizontal header for empty query with pending insert
+ QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("id"));
+ model.setEditStrategy(QSqlTableModel::OnManualSubmit);
+ model.insertRow(0);
+ QCOMPARE(model.rowCount(), 1);
+ QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("id"));
+ model.revertAll();
}
void tst_QSqlTableModel::tablesAndSchemas()