summaryrefslogtreecommitdiffstats
path: root/tests/auto/sql/kernel/qsqldatabase
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/sql/kernel/qsqldatabase')
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt6
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_databases.h51
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp243
3 files changed, 176 insertions, 124 deletions
diff --git a/tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt b/tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt
index 25e4ff125c..97dbf94af7 100644
--- a/tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt
+++ b/tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qsqldatabase Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqldatabase LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqldatabase
SOURCES
tst_qsqldatabase.cpp
diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
index c715c1c2a8..5a10bde814 100644
--- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
+++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
/* possible connection parameters */
#ifndef TST_DATABASES_H
@@ -9,6 +9,7 @@
#include <QSqlDriver>
#include <QSqlError>
#include <QSqlQuery>
+#include <QSqlRecord>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QDir>
@@ -20,9 +21,12 @@
#include <QJsonObject>
#include <QJsonDocument>
#include <QSysInfo>
+#include <QVersionNumber>
#include <QtSql/private/qsqldriver_p.h>
#include <QTest>
+using namespace Qt::StringLiterals;
+
#define CHECK_DATABASE( db ) \
if ( !db.isValid() ) { qFatal( "db is Invalid" ); }
@@ -114,12 +118,14 @@ public:
if (port > 0)
cName += QLatin1Char(':') + QString::number(port);
+ QString opts = params;
if (driver == "QSQLITE") {
// Since the database for sqlite is generated at runtime it's always
// available, but we use QTempDir so it's always in a different
// location. Thus, let's ignore the path completely.
cName = "SQLite";
qInfo("SQLite will use the database located at %ls", qUtf16Printable(dbName));
+ opts += QStringLiteral(";QSQLITE_ENABLE_NON_ASCII_CASE_FOLDING");
}
auto db = QSqlDatabase::addDatabase(driver, cName);
@@ -133,7 +139,7 @@ public:
db.setPassword(passwd);
db.setHostName(host);
db.setPort(port);
- db.setConnectOptions(params);
+ db.setConnectOptions(opts);
dbNames.append(cName);
}
@@ -434,6 +440,16 @@ public:
return ver;
}
+ static QVersionNumber getIbaseEngineVersion(const QSqlDatabase &db)
+ {
+ QSqlQuery q(db);
+ q.exec("SELECT rdb$get_context('SYSTEM', 'ENGINE_VERSION') as version from rdb$database;"_L1);
+ q.next();
+ auto record = q.record();
+ auto version = QVersionNumber::fromString(record.value(0).toString());
+ return version;
+ }
+
QStringList dbNames;
int counter = 0;
@@ -481,5 +497,36 @@ private:
QString m_tableName;
};
+class ProcScope
+{
+public:
+ ProcScope(const QSqlDatabase &db, const char *procName, const char *file)
+ : m_db(db),
+ m_procName(qTableName(procName, file, db))
+ {
+ cleanup();
+ }
+ ~ProcScope()
+ {
+ cleanup();
+ }
+ QString name() const
+ {
+ return m_procName;
+ }
+protected:
+ void cleanup()
+ {
+ QSqlQuery q(m_db);
+ if (m_db.driverName() == "QIBASE")
+ q.exec("DROP PROCEDURE " + m_procName);
+ else
+ q.exec("DROP PROCEDURE IF EXISTS " + m_procName);
+ }
+private:
+ QSqlDatabase m_db;
+ const QString m_procName;
+};
+
#endif
diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
index f34045b2a0..79fe9d6333 100644
--- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
+++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -104,6 +104,8 @@ private slots:
void infinityAndNan();
void multipleThreads_data() { generic_data(); }
void multipleThreads();
+ void moveToThread_data() { generic_data(); }
+ void moveToThread();
void db2_valueCacheUpdate_data() { generic_data("QDB2"); }
void db2_valueCacheUpdate();
@@ -175,13 +177,13 @@ private slots:
void sqlite_check_json1();
private:
- void createTestTables(QSqlDatabase db);
- void dropTestTables(QSqlDatabase db);
- void populateTestTables(QSqlDatabase db);
+ void createTestTables(const QSqlDatabase &db);
+ void dropTestTables(const QSqlDatabase &db);
+ void populateTestTables(const QSqlDatabase &db);
void generic_data(const QString &engine=QString());
- void testRecord(const FieldDef fieldDefs[], const QSqlRecord& inf, QSqlDatabase db);
- void commonFieldTest(const FieldDef fieldDefs[], QSqlDatabase, const int);
+ void testRecord(const FieldDef fieldDefs[], const QSqlRecord& inf, const QSqlDatabase &db);
+ void commonFieldTest(const FieldDef fieldDefs[], const QSqlDatabase &db, const int fieldCount);
tst_Databases dbs;
};
@@ -216,7 +218,7 @@ struct FieldDef {
// creates a table out of the FieldDefs and returns the number of fields
// excluding the primary key field
-static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db)
+static int createFieldTable(const FieldDef fieldDefs[], const QSqlDatabase &db)
{
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
const QString tableName = qTableName("qtestfields", __FILE__, db);
@@ -251,7 +253,7 @@ static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db)
return i;
}
-void tst_QSqlDatabase::createTestTables(QSqlDatabase db)
+void tst_QSqlDatabase::createTestTables(const QSqlDatabase &db)
{
if (!db.isValid())
return;
@@ -285,7 +287,7 @@ void tst_QSqlDatabase::createTestTables(QSqlDatabase db)
QVERIFY_SQL(q, exec(qry));
}
-void tst_QSqlDatabase::dropTestTables(QSqlDatabase db)
+void tst_QSqlDatabase::dropTestTables(const QSqlDatabase &db)
{
if (!db.isValid())
return;
@@ -297,30 +299,11 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db)
}
// drop the view first, otherwise we'll get dependency problems
- tst_Databases::safeDropViews(db, QStringList() << qTableName("qtest_view", __FILE__, db) << qTableName("qtest_view2", __FILE__, db));
- const QString qtestTable = qTableName("qtest", __FILE__, db);
- QStringList tableNames;
- tableNames << qtestTable
- << qTableName("qtest test", __FILE__, db)
- << qTableName("qtestfields", __FILE__, db)
- << qTableName("qtestalter", __FILE__, db)
- << qTableName("qtest_temp", __FILE__, db)
- << qTableName("qtest_xmltype", __FILE__, db)
- << qTableName("latin1table", __FILE__, db)
- << qTableName("qtest_sqlguid", __FILE__, db)
- << qTableName("batable", __FILE__, db)
- << qTableName("qtest_prec", __FILE__, db)
- << qTableName("uint", __FILE__, db)
- << qTableName("strings", __FILE__, db)
- << qTableName("numericfields", __FILE__, db)
- << qTableName("qtest_ibaseblobs", __FILE__, db)
- << qTableName("qtestBindBool", __FILE__, db)
- << qTableName("testqGetString", __FILE__, db)
- << qTableName("qtest_sqlguid", __FILE__, db)
- << qTableName("uint_table", __FILE__, db)
- << qTableName("uint_test", __FILE__, db)
- << qTableName("bug_249059", __FILE__, db)
- << qTableName("regexp_test", __FILE__, db);
+ tst_Databases::safeDropViews(db, {qTableName("qtest_view", __FILE__, db),
+ qTableName("qtest_view2", __FILE__, db)});
+ QStringList tableNames = {qTableName("qtest", __FILE__, db),
+ qTableName("qtest test", __FILE__, db),
+ qTableName("qtestfields", __FILE__, db)};
QSqlQuery q(0, db);
if (dbType == QSqlDriver::PostgreSQL) {
@@ -340,7 +323,7 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db)
}
}
-void tst_QSqlDatabase::populateTestTables(QSqlDatabase db)
+void tst_QSqlDatabase::populateTestTables(const QSqlDatabase &db)
{
if (!db.isValid())
return;
@@ -526,11 +509,11 @@ void tst_QSqlDatabase::alterTable()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString qtestalter(qTableName("qtestalter", __FILE__, db));
+ TableScope ts(db, "qtestalter", __FILE__);
QSqlQuery q(db);
- QVERIFY_SQL(q, exec("create table " + qtestalter + " (F1 char(20), F2 char(20), F3 char(20))"));
- QSqlRecord rec = db.record(qtestalter);
+ QVERIFY_SQL(q, exec("create table " + ts.tableName() + " (F1 char(20), F2 char(20), F3 char(20))"));
+ QSqlRecord rec = db.record(ts.tableName());
QCOMPARE((int)rec.count(), 3);
int i;
@@ -538,18 +521,18 @@ void tst_QSqlDatabase::alterTable()
QCOMPARE(rec.field(i).name().toUpper(), QString("F%1").arg(i + 1));
}
- if (!q.exec("alter table " + qtestalter + " drop column F2")) {
+ if (!q.exec("alter table " + ts.tableName() + " drop column F2")) {
QSKIP("DBMS doesn't support dropping columns in ALTER TABLE statement");
}
- rec = db.record(qtestalter);
+ rec = db.record(ts.tableName());
QCOMPARE(rec.count(), 2);
QCOMPARE(rec.field(0).name().toUpper(), QString("F1"));
QCOMPARE(rec.field(1).name().toUpper(), QString("F3"));
- q.exec("select * from " + qtestalter);
+ q.exec("select * from " + ts.tableName());
}
#if 0
@@ -577,12 +560,11 @@ void tst_QSqlDatabase::record()
}
#endif
-void tst_QSqlDatabase::testRecord(const FieldDef fieldDefs[], const QSqlRecord& inf, QSqlDatabase db)
+void tst_QSqlDatabase::testRecord(const FieldDef fieldDefs[], const QSqlRecord &inf, const QSqlDatabase &db)
{
- int i = 0;
if (!tst_Databases::autoFieldName(db).isEmpty()) // Currently only MySQL is tested
- QVERIFY2(inf.field(i).isAutoValue(), qPrintable(inf.field(i).name() + " should be reporting as an autovalue"));
- for (i = 0; !fieldDefs[ i ].typeName.isNull(); ++i) {
+ QVERIFY2(inf.field(0).isAutoValue(), qPrintable(inf.field(0).name() + " should be reporting as an autovalue"));
+ for (int i = 0; !fieldDefs[ i ].typeName.isNull(); ++i) {
QCOMPARE(inf.field(i+1).name().toUpper(), fieldDefs[ i ].fieldName().toUpper());
if (inf.field(i+1).metaType().id() != fieldDefs[ i ].type) {
QFAIL(qPrintable(QString(" Expected: '%1' Received: '%2' for field %3 in testRecord").arg(
@@ -597,7 +579,7 @@ void tst_QSqlDatabase::testRecord(const FieldDef fieldDefs[], const QSqlRecord&
}
// non-dbms specific tests
-void tst_QSqlDatabase::commonFieldTest(const FieldDef fieldDefs[], QSqlDatabase db, const int fieldCount)
+void tst_QSqlDatabase::commonFieldTest(const FieldDef fieldDefs[], const QSqlDatabase &db, const int fieldCount)
{
CHECK_DATABASE(db);
@@ -1267,24 +1249,24 @@ void tst_QSqlDatabase::psql_escapeBytea()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "batable", __FILE__);
const char dta[4] = {'\x71', '\x14', '\x32', '\x81'};
QByteArray ba(dta, 4);
QSqlQuery q(db);
- const QString tableName(qTableName("batable", __FILE__, db));
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (ba bytea)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (ba bytea)").arg(ts.tableName())));
QSqlQuery iq(db);
- QVERIFY_SQL(iq, prepare(QString("INSERT INTO %1 VALUES (?)").arg(tableName)));
+ QVERIFY_SQL(iq, prepare(QString("INSERT INTO %1 VALUES (?)").arg(ts.tableName())));
iq.bindValue(0, QVariant(ba));
QVERIFY_SQL(iq, exec());
- QVERIFY_SQL(q, exec(QString("SELECT ba FROM %1").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("SELECT ba FROM %1").arg(ts.tableName())));
QVERIFY_SQL(q, next());
QByteArray res = q.value(0).toByteArray();
- int i = 0;
+ qsizetype i = 0;
for (; i < ba.size(); ++i){
if (ba[i] != res[i])
break;
@@ -1298,13 +1280,13 @@ void tst_QSqlDatabase::psql_bug249059()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "bug_249059", __FILE__);
QSqlQuery q(db);
- const QString tableName(qTableName("bug_249059", __FILE__, db));
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (dt timestamp, t time)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (dt timestamp, t time)").arg(ts.tableName())));
QSqlQuery iq(db);
- QVERIFY_SQL(iq, prepare(QString("INSERT INTO %1 VALUES (?, ?)").arg(tableName)));
+ QVERIFY_SQL(iq, prepare(QString("INSERT INTO %1 VALUES (?, ?)").arg(ts.tableName())));
iq.bindValue(0, QVariant(QString("2001-09-09 04:05:06.789 -5:00")));
iq.bindValue(1, QVariant(QString("04:05:06.789 -5:00")));
QVERIFY_SQL(iq, exec());
@@ -1312,7 +1294,7 @@ void tst_QSqlDatabase::psql_bug249059()
iq.bindValue(1, QVariant(QString("04:05:06.789 +5:00")));
QVERIFY_SQL(iq, exec());
- QVERIFY_SQL(q, exec(QString("SELECT dt, t FROM %1").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("SELECT dt, t FROM %1").arg(ts.tableName())));
QVERIFY_SQL(q, next());
QDateTime dt1=q.value(0).toDateTime();
QTime t1=q.value(1).toTime();
@@ -1325,17 +1307,15 @@ void tst_QSqlDatabase::psql_bug249059()
QCOMPARE(t1, t2);
}
-// This test should be rewritten to work with Oracle as well - or the Oracle driver
-// should be fixed to make this test pass (handle overflows)
void tst_QSqlDatabase::precisionPolicy()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
-// DBMS_SPECIFIC(db, "QPSQL");
+ TableScope ts(db, "qtest_prec", __FILE__);
+ const auto &tableName = ts.tableName();
QSqlQuery q(db);
- const QString tableName(qTableName("qtest_prec", __FILE__, db));
if(!db.driver()->hasFeature(QSqlDriver::LowPrecisionNumbers))
QSKIP("Driver or database doesn't support setting precision policy");
@@ -1466,14 +1446,14 @@ void tst_QSqlDatabase::mysqlOdbc_unsignedIntegers()
if (tst_Databases::getDatabaseType(db) != QSqlDriver::MySqlServer || !db.driverName().startsWith("QODBC"))
QSKIP("MySQL through ODBC-driver specific test");
+ TableScope ts(db, "uint", __FILE__);
QSqlQuery q(db);
- const QString tableName(qTableName("uint", __FILE__, db));
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (foo integer(10) unsigned, bar integer(10))").arg(tableName)));
- QVERIFY_SQL(q, exec(QString("INSERT INTO %1 VALUES (-4000000000, -4000000000)").arg(tableName)));
- QVERIFY_SQL(q, exec(QString("INSERT INTO %1 VALUES (4000000000, 4000000000)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (foo integer(10) unsigned, bar integer(10))").arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QString("INSERT INTO %1 VALUES (-4000000000, -4000000000)").arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QString("INSERT INTO %1 VALUES (4000000000, 4000000000)").arg(ts.tableName())));
- QVERIFY_SQL(q, exec(QString("SELECT foo, bar FROM %1").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("SELECT foo, bar FROM %1").arg(ts.tableName())));
QVERIFY(q.next());
QCOMPARE(q.value(0).toString(), QString("0"));
QCOMPARE(q.value(1).toString(), QString("-2147483648"));
@@ -1490,13 +1470,13 @@ void tst_QSqlDatabase::accessOdbc_strings()
if (!tst_Databases::isMSAccess(db))
QSKIP("MS Access specific test");
+ TableScope ts(db, "strings", __FILE__);
QSqlQuery q(db);
- const QString tableName(qTableName("strings", __FILE__, db));
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (aStr memo, bStr memo, cStr memo, dStr memo"
- ", eStr memo, fStr memo, gStr memo, hStr memo)").arg(tableName)));
+ ", eStr memo, fStr memo, gStr memo, hStr memo)").arg(ts.tableName())));
- QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES (?, ?, ?, ?, ?, ?, ?, ?)").arg(tableName)));
+ QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES (?, ?, ?, ?, ?, ?, ?, ?)").arg(ts.tableName())));
QString aStr, bStr, cStr, dStr, eStr, fStr, gStr, hStr;
q.bindValue(0, aStr.fill('A', 32));
@@ -1510,7 +1490,7 @@ void tst_QSqlDatabase::accessOdbc_strings()
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec(QString("SELECT aStr, bStr, cStr, dStr, eStr, fStr, gStr, hStr FROM %1").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("SELECT aStr, bStr, cStr, dStr, eStr, fStr, gStr, hStr FROM %1").arg(ts.tableName())));
q.next();
QCOMPARE(q.value(0).toString(), aStr);
QCOMPARE(q.value(1).toString(), bStr);
@@ -1528,9 +1508,10 @@ void tst_QSqlDatabase::ibase_numericFields()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "numericfields", __FILE__);
+ const auto &tableName = ts.tableName();
QSqlQuery q(db);
- const QString tableName(qTableName("numericfields", __FILE__, db));
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (id int not null, num1 NUMERIC(2,1), "
"num2 NUMERIC(5,2), num3 NUMERIC(10,3), "
"num4 NUMERIC(18,4))").arg(tableName)));
@@ -1601,8 +1582,9 @@ void tst_QSqlDatabase::ibase_fetchBlobs()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "qtest_ibaseblobs", __FILE__);
+ const auto &tableName = ts.tableName();
- const QString tableName(qTableName("qtest_ibaseblobs", __FILE__, db));
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (blob1 BLOB segment size 256)").arg(tableName)));
@@ -1633,13 +1615,11 @@ void tst_QSqlDatabase::ibase_procWithoutReturnValues()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ ProcScope ps(db, "qtest_proc1", __FILE__);
QSqlQuery q(db);
- const QString procName(qTableName("qtest_proc1", __FILE__, db));
- q.exec(QString("drop procedure %1").arg(procName));
- QVERIFY_SQL(q, exec("CREATE PROCEDURE " + procName + " (str VARCHAR(10))\nAS BEGIN\nstr='test';\nEND;"));
- QVERIFY_SQL(q, exec(QString("execute procedure %1('qtest')").arg(procName)));
- q.exec(QString("drop procedure %1").arg(procName));
+ QVERIFY_SQL(q, exec("CREATE PROCEDURE " + ps.name() + " (str VARCHAR(10))\nAS BEGIN\nstr='test';\nEND;"));
+ QVERIFY_SQL(q, exec(QString("execute procedure %1('qtest')").arg(ps.name())));
}
void tst_QSqlDatabase::ibase_procWithReturnValues()
@@ -1647,12 +1627,10 @@ void tst_QSqlDatabase::ibase_procWithReturnValues()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
-
- const QString procName(qTableName("qtest_proc2", __FILE__, db));
+ ProcScope ps(db, "qtest_proc2", __FILE__);
QSqlQuery q(db);
- q.exec(QString("drop procedure %1").arg(procName));
- QVERIFY_SQL(q, exec("CREATE PROCEDURE " + procName + " ("
+ QVERIFY_SQL(q, exec("CREATE PROCEDURE " + ps.name() + " ("
"\nABC INTEGER)"
"\nRETURNS ("
"\nRESULT INTEGER)"
@@ -1663,13 +1641,13 @@ void tst_QSqlDatabase::ibase_procWithReturnValues()
"\nend"));
// Interbase procedures can be executed in two ways: EXECUTE PROCEDURE or SELECT
- QVERIFY_SQL(q, exec(QString("execute procedure %1(123)").arg(procName)));
+ QVERIFY_SQL(q, exec(QString("execute procedure %1(123)").arg(ps.name())));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 1230);
- QVERIFY_SQL(q, exec(QString("select result from %1(456)").arg(procName)));
+ QVERIFY_SQL(q, exec(QString("select result from %1(456)").arg(ps.name())));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 4560);
- QVERIFY_SQL(q, prepare(QLatin1String("execute procedure ")+procName+QLatin1String("(?)")));
+ QVERIFY_SQL(q, prepare(QLatin1String("execute procedure ") + ps.name() + QLatin1String("(?)")));
q.bindValue(0, 123);
QVERIFY_SQL(q, exec());
QVERIFY_SQL(q, next());
@@ -1678,8 +1656,6 @@ void tst_QSqlDatabase::ibase_procWithReturnValues()
QVERIFY_SQL(q, exec());
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 4560);
-
- q.exec(QString("drop procedure %1").arg(procName));
}
void tst_QSqlDatabase::formatValueTrimStrings()
@@ -1736,13 +1712,13 @@ void tst_QSqlDatabase::odbc_bindBoolean()
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::MySqlServer)
QSKIP("MySql has inconsistent behaviour of bit field type across versions.");
+ TableScope ts(db, "qtestBindBool", __FILE__);
QSqlQuery q(db);
- const QString tableName = qTableName("qtestBindBool", __FILE__, db);
- QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + "(id int, boolvalue bit)"));
+ QVERIFY_SQL(q, exec("CREATE TABLE " + ts.tableName() + "(id int, boolvalue bit)"));
// Bind and insert
- QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " VALUES(?, ?)"));
+ QVERIFY_SQL(q, prepare("INSERT INTO " + ts.tableName() + " VALUES(?, ?)"));
q.bindValue(0, 1);
q.bindValue(1, true);
QVERIFY_SQL(q, exec());
@@ -1751,7 +1727,7 @@ void tst_QSqlDatabase::odbc_bindBoolean()
QVERIFY_SQL(q, exec());
// Retrive
- QVERIFY_SQL(q, exec("SELECT id, boolvalue FROM " + tableName + " ORDER BY id"));
+ QVERIFY_SQL(q, exec("SELECT id, boolvalue FROM " + ts.tableName() + " ORDER BY id"));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 1);
QCOMPARE(q.value(1).toBool(), true);
@@ -1765,7 +1741,8 @@ void tst_QSqlDatabase::odbc_testqGetString()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString testqGetString(qTableName("testqGetString", __FILE__, db));
+ TableScope ts(db, "testqGetString", __FILE__);
+ const auto &testqGetString = ts.tableName();
QSqlQuery q(db);
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
@@ -1845,8 +1822,9 @@ void tst_QSqlDatabase::oci_xmltypeSupport()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "qtest_xmltype", __FILE__);
+ const auto &tableName = ts.tableName();
- const QString tableName(qTableName("qtest_xmltype", __FILE__, db));
QString xml("<?xml version=\"1.0\"?>\n<TABLE_NAME>MY_TABLE</TABLE_NAME>\n");
QSqlQuery q(db);
@@ -1924,14 +1902,14 @@ void tst_QSqlDatabase::odbc_uniqueidentifier()
if (dbType != QSqlDriver::MSSqlServer)
QSKIP("SQL Server (ODBC) specific test");
- const QString tableName(qTableName("qtest_sqlguid", __FILE__, db));
+ TableScope ts(db, "qtest_sqlguid", __FILE__);
QString guid = QString("AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE");
QString invalidGuid = QString("GAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE");
QSqlQuery q(db);
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(id uniqueidentifier)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(id uniqueidentifier)").arg(ts.tableName())));
- q.prepare(QString("INSERT INTO %1 VALUES(?)").arg(tableName));;
+ q.prepare(QString("INSERT INTO %1 VALUES(?)").arg(ts.tableName()));
q.addBindValue(guid);
QVERIFY_SQL(q, exec());
@@ -1940,7 +1918,7 @@ void tst_QSqlDatabase::odbc_uniqueidentifier()
Continue);
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec(QString("SELECT id FROM %1").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("SELECT id FROM %1").arg(ts.tableName())));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toString(), guid);
}
@@ -1966,20 +1944,20 @@ void tst_QSqlDatabase::odbc_uintfield()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "uint_table", __FILE__);
- const QString tableName(qTableName("uint_table", __FILE__, db));
- unsigned int val = 4294967295U;
+ constexpr auto val = std::numeric_limits<unsigned int>::max();
QSqlQuery q(db);
if ( tst_Databases::isMSAccess( db ) )
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(num number)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(num number)").arg(ts.tableName())));
else
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(num numeric(10))").arg(tableName)));
- q.prepare(QString("INSERT INTO %1 VALUES(?)").arg(tableName));
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(num numeric(10))").arg(ts.tableName())));
+ q.prepare(QString("INSERT INTO %1 VALUES(?)").arg(ts.tableName()));
q.addBindValue(val);
QVERIFY_SQL(q, exec());
- q.exec(QString("SELECT num FROM %1").arg(tableName));
+ q.exec(QString("SELECT num FROM %1").arg(ts.tableName()));
if (q.next())
QCOMPARE(q.value(0).toUInt(), val);
}
@@ -2038,34 +2016,30 @@ void tst_QSqlDatabase::eventNotificationIBase()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString procedureName(qTableName("posteventProc", __FILE__, db));
+ ProcScope ps(db, "posteventProc", __FILE__);
QSqlDriver *driver=db.driver();
- QVERIFY_SQL(*driver, subscribeToNotification(procedureName));
+ QVERIFY_SQL(*driver, subscribeToNotification(ps.name()));
QTest::qWait(300); // Interbase needs some time to call the driver callback.
db.transaction(); // InterBase events are posted from within transactions.
QSqlQuery q(db);
- q.exec(QString("DROP PROCEDURE %1").arg(procedureName));
- q.exec(QString("CREATE PROCEDURE %1\nAS BEGIN\nPOST_EVENT '%1';\nEND;").arg(procedureName));
- q.exec(QString("EXECUTE PROCEDURE %1").arg(procedureName));
- QSignalSpy spy(driver, QOverload<const QString &, QSqlDriver::NotificationSource, const QVariant &>::of(&QSqlDriver::notification));
+ q.exec(QString("CREATE PROCEDURE %1\nAS BEGIN\nPOST_EVENT '%1';\nEND;").arg(ps.name()));
+ q.exec(QString("EXECUTE PROCEDURE %1").arg(ps.name()));
+ QSignalSpy spy(driver, &QSqlDriver::notification);
db.commit(); // No notifications are posted until the transaction is committed.
// Interbase needs some time to post the notification and call the driver callback.
// This happends from another thread, and we have to process events in order for the
// event handler in the driver to be executed and emit the notification signal.
QTRY_COMPARE(spy.size(), 1);
QList<QVariant> arguments = spy.takeFirst();
- QCOMPARE(arguments.at(0).toString(), procedureName);
- QVERIFY_SQL(*driver, unsubscribeFromNotification(procedureName));
- q.exec(QString("DROP PROCEDURE %1").arg(procedureName));
+ QCOMPARE(arguments.at(0).toString(), ps.name());
+ QVERIFY_SQL(*driver, unsubscribeFromNotification(ps.name()));
}
void tst_QSqlDatabase::eventNotificationPSQL()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
- if (db.driverName().compare(QLatin1String("QPSQL"), Qt::CaseInsensitive))
- QSKIP("QPSQL specific test");
CHECK_DATABASE(db);
QSqlQuery query(db);
@@ -2073,7 +2047,7 @@ void tst_QSqlDatabase::eventNotificationPSQL()
QString payload = "payload";
QSqlDriver *driver = db.driver();
QVERIFY_SQL(*driver, subscribeToNotification(procedureName));
- QSignalSpy spy(driver, QOverload<const QString &, QSqlDriver::NotificationSource, const QVariant &>::of(&QSqlDriver::notification));
+ QSignalSpy spy(driver, &QSqlDriver::notification);
query.exec(QString("NOTIFY \"%1\", '%2'").arg(procedureName).arg(payload));
QTRY_COMPARE(spy.size(), 1);
QList<QVariant> arguments = spy.takeFirst();
@@ -2087,15 +2061,13 @@ void tst_QSqlDatabase::eventNotificationSQLite()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
- if (db.driverName().compare(QLatin1String("QSQLITE"), Qt::CaseInsensitive))
- QSKIP("QSQLITE specific test");
CHECK_DATABASE(db);
TableScope ts(db, "sqlitnotifytest", __FILE__);
TableScope tsEscape(db, "sqlitnotifytest", __FILE__, false);
QSqlDriver *driver = db.driver();
- QSignalSpy spy(driver, QOverload<const QString &, QSqlDriver::NotificationSource, const QVariant &>::of(&QSqlDriver::notification));
+ QSignalSpy spy(driver, &QSqlDriver::notification);
QSqlQuery q(db);
QVERIFY_SQL(q, exec("CREATE TABLE " + ts.tableName() + " (id INTEGER, realVal REAL)"));
driver->subscribeToNotification(tsEscape.tableName());
@@ -2113,13 +2085,13 @@ void tst_QSqlDatabase::sqlite_bindAndFetchUInt()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "uint_test", __FILE__);
QSqlQuery q(db);
- const QString tableName(qTableName("uint_test", __FILE__, db));
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(uint_field UNSIGNED INTEGER)").arg(tableName)));
- QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES(?)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(uint_field UNSIGNED INTEGER)").arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES(?)").arg(ts.tableName())));
q.addBindValue(4000000000U);
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec(QString("SELECT uint_field FROM %1").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("SELECT uint_field FROM %1").arg(ts.tableName())));
QVERIFY_SQL(q, next());
// All integers in SQLite are signed, so even though we bound the value
@@ -2229,18 +2201,18 @@ void tst_QSqlDatabase::sqlite_enableRegexp()
db.close();
db.setConnectOptions("QSQLITE_ENABLE_REGEXP");
QVERIFY_SQL(db, open());
+ TableScope ts(db, "regexp_test", __FILE__);
QSqlQuery q(db);
- const QString tableName(qTableName("regexp_test", __FILE__, db));
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(text TEXT)").arg(tableName)));
- QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES(?)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(text TEXT)").arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES(?)").arg(ts.tableName())));
q.addBindValue("a0");
QVERIFY_SQL(q, exec());
q.addBindValue("a1");
QVERIFY_SQL(q, exec());
QVERIFY_SQL(q, exec(QString("SELECT text FROM %1 WHERE text REGEXP 'a[^0]' "
- "ORDER BY text").arg(tableName)));
+ "ORDER BY text").arg(ts.tableName())));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toString(), QString("a1"));
QFAIL_SQL(q, next());
@@ -2365,5 +2337,32 @@ void tst_QSqlDatabase::multipleThreads()
QTRY_VERIFY(t.isFinished());
}
+void tst_QSqlDatabase::moveToThread()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ auto clonedDb = QSqlDatabase::cloneDatabase(db, "clonedDb");
+ auto mainThread = QThread::currentThread();
+ CHECK_DATABASE(db);
+ QCOMPARE(db.thread(), mainThread);
+ QCOMPARE(clonedDb.thread(), mainThread);
+ std::unique_ptr<QThread> t(QThread::create([&] {
+ db.moveToThread(mainThread);
+ QThread::currentThread()->exit();
+ }));
+ db.moveToThread(t.get());
+ QCOMPARE(db.thread(), t.get());
+ QCOMPARE(clonedDb.thread(), mainThread);
+ t->start();
+ QTRY_VERIFY(t->isRunning());
+ QTRY_VERIFY(t->wait(30000));
+ QCOMPARE(db.thread(), mainThread);
+ QCOMPARE(clonedDb.thread(), mainThread);
+ db = QSqlDatabase();
+ clonedDb = QSqlDatabase();
+ QSqlDatabase::removeDatabase("clonedDb");
+}
+
+
QTEST_MAIN(tst_QSqlDatabase)
#include "tst_qsqldatabase.moc"