summaryrefslogtreecommitdiffstats
path: root/tests/auto/sql
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-02-13 11:58:07 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-02-14 14:24:57 +0100
commite65cd6f3794e12e6bc5c2ee985eae8e70ff5f333 (patch)
tree8965835c375422d63b2ccfa927b31a56e64bda1d /tests/auto/sql
parentd1ee7189553e13337b198fe4ba66d79fb7a7f41d (diff)
parente95a758236cf2c68e33da4ddb62bff4fe8d9dd8b (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: src/concurrent/doc/qtconcurrent.qdocconf src/corelib/doc/qtcore.qdocconf src/corelib/global/qglobal.h src/dbus/doc/qtdbus.qdocconf src/dbus/qdbusmessage.h src/gui/doc/qtgui.qdocconf src/gui/image/qimagereader.cpp src/network/doc/qtnetwork.qdocconf src/opengl/doc/qtopengl.qdocconf src/opengl/qgl.h src/plugins/platforms/windows/qwindowswindow.cpp src/printsupport/doc/qtprintsupport.qdocconf src/sql/doc/qtsql.qdocconf src/testlib/doc/qttestlib.qdocconf src/tools/qdoc/doc/config/qt-cpp-ignore.qdocconf src/widgets/doc/qtwidgets.qdocconf src/xml/doc/qtxml.qdocconf Change-Id: Ie9a1fa2cc44bec22a0b942e817a1095ca3414629
Diffstat (limited to 'tests/auto/sql')
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_databases.h36
-rw-r--r--tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp2
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp52
-rw-r--r--tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp228
4 files changed, 283 insertions, 35 deletions
diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
index 9e3b37ed53..9d3523576f 100644
--- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
+++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
@@ -232,7 +232,7 @@ public:
// addDb( "QOCI8", "//horsehead.nokia.troll.no:1521/ustest.troll.no", "scott", "tiger", "" ); // Oracle 9i on horsehead
// addDb( "QOCI8", "//iceblink.nokia.troll.no:1521/ice.troll.no", "scott", "tiger", "" ); // Oracle 8 on iceblink (not currently working)
// addDb( "QOCI", "//silence.nokia.troll.no:1521/testdb", "scott", "tiger" ); // Oracle 10g on silence
-// addDb( "QOCI", "//bq-oracle10g.apac.nokia.com:1521/XE", "scott", "tiger" ); // Oracle 10gexpress
+// addDb( "QOCI", "//bq-oracle10g.qt-project.org:1521/XE", "scott", "tiger" ); // Oracle 10gexpress
// This requires a local ODBC data source to be configured( pointing to a MySql database )
// addDb( "QODBC", "mysqlodbc", "troll", "trond" );
@@ -247,9 +247,9 @@ public:
// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3309, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 5.0.18 Linux
// addDb( "QMYSQL3", "testdb", "troll", "trond", "silence.nokia.troll.no" ); // MySQL 5.1.36 Windows
-// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql41.apac.nokia.com" ); // MySQL 4.1.22-2.el4 linux
-// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql50.apac.nokia.com" ); // MySQL 5.0.45-7.el5 linux
-// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql51.apac.nokia.com" ); // MySQL 5.1.36-6.7.2.i586 linux
+// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql41.qt-project.org" ); // MySQL 4.1.22-2.el4 linux
+// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql50.qt-project.org" ); // MySQL 5.0.45-7.el5 linux
+// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql51.qt-project.org" ); // MySQL 5.1.36-6.7.2.i586 linux
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no" ); // V7.2 NOT SUPPORTED!
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5434 ); // V7.2 NOT SUPPORTED! Multi-byte
@@ -258,14 +258,14 @@ public:
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5437 ); // V8.0.3
// addDb( "QPSQL7", "testdb", "troll", "trond", "silence.nokia.troll.no" ); // V8.2.1, UTF-8
-// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-postgres74.apac.nokia.com" ); // Version 7.4.19-1.el4_6.1
-// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql81.apac.nokia.com" ); // Version 8.1.11-1.el5_1.1
-// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql84.apac.nokia.com" ); // Version 8.4.1-2.1.i586
-// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql90.apac.nokia.com" ); // Version 9.0.0
+// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-postgres74.qt-project.org" ); // Version 7.4.19-1.el4_6.1
+// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql81.qt-project.org" ); // Version 8.1.11-1.el5_1.1
+// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql84.qt-project.org" ); // Version 8.4.1-2.1.i586
+// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql90.qt-project.org" ); // Version 9.0.0
// addDb( "QDB2", "testdb", "troll", "trond", "silence.nokia.troll.no" ); // DB2 v9.1 on silence
-// addDb( "QDB2", "testdb", "testuser", "Ee4Gabf6_", "bq-db2-972.apac.nokia.com" ); // DB2
+// addDb( "QDB2", "testdb", "testuser", "Ee4Gabf6_", "bq-db2-972.qt-project.org" ); // DB2
// yes - interbase really wants the physical path on the host machine.
// addDb( "QIBASE", "/opt/interbase/qttest.gdb", "SYSDBA", "masterkey", "horsehead.nokia.troll.no" );
@@ -274,8 +274,8 @@ public:
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird1-nokia.trolltech.com.au" ); // Firebird 1.5.5
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird2-nokia.trolltech.com.au" ); // Firebird 2.1.1
-// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "bq-firebird1.apac.nokia.com" ); // Firebird 1.5.5
-// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "bq-firebird2.apac.nokia.com" ); // Firebird 2.1.1
+// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "bq-firebird1.qt-project.org" ); // Firebird 1.5.5
+// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "bq-firebird2.qt-project.org" ); // Firebird 2.1.1
// use in-memory database to prevent local files
// addDb("QSQLITE", ":memory:");
@@ -284,18 +284,18 @@ public:
// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.nokia.troll.no\\ICEBLINK", "troll", "trond", "" );
// addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" );
-// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=bq-mysql50.apac.nokia.com;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
-// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=bq-mysql51.apac.nokia.com;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
+// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=bq-mysql50.qt-project.org;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
+// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=bq-mysql51.qt-project.org;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" );
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond", "troll", "trond", "" );
-// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" );
-// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" );
+// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.qt-project.org;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" );
+// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.qt-project.org;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" );
// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2003" );
// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2008" );
-// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
-// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
+// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2003-x86-01.qt-project.org;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
+// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2008-x86-01.qt-project.org;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
// addDb( "QODBC", "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\\dbs\\access\\testdb.mdb", "", "", "" );
-// addDb( "QODBC", "DRIVER={Postgresql};SERVER=bq-pgsql84.apac.nokia.com;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
+// addDb( "QODBC", "DRIVER={Postgresql};SERVER=bq-pgsql84.qt-project.org;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
}
void open()
diff --git a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp
index 1302aedb14..bee4441c0f 100644
--- a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp
+++ b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp
@@ -102,7 +102,7 @@ void tst_QSqlError::construction()
QCOMPARE(obj1.databaseText(), QString("databasetext"));
QCOMPARE(obj1.type(), QSqlError::UnknownError);
QCOMPARE(obj1.number(), 123);
- obj1.isValid();
+ QVERIFY(obj1.isValid());
QSqlError obj2(obj1);
QCOMPARE(obj2.driverText(), obj1.driverText());
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index 4e821dacc5..1d2a60506f 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -420,9 +420,11 @@ void tst_QSqlQuery::char1Select()
{
QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "create table " + qTableName( "char1Select", __FILE__ ) + " (id char(1))" ) );
- QVERIFY_SQL( q, exec( "insert into " + qTableName( "char1Select", __FILE__ ) + " values ('a')" ) );
- QVERIFY_SQL( q, exec( "select * from " + qTableName( "char1Select", __FILE__ ) ) );
+ const QString tbl = qTableName("char1Select", __FILE__);
+ q.exec( "drop table " + tbl);
+ QVERIFY_SQL(q, exec("create table " + tbl + " (id char(1))"));
+ QVERIFY_SQL(q, exec("insert into " + tbl + " values ('a')"));
+ QVERIFY_SQL(q, exec("select * from " + tbl));
QVERIFY( q.next() );
if ( db.driverName().startsWith( "QIBASE" ) )
@@ -540,7 +542,7 @@ void tst_QSqlQuery::mysqlOutValues()
q.exec( "drop function " + hello );
- QVERIFY_SQL( q, exec( "create function " + hello + " (s char(20)) returns varchar(50) return concat('Hello ', s)" ) );
+ QVERIFY_SQL(q, exec("create function " + hello + " (s char(20)) returns varchar(50) READS SQL DATA return concat('Hello ', s)"));
QVERIFY_SQL( q, exec( "select " + hello + "('world')" ) );
QVERIFY_SQL( q, next() );
@@ -580,9 +582,10 @@ void tst_QSqlQuery::mysqlOutValues()
void tst_QSqlQuery::bindBool()
{
// QTBUG-27763: bool value got converted to int 127 by mysql driver because sizeof(bool) < sizeof(int).
- // The problem was the way the bool value from the application was handled. It doesn't matter
- // whether the table column type is BOOL or INT. Use INT here because all DBMSs have it and all
- // should pass this test.
+ // The problem was the way the bool value from the application was handled. For our purposes here, it
+ // doesn't matter whether the column type is BOOLEAN or INT. All DBMSs have INT, and this usually
+ // works for this test. Postresql is an exception because its INT type does not accept BOOLEAN
+ // values and its BOOLEAN columns do not accept INT values.
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
@@ -590,7 +593,8 @@ void tst_QSqlQuery::bindBool()
const QString tableName(qTableName( "bindBool", __FILE__ ));
q.exec("DROP TABLE " + tableName);
- QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id INT, flag INT NOT NULL, PRIMARY KEY(id))"));
+ QString colType = db.driverName().startsWith("QPSQL") ? QLatin1String("BOOLEAN") : QLatin1String("INT");
+ QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id INT, flag " + colType + " NOT NULL, PRIMARY KEY(id))"));
for (int i = 0; i < 2; ++i) {
bool flag = i;
@@ -1487,6 +1491,7 @@ void tst_QSqlQuery::precision()
// need a new scope for SQLITE
QSqlQuery q( db );
+ q.exec("drop table " + qtest_precision);
if ( tst_Databases::isMSAccess( db ) )
QVERIFY_SQL( q, exec( "create table " + qtest_precision + " (col1 number)" ) );
else
@@ -1751,6 +1756,7 @@ void tst_QSqlQuery::prepare_bind_exec()
else
createQuery = "create table " + qtest_prepare + " (id int not null primary key, name varchar(200), name2 varchar(200))";
+ q.exec("drop table " + qtest_prepare);
QVERIFY_SQL( q, exec( createQuery ) );
QVERIFY( q.prepare( "insert into " + qtest_prepare + " (id, name) values (:id, :name)" ) );
@@ -2284,8 +2290,10 @@ void tst_QSqlQuery::execErrorRecovery()
QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_exerr", __FILE__ ) + " (id int not null primary key)" ) );
- QVERIFY_SQL( q, prepare( "insert into " + qTableName( "qtest_exerr", __FILE__ ) + " values (?)" ) );
+ const QString tbl = qTableName("qtest_exerr", __FILE__);
+ q.exec("drop table " + tbl);
+ QVERIFY_SQL(q, exec("create table " + tbl + " (id int not null primary key)"));
+ QVERIFY_SQL(q, prepare("insert into " + tbl + " values (?)" ));
q.addBindValue( 1 );
QVERIFY_SQL( q, exec() );
@@ -2788,8 +2796,10 @@ void tst_QSqlQuery::emptyTableNavigate()
{
QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_empty", __FILE__ ) + " (id char(10))" ) );
- QVERIFY_SQL( q, prepare( "select * from " + qTableName( "qtest_empty", __FILE__ ) ) );
+ const QString tbl = qTableName("qtest_empty", __FILE__);
+ q.exec("drop table " + tbl);
+ QVERIFY_SQL(q, exec("create table " + tbl + " (id char(10))"));
+ QVERIFY_SQL(q, prepare("select * from " + qTableName("qtest_empty", __FILE__ )));
QVERIFY_SQL( q, exec() );
QVERIFY( !q.next() );
QCOMPARE( q.lastError().isValid(), false );
@@ -2804,6 +2814,7 @@ void tst_QSqlQuery::task_217003()
QSqlQuery q( db );
const QString Planet(qTableName( "Planet", __FILE__));
+ q.exec("drop table " + Planet);
QVERIFY_SQL( q, exec( "create table " + Planet + " (Name varchar(20))" ) );
QVERIFY_SQL( q, exec( "insert into " + Planet + " VALUES ('Mercury')" ) );
QVERIFY_SQL( q, exec( "insert into " + Planet + " VALUES ('Venus')" ) );
@@ -3580,7 +3591,7 @@ void tst_QSqlQuery::aggregateFunctionTypes()
CHECK_DATABASE(db);
QVariant::Type intType = QVariant::Int;
// QPSQL uses LongLong for manipulation of integers
- if (db.driverName().startsWith("QPSQL"))
+ if (db.driverName().startsWith("QPSQL") || db.driverName().startsWith("QMYSQL"))
intType = QVariant::LongLong;
{
const QString tableName(qTableName("numericFunctionsWithIntValues", __FILE__));
@@ -3594,6 +3605,8 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY(q.next());
if (db.driverName().startsWith("QSQLITE"))
QCOMPARE(q.record().field(0).type(), QVariant::Invalid);
+ else if (db.driverName().startsWith("QMYSQL"))
+ QCOMPARE(q.record().field(0).type(), QVariant::Double);
else
QCOMPARE(q.record().field(0).type(), intType);
@@ -3603,11 +3616,15 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY_SQL(q, exec("SELECT SUM(id) FROM " + tableName));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 3);
- QCOMPARE(q.record().field(0).type(), intType);
+ if (db.driverName().startsWith("QMYSQL"))
+ QCOMPARE(q.record().field(0).type(), QVariant::Double);
+ else
+ QCOMPARE(q.record().field(0).type(), intType);
QVERIFY_SQL(q, exec("SELECT AVG(id) FROM " + tableName));
QVERIFY(q.next());
- if (db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QPSQL")) {
+ if (db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QPSQL")
+ || (db.driverName().startsWith("QMYSQL"))) {
QCOMPARE(q.value(0).toDouble(), 1.5);
QCOMPARE(q.record().field(0).type(), QVariant::Double);
} else {
@@ -3682,7 +3699,10 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY_SQL(q, exec("SELECT ROUND(id, 0) FROM " + tableName + " WHERE id=2.5"));
QVERIFY(q.next());
- QCOMPARE(q.value(0).toDouble(), 3.0);
+ if (db.driverName().startsWith("QMYSQL"))
+ QCOMPARE(q.value(0).toDouble(), 2.0);
+ else
+ QCOMPARE(q.value(0).toDouble(), 3.0);
QCOMPARE(q.record().field(0).type(), QVariant::Double);
}
}
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()