summaryrefslogtreecommitdiffstats
path: root/tests/auto/sql
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/sql')
-rw-r--r--tests/auto/sql/CMakeLists.txt3
-rw-r--r--tests/auto/sql/kernel/CMakeLists.txt5
-rw-r--r--tests/auto/sql/kernel/qsql/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsql/tst_qsql.cpp30
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_databases.h423
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp602
-rw-r--r--tests/auto/sql/kernel/qsqldriver/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp70
-rw-r--r--tests/auto/sql/kernel/qsqlerror/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp12
-rw-r--r--tests/auto/sql/kernel/qsqlfield/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlfield/tst_qsqlfield.cpp22
-rw-r--r--tests/auto/sql/kernel/qsqlindex/CMakeLists.txt21
-rw-r--r--tests/auto/sql/kernel/qsqlindex/tst_qsqlindex.cpp126
-rw-r--r--tests/auto/sql/kernel/qsqlquery/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp1062
-rw-r--r--tests/auto/sql/kernel/qsqlrecord/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp91
-rw-r--r--tests/auto/sql/kernel/qsqlresult/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlresult/testsqldriver.h2
-rw-r--r--tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp36
-rw-r--r--tests/auto/sql/kernel/qsqlthread/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp18
-rw-r--r--tests/auto/sql/kernel/qvfssql/CMakeLists.txt30
-rw-r--r--tests/auto/sql/kernel/qvfssql/sample.dbbin0 -> 49152 bytes
-rw-r--r--tests/auto/sql/kernel/qvfssql/tst_qvfssql.cpp94
-rw-r--r--tests/auto/sql/models/CMakeLists.txt3
-rw-r--r--tests/auto/sql/models/qsqlquerymodel/CMakeLists.txt11
-rw-r--r--tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp62
-rw-r--r--tests/auto/sql/models/qsqlrelationaldelegate/CMakeLists.txt11
-rw-r--r--tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp19
-rw-r--r--tests/auto/sql/models/qsqlrelationaltablemodel/CMakeLists.txt11
-rw-r--r--tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp347
-rw-r--r--tests/auto/sql/models/qsqltablemodel/CMakeLists.txt11
-rw-r--r--tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp206
36 files changed, 1882 insertions, 1545 deletions
diff --git a/tests/auto/sql/CMakeLists.txt b/tests/auto/sql/CMakeLists.txt
index 415d7598ae..94d7644d5d 100644
--- a/tests/auto/sql/CMakeLists.txt
+++ b/tests/auto/sql/CMakeLists.txt
@@ -1,4 +1,5 @@
-# Generated from sql.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(kernel)
add_subdirectory(models)
diff --git a/tests/auto/sql/kernel/CMakeLists.txt b/tests/auto/sql/kernel/CMakeLists.txt
index dbd36bf012..d51cb75f31 100644
--- a/tests/auto/sql/kernel/CMakeLists.txt
+++ b/tests/auto/sql/kernel/CMakeLists.txt
@@ -1,11 +1,14 @@
-# Generated from kernel.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(qsqlfield)
add_subdirectory(qsqldatabase)
add_subdirectory(qsqlerror)
add_subdirectory(qsqldriver)
+add_subdirectory(qsqlindex)
add_subdirectory(qsqlquery)
add_subdirectory(qsqlrecord)
add_subdirectory(qsqlthread)
add_subdirectory(qsql)
add_subdirectory(qsqlresult)
+add_subdirectory(qvfssql)
diff --git a/tests/auto/sql/kernel/qsql/CMakeLists.txt b/tests/auto/sql/kernel/qsql/CMakeLists.txt
index b42a1b110d..8e0448a786 100644
--- a/tests/auto/sql/kernel/qsql/CMakeLists.txt
+++ b/tests/auto/sql/kernel/qsql/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qsql.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsql Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsql LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsql
SOURCES
tst_qsql.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::SqlPrivate
)
diff --git a/tests/auto/sql/kernel/qsql/tst_qsql.cpp b/tests/auto/sql/kernel/qsql/tst_qsql.cpp
index 1d6b271f44..7b6e260ebf 100644
--- a/tests/auto/sql/kernel/qsql/tst_qsql.cpp
+++ b/tests/auto/sql/kernel/qsql/tst_qsql.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>
@@ -19,11 +19,6 @@ class tst_QSql : public QObject
{
Q_OBJECT
-public:
- tst_QSql();
- virtual ~tst_QSql();
-
-
public slots:
void initTestCase();
void cleanupTestCase();
@@ -41,15 +36,6 @@ private slots:
};
/****************** General Qt SQL Module tests *****************/
-
-tst_QSql::tst_QSql()
-{
-}
-
-tst_QSql::~tst_QSql()
-{
-}
-
void tst_QSql::initTestCase()
{
}
@@ -80,7 +66,7 @@ void tst_QSql::basicDriverTest()
tst_Databases dbs;
QVERIFY(dbs.open());
- foreach (const QString& dbName, dbs.dbNames) {
+ for (const QString &dbName : std::as_const(dbs.dbNames)) {
QSqlDatabase db = QSqlDatabase::database(dbName);
QVERIFY_SQL(db, isValid());
@@ -125,16 +111,20 @@ void tst_QSql::open()
QVERIFY(dbs.open());
if (count == -1)
// first iteration: see how many dbs are open
- count = (int) dbs.dbNames.count();
+ count = (int) dbs.dbNames.size();
else
// next iterations: make sure all are opened again
- QCOMPARE(count, (int)dbs.dbNames.count());
+ QCOMPARE(count, (int)dbs.dbNames.size());
dbs.close();
}
}
void tst_QSql::openInvalid()
{
+ int argc = 1;
+ char *argv[] = { const_cast<char*>(QTest::currentAppName()) };
+ QCoreApplication app(argc, argv, false);
+
QSqlDatabase db;
QVERIFY(!db.open());
@@ -150,7 +140,7 @@ void tst_QSql::concurrentAccess()
tst_Databases dbs;
QVERIFY(dbs.open());
- foreach (const QString& dbName, dbs.dbNames) {
+ for (const QString &dbName : std::as_const(dbs.dbNames)) {
QSqlDatabase db = QSqlDatabase::database(dbName);
QVERIFY(db.isValid());
if (tst_Databases::isMSAccess(db))
@@ -182,7 +172,7 @@ void tst_QSql::openErrorRecovery()
QVERIFY(dbs.addDbs());
if (dbs.dbNames.isEmpty())
QSKIP("No database drivers installed");
- foreach (const QString& dbName, dbs.dbNames) {
+ for (const QString &dbName : std::as_const(dbs.dbNames)) {
QSqlDatabase db = QSqlDatabase::database(dbName, false);
CHECK_DATABASE(db);
diff --git a/tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt b/tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt
index aebf9013ff..97dbf94af7 100644
--- a/tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt
+++ b/tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qsqldatabase.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## 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
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Sql
Qt::SqlPrivate
diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
index 5b0283d285..f81fe5548b 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>
@@ -19,9 +20,13 @@
#include <QJsonArray>
#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" ); }
@@ -31,88 +36,26 @@
#define DBMS_SPECIFIC(db, driver) \
if (!db.driverName().startsWith(driver)) { QSKIP(driver " specific test"); }
-// ### use QSystem::hostName if it is integrated in qtest/main
-static QString qGetHostName()
-{
- static QString hostname;
-
- if (hostname.isEmpty()) {
- hostname = QSysInfo::machineHostName();
- hostname.replace(QLatin1Char( '.' ), QLatin1Char( '_' ));
- hostname.replace(QLatin1Char( '-' ), QLatin1Char( '_' ));
- }
-
- return hostname;
-}
-
-inline QString fixupTableName(const QString &tableName, QSqlDatabase db)
-{
- QString tbName = tableName;
- // On Oracle we are limited to 30 character tablenames
- QSqlDriverPrivate *d = static_cast<QSqlDriverPrivate *>(QObjectPrivate::get(db.driver()));
- if (d && d->dbmsType == QSqlDriver::Oracle)
- tbName.truncate(30);
- // On Interbase we are limited to 31 character tablenames
- if (d && d->dbmsType == QSqlDriver::Interbase)
- tbName.truncate(31);
- return tbName;
-}
-
// to prevent nameclashes on our database server, each machine
// will use its own set of table names. Call this function to get
// "tablename_hostname"
inline static QString qTableName(const QString &prefix, const char *sourceFileName,
QSqlDatabase db, bool escape = true)
{
- const auto tableStr = fixupTableName(QString(QLatin1String("dbtst") + db.driverName() + "_" +
- prefix + QString::number(qHash(QLatin1String(sourceFileName) +
- "_" + qGetHostName().replace("-", "_")), 16)), db);
+ const auto hash = qHash(QLatin1String(sourceFileName) + '_' +
+ QSysInfo::machineHostName().replace('-', '_'));
+ auto tableStr = QLatin1String("dbtst") + db.driverName() + '_' + prefix +
+ QString::number(hash, 16);
+ // Oracle & Interbase/Firebird have a limit on the tablename length
+ QSqlDriver *drv = db.driver();
+ if (drv)
+ tableStr.truncate(drv->maximumIdentifierLength(QSqlDriver::TableName));
return escape ? db.driver()->escapeIdentifier(tableStr, QSqlDriver::TableName) : tableStr;
}
-inline static QString qTableName(const QString& prefix, QSqlDatabase db)
-{
- QString tableStr;
- if (db.driverName().toLower().contains("ODBC"))
- tableStr += QLatin1String("_odbc");
- return fixupTableName(QString(db.driver()->escapeIdentifier(prefix + tableStr + QLatin1Char('_') +
- qGetHostName(), QSqlDriver::TableName)),db);
-}
-
-inline static bool testWhiteSpaceNames( const QString &name )
-{
-/* return name.startsWith( "QPSQL" )
- || name.startsWith( "QODBC" )
- || name.startsWith( "QSQLITE" )
- || name.startsWith( "QMYSQL" );*/
- return name != QLatin1String("QSQLITE2");
-}
-
-inline static QString toHex( const QString& binary )
-{
- QString str;
- static char const hexchars[] = "0123456789ABCDEF";
-
- for ( int i = 0; i < binary.size(); i++ ) {
- ushort code = binary.at(i).unicode();
- str += (QChar)(hexchars[ (code >> 12) & 0x0F ]);
- str += (QChar)(hexchars[ (code >> 8) & 0x0F ]);
- str += (QChar)(hexchars[ (code >> 4) & 0x0F ]);
- str += (QChar)(hexchars[ code & 0x0F ]);
- }
-
- return str;
-}
-
-
class tst_Databases
{
-
public:
- tst_Databases(): counter( 0 )
- {
- }
-
~tst_Databases()
{
close();
@@ -120,83 +63,84 @@ public:
// returns a testtable consisting of the names of all database connections if
// driverPrefix is empty, otherwise only those that start with driverPrefix.
- int fillTestTable( const QString& driverPrefix = QString() ) const
+ int fillTestTable(const QString &driverPrefix = QString()) const
{
- QTest::addColumn<QString>( "dbName" );
+ QTest::addColumn<QString>("dbName");
int count = 0;
- for ( int i = 0; i < dbNames.count(); ++i ) {
- QSqlDatabase db = QSqlDatabase::database( dbNames.at( i ) );
-
- if ( !db.isValid() )
+ for (const auto &dbName : std::as_const(dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ if (!db.isValid())
continue;
-
- if ( driverPrefix.isEmpty() || db.driverName().startsWith( driverPrefix ) ) {
- QTest::newRow( dbNames.at( i ).toLatin1() ) << dbNames.at( i );
+ if (driverPrefix.isEmpty() || db.driverName().startsWith(driverPrefix)) {
+ QTest::newRow(dbName.toLatin1()) << dbName;
++count;
}
}
-
return count;
}
- int fillTestTableWithStrategies( const QString& driverPrefix = QString() ) const
+ int fillTestTableWithStrategies(const QString &driverPrefix = QString()) const
{
- QTest::addColumn<QString>( "dbName" );
- QTest::addColumn<int>("submitpolicy_i");
+ QTest::addColumn<QString>("dbName");
+ QTest::addColumn<QSqlTableModel::EditStrategy>("submitpolicy");
int count = 0;
- for ( int i = 0; i < dbNames.count(); ++i ) {
- QSqlDatabase db = QSqlDatabase::database( dbNames.at( i ) );
-
- if ( !db.isValid() )
+ for (const auto &dbName : std::as_const(dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ if (!db.isValid())
continue;
if ( driverPrefix.isEmpty() || db.driverName().startsWith( driverPrefix ) ) {
- QTest::newRow( QString("%1 [field]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnFieldChange;
- QTest::newRow( QString("%1 [row]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnRowChange;
- QTest::newRow( QString("%1 [manual]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnManualSubmit;
+ QTest::newRow(QString("%1 [field]").arg(dbName).toLatin1() ) << dbName << QSqlTableModel::OnFieldChange;
+ QTest::newRow(QString("%1 [row]").arg(dbName).toLatin1() ) << dbName << QSqlTableModel::OnRowChange;
+ QTest::newRow(QString("%1 [manual]").arg(dbName).toLatin1() ) << dbName << QSqlTableModel::OnManualSubmit;
++count;
}
}
-
return count;
}
- void addDb( const QString& driver, const QString& dbName,
- const QString& user = QString(), const QString& passwd = QString(),
- const QString& host = QString(), int port = -1, const QString params = QString() )
+ void addDb(const QString &driver, const QString &dbName,
+ const QString &user = QString(), const QString &passwd = QString(),
+ const QString &host = QString(), int port = -1, const QString &params = QString())
{
- QSqlDatabase db;
-
- if ( !QSqlDatabase::drivers().contains( driver ) ) {
+ if (!QSqlDatabase::drivers().contains(driver)) {
qWarning() << "Driver" << driver << "is not installed";
return;
}
// construct a stupid unique name
- QString cName = QString::number( counter++ ) + QLatin1Char('_') + driver + QLatin1Char('@');
+ QString cName = QString::number(counter++) + QLatin1Char('_') + driver + QLatin1Char('@');
cName += host.isEmpty() ? dbName : host;
- if ( port > 0 )
- cName += QLatin1Char(':') + QString::number( port );
-
- db = QSqlDatabase::addDatabase( driver, cName );
+ 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");
+ }
- if ( !db.isValid() ) {
+ auto db = QSqlDatabase::addDatabase(driver, cName);
+ if (!db.isValid()) {
qWarning( "Could not create database object" );
return;
}
- db.setDatabaseName( dbName );
-
- db.setUserName( user );
- db.setPassword( passwd );
- db.setHostName( host );
- db.setPort( port );
- db.setConnectOptions( params );
- dbNames.append( cName );
+ db.setDatabaseName(dbName);
+ db.setUserName(user);
+ db.setPassword(passwd);
+ db.setHostName(host);
+ db.setPort(port);
+ db.setConnectOptions(opts);
+ dbNames.append(cName);
}
bool addDbs()
@@ -231,10 +175,9 @@ public:
qWarning() << "No entries in " + f.fileName();
} else {
const QJsonArray entriesA = entriesV.toArray();
- QJsonArray::const_iterator it = entriesA.constBegin();
- while (it != entriesA.constEnd()) {
- if ((*it).isObject()) {
- const QJsonObject object = (*it).toObject();
+ for (const auto &elem : entriesA) {
+ if (elem.isObject()) {
+ const QJsonObject object = elem.toObject();
addDb(object.value(QStringLiteral("driver")).toString(),
object.value(QStringLiteral("name")).toString(),
object.value(QStringLiteral("username")).toString(),
@@ -244,13 +187,12 @@ public:
object.value(QStringLiteral("parameters")).toString());
added = true;
}
- ++it;
}
}
}
QTemporaryDir *sqLiteDir = dbDir();
if (sqLiteDir) {
- addDb(QStringLiteral("QSQLITE"), QDir::toNativeSeparators(sqLiteDir->path() + QStringLiteral("/foo.db")));
+ addDb(QStringLiteral("QSQLITE"), QDir::toNativeSeparators(sqLiteDir->path() + QStringLiteral("/sqlite.db")));
added = true;
}
return added;
@@ -262,17 +204,18 @@ public:
if (!addDbs())
return false;
- QStringList::Iterator it = dbNames.begin();
-
- while ( it != dbNames.end() ) {
- QSqlDatabase db = QSqlDatabase::database(( *it ), false );
- qDebug() << "Opening:" << (*it);
+ auto it = dbNames.begin();
+ while (it != dbNames.end()) {
+ const auto &dbName = *it;
+ QSqlDatabase db = QSqlDatabase::database(dbName, false );
+ qDebug() << "Opening:" << dbName;
- if ( db.isValid() && !db.isOpen() ) {
- if ( !db.open() ) {
- qWarning( "tst_Databases: Unable to open %s on %s:\n%s", qPrintable( db.driverName() ), qPrintable( *it ), qPrintable( db.lastError().databaseText() ) );
+ if (db.isValid() && !db.isOpen()) {
+ if (!db.open()) {
+ qWarning("tst_Databases: Unable to open %s on %s:\n%s", qPrintable(db.driverName()),
+ qPrintable(dbName), qPrintable(db.lastError().databaseText()));
// well... opening failed, so we just ignore the server, maybe it is not running
- it = dbNames.erase( it );
+ it = dbNames.erase(it);
} else {
++it;
}
@@ -283,57 +226,51 @@ public:
void close()
{
- for ( QStringList::Iterator it = dbNames.begin(); it != dbNames.end(); ++it ) {
+ for (const auto &dbName : std::as_const(dbNames)) {
{
- QSqlDatabase db = QSqlDatabase::database(( *it ), false );
-
- if ( db.isValid() && db.isOpen() )
+ QSqlDatabase db = QSqlDatabase::database(dbName, false);
+ if (db.isValid() && db.isOpen())
db.close();
}
-
- QSqlDatabase::removeDatabase(( *it ) );
+ QSqlDatabase::removeDatabase(dbName);
}
-
dbNames.clear();
}
// for debugging only: outputs the connection as string
- static QString dbToString( const QSqlDatabase db )
+ static QString dbToString(const QSqlDatabase &db)
{
QString res = db.driverName() + QLatin1Char('@');
- if ( db.driverName().startsWith( "QODBC" ) || db.driverName().startsWith( "QOCI" ) ) {
+ if (db.driverName().startsWith("QODBC") || db.driverName().startsWith("QOCI"))
res += db.databaseName();
- } else {
+ else
res += db.hostName();
- }
- if ( db.port() > 0 ) {
- res += QLatin1Char(':') + QString::number( db.port() );
- }
+ if (db.port() > 0)
+ res += QLatin1Char(':') + QString::number(db.port());
return res;
}
// drop a table only if it exists to prevent warnings
- static void safeDropTables( QSqlDatabase db, const QStringList& tableNames )
+ static void safeDropTables(const QSqlDatabase &db, const QStringList &tableNames)
{
- bool wasDropped;
- QSqlQuery q( db );
- QStringList dbtables=db.tables();
+ QSqlQuery q(db);
+ QStringList dbtables = db.tables();
QSqlDriver::DbmsType dbType = getDatabaseType(db);
- foreach(const QString &tableName, tableNames)
+ for (const QString &tableName : tableNames)
{
- wasDropped = true;
- QString table=tableName;
- if ( db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName))
+ bool wasDropped = true;
+ QString table = tableName;
+ if (db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName))
table = db.driver()->stripDelimiters(table, QSqlDriver::TableName);
- if ( dbtables.contains( table, Qt::CaseInsensitive ) ) {
- foreach(const QString &table2, dbtables.filter(table, Qt::CaseInsensitive)) {
- if(table2.compare(table.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
- table=db.driver()->escapeIdentifier(table2, QSqlDriver::TableName);
- if (dbType == QSqlDriver::PostgreSQL)
+ if (dbtables.contains(table, Qt::CaseInsensitive)) {
+ for (const QString &table2 : dbtables.filter(table, Qt::CaseInsensitive)) {
+ if (table2.compare(table.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
+ table = db.driver()->escapeIdentifier(table2, QSqlDriver::TableName);
+ if (dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::MimerSQL)
wasDropped = q.exec( "drop table " + table + " cascade");
else
wasDropped = q.exec( "drop table " + table);
@@ -341,7 +278,7 @@ public:
}
}
}
- if ( !wasDropped ) {
+ if (!wasDropped) {
qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError();
// qWarning() << "last query:" << q.lastQuery();
// qWarning() << "dbtables:" << dbtables;
@@ -350,38 +287,31 @@ public:
}
}
- static void safeDropTable( QSqlDatabase db, const QString& tableName )
+ static void safeDropViews(const QSqlDatabase &db, const QStringList &viewNames)
{
- safeDropTables(db, QStringList() << tableName);
- }
+ if (isMSAccess(db)) // Access is sooo stupid.
+ safeDropTables(db, viewNames);
- static void safeDropViews( QSqlDatabase db, const QStringList &viewNames )
- {
- if ( isMSAccess( db ) ) // Access is sooo stupid.
- safeDropTables( db, viewNames );
-
- bool wasDropped;
- QSqlQuery q( db );
- QStringList dbtables=db.tables(QSql::Views);
-
- foreach(QString viewName, viewNames)
+ QSqlQuery q(db);
+ QStringList dbtables = db.tables(QSql::Views);
+ for (const QString &viewName : viewNames)
{
- wasDropped = true;
- QString view=viewName;
- if ( db.driver()->isIdentifierEscaped(view, QSqlDriver::TableName))
+ bool wasDropped = true;
+ QString view = viewName;
+ if (db.driver()->isIdentifierEscaped(view, QSqlDriver::TableName))
view = db.driver()->stripDelimiters(view, QSqlDriver::TableName);
- if ( dbtables.contains( view, Qt::CaseInsensitive ) ) {
- foreach(const QString &view2, dbtables.filter(view, Qt::CaseInsensitive)) {
- if(view2.compare(view.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
- view=db.driver()->escapeIdentifier(view2, QSqlDriver::TableName);
- wasDropped = q.exec( "drop view " + view);
+ if (dbtables.contains(view, Qt::CaseInsensitive)) {
+ for (const QString &view2 : dbtables.filter(view, Qt::CaseInsensitive)) {
+ if (view2.compare(view.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
+ view = db.driver()->escapeIdentifier(view2, QSqlDriver::TableName);
+ wasDropped = q.exec("drop view " + view);
dbtables.removeAll(view);
}
}
}
- if ( !wasDropped )
+ if (!wasDropped)
qWarning() << dbToString(db) << "unable to drop view" << viewName << ':' << q.lastError();
// << "\nlast query:" << q.lastQuery()
// << "\ndbtables:" << dbtables
@@ -389,14 +319,9 @@ public:
}
}
- static void safeDropView( QSqlDatabase db, const QString& tableName )
- {
- safeDropViews(db, QStringList() << tableName);
- }
-
// returns the type name of the blob datatype for the database db.
// blobSize is only used if the db doesn't have a generic blob type
- static QString blobTypeName( QSqlDatabase db, int blobSize = 10000 )
+ static QString blobTypeName(const QSqlDatabase &db, int blobSize = 10000)
{
const QSqlDriver::DbmsType dbType = getDatabaseType(db);
if (dbType == QSqlDriver::MySqlServer)
@@ -425,19 +350,35 @@ public:
return "blob";
}
- static QString dateTimeTypeName(QSqlDatabase db)
+ static QString dateTimeTypeName(const QSqlDatabase &db)
{
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::PostgreSQL)
return QLatin1String("timestamptz");
if (dbType == QSqlDriver::Oracle && getOraVersion(db) >= 9)
return QLatin1String("timestamp(0)");
- if (dbType == QSqlDriver::Interbase)
+ if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::MimerSQL)
return QLatin1String("timestamp");
return QLatin1String("datetime");
}
- static QString autoFieldName( QSqlDatabase db )
+ static QString timeTypeName(const QSqlDatabase &db)
+ {
+ const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ if (dbType == QSqlDriver::Oracle && getOraVersion(db) >= 9)
+ return QLatin1String("timestamp(0)");
+ return QLatin1String("time");
+ }
+
+ static QString dateTypeName(const QSqlDatabase &db)
+ {
+ const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ if (dbType == QSqlDriver::Oracle && getOraVersion(db) >= 9)
+ return QLatin1String("timestamp(0)");
+ return QLatin1String("date");
+ }
+
+ static QString autoFieldName(const QSqlDatabase &db)
{
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::MySqlServer)
@@ -452,43 +393,35 @@ public:
return QString();
}
- static QByteArray printError( const QSqlError& err )
+ static QByteArray printError(const QSqlError &err)
{
QString result;
if (!err.nativeErrorCode().isEmpty())
- result += '(' + err.nativeErrorCode() + ") ";
- result += '\'';
- if(!err.driverText().isEmpty())
+ result += u'(' + err.nativeErrorCode() + ") ";
+ result += u'\'';
+ if (!err.driverText().isEmpty())
result += err.driverText() + "' || '";
- result += err.databaseText() + QLatin1Char('\'');
+ result += err.databaseText() + u'\'';
return result.toLocal8Bit();
}
- static QByteArray printError( const QSqlError& err, const QSqlDatabase& db )
+ static QByteArray printError(const QSqlError &err, const QSqlDatabase &db)
{
- QString result(dbToString(db) + ": ");
- if (!err.nativeErrorCode().isEmpty())
- result += '(' + err.nativeErrorCode() + ") ";
- result += '\'';
- if(!err.driverText().isEmpty())
- result += err.driverText() + "' || '";
- result += err.databaseText() + QLatin1Char('\'');
- return result.toLocal8Bit();
+ return dbToString(db).toLocal8Bit() + ": " + printError(err);
}
- static QSqlDriver::DbmsType getDatabaseType(QSqlDatabase db)
+ static QSqlDriver::DbmsType getDatabaseType(const QSqlDatabase &db)
{
- QSqlDriverPrivate *d = static_cast<QSqlDriverPrivate *>(QObjectPrivate::get(db.driver()));
- return d->dbmsType;
+ return db.driver()->dbmsType();
}
- static bool isMSAccess( QSqlDatabase db )
+ static bool isMSAccess(const QSqlDatabase &db)
{
return db.databaseName().contains( "Access Driver", Qt::CaseInsensitive );
}
// -1 on fail, else Oracle version
- static int getOraVersion( QSqlDatabase db )
+ static int getOraVersion(const QSqlDatabase &db)
{
int ver = -1;
QSqlQuery q( "SELECT banner FROM v$version", db );
@@ -507,28 +440,18 @@ public:
return ver;
}
- static QString getMySqlVersion( const QSqlDatabase &db )
+ static QVersionNumber getIbaseEngineVersion(const QSqlDatabase &db)
{
QSqlQuery q(db);
- q.exec( "select version()" );
- if(q.next())
- return q.value( 0 ).toString();
- else
- return QString();
- }
-
- static QString getPSQLVersion( const QSqlDatabase &db )
- {
- QSqlQuery q(db);
- q.exec( "select version()" );
- if(q.next())
- return q.value( 0 ).toString();
- else
- return QString();
+ 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;
+ int counter = 0;
private:
QTemporaryDir *dbDir()
@@ -546,5 +469,61 @@ private:
QScopedPointer<QTemporaryDir> m_dbDir;
};
+class TableScope
+{
+public:
+ TableScope(const QSqlDatabase &db, const QString &fullTableName)
+ : m_db(db)
+ , m_tableName(fullTableName)
+ {
+ tst_Databases::safeDropTables(m_db, {m_tableName});
+ }
+ TableScope(const QSqlDatabase &db, const char *tableName, const char *file, bool escape = true)
+ : TableScope(db, qTableName(tableName, file, db, escape))
+ {
+ }
+
+ ~TableScope()
+ {
+ tst_Databases::safeDropTables(m_db, {m_tableName});
+ }
+
+ QString tableName() const
+ {
+ return m_tableName;
+ }
+private:
+ QSqlDatabase m_db;
+ 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);
+ 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 2e143aff21..19afacf6f9 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>
@@ -28,8 +28,7 @@ class tst_QSqlDatabase : public QObject
Q_OBJECT
public:
- tst_QSqlDatabase();
- virtual ~tst_QSqlDatabase();
+ using QObject::QObject;
public slots:
void initTestCase();
@@ -50,8 +49,6 @@ private slots:
void eventNotification_data() { generic_data(); }
void eventNotification();
void addDatabase();
- void errorReporting_data();
- void errorReporting();
void cloneDatabase_data() { generic_data(); }
void cloneDatabase();
@@ -62,8 +59,6 @@ private slots:
void recordPSQL();
void recordOCI_data() { generic_data("QOCI"); }
void recordOCI();
- void recordTDS_data() { generic_data("QTDS"); }
- void recordTDS();
void recordDB2_data() { generic_data("QDB2"); }
void recordDB2();
void recordSQLite_data() { generic_data("QSQLITE"); }
@@ -109,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();
@@ -137,8 +134,6 @@ private slots:
void ibase_numericFields(); // For task 125053
void ibase_fetchBlobs_data() { generic_data("QIBASE"); }
void ibase_fetchBlobs(); // For task 143471
- void ibase_useCustomCharset_data() { generic_data("QIBASE"); }
- void ibase_useCustomCharset(); // For task 134608
void ibase_procWithoutReturnValues_data() { generic_data("QIBASE"); } // For task 165423
void ibase_procWithoutReturnValues();
void ibase_procWithReturnValues_data() { generic_data("QIBASE"); } // For task 177530
@@ -182,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;
};
@@ -210,7 +205,7 @@ struct FieldDef {
rt.replace(QRegularExpression("\\s"), QString("_"));
int i = rt.indexOf(QLatin1Char('('));
if (i == -1)
- i = rt.length();
+ i = rt.size();
if (i > 20)
i = 20;
return "t_" + rt.left(i);
@@ -223,11 +218,11 @@ 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);
- tst_Databases::safeDropTable(db, tableName);
+ tst_Databases::safeDropTables(db, {tableName});
QSqlQuery q(db);
// construct a create table statement consisting of all fieldtypes
QString qs = "create table " + tableName;
@@ -258,22 +253,7 @@ static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db)
return i;
}
-bool driverQuotedCaseSensitive(QSqlDatabase db)
-{
- // On Interbase it will be case sensitive if it was created with quotes
- QSqlDriverPrivate *d = static_cast<QSqlDriverPrivate *>(QObjectPrivate::get(db.driver()));
- return (d && d->dbmsType == QSqlDriver::Interbase);
-}
-
-tst_QSqlDatabase::tst_QSqlDatabase()
-{
-}
-
-tst_QSqlDatabase::~tst_QSqlDatabase()
-{
-}
-
-void tst_QSqlDatabase::createTestTables(QSqlDatabase db)
+void tst_QSqlDatabase::createTestTables(const QSqlDatabase &db)
{
if (!db.isValid())
return;
@@ -300,16 +280,14 @@ void tst_QSqlDatabase::createTestTables(QSqlDatabase db)
" (id integer not null, t_varchar varchar(40) not null, "
"t_char char(40), t_numeric numeric(6, 3), primary key (id, t_varchar))"));
}
- if (testWhiteSpaceNames(db.driverName())) {
- QString qry = "create table " + qTableName("qtest test", __FILE__, db)
- + '('
- + db.driver()->escapeIdentifier(QLatin1String("test test"), QSqlDriver::FieldName)
- + " int not null primary key)";
- QVERIFY_SQL(q, exec(qry));
- }
+ QString qry = "create table " + qTableName("qtest test", __FILE__, db)
+ + '('
+ + db.driver()->escapeIdentifier(QLatin1String("test test"), QSqlDriver::FieldName)
+ + " int not null primary key)";
+ QVERIFY_SQL(q, exec(qry));
}
-void tst_QSqlDatabase::dropTestTables(QSqlDatabase db)
+void tst_QSqlDatabase::dropTestTables(const QSqlDatabase &db)
{
if (!db.isValid())
return;
@@ -321,31 +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_bigint", __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) {
@@ -353,11 +311,8 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db)
q.exec("drop schema " + qTableName("qtestScHeMa", __FILE__, db) + " cascade");
}
- if (testWhiteSpaceNames(db.driverName())) {
- tableNames << db.driver()->escapeIdentifier(qTableName("qtest test", __FILE__, db),
- QSqlDriver::TableName);
- }
-
+ tableNames << db.driver()->escapeIdentifier(qTableName("qtest test", __FILE__, db),
+ QSqlDriver::TableName);
tst_Databases::safeDropTables(db, tableNames);
if (dbType == QSqlDriver::Oracle) {
@@ -368,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;
@@ -440,36 +395,6 @@ void tst_QSqlDatabase::addDatabase()
QVERIFY(!QSqlDatabase::contains("INVALID_CONNECTION"));
}
-void tst_QSqlDatabase::errorReporting_data()
-{
- QTest::addColumn<QString>("driver");
-
- QTest::newRow("QTDS") << QString::fromLatin1("QTDS");
- QTest::newRow("QTDS7") << QString::fromLatin1("QTDS7");
-}
-
-void tst_QSqlDatabase::errorReporting()
-{
- QFETCH(QString, driver);
-
- if (!QSqlDatabase::drivers().contains(driver))
- QSKIP(QString::fromLatin1("Database driver %1 not available").arg(driver).toLocal8Bit().constData());
-
- const QString dbName = QLatin1String("errorReportingDb-") + driver;
- QSqlDatabase db = QSqlDatabase::addDatabase(driver, dbName);
-
- db.setHostName(QLatin1String("127.0.0.1"));
- db.setDatabaseName(QLatin1String("NonExistantDatabase"));
- db.setUserName(QLatin1String("InvalidUser"));
- db.setPassword(QLatin1String("IncorrectPassword"));
-
- QVERIFY(!db.open());
-
- db = QSqlDatabase();
-
- QSqlDatabase::removeDatabase(dbName);
-}
-
void tst_QSqlDatabase::open()
{
QFETCH(QString, dbName);
@@ -509,7 +434,7 @@ void tst_QSqlDatabase::tables()
bool tempTables = false;
QSqlQuery q(db);
- if (!q.exec("CREATE VIEW " + qtest_view + " as select * from " + qtest)) {
+ if (!q.exec("CREATE VIEW " + qtest_view + " as select * from " + db.driver()->escapeIdentifier(qtest, QSqlDriver::TableName))) {
qDebug("DBMS '%s' cannot handle VIEWs: %s",
qPrintable(tst_Databases::dbToString(db)),
qPrintable(tst_Databases::printError(q.lastError())));
@@ -562,34 +487,21 @@ void tst_QSqlDatabase::whitespaceInIdentifiers()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ const auto metaTypeToCheck = dbType == QSqlDriver::Oracle
+ ? QMetaType(QMetaType::Double) : QMetaType(QMetaType::Int);
- if (testWhiteSpaceNames(db.driverName())) {
- const bool isCaseSensitive = driverQuotedCaseSensitive(db);
- const auto tableName(qTableName("qtest test", __FILE__, db, isCaseSensitive));
- if (isCaseSensitive) {
- QVERIFY(db.tables().contains(db.driver()->stripDelimiters(tableName, QSqlDriver::TableName)));
- } else {
- QVERIFY(db.tables().contains(tableName, Qt::CaseInsensitive));
- }
+ const auto tableName(qTableName("qtest test", __FILE__, db, true));
+ QVERIFY(db.tables().contains(db.driver()->stripDelimiters(tableName, QSqlDriver::TableName)));
- QSqlRecord rec = db.record(tableName);
- QCOMPARE(rec.count(), 1);
- QCOMPARE(rec.fieldName(0), QString("test test"));
- if (dbType == QSqlDriver::Oracle)
- QCOMPARE(rec.field(0).metaType(), QMetaType(QMetaType::Double));
- else
- QCOMPARE(rec.field(0).metaType(), QMetaType(QMetaType::Int));
+ QSqlRecord rec = db.record(tableName);
+ QCOMPARE(rec.count(), 1);
+ QCOMPARE(rec.fieldName(0), QString("test test"));
+ QCOMPARE(rec.field(0).metaType(), metaTypeToCheck);
- QSqlIndex idx = db.primaryIndex(tableName);
- QCOMPARE(idx.count(), 1);
- QCOMPARE(idx.fieldName(0), QString("test test"));
- if (dbType == QSqlDriver::Oracle)
- QCOMPARE(idx.field(0).metaType(), QMetaType(QMetaType::Double));
- else
- QCOMPARE(idx.field(0).metaType(), QMetaType(QMetaType::Int));
- } else {
- QSKIP("DBMS does not support whitespaces in identifiers");
- }
+ QSqlIndex idx = db.primaryIndex(tableName);
+ QCOMPARE(idx.count(), 1);
+ QCOMPARE(idx.fieldName(0), QString("test test"));
+ QCOMPARE(idx.field(0).metaType(), metaTypeToCheck);
}
void tst_QSqlDatabase::alterTable()
@@ -597,13 +509,11 @@ void tst_QSqlDatabase::alterTable()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString qtestalter(qTableName("qtestalter", __FILE__, db));
- const auto noEscapeAlterTable = qTableName("qtestalter", __FILE__, db, false);
- const bool isCaseSensitive = driverQuotedCaseSensitive(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(isCaseSensitive ? qtestalter : noEscapeAlterTable);
+ 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;
@@ -611,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(isCaseSensitive ? qtestalter : noEscapeAlterTable);
+ rec = db.record(ts.tableName());
- QCOMPARE((int)rec.count(), 2);
+ 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
@@ -650,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(
@@ -670,13 +579,12 @@ 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);
- QStringList tableNames = { qTableName("qtestfields", __FILE__, db) };
- if (!driverQuotedCaseSensitive(db))
- tableNames << qTableName("qtestfields", __FILE__, db, false);
+ const QStringList tableNames = { qTableName("qtestfields", __FILE__, db),
+ qTableName("qtestfields", __FILE__, db, false) };
for (const QString &table : tableNames) {
QSqlRecord rec = db.record(table);
@@ -688,43 +596,6 @@ void tst_QSqlDatabase::commonFieldTest(const FieldDef fieldDefs[], QSqlDatabase
QVERIFY_SQL(q, exec("select * from " + tableNames.at(0)));
}
-void tst_QSqlDatabase::recordTDS()
-{
- QFETCH(QString, dbName);
- QSqlDatabase db = QSqlDatabase::database(dbName);
- CHECK_DATABASE(db);
-
- static const FieldDef fieldDefs[] = {
- FieldDef("tinyint", QMetaType::Int, 255),
- FieldDef("smallint", QMetaType::Int, 32767),
- FieldDef("int", QMetaType::Int, 2147483647),
- FieldDef("numeric(10,9)", QMetaType::Double, 1.23456789),
- FieldDef("decimal(10,9)", QMetaType::Double, 1.23456789),
- FieldDef("float(4)", QMetaType::Double, 1.23456789),
- FieldDef("double precision", QMetaType::Double, 1.23456789),
- FieldDef("real", QMetaType::Double, 1.23456789),
- FieldDef("smallmoney", QMetaType::Double, 100.42),
- FieldDef("money", QMetaType::Double, 200.42),
- // accuracy is that of a minute
- FieldDef("smalldatetime", QMetaType::QDateTime, QDateTime(QDate::currentDate(), QTime(1, 2, 0, 0))),
- // accuracy is that of a second
- FieldDef("datetime", QMetaType::QDateTime, QDateTime(QDate::currentDate(), QTime(1, 2, 3, 0))),
- FieldDef("char(20)", QMetaType::QString, "blah1"),
- FieldDef("varchar(20)", QMetaType::QString, "blah2"),
- FieldDef("nchar(20)", QMetaType::QString, "blah3"),
- FieldDef("nvarchar(20)", QMetaType::QString, "blah4"),
- FieldDef("text", QMetaType::QString, "blah5"),
- FieldDef("bit", QMetaType::Int, 1, false),
-
- FieldDef()
- };
-
- const int fieldCount = createFieldTable(fieldDefs, db);
- QVERIFY(fieldCount > 0);
-
- commonFieldTest(fieldDefs, db, fieldCount);
-}
-
void tst_QSqlDatabase::recordOCI()
{
bool hasTimeStamp = false;
@@ -871,22 +742,6 @@ void tst_QSqlDatabase::recordMySQL()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- FieldDef bin10, varbin10;
- int major = tst_Databases::getMySqlVersion( db ).section( QChar('.'), 0, 0 ).toInt();
- int minor = tst_Databases::getMySqlVersion( db ).section( QChar('.'), 1, 1 ).toInt();
- int revision = tst_Databases::getMySqlVersion( db ).section( QChar('.'), 2, 2 ).toInt();
- int vernum = (major << 16) + (minor << 8) + revision;
-
- /* The below is broken in mysql below 5.0.15
- see http://dev.mysql.com/doc/refman/5.0/en/binary-varbinary.html
- specifically: Before MySQL 5.0.15, the pad value is space. Values are right-padded
- with space on insert, and trailing spaces are removed on select.
- */
- if( vernum >= ((5 << 16) + 15) ) {
- bin10 = FieldDef("binary(10)", QMetaType::QByteArray, QString("123abc "));
- varbin10 = FieldDef("varbinary(10)", QMetaType::QByteArray, QString("123abcv "));
- }
-
static QDateTime dt(QDate::currentDate(), QTime(1, 2, 3, 0));
static const FieldDef fieldDefs[] = {
FieldDef("tinyint", QMetaType::Char, 127),
@@ -1168,28 +1023,37 @@ void tst_QSqlDatabase::bigIntField()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- const QString qtest_bigint(qTableName("qtest_bigint", __FILE__, db));
+ QString queryString;
+ switch (dbType) {
+ case QSqlDriver::MySqlServer:
+ queryString = "create table %1 (id int, t_s64bit bigint, t_u64bit bigint unsigned)";
+ break;
+ case QSqlDriver::DB2:
+ case QSqlDriver::Interbase:
+ case QSqlDriver::MimerSQL:
+ case QSqlDriver::MSSqlServer:
+ case QSqlDriver::PostgreSQL:
+ queryString = "create table %1 (id int, t_s64bit bigint, t_u64bit bigint)";
+ break;
+ case QSqlDriver::Oracle:
+ case QSqlDriver::SQLite:
+ queryString = "create table %1 (id int, t_s64bit int, t_u64bit int)";
+ break;
+ case QSqlDriver::Sybase:
+ case QSqlDriver::UnknownDbms:
+ break;
+ }
+ if (queryString.isEmpty())
+ QSKIP("no 64 bit integer support");
+
+ TableScope ts(db, "qtest_bigint", __FILE__);
QSqlQuery q(db);
q.setForwardOnly(true);
-
if (dbType == QSqlDriver::Oracle)
q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64);
-
- if (dbType == QSqlDriver::MySqlServer) {
- QVERIFY_SQL(q, exec("create table " + qtest_bigint + " (id int, t_s64bit bigint, t_u64bit bigint unsigned)"));
- } else if (dbType == QSqlDriver::PostgreSQL
- || dbType == QSqlDriver::DB2
- || dbType == QSqlDriver::MSSqlServer) {
- QVERIFY_SQL(q, exec("create table " + qtest_bigint + "(id int, t_s64bit bigint, t_u64bit bigint)"));
- } else if (dbType == QSqlDriver::Oracle) {
- QVERIFY_SQL(q, exec("create table " + qtest_bigint + " (id int, t_s64bit int, t_u64bit int)"));
- //} else if (dbType == QSqlDriver::Interbase) {
- // QVERIFY_SQL(q, exec("create table " + qtest_bigint + " (id int, t_s64bit int64, t_u64bit int64)"));
- } else {
- QSKIP("no 64 bit integer support");
- }
- QVERIFY(q.prepare("insert into " + qtest_bigint + " values (?, ?, ?)"));
+ QVERIFY_SQL(q, exec(queryString.arg(ts.tableName())));
+ QVERIFY(q.prepare("insert into " + ts.tableName() + " values (?, ?, ?)"));
qlonglong ll = Q_INT64_C(9223372036854775807);
qulonglong ull = Q_UINT64_C(18446744073709551615);
@@ -1213,7 +1077,7 @@ void tst_QSqlDatabase::bigIntField()
q.bindValue(2, (qlonglong) ull);
QVERIFY_SQL(q, exec());
}
- QVERIFY(q.exec("select * from " + qtest_bigint + " order by id"));
+ QVERIFY(q.exec("select * from " + ts.tableName() + " order by id"));
QVERIFY(q.next());
QCOMPARE(q.value(1).toDouble(), (double)ll);
QCOMPARE(q.value(1).toLongLong(), ll);
@@ -1242,34 +1106,44 @@ void tst_QSqlDatabase::caseSensivity()
cs = true;
}
- QSqlRecord rec = db.record(qTableName("qtest", __FILE__, db, driverQuotedCaseSensitive(db)));
- QVERIFY((int)rec.count() > 0);
+ QSqlRecord rec = db.record(qTableName("qtest", __FILE__, db));
+ QVERIFY(rec.count() > 0);
if (!cs) {
- rec = db.record(qTableName("QTEST", __FILE__, db, false).toUpper());
- QVERIFY((int)rec.count() > 0);
- rec = db.record(qTableName("qTesT", __FILE__, db, false));
- QVERIFY((int)rec.count() > 0);
+ rec = db.record(qTableName("QTEST", __FILE__, db, false).toUpper());
+ QVERIFY(rec.count() > 0);
+ rec = db.record(qTableName("qTesT", __FILE__, db, false));
+ QVERIFY(rec.count() > 0);
}
- rec = db.primaryIndex(qTableName("qtest", __FILE__, db, driverQuotedCaseSensitive(db)));
- QVERIFY((int)rec.count() > 0);
+ rec = db.primaryIndex(qTableName("qtest", __FILE__, db));
+ QVERIFY(rec.count() > 0);
if (!cs) {
- rec = db.primaryIndex(qTableName("QTEST", __FILE__, db, false).toUpper());
- QVERIFY((int)rec.count() > 0);
- rec = db.primaryIndex(qTableName("qTesT", __FILE__, db, false));
- QVERIFY((int)rec.count() > 0);
+ rec = db.primaryIndex(qTableName("QTEST", __FILE__, db, false).toUpper());
+ QVERIFY(rec.count() > 0);
+ rec = db.primaryIndex(qTableName("qTesT", __FILE__, db, false));
+ QVERIFY(rec.count() > 0);
}
// Explicit test for case sensitive table creation without quoting
+ TableScope ts(db, "NoQuotes", __FILE__, false);
QSqlQuery qry(db);
- const auto noQuotesTable = qTableName("NoQuotes", __FILE__, db, false);
- tst_Databases::safeDropTable(db, noQuotesTable);
- QVERIFY_SQL(qry, exec("CREATE TABLE " + noQuotesTable + " (id INTEGER)"));
- QVERIFY_SQL(qry, exec("INSERT INTO " + noQuotesTable + " VALUES(1)"));
- QVERIFY_SQL(qry, exec("SELECT * FROM " + noQuotesTable));
+ QVERIFY_SQL(qry, exec("CREATE TABLE " + ts.tableName() + " (id INTEGER)"));
+ QVERIFY_SQL(qry, exec("INSERT INTO " + ts.tableName() + " VALUES(1)"));
+ QVERIFY_SQL(qry, exec("SELECT * FROM " + ts.tableName()));
QVERIFY_SQL(qry, next());
QCOMPARE(qry.value(0).toInt(), 1);
- rec = db.record(cs ? noQuotesTable.toLower() : noQuotesTable);
+ // QMYSQLDriver::record() is using a mysql function instead of a query, so quoting
+ // will not help when the table names are not stored lowercase.
+ if (dbType == QSqlDriver::MySqlServer) {
+ QVERIFY_SQL(qry, exec("SHOW GLOBAL VARIABLES LIKE 'lower_case_table_names'"));
+ QVERIFY_SQL(qry, next());
+ cs = qry.value(1).toInt() != 0;
+ }
+ if (dbType == QSqlDriver::Interbase) {
+ rec = db.record(ts.tableName().toUpper());
+ } else {
+ rec = db.record(cs ? ts.tableName().toLower() : ts.tableName());
+ }
QVERIFY(rec.count() > 0);
}
@@ -1375,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;
@@ -1406,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());
@@ -1420,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();
@@ -1433,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");
@@ -1536,11 +1408,10 @@ void tst_QSqlDatabase::infinityAndNan()
QSKIP("checking for infinity/nan currently only works for PostgreSQL");
QSqlQuery q(db);
- const QString tableName(qTableName("infititytest", __FILE__, db));
- tst_Databases::safeDropTables(db, {tableName});
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (id smallint, val double precision)").arg(tableName)));
+ TableScope ts(db, "infititytest", __FILE__);
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (id smallint, val double precision)").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())));
q.bindValue(0, 1);
q.bindValue(1, qQNaN());
@@ -1552,7 +1423,7 @@ void tst_QSqlDatabase::infinityAndNan()
q.bindValue(1, -qInf());
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec(QString("SELECT val FROM %1 ORDER BY id").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString("SELECT val FROM %1 ORDER BY id").arg(ts.tableName())));
QVERIFY_SQL(q, next());
QVERIFY(qIsNaN(q.value(0).toDouble()));
@@ -1575,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"));
@@ -1599,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));
@@ -1619,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);
@@ -1637,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)));
@@ -1710,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)));
@@ -1742,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()
@@ -1756,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)"
@@ -1772,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());
@@ -1787,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()
@@ -1845,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());
@@ -1860,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);
@@ -1874,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);
@@ -1904,13 +1772,13 @@ void tst_QSqlDatabase::odbc_testqGetString()
QVERIFY_SQL(q, exec("SELECT id, vcvalue FROM " + testqGetString + " ORDER BY id"));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 1);
- QCOMPARE(q.value(1).toString().length(), 65536);
+ QCOMPARE(q.value(1).toString().size(), 65536);
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 2);
- QCOMPARE(q.value(1).toString().length(), 65537);
+ QCOMPARE(q.value(1).toString().size(), 65537);
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 3);
- QCOMPARE(q.value(1).toString().length(), 65538);
+ QCOMPARE(q.value(1).toString().size(), 65538);
}
@@ -1929,31 +1797,6 @@ void tst_QSqlDatabase::mysql_multiselect()
QVERIFY_SQL(q, exec("SELECT * FROM " + qtest));
}
-void tst_QSqlDatabase::ibase_useCustomCharset()
-{
- QFETCH(QString, dbName);
- QSqlDatabase db = QSqlDatabase::database(dbName);
- CHECK_DATABASE(db);
- QString nonlatin1string("��");
-
- db.close();
- db.setConnectOptions("ISC_DPB_LC_CTYPE=Latin1");
- db.open();
-
- const QString tableName(qTableName("latin1table", __FILE__, db));
-
- QSqlQuery q(db);
- QEXPECT_FAIL("", "Currently fails, potentially due to invalid test - needs further "
- "investigation - QTBUG-85828", Abort);
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(text VARCHAR(6) CHARACTER SET Latin1)").arg(tableName)));
- QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES(?)").arg(tableName)));
- q.addBindValue(nonlatin1string);
- QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec(QString("SELECT text FROM %1").arg(tableName)));
- QVERIFY_SQL(q, next());
- QCOMPARE(toHex(q.value(0).toString()), toHex(nonlatin1string));
-}
-
void tst_QSqlDatabase::oci_serverDetach()
{
QFETCH(QString, dbName);
@@ -1979,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);
@@ -2058,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());
@@ -2074,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);
}
@@ -2100,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);
}
@@ -2170,38 +2014,32 @@ void tst_QSqlDatabase::eventNotificationIBase()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
- if (db.driverName().compare(QLatin1String("QIBASE"), Qt::CaseInsensitive))
- QSKIP("QIBASE specific test");
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.count(), 1);
+ 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);
@@ -2209,9 +2047,9 @@ 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.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QList<QVariant> arguments = spy.takeFirst();
QCOMPARE(arguments.at(0).toString(), procedureName);
QCOMPARE(qvariant_cast<QSqlDriver::NotificationSource>(arguments.at(1)), QSqlDriver::SelfSource);
@@ -2223,26 +2061,23 @@ 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);
- const QString tableName(qTableName("sqlitnotifytest", __FILE__, db));
- const auto noEscapeTableName(qTableName("sqlitnotifytest", __FILE__, db, false));
- tst_Databases::safeDropTable(db, tableName);
+ 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 " + tableName + " (id INTEGER, realVal REAL)"));
- driver->subscribeToNotification(noEscapeTableName);
- QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id, realVal) VALUES (1, 2.3)"));
- QTRY_COMPARE(spy.count(), 1);
+ QVERIFY_SQL(q, exec("CREATE TABLE " + ts.tableName() + " (id INTEGER, realVal REAL)"));
+ driver->subscribeToNotification(tsEscape.tableName());
+ QVERIFY_SQL(q, exec("INSERT INTO " + ts.tableName() + " (id, realVal) VALUES (1, 2.3)"));
+ QTRY_COMPARE(spy.size(), 1);
QList<QVariant> arguments = spy.takeFirst();
- QCOMPARE(arguments.at(0).toString(), noEscapeTableName);
- driver->unsubscribeFromNotification(noEscapeTableName);
- QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id, realVal) VALUES (1, 2.3)"));
- QTRY_COMPARE(spy.count(), 0);
+ QCOMPARE(arguments.at(0).toString(), tsEscape.tableName());
+ driver->unsubscribeFromNotification(tsEscape.tableName());
+ QVERIFY_SQL(q, exec("INSERT INTO " + ts.tableName() + " (id, realVal) VALUES (1, 2.3)"));
+ QTRY_COMPARE(spy.size(), 0);
}
void tst_QSqlDatabase::sqlite_bindAndFetchUInt()
@@ -2250,16 +2085,13 @@ void tst_QSqlDatabase::sqlite_bindAndFetchUInt()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- if (db.driverName().startsWith("QSQLITE2"))
- QSKIP("SQLite3 specific test");
-
+ 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
@@ -2366,24 +2198,21 @@ void tst_QSqlDatabase::sqlite_enableRegexp()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- if (db.driverName().startsWith("QSQLITE2"))
- QSKIP("SQLite3 specific test");
-
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());
@@ -2416,13 +2245,12 @@ void tst_QSqlDatabase::sqlite_check_json1()
QSqlQuery q(db);
const QString json1("{\"id\":1}");
- const QString tableName(qTableName("sqlite_check_json1", __FILE__, db));
- tst_Databases::safeDropTable(db, tableName);
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(text TEXT)").arg(tableName)));
- QVERIFY_SQL(q, exec(QString("INSERT INTO %1 VALUES(json('%2'))").arg(tableName, json1)));
- QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES(?)").arg(tableName)));
+ TableScope ts(db, "sqlite_check_json1", __FILE__);
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(text TEXT)").arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QString("INSERT INTO %1 VALUES(json('%2'))").arg(ts.tableName(), json1)));
+ QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES(?)").arg(ts.tableName())));
q.addBindValue("json('{\"id\":2}')");
- QVERIFY_SQL(q, prepare(QString("SELECT * from %1 WHERE text = json('%2')").arg(tableName, json1)));
+ QVERIFY_SQL(q, prepare(QString("SELECT * from %1 WHERE text = json('%2')").arg(ts.tableName(), json1)));
QVERIFY_SQL(q, exec());
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toString(), json1);
@@ -2434,6 +2262,10 @@ void tst_QSqlDatabase::cloneDatabase()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ const auto wrapup = qScopeGuard([&]() {
+ QSqlDatabase::removeDatabase("clonedDatabase");
+ QSqlDatabase::removeDatabase("clonedDatabaseCopy");
+ });
{
QSqlDatabase clonedDatabase = QSqlDatabase::cloneDatabase(db, "clonedDatabase");
QCOMPARE(clonedDatabase.databaseName(), db.databaseName());
@@ -2475,6 +2307,7 @@ public slots:
QSqlDatabase invalidDb = QSqlDatabase::database("invalid");
QVERIFY(!invalidDb.isValid());
+ const auto wrapup = qScopeGuard([&]() { QSqlDatabase::removeDatabase("CloneDB"); });
{
QSqlDatabase clonedDatabase = QSqlDatabase::cloneDatabase(dbName, "CloneDB");
QVERIFY(!clonedDatabase.isOpen());
@@ -2504,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.currentThread(), mainThread);
+ QCOMPARE(clonedDb.currentThread(), mainThread);
+ std::unique_ptr<QThread> t(QThread::create([&] {
+ db.moveToThread(mainThread);
+ QThread::currentThread()->exit();
+ }));
+ db.moveToThread(t.get());
+ QCOMPARE(db.currentThread(), t.get());
+ QCOMPARE(clonedDb.currentThread(), mainThread);
+ t->start();
+ QTRY_VERIFY(t->isRunning());
+ QTRY_VERIFY(t->wait(30000));
+ QCOMPARE(db.currentThread(), mainThread);
+ QCOMPARE(clonedDb.currentThread(), mainThread);
+ db = QSqlDatabase();
+ clonedDb = QSqlDatabase();
+ QSqlDatabase::removeDatabase("clonedDb");
+}
+
+
QTEST_MAIN(tst_QSqlDatabase)
#include "tst_qsqldatabase.moc"
diff --git a/tests/auto/sql/kernel/qsqldriver/CMakeLists.txt b/tests/auto/sql/kernel/qsqldriver/CMakeLists.txt
index 0acfed40ee..21dd3a6417 100644
--- a/tests/auto/sql/kernel/qsqldriver/CMakeLists.txt
+++ b/tests/auto/sql/kernel/qsqldriver/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qsqldriver.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqldriver Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqldriver LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqldriver
SOURCES
tst_qsqldriver.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Sql
Qt::SqlPrivate
diff --git a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
index 3a6e16020f..fb8d804843 100644
--- a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
+++ b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.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>
@@ -35,6 +35,7 @@ static bool driverSupportsDefaultValues(QSqlDriver::DbmsType dbType)
case QSqlDriver::SQLite:
case QSqlDriver::PostgreSQL:
case QSqlDriver::Oracle:
+ case QSqlDriver::MySqlServer:
return true;
default:
break;
@@ -52,47 +53,48 @@ void tst_QSqlDriver::initTestCase_data()
void tst_QSqlDriver::recreateTestTables(QSqlDatabase db)
{
QSqlQuery q(db);
- const QString relTEST1(qTableName("relTEST1", __FILE__, db));
+ const QString tableName(qTableName("relTEST1", __FILE__, db));
+ tst_Databases::safeDropTables(db, {tableName});
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::PostgreSQL)
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
- tst_Databases::safeDropTable( db, relTEST1 );
QString doubleField;
if (dbType == QSqlDriver::SQLite)
doubleField = "more_data double";
else if (dbType == QSqlDriver::Oracle)
doubleField = "more_data number(8,7)";
- else if (dbType == QSqlDriver::PostgreSQL)
+ else if (dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::MimerSQL)
doubleField = "more_data double precision";
else if (dbType == QSqlDriver::Interbase)
doubleField = "more_data numeric(8,7)";
else
doubleField = "more_data double(8,7)";
const QString defValue(driverSupportsDefaultValues(dbType) ? QStringLiteral("DEFAULT 'defaultVal'") : QString());
- QVERIFY_SQL( q, exec("create table " + relTEST1 +
+ QVERIFY_SQL( q, exec("create table " + tableName +
" (id int not null primary key, name varchar(20) " + defValue + ", title_key int, another_title_key int, " + doubleField + QLatin1Char(')')));
- QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(1, 'harry', 1, 2, 1.234567)"));
- QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(2, 'trond', 2, 1, 8.901234)"));
- QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(3, 'vohi', 1, 2, 5.678901)"));
- QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(4, 'boris', 2, 2, 2.345678)"));
+ QVERIFY_SQL( q, exec("insert into " + tableName + " values(1, 'harry', 1, 2, 1.234567)"));
+ QVERIFY_SQL( q, exec("insert into " + tableName + " values(2, 'trond', 2, 1, 8.901234)"));
+ QVERIFY_SQL( q, exec("insert into " + tableName + " values(3, 'vohi', 1, 2, 5.678901)"));
+ QVERIFY_SQL( q, exec("insert into " + tableName + " values(4, 'boris', 2, 2, 2.345678)"));
}
void tst_QSqlDriver::initTestCase()
{
- foreach (const QString &dbname, dbs.dbNames)
+ for (const QString &dbname : std::as_const(dbs.dbNames))
recreateTestTables(QSqlDatabase::database(dbname));
}
void tst_QSqlDriver::cleanupTestCase()
{
- foreach (const QString &dbName, dbs.dbNames) {
+ for (const QString &dbName : std::as_const(dbs.dbNames)) {
QSqlDatabase db = QSqlDatabase::database(dbName);
- tst_Databases::safeDropTable(db, qTableName("relTEST1", __FILE__, db));
+ QStringList tables = {qTableName("relTEST1", __FILE__, db)};
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::Oracle)
- tst_Databases::safeDropTable(db, qTableName("clobTable", __FILE__, db));
+ tables.push_back(qTableName("clobTable", __FILE__, db));
+ tst_Databases::safeDropTables(db, tables);
}
dbs.close();
}
@@ -111,7 +113,7 @@ void tst_QSqlDriver::record()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QString tablename(qTableName("relTEST1", __FILE__, db));
+ QString tablename(qTableName("relTEST1", __FILE__, db, false));
QStringList fields;
fields << "id" << "name" << "title_key" << "another_title_key" << "more_data";
@@ -125,14 +127,20 @@ void tst_QSqlDriver::record()
QCOMPARE(rec.field(1).length(), 20);
if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2)
- for(int i = 0; i < fields.count(); ++i)
+ for(int i = 0; i < fields.size(); ++i)
fields[i] = fields[i].toUpper();
- for (int i = 0; i < fields.count(); ++i)
+ for (int i = 0; i < fields.size(); ++i)
QCOMPARE(rec.fieldName(i), fields[i]);
- if (driverSupportsDefaultValues(dbType))
- QCOMPARE(rec.field(QStringLiteral("name")).defaultValue().toString(), QStringLiteral("defaultVal"));
+ if (driverSupportsDefaultValues(dbType)) {
+ auto defVal = rec.field(QStringLiteral("name")).defaultValue().toString();
+ if (dbType == QSqlDriver::MySqlServer && defVal.startsWith('\'') && defVal.endsWith('\'')) {
+ qDebug() << "MariaDB 10.6 default string value is escaped:" << defVal;
+ defVal = defVal.mid(1, defVal.size() - 2);
+ }
+ QCOMPARE(defVal, QStringLiteral("defaultVal"));
+ }
if (dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2)
tablename = tablename.toUpper();
@@ -145,7 +153,7 @@ void tst_QSqlDriver::record()
QCOMPARE(rec.count(), 5);
}
- for (int i = 0; i < fields.count(); ++i)
+ for (int i = 0; i < fields.size(); ++i)
QCOMPARE(rec.fieldName(i), fields[i]);
if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2)
@@ -155,8 +163,9 @@ void tst_QSqlDriver::record()
//check that we can't get records using incorrect tablename casing that's been quoted
rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName));
- if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::SQLite || dbType == QSqlDriver::Sybase
- || dbType == QSqlDriver::MSSqlServer || tst_Databases::isMSAccess(db))
+ if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::SQLite
+ || dbType == QSqlDriver::Sybase || dbType == QSqlDriver::MSSqlServer
+ || tst_Databases::isMSAccess(db) || dbType == QSqlDriver::MimerSQL)
QCOMPARE(rec.count(), 5); //mysql, sqlite and tds will match
else
QCOMPARE(rec.count(), 0);
@@ -169,7 +178,7 @@ void tst_QSqlDriver::primaryIndex()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QString tablename(qTableName("relTEST1", __FILE__, db));
+ QString tablename(qTableName("relTEST1", __FILE__, db, false));
//check that we can get primary index using unquoted mixed case table name
QSqlIndex index = db.driver()->primaryIndex(tablename);
QCOMPARE(index.count(), 1);
@@ -205,22 +214,23 @@ void tst_QSqlDriver::primaryIndex()
tablename = tablename.toUpper();
index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName));
- if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::SQLite || dbType == QSqlDriver::Sybase
- || dbType == QSqlDriver::MSSqlServer || tst_Databases::isMSAccess(db))
+ if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::SQLite
+ || dbType == QSqlDriver::Sybase || dbType == QSqlDriver::MSSqlServer
+ || tst_Databases::isMSAccess(db) || dbType == QSqlDriver::MimerSQL)
QCOMPARE(index.count(), 1); //mysql will always find the table name regardless of casing
else
QCOMPARE(index.count(), 0);
// Test getting a primary index for a table with a clob in it - QTBUG-64427
if (dbType == QSqlDriver::Oracle) {
- const QString clobTable(qTableName("clobTable", __FILE__, db));
+ TableScope ts(db, "clobTable", __FILE__);
QSqlQuery qry(db);
- QVERIFY_SQL(qry, exec("CREATE TABLE " + clobTable + " (id INTEGER, clobField CLOB)"));
- QVERIFY_SQL(qry, exec("CREATE UNIQUE INDEX " + clobTable + "IDX ON " + clobTable + " (id)"));
- QVERIFY_SQL(qry, exec("ALTER TABLE " + clobTable + " ADD CONSTRAINT " + clobTable +
+ QVERIFY_SQL(qry, exec("CREATE TABLE " + ts.tableName() + " (id INTEGER, clobField CLOB)"));
+ QVERIFY_SQL(qry, exec("CREATE UNIQUE INDEX " + ts.tableName() + "IDX ON " + ts.tableName() + " (id)"));
+ QVERIFY_SQL(qry, exec("ALTER TABLE " + ts.tableName() + " ADD CONSTRAINT " + ts.tableName() +
"PK PRIMARY KEY(id)"));
- QVERIFY_SQL(qry, exec("ALTER TABLE " + clobTable + " MODIFY (id NOT NULL ENABLE)"));
- const QSqlIndex primaryIndex = db.driver()->primaryIndex(clobTable);
+ QVERIFY_SQL(qry, exec("ALTER TABLE " + ts.tableName() + " MODIFY (id NOT NULL ENABLE)"));
+ const QSqlIndex primaryIndex = db.driver()->primaryIndex(ts.tableName());
QCOMPARE(primaryIndex.count(), 1);
QCOMPARE(primaryIndex.fieldName(0), QStringLiteral("ID"));
}
diff --git a/tests/auto/sql/kernel/qsqlerror/CMakeLists.txt b/tests/auto/sql/kernel/qsqlerror/CMakeLists.txt
index d5100c1836..b604399ef1 100644
--- a/tests/auto/sql/kernel/qsqlerror/CMakeLists.txt
+++ b/tests/auto/sql/kernel/qsqlerror/CMakeLists.txt
@@ -1,12 +1,19 @@
-# Generated from qsqlerror.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqlerror Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqlerror LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqlerror
SOURCES
tst_qsqlerror.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Sql
)
diff --git a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp
index c83867fcc4..2be7d08cf8 100644
--- a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp
+++ b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.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>
@@ -108,12 +108,16 @@ void tst_QSqlError::moveOperator()
void tst_QSqlError::operators()
{
- QSqlError error1(QString(), QString(), QSqlError::NoError);
- QSqlError error2(QString(), QString(), QSqlError::NoError);
- QSqlError error3(QString(), QString(), QSqlError::UnknownError);
+ QSqlError error1(QStringLiteral("a"), QStringLiteral("b"), QSqlError::NoError, QStringLiteral("ec1"));
+ QSqlError error2(QStringLiteral("c"), QStringLiteral("d"), QSqlError::NoError, QStringLiteral("ec1"));
+ QSqlError error3(QString(), QString(), QSqlError::UnknownError, QStringLiteral("ec1"));
+ QSqlError error4(QString(), QString(), QSqlError::NoError, QStringLiteral("ec2"));
+ QSqlError error5(QString(), QString(), QSqlError::UnknownError, QStringLiteral("ec2"));
QCOMPARE(error1, error2);
QVERIFY(error1 != error3);
+ QVERIFY(error1 != error4);
+ QVERIFY(error4 != error5);
}
void tst_QSqlError::qtbug_74575()
diff --git a/tests/auto/sql/kernel/qsqlfield/CMakeLists.txt b/tests/auto/sql/kernel/qsqlfield/CMakeLists.txt
index 7f8c97f584..2fef227201 100644
--- a/tests/auto/sql/kernel/qsqlfield/CMakeLists.txt
+++ b/tests/auto/sql/kernel/qsqlfield/CMakeLists.txt
@@ -1,12 +1,19 @@
-# Generated from qsqlfield.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqlfield Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqlfield LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqlfield
SOURCES
tst_qsqlfield.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Sql
)
diff --git a/tests/auto/sql/kernel/qsqlfield/tst_qsqlfield.cpp b/tests/auto/sql/kernel/qsqlfield/tst_qsqlfield.cpp
index 79c774630d..5e012ba39c 100644
--- a/tests/auto/sql/kernel/qsqlfield/tst_qsqlfield.cpp
+++ b/tests/auto/sql/kernel/qsqlfield/tst_qsqlfield.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>
@@ -39,6 +39,7 @@ private slots:
void clear();
void setTableName_data();
void setTableName();
+ void moveSemantics();
};
// Testing get/set functions
@@ -344,5 +345,24 @@ void tst_QSqlField::setTableName()
QCOMPARE(field.tableName(), tableName);
}
+void tst_QSqlField::moveSemantics()
+{
+ QSqlField field("test", QMetaType(QMetaType::QString), "testTable");
+ QSqlField empty;
+ field.setValue("string");
+ auto moved = std::move(field);
+ // `field` is now partially-formed
+
+ // moving transfers state:
+ QCOMPARE(moved.value().toString(), QLatin1String("string"));
+
+ // moved-from objects can be assigned-to:
+ field = empty;
+ QVERIFY(field.value().isNull());
+
+ // moved-from object can be destroyed:
+ moved = std::move(field);
+}
+
QTEST_MAIN(tst_QSqlField)
#include "tst_qsqlfield.moc"
diff --git a/tests/auto/sql/kernel/qsqlindex/CMakeLists.txt b/tests/auto/sql/kernel/qsqlindex/CMakeLists.txt
new file mode 100644
index 0000000000..3373948b5f
--- /dev/null
+++ b/tests/auto/sql/kernel/qsqlindex/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsqlindex Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqlindex LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsqlindex
+ SOURCES
+ tst_qsqlindex.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Sql
+ Qt::SqlPrivate
+)
diff --git a/tests/auto/sql/kernel/qsqlindex/tst_qsqlindex.cpp b/tests/auto/sql/kernel/qsqlindex/tst_qsqlindex.cpp
new file mode 100644
index 0000000000..2f44359133
--- /dev/null
+++ b/tests/auto/sql/kernel/qsqlindex/tst_qsqlindex.cpp
@@ -0,0 +1,126 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtSql/QtSql>
+
+#include <QtCore/QDateTime>
+#include <QtCore/QTimeZone>
+
+#include <numeric>
+
+#include "../qsqldatabase/tst_databases.h"
+
+using namespace Qt::StringLiterals;
+
+QString qtest;
+
+class tst_QSqlIndex : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QSqlIndex();
+
+private slots:
+ void construction_data();
+ void construction();
+ void assignment_data();
+ void assignment();
+ void basicFunctions();
+};
+
+tst_QSqlIndex::tst_QSqlIndex()
+{
+}
+
+void tst_QSqlIndex::construction_data()
+{
+ QTest::addColumn<QSqlIndex>("sqlIndex");
+ QTest::addColumn<QString>("cursorName");
+ QTest::addColumn<QString>("name");
+
+ const QString cursorName("cusorName"_L1);
+ const QString name("name"_L1);
+ QSqlIndex sqlIndex(cursorName, name);
+ QTest::newRow("ctor1") << QSqlIndex() << QString() << QString();
+ QTest::newRow("ctor2") << sqlIndex << cursorName << name;
+ QTest::newRow("copy ctor") << QSqlIndex(sqlIndex) << cursorName << name;
+ QTest::newRow("move ctor") << QSqlIndex(std::move(sqlIndex)) << cursorName << name;
+}
+
+void tst_QSqlIndex::construction()
+{
+ QFETCH(QSqlIndex, sqlIndex);
+ QFETCH(QString, cursorName);
+ QFETCH(QString, name);
+
+ QCOMPARE(sqlIndex.cursorName(), cursorName);
+ QCOMPARE(sqlIndex.name(), name);
+ QCOMPARE(sqlIndex.isDescending(0), false);
+ QCOMPARE(sqlIndex.count(), 0);
+}
+
+void tst_QSqlIndex::assignment_data()
+{
+ QTest::addColumn<QSqlIndex>("sqlIndex");
+ QTest::addColumn<QString>("cursorName");
+ QTest::addColumn<QString>("name");
+
+ const QString cursorName("cusorName"_L1);
+ const QString name("name"_L1);
+ QSqlIndex sqlIndex(cursorName, name);
+ QSqlIndex sqlIndex1 = sqlIndex;
+ QSqlIndex sqlIndex2 = std::move(sqlIndex);
+ sqlIndex = std::move(sqlIndex2);
+ QTest::newRow("copy assignment") << sqlIndex1 << cursorName << name;
+ QTest::newRow("move assignment") << sqlIndex << cursorName << name;
+}
+
+void tst_QSqlIndex::assignment()
+{
+ QFETCH(QSqlIndex, sqlIndex);
+ QFETCH(QString, cursorName);
+ QFETCH(QString, name);
+
+ QCOMPARE(sqlIndex.cursorName(), cursorName);
+ QCOMPARE(sqlIndex.name(), name);
+ QCOMPARE(sqlIndex.isDescending(0), false);
+ QCOMPARE(sqlIndex.count(), 0);
+}
+
+void tst_QSqlIndex::basicFunctions()
+{
+ QSqlIndex sqlIndex("cursorName"_L1, "name"_L1);
+ const QSqlField f1("field1"_L1, QMetaType(QMetaType::UInt), "table1"_L1);
+ const QSqlField f2("field2"_L1, QMetaType(QMetaType::Double), "table2"_L1);
+
+ QCOMPARE(sqlIndex.cursorName(), "cursorName"_L1);
+ sqlIndex.setCursorName("updatedCursorName"_L1);
+ QCOMPARE(sqlIndex.name(), "name"_L1);
+ sqlIndex.setName("updatedName"_L1);
+ QCOMPARE(sqlIndex.cursorName(), "updatedCursorName"_L1);
+ QCOMPARE(sqlIndex.name(), "updatedName"_L1);
+
+ sqlIndex.append(f1);
+ QCOMPARE(sqlIndex.count(), 1);
+ QCOMPARE(sqlIndex.isDescending(0), false);
+
+ sqlIndex.append(f2, true);
+ QCOMPARE(sqlIndex.count(), 2);
+ QCOMPARE(sqlIndex.isDescending(0), false);
+ QCOMPARE(sqlIndex.isDescending(1), true);
+
+ sqlIndex.setDescending(0, true);
+ sqlIndex.setDescending(1, false);
+ sqlIndex.setDescending(2, true);
+ QCOMPARE(sqlIndex.count(), 2);
+ QCOMPARE(sqlIndex.isDescending(0), true);
+ QCOMPARE(sqlIndex.isDescending(1), false);
+
+ QCOMPARE(sqlIndex.field(0), f1);
+ QCOMPARE(sqlIndex.field(1), f2);
+}
+
+QTEST_MAIN(tst_QSqlIndex)
+#include "tst_qsqlindex.moc"
diff --git a/tests/auto/sql/kernel/qsqlquery/CMakeLists.txt b/tests/auto/sql/kernel/qsqlquery/CMakeLists.txt
index f00845a7cf..e5a5b2b2f8 100644
--- a/tests/auto/sql/kernel/qsqlquery/CMakeLists.txt
+++ b/tests/auto/sql/kernel/qsqlquery/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qsqlquery.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqlquery Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqlquery LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqlquery
SOURCES
tst_qsqlquery.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Sql
Qt::SqlPrivate
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index 026c9becec..56fb5cd05f 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -1,9 +1,12 @@
// Copyright (C) 2022 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>
#include <QtSql/QtSql>
+#include <QtCore/QDateTime>
+#include <QtCore/QTimeZone>
+
#include <numeric>
#include "../qsqldatabase/tst_databases.h"
@@ -55,8 +58,6 @@ private slots:
void last();
void seek_data() { generic_data(); }
void seek();
- void transaction_data() { generic_data(); }
- void transaction();
void record_data() { generic_data(); }
void record();
void record_sqlite_data() { generic_data("QSQLITE"); }
@@ -76,9 +77,10 @@ private slots:
void psql_forwardOnlyQueryResultsLost_data() { generic_data("QPSQL"); }
void psql_forwardOnlyQueryResultsLost();
+ void positionalBindingEnabled_data() { generic_data(); }
+ void positionalBindingEnabled();
+
// Bug-specific tests:
- void tds_bitField_data() { generic_data("QTDS"); }
- void tds_bitField();
void oci_nullBlob_data() { generic_data("QOCI"); }
void oci_nullBlob();
void blob_data() { generic_data(); }
@@ -171,11 +173,11 @@ private slots:
void task_250026();
void crashQueryOnCloseDatabase();
- void task_233829_data() { generic_data("QPSQL"); }
- void task_233829();
+ void testNaN_data() { generic_data("QPSQL"); }
+ void testNaN();
- void QTBUG_12477_data() { generic_data("QPSQL"); }
- void QTBUG_12477();
+ void psqlNumericMetadata_data() { generic_data("QPSQL"); }
+ void psqlNumericMetadata();
void sqlServerReturn0_data() { generic_data(); }
void sqlServerReturn0();
@@ -226,6 +228,9 @@ private slots:
void sqlite_real_data() { generic_data("QSQLITE"); }
void sqlite_real();
+ void prepared_query_json_row_data() { generic_data(); }
+ void prepared_query_json_row();
+
void aggregateFunctionTypes_data() { generic_data(); }
void aggregateFunctionTypes();
@@ -238,12 +243,23 @@ private slots:
void QTBUG_73286_data() { generic_data("QODBC"); }
void QTBUG_73286();
+ void insertVarChar1_data() { generic_data("QODBC"); }
+ void insertVarChar1();
+
void dateTime_data();
void dateTime();
void ibaseArray_data() { generic_data("QIBASE"); }
void ibaseArray();
+ void ibaseDateTimeWithTZ_data();
+ void ibaseDateTimeWithTZ();
+ void ibaseTimeStampTzArray_data() { generic_data("QIBASE"); }
+ void ibaseTimeStampTzArray();
+
+ void psqlJsonOperator_data() { generic_data("QPSQL"); }
+ void psqlJsonOperator();
+
// Double addDatabase() with same name leaves system in a state that breaks
// invalidQuery() if run later; so put this one last !
void prematureExec_data() { generic_data(); }
@@ -330,55 +346,8 @@ void tst_QSqlQuery::dropTestTables(QSqlDatabase db)
// Drop all the table in case a testcase failed:
tablenames << qtest
<< qTableName("qtest_null", __FILE__, db)
- << qTableName("qtest_writenull", __FILE__, db)
- << qTableName("qtest_blob", __FILE__, db)
- << qTableName("qtest_bittest", __FILE__, db)
- << qTableName("qtest_nullblob", __FILE__, db)
- << qTableName("qtest_rawtest", __FILE__, db)
- << qTableName("qtest_precision", __FILE__, db)
- << qTableName("qtest_prepare", __FILE__, db)
- << qTableName("qtestj1", __FILE__, db)
- << qTableName("qtestj2", __FILE__, db)
- << qTableName("char1Select", __FILE__, db)
- << qTableName("char1SU", __FILE__, db)
- << qTableName("qxmltest", __FILE__, db)
- << qTableName("qtest_exerr", __FILE__, db)
- << qTableName("qtest_empty", __FILE__, db)
- << qTableName("clobby", __FILE__, db)
- << qTableName("bindtest", __FILE__, db)
- << qTableName("more_results", __FILE__, db)
- << qTableName("blobstest", __FILE__, db)
- << qTableName("oraRowId", __FILE__, db)
- << qTableName("bug43874", __FILE__, db)
- << qTableName("bug6421", __FILE__, db).toUpper()
- << qTableName("bug5765", __FILE__, db)
- << qTableName("bug6852", __FILE__, db)
- << qTableName("bug21884", __FILE__, db)
- << qTableName("bug23895", __FILE__, db)
- << qTableName("qtest_lockedtable", __FILE__, db)
- << qTableName("Planet", __FILE__, db)
- << qTableName("task_250026", __FILE__, db)
- << qTableName("task_234422", __FILE__, db)
- << qTableName("test141895", __FILE__, db)
- << qTableName("qtest_oraOCINumber", __FILE__, db)
- << qTableName("bug2192", __FILE__, db)
<< qTableName("tst_record", __FILE__, db);
- if (dbType == QSqlDriver::PostgreSQL)
- tablenames << qTableName("task_233829", __FILE__, db);
-
- if (dbType == QSqlDriver::SQLite)
- tablenames << qTableName("record_sqlite", __FILE__, db);
-
- if (dbType == QSqlDriver::MSSqlServer || dbType == QSqlDriver::Oracle)
- tablenames << qTableName("qtest_longstr", __FILE__, db);
-
- if (dbType == QSqlDriver::MSSqlServer)
- db.exec("DROP PROCEDURE " + qTableName("test141895_proc", __FILE__, db));
-
- if (dbType == QSqlDriver::MySqlServer)
- db.exec("DROP PROCEDURE IF EXISTS " + qTableName("bug6852_proc", __FILE__, db));
-
tst_Databases::safeDropTables(db, tablenames);
if (dbType == QSqlDriver::Oracle) {
@@ -401,7 +370,7 @@ void tst_QSqlQuery::createTestTables(QSqlDatabase db)
if (dbType == QSqlDriver::PostgreSQL) {
QVERIFY_SQL(q, exec(QLatin1String(
"create table %1 (id serial NOT NULL, t_varchar varchar(20), "
- "t_char char(20), primary key(id)) WITH OIDS").arg(qtest)));
+ "t_char char(20), primary key(id))").arg(qtest)));
} else {
QVERIFY_SQL(q, exec(QLatin1String(
"create table %1 (id int %2 NOT NULL, t_varchar varchar(20), "
@@ -446,12 +415,11 @@ void tst_QSqlQuery::char1Select()
CHECK_DATABASE(db);
{
+ TableScope ts(db, "char1Select", __FILE__);
QSqlQuery q(db);
- const QString tbl = qTableName("char1Select", __FILE__, db);
- q.exec("drop table " + tbl);
- QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id char(1))").arg(tbl)));
- QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values ('a')").arg(tbl)));
- QVERIFY_SQL(q, exec("select * from " + tbl));
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id char(1))").arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values ('a')").arg(ts.tableName())));
+ QVERIFY_SQL(q, exec("select * from " + ts.tableName()));
QVERIFY(q.next());
if (tst_Databases::getDatabaseType(db) == QSqlDriver::Interbase)
QCOMPARE(q.value(0).toString().left(1), u"a");
@@ -475,11 +443,12 @@ void tst_QSqlQuery::char1SelectUnicode()
QSKIP("Database not unicode capable");
QString uniStr(QChar(0x0915)); // DEVANAGARI LETTER KA
+ TableScope ts(db, "char1SU", __FILE__);
QSqlQuery q(db);
QLatin1String createQuery;
- const QString char1SelectUnicode(qTableName("char1SU", __FILE__, db));
switch (dbType) {
+ case QSqlDriver::MimerSQL:
case QSqlDriver::MSSqlServer:
createQuery = QLatin1String("create table %1(id nchar(1))");
break;
@@ -499,12 +468,12 @@ void tst_QSqlQuery::char1SelectUnicode()
break;
}
- QVERIFY_SQL(q, exec(createQuery.arg(char1SelectUnicode)));
- QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values(?)").arg(char1SelectUnicode)));
+ QVERIFY_SQL(q, exec(createQuery.arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values(?)").arg(ts.tableName())));
q.bindValue(0, uniStr);
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec("select * from " + char1SelectUnicode));
+ QVERIFY_SQL(q, exec("select * from " + ts.tableName()));
QVERIFY(q.next());
if (!q.value(0).toString().isEmpty())
@@ -519,7 +488,8 @@ void tst_QSqlQuery::oraRowId()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString oraRowId(qTableName("oraRowId", __FILE__, db));
+ TableScope ts(db, "oraRowId", __FILE__);
+ const auto &oraRowId = ts.tableName();
QSqlQuery q(db);
QVERIFY_SQL(q, exec("select rowid from " + qtest));
@@ -555,7 +525,7 @@ void tst_QSqlQuery::mysql_outValues()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
const QString hello(qTableName("hello", __FILE__, db));
- const QString qtestproc(qTableName("qtestproc", __FILE__, db));
+ ProcScope ps(db, "qtestproc", __FILE__);
QSqlQuery q(db);
@@ -577,25 +547,22 @@ void tst_QSqlQuery::mysql_outValues()
QCOMPARE(q.value(0).toString(), u"Hello harald");
QVERIFY_SQL(q, exec("drop function " + hello));
- q.exec("drop procedure " + qtestproc);
QVERIFY_SQL(q, exec(QLatin1String("create procedure %1 () BEGIN "
- "select * from %2 order by id; END").arg(qtestproc, qtest)));
- QVERIFY_SQL(q, exec(QLatin1String("call %1()").arg(qtestproc)));
+ "select * from %2 order by id; END").arg(ps.name(), qtest)));
+ QVERIFY_SQL(q, exec(QLatin1String("call %1()").arg(ps.name())));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(1).toString(), u"VarChar1");
- QVERIFY_SQL(q, exec("drop procedure " + qtestproc));
+ QVERIFY_SQL(q, exec("drop procedure " + ps.name()));
QVERIFY_SQL(q, exec(QLatin1String("create procedure %1 (OUT param1 INT) "
- "BEGIN set param1 = 42; END").arg(qtestproc)));
+ "BEGIN set param1 = 42; END").arg(ps.name())));
- QVERIFY_SQL(q, exec(QLatin1String("call %1 (@out)").arg(qtestproc)));
+ QVERIFY_SQL(q, exec(QLatin1String("call %1 (@out)").arg(ps.name())));
QVERIFY_SQL(q, exec("select @out"));
QCOMPARE(q.record().fieldName(0), u"@out");
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 42);
-
- QVERIFY_SQL(q, exec("drop procedure " + qtestproc));
}
void tst_QSqlQuery::bindBool()
@@ -778,7 +745,8 @@ void tst_QSqlQuery::oraClob()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString clobby(qTableName("clobby", __FILE__, db));
+ TableScope ts(db, "clobby", __FILE__);
+ const auto &clobby = ts.tableName();
QSqlQuery q(db);
@@ -854,19 +822,15 @@ void tst_QSqlQuery::storedProceduresIBase()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ ProcScope ps(db, "TESTPROC", __FILE__);
QSqlQuery q(db);
- const auto procName = qTableName("TESTPROC", __FILE__, db);
- q.exec("drop procedure " + procName);
-
QVERIFY_SQL(q, exec(QLatin1String("create procedure %1 RETURNS (x integer, y varchar(20)) "
"AS BEGIN "
" x = 42; "
" y = 'Hello Anders'; "
- "END").arg(procName)));
- const auto tidier = qScopeGuard([&]() { q.exec("drop procedure " + procName); });
-
- QVERIFY_SQL(q, prepare("execute procedure " + procName));
+ "END").arg(ps.name())));
+ QVERIFY_SQL(q, prepare("execute procedure " + ps.name()));
QVERIFY_SQL(q, exec());
// Check for a valid result set:
@@ -893,12 +857,11 @@ void tst_QSqlQuery::outValuesDB2()
if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries))
QSKIP("Test requires prepared query support");
- QSqlQuery q(db);
+ ProcScope ps(db, "tst_outValues", __FILE__);
+ QSqlQuery q(db);
q.setForwardOnly(true);
- const QString procName = qTableName("tst_outValues", __FILE__, db);
- q.exec("drop procedure " + procName); // non-fatal
QVERIFY_SQL(q, exec(QLatin1String("CREATE PROCEDURE %1 "
"(OUT x int, OUT x2 double, OUT x3 char(20))\n"
"LANGUAGE SQL\n"
@@ -906,9 +869,9 @@ void tst_QSqlQuery::outValuesDB2()
" SET x = 42;\n"
" SET x2 = 4.2;\n"
" SET x3 = 'Homer';\n"
- "END P1").arg(procName)));
+ "END P1").arg(ps.name())));
- QVERIFY_SQL(q, prepare(QLatin1String("call %1(?, ?, ?)").arg(procName)));
+ QVERIFY_SQL(q, prepare(QLatin1String("call %1(?, ?, ?)").arg(ps.name())));
q.addBindValue(0, QSql::Out);
q.addBindValue(0.0, QSql::Out);
@@ -926,11 +889,11 @@ void tst_QSqlQuery::outValues()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString tst_outValues(qTableName("tst_outValues", __FILE__, db));
if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries))
QSKIP("Test requires prepared query support");
+ ProcScope ps(db, "tst_outValues", __FILE__);
QSqlQuery q(db);
q.setForwardOnly(true);
@@ -944,7 +907,6 @@ void tst_QSqlQuery::outValues()
caller = QLatin1String("call %1(?)");
break;
case QSqlDriver::DB2:
- q.exec("drop procedure " + tst_outValues); // non-fatal
creator = QLatin1String("CREATE PROCEDURE %1 (OUT x int)\n"
"LANGUAGE SQL\n"
"P1: BEGIN\n"
@@ -953,7 +915,6 @@ void tst_QSqlQuery::outValues()
caller = QLatin1String("call %1(?)");
break;
case QSqlDriver::MSSqlServer:
- q.exec("drop procedure " + tst_outValues); // non-fatal
creator = QLatin1String("create procedure %1 (@x int out) as\n"
"begin\n"
" set @x = 42\n"
@@ -964,8 +925,8 @@ void tst_QSqlQuery::outValues()
QSKIP("Don't know how to create a stored procedure for this database server, "
"please fix this test");
}
- QVERIFY_SQL(q, exec(creator.arg(tst_outValues)));
- QVERIFY(q.prepare(caller.arg(tst_outValues)));
+ QVERIFY_SQL(q, exec(creator.arg(ps.name())));
+ QVERIFY(q.prepare(caller.arg(ps.name())));
q.addBindValue(0, QSql::Out);
@@ -991,15 +952,15 @@ void tst_QSqlQuery::blob()
for (int i = 0; i < ba.size(); ++i)
ba[i] = i % 256;
+ TableScope ts(db, "qtest_blob", __FILE__);
QSqlQuery q(db);
q.setForwardOnly(true);
- const QString tableName = qTableName("qtest_blob", __FILE__, db);
QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int not null primary key, t_blob %2)")
- .arg(tableName, tst_Databases::blobTypeName(db, BLOBSIZE))));
+ .arg(ts.tableName(), tst_Databases::blobTypeName(db, BLOBSIZE))));
QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 (id, t_blob) values (?, ?)")
- .arg(tableName)));
+ .arg(ts.tableName())));
for (int i = 0; i < BLOBCOUNT; ++i) {
q.addBindValue(i);
@@ -1007,7 +968,7 @@ void tst_QSqlQuery::blob()
QVERIFY_SQL(q, exec());
}
- QVERIFY_SQL(q, exec("select * from " + tableName));
+ QVERIFY_SQL(q, exec("select * from " + ts.tableName()));
for (int i = 0; i < BLOBCOUNT; ++i) {
QVERIFY(q.next());
@@ -1017,10 +978,10 @@ void tst_QSqlQuery::blob()
"array sizes differ, expected (at least) %" PRIdQSIZETYPE
", got %" PRIdQSIZETYPE, ba.size(), res.size())));
- for (int i2 = 0; i2 < ba.size(); ++i2) {
+ for (qsizetype i2 = 0; i2 < ba.size(); ++i2) {
if (res[i2] != ba[i2]) {
QFAIL(qPrintable(QString::asprintf(
- "ByteArrays differ at position %d, expected %hhu, got %hhu",
+ "ByteArrays differ at position %lld, expected %hhu, got %hhu",
i2, ba[i2], res[i2])));
}
}
@@ -1107,8 +1068,9 @@ void tst_QSqlQuery::record()
QCOMPARE(q.record().fieldName(0).toLower(), u"id");
QCOMPARE(q.value(0).toInt(), 2);
- if (tst_Databases::getDatabaseType(db) == QSqlDriver::Oracle)
- QSKIP("Getting the tablename is not supported in Oracle");
+ if (tst_Databases::getDatabaseType(db) == QSqlDriver::Oracle
+ || tst_Databases::getDatabaseType(db) == QSqlDriver::MimerSQL)
+ QSKIP("Getting the tablename is not supported in Oracle and Mimer SQL");
const auto lowerQTest = qtest.toLower();
for (int i = 0; i < 3; ++i)
@@ -1224,12 +1186,8 @@ void tst_QSqlQuery::numRowsAffected()
QSqlQuery q2(db);
QVERIFY_SQL(q2, exec(QLatin1String("insert into %1 values (42001, 'homer', 'marge')")
.arg(qtest)));
-
- if (!db.driverName().startsWith("QSQLITE2")) {
- // SQLite 2.x accumulates changed rows in nested queries. See task 33794
- QCOMPARE(q2.numRowsAffected(), 1);
- QCOMPARE(q2.numRowsAffected(), 1); // yes, we check twice
- }
+ QCOMPARE(q2.numRowsAffected(), 1);
+ QCOMPARE(q2.numRowsAffected(), 1); // yes, we check twice
}
void tst_QSqlQuery::size()
@@ -1489,16 +1447,8 @@ void tst_QSqlQuery::forwardOnly()
QCOMPARE(q.at(), QSql::AfterLastRow);
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
- QSqlQuery q2 = q;
-QT_WARNING_POP
-
- QVERIFY(q2.isForwardOnly());
-
QVERIFY_SQL(q, exec(QLatin1String("select * from %1 order by id").arg(qtest)));
QVERIFY(q.isForwardOnly());
- QVERIFY(q2.isForwardOnly());
QCOMPARE(q.at(), QSql::BeforeFirstRow);
QVERIFY_SQL(q, seek(3));
@@ -1784,25 +1734,24 @@ void tst_QSqlQuery::writeNull()
CHECK_DATABASE(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- QSqlQuery q(db);
- const QString tableName = qTableName("qtest_writenull", __FILE__, db);
-
// The test data table is already used, so use a local hash to exercise the various
- // cases from the QSqlResultPrivate::isVariantNull helper. Only PostgreSQL supports
- // QUuid.
+ // cases from the QSqlResultPrivate::isVariantNull helper. Only PostgreSQL and Mimer SQL
+ // supports QUuid.
QMultiHash<QString, QVariant> nullableTypes = {
- {"varchar(20)", u"not null"_s},
- {"varchar(20)", "not null"_ba},
- {"date", QDateTime::currentDateTime()},
- {"date", QDate::currentDate()},
- {"date", QTime::currentTime()},
+ { "varchar(20)", u"not null"_s },
+ { "varchar(20)", "not null"_ba },
+ { tst_Databases::dateTimeTypeName(db), QDateTime::currentDateTime() },
+ { tst_Databases::dateTypeName(db), QDate::currentDate() },
+ { tst_Databases::timeTypeName(db), QTime::currentTime() },
};
if (dbType == QSqlDriver::PostgreSQL)
nullableTypes["uuid"] = QUuid::createUuid();
+ if (dbType == QSqlDriver::MimerSQL)
+ nullableTypes["builtin.uuid"] = QUuid::createUuid();
// Helper to count rows with null values in the data column.
// Since QSqlDriver::QuerySize might not be supported, we have to count anyway
- const auto countRowsWithNull = [&]{
+ const auto countRowsWithNull = [&](QSqlQuery &q, const QString &tableName){
q.exec(QLatin1String("select id, data from %1 where data is null").arg(tableName));
int size = 0;
while (q.next())
@@ -1811,37 +1760,37 @@ void tst_QSqlQuery::writeNull()
};
for (const auto &nullableType : nullableTypes.keys()) {
- const auto tableGuard = qScopeGuard([&]{
- q.exec("drop table " + tableName);
- });
+ TableScope ts(db, "qtest_writenull", __FILE__);
+ QSqlQuery q(db);
+
const QVariant nonNullValue = nullableTypes.value(nullableType);
// some useful diagnostic output in case of any test failure
auto errorHandler = qScopeGuard([&]{
qWarning() << "Test failure for data type" << nonNullValue.metaType().name();
- q.exec("select id, data from " + tableName);
+ q.exec("select id, data from " + ts.tableName());
while (q.next())
qWarning() << q.value(0) << q.value(1);
});
QString createQuery = QLatin1String("create table %3 (id int, data %1%2)")
.arg(nullableType,
dbType == QSqlDriver::MSSqlServer || dbType == QSqlDriver::Sybase ? " null" : "",
- tableName);
+ ts.tableName());
QVERIFY_SQL(q, exec(createQuery));
int expectedNullCount = 0;
// Verify that inserting a non-null value works:
- QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values(:id, :data)").arg(tableName)));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values(:id, :data)").arg(ts.tableName())));
q.bindValue(":id", expectedNullCount);
q.bindValue(":data", nonNullValue);
QVERIFY_SQL(q, exec());
- QCOMPARE(countRowsWithNull(), expectedNullCount);
+ QCOMPARE(countRowsWithNull(q, ts.tableName()), expectedNullCount);
// Verify that inserting using a null QVariant produces a null entry in the database:
- QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values(:id, :data)").arg(tableName)));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values(:id, :data)").arg(ts.tableName())));
q.bindValue(":id", ++expectedNullCount);
q.bindValue(":data", QVariant());
QVERIFY_SQL(q, exec());
- QCOMPARE(countRowsWithNull(), expectedNullCount);
+ QCOMPARE(countRowsWithNull(q, ts.tableName()), expectedNullCount);
// Verify that writing a null-value (but not a null-variant) produces a
// null entry in the database:
@@ -1856,57 +1805,36 @@ void tst_QSqlQuery::writeNull()
const QVariant nullValueVariant(nullableMetaType, defaultData);
QVERIFY(!nullValueVariant.isNull());
- QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values(:id, :data)").arg(tableName)));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values(:id, :data)").arg(ts.tableName())));
q.bindValue(":id", ++expectedNullCount);
q.bindValue(":data", nullValueVariant);
QVERIFY_SQL(q, exec());
- QCOMPARE(countRowsWithNull(), expectedNullCount);
+ QCOMPARE(countRowsWithNull(q, ts.tableName()), expectedNullCount);
// All tests passed for this type if we got here, so don't print diagnostics:
errorHandler.dismiss();
}
}
-// TDS-specific BIT field test:
-void tst_QSqlQuery::tds_bitField()
-{
- QFETCH(QString, dbName);
- QSqlDatabase db = QSqlDatabase::database(dbName);
- CHECK_DATABASE(db);
- const QString tableName = qTableName("qtest_bittest", __FILE__, db);
- QSqlQuery q(db);
-
- QVERIFY_SQL(q, exec(QLatin1String("create table %1 (bitty bit)").arg(tableName)));
- QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (0)").arg(tableName)));
- QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1)").arg(tableName)));
- QVERIFY_SQL(q, exec("select bitty from " + tableName));
-
- QVERIFY(q.next());
- QCOMPARE(q.value(0).toInt(), 0);
-
- QVERIFY(q.next());
- QCOMPARE(q.value(0).toInt(), 1);
-}
-
// Oracle-specific NULL BLOB test:
void tst_QSqlQuery::oci_nullBlob()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString qtest_nullblob(qTableName("qtest_nullblob", __FILE__, db));
+ TableScope ts(db, "qtest_nullblob", __FILE__);
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int primary key, bb blob)")
- .arg(qtest_nullblob)));
+ .arg(ts.tableName())));
QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (0, EMPTY_BLOB())")
- .arg(qtest_nullblob)));
- QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, NULL)").arg(qtest_nullblob)));
+ .arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, NULL)").arg(ts.tableName())));
QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (2, 'aabbcc00112233445566')")
- .arg(qtest_nullblob)));
+ .arg(ts.tableName())));
// Necessary otherwise Oracle will bombard you with internal errors:
q.setForwardOnly(true);
- QVERIFY_SQL(q, exec(QLatin1String("select * from %1 order by id").arg(qtest_nullblob)));
+ QVERIFY_SQL(q, exec(QLatin1String("select * from %1 order by id").arg(ts.tableName())));
QVERIFY(q.next());
QVERIFY(q.value(1).toByteArray().isEmpty());
@@ -1927,15 +1855,15 @@ void tst_QSqlQuery::oci_rawField()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString qtest_rawtest(qTableName("qtest_rawtest", __FILE__, db));
+ TableScope ts(db, "qtest_rawtest", __FILE__);
QSqlQuery q(db);
q.setForwardOnly(true);
- QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int, col raw(20))").arg(qtest_rawtest)));
- QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (0, NULL)").arg(qtest_rawtest)));
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int, col raw(20))").arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (0, NULL)").arg(ts.tableName())));
QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, '00aa1100ddeeff')")
- .arg(qtest_rawtest)));
- QVERIFY_SQL(q, exec(QLatin1String("select col from %1 order by id").arg(qtest_rawtest)));
+ .arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("select col from %1 order by id").arg(ts.tableName())));
QVERIFY(q.next());
QVERIFY(q.isNull(0));
QVERIFY(q.value(0).toByteArray().isEmpty());
@@ -1961,22 +1889,21 @@ void tst_QSqlQuery::precision()
});
db.driver()->setNumericalPrecisionPolicy(QSql::HighPrecision);
- const QString qtest_precision(qTableName("qtest_precision", __FILE__, db));
+ TableScope ts(db, "qtest_precision", __FILE__);
static const QLatin1String precStr("1.2345678901234567891");
{
// need a new scope for SQLITE
QSqlQuery q(db);
- q.exec("drop table " + qtest_precision);
QVERIFY_SQL(q, exec(QLatin1String(tst_Databases::isMSAccess(db)
? "CREATE TABLE %1 (col1 number)"
: "CREATE TABLE %1 (col1 numeric(21, 20))")
- .arg(qtest_precision)));
+ .arg(ts.tableName())));
QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (col1) VALUES (%2)")
- .arg(qtest_precision, precStr)));
- QVERIFY_SQL(q, exec("SELECT * FROM " + qtest_precision));
+ .arg(ts.tableName(), precStr)));
+ QVERIFY_SQL(q, exec("SELECT * FROM " + ts.tableName()));
QVERIFY(q.next());
const QString val = q.value(0).toString();
if (!val.startsWith(precStr)) {
@@ -2016,113 +1943,35 @@ void tst_QSqlQuery::nullResult()
QVERIFY(!q.seek(0));
}
-// This test is just an experiment to see whether we can do query-based transactions.
-// The real transaction test is in tst_QSqlDatabase.
-void tst_QSqlQuery::transaction()
-{
- // Query-based transaction is not really possible with Qt:
- QSKIP("only tested manually by trained staff");
-
- QFETCH(QString, dbName);
- QSqlDatabase db = QSqlDatabase::database(dbName);
- CHECK_DATABASE(db);
- const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (!db.driver()->hasFeature(QSqlDriver::Transactions))
- QSKIP("DBMS not transaction-capable");
-
- // This is the standard SQL:
- QString startTransactionStr("start transaction");
-
- if (dbType == QSqlDriver::MySqlServer)
- startTransactionStr = "begin work";
-
- QSqlQuery q(db);
- QSqlQuery q2(db);
-
- // Test a working transaction:
- q.exec(startTransactionStr);
- QVERIFY_SQL(q, exec(QLatin1String("insert into%1 values (40, 'VarChar40', 'Char40')")
- .arg(qtest)));
- QVERIFY_SQL(q, exec(QLatin1String("select * from%1 where id = 40").arg(qtest)));
-
- QVERIFY(q.next());
- QCOMPARE(q.value(0).toInt(), 40);
-
- QVERIFY_SQL(q, exec("commit"));
- QVERIFY_SQL(q, exec(QLatin1String("select * from%1 where id = 40").arg(qtest)));
-
- QVERIFY(q.next());
- QCOMPARE(q.value(0).toInt(), 40);
-
- // Test a rollback:
- q.exec(startTransactionStr);
- QVERIFY_SQL(q, exec(QLatin1String("insert into%1 values (41, 'VarChar41', 'Char41')")
- .arg(qtest)));
- QVERIFY_SQL(q, exec(QLatin1String("select * from%1 where id = 41").arg(qtest)));
-
- QVERIFY(q.next());
- QCOMPARE(q.value(0).toInt(), 41);
-
- if (!q.exec("rollback")) {
- if (dbType == QSqlDriver::MySqlServer) {
- qDebug("MySQL: %s", qPrintable(tst_Databases::printError(q.lastError())));
- QSKIP("MySQL transaction failed "); // non-fatal
- } else {
- QFAIL("Could not rollback transaction: " + tst_Databases::printError(q.lastError()));
- }
- }
- QVERIFY_SQL(q, exec(QLatin1String("select * from%1 where id = 41").arg(qtest)));
- QVERIFY(!q.next());
-
- // Test concurrent access:
- q.exec(startTransactionStr);
- QVERIFY_SQL(q, exec(QLatin1String("insert into%1 values (42, 'VarChar42', 'Char42')")
- .arg(qtest)));
- QVERIFY_SQL(q, exec(QLatin1String("select * from%1 where id = 42").arg(qtest)));
- QVERIFY(q.next());
- QCOMPARE(q.value(0).toInt(), 42);
-
- QVERIFY_SQL(q2, exec(QLatin1String("select * from%1 where id = 42").arg(qtest)));
- if (q2.next())
- qDebug("DBMS '%s' doesn't support query based transactions with concurrent access",
- qPrintable(tst_Databases::dbToString(db)));
-
- QVERIFY_SQL(q, exec("commit"));
- QVERIFY_SQL(q2, exec(QLatin1String("select * from%1 where id = 42").arg(qtest)));
-
- QVERIFY(q2.next());
- QCOMPARE(q2.value(0).toInt(), 42);
-}
-
void tst_QSqlQuery::joins()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- const QString qtestj1(qTableName("qtestj1", __FILE__, db));
- const QString qtestj2(qTableName("qtestj2", __FILE__, db));
if (dbType == QSqlDriver::Oracle || dbType == QSqlDriver::Sybase
|| dbType == QSqlDriver::Interbase || db.driverName().startsWith("QODBC")) {
// Oracle broken beyond recognition - cannot outer join on more than one table:
QSKIP("DBMS cannot understand standard SQL");
}
+ TableScope j1(db, "qtestj1", __FILE__);
+ TableScope j2(db, "qtestj2", __FILE__);
QSqlQuery q(db);
- QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id1 int, id2 int)").arg(qtestj1)));
- QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int, name varchar(20))").arg(qtestj2)));
- QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, 1)").arg(qtestj1)));
- QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, 2)").arg(qtestj1)));
- QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values(1, 'trenton')").arg(qtestj2)));
- QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values(2, 'marius')").arg(qtestj2)));
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id1 int, id2 int)").arg(j1.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int, name varchar(20))").arg(j2.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, 1)").arg(j1.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, 2)").arg(j1.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values(1, 'trenton')").arg(j2.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values(2, 'marius')").arg(j2.tableName())));
QVERIFY_SQL(q, exec(QLatin1String(
"select qtestj1.id1, qtestj1.id2, qtestj2.id, qtestj2.name, "
"qtestj3.id, qtestj3.name from %1 qtestj1 left outer join %2 qtestj2 "
"on (qtestj1.id1 = qtestj2.id) left outer join %2 as qtestj3 "
- "on (qtestj1.id2 = qtestj3.id)").arg(qtestj1, qtestj2)));
+ "on (qtestj1.id2 = qtestj3.id)").arg(j1.tableName(), j2.tableName())));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 1);
@@ -2170,7 +2019,8 @@ void tst_QSqlQuery::prepare_bind_exec()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- const QString qtest_prepare(qTableName("qtest_prepare", __FILE__, db));
+ TableScope ts(db, "qtest_prepare", __FILE__);
+ const auto &qtest_prepare = ts.tableName();
if (dbType == QSqlDriver::DB2)
QSKIP("Needs someone with more Unicode knowledge than I have to fix");
@@ -2193,6 +2043,7 @@ void tst_QSqlQuery::prepare_bind_exec()
switch (dbType) {
case QSqlDriver::MSSqlServer:
case QSqlDriver::Sybase:
+ case QSqlDriver::MimerSQL:
createQuery = QLatin1String("create table %1 (id int primary key, "
"name nvarchar(200) null, name2 nvarchar(200) null)");
break;
@@ -2210,20 +2061,23 @@ void tst_QSqlQuery::prepare_bind_exec()
break;
}
- q.exec("drop table " + qtest_prepare);
QVERIFY_SQL(q, exec(createQuery.arg(qtest_prepare)));
QVERIFY(q.prepare(QLatin1String("insert into %1 (id, name) values (:id, :name)")
.arg(qtest_prepare)));
- int i;
-
- for (i = 0; i < 6; ++i) {
+ for (int i = 0; i < 6; ++i) {
q.bindValue(":name", values[i]);
q.bindValue(":id", i);
QVERIFY_SQL(q, exec());
const QVariantList m = q.boundValues();
- QCOMPARE(m.count(), qsizetype(2));
+ QCOMPARE(m.size(), qsizetype(2));
QCOMPARE(m.at(0).toInt(), i);
QCOMPARE(m.at(1).toString(), values[i]);
+ const QStringList n = q.boundValueNames();
+ QCOMPARE(n.size(), 2);
+ QCOMPARE(n.at(0), ":id");
+ QCOMPARE(n.at(1), ":name");
+ QCOMPARE(q.boundValueName(0), ":id");
+ QCOMPARE(q.boundValueName(1), ":name");
}
q.bindValue(":id", 8);
@@ -2236,7 +2090,7 @@ void tst_QSqlQuery::prepare_bind_exec()
}
QVERIFY_SQL(q, exec(QLatin1String("SELECT * FROM %1 order by id").arg(qtest_prepare)));
- for (i = 0; i < 6; ++i) {
+ for (int i = 0; i < 6; ++i) {
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), i);
QCOMPARE(q.value(1).toString().trimmed(), values[i]);
@@ -2261,7 +2115,7 @@ void tst_QSqlQuery::prepare_bind_exec()
QVERIFY(q.exec(QLatin1String("select * from %1 where id > 98 order by id")
.arg(qtest_prepare)));
- for (i = 99; i <= 100; ++i) {
+ for (int i = 99; i <= 100; ++i) {
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), i);
QCOMPARE(q.value(1).toString().trimmed(), u"Bart");
@@ -2270,7 +2124,7 @@ void tst_QSqlQuery::prepare_bind_exec()
/*** SELECT stuff ***/
QVERIFY(q.prepare(QLatin1String("select * from %1 where id = :id").arg(qtest_prepare)));
- for (i = 0; i < 6; ++i) {
+ for (int i = 0; i < 6; ++i) {
q.bindValue(":id", i);
QVERIFY_SQL(q, exec());
QVERIFY_SQL(q, next());
@@ -2383,7 +2237,7 @@ void tst_QSqlQuery::prepare_bind_exec()
QFAIL_SQL(q, exec());
QVERIFY_SQL(q, exec(QLatin1String("SELECT * FROM %1 order by id").arg(qtest_prepare)));
- for (i = 0; i < 6; ++i) {
+ for (int i = 0; i < 6; ++i) {
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), i);
QCOMPARE(q.value(1).toString().trimmed(), values[i]);
@@ -2409,7 +2263,7 @@ void tst_QSqlQuery::prepare_bind_exec()
QVERIFY(q.exec(QLatin1String("select * from %1 where id > 98 order by id")
.arg(qtest_prepare)));
- for (i = 99; i <= 100; ++i) {
+ for (int i = 99; i <= 100; ++i) {
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), i);
QCOMPARE(q.value(1).toString().trimmed(), u"Bart");
@@ -2428,7 +2282,7 @@ void tst_QSqlQuery::prepare_bind_exec()
QVERIFY(q.prepare(QLatin1String(
"insert into %1 (id, name, name2) values (:id, :name, :name)")
.arg(qtest_prepare)));
- for (i = 101; i < 103; ++i) {
+ for (int i = 101; i < 103; ++i) {
q.bindValue(":id", i);
q.bindValue(":name", "name");
QVERIFY(q.exec());
@@ -2446,7 +2300,7 @@ void tst_QSqlQuery::prepare_bind_exec()
// works correctly - QTBUG-65150
QVERIFY(q.prepare(QLatin1String("insert into %1 (id, name, name2) values (:id, :id, :name)")
.arg(qtest_prepare)));
- for (i = 104; i < 106; ++i) {
+ for (int i = 104; i < 106; ++i) {
q.bindValue(":id", i);
q.bindValue(":name", "name");
QVERIFY(q.exec());
@@ -2461,7 +2315,7 @@ void tst_QSqlQuery::prepare_bind_exec()
// Test that duplicated named placeholders in any order
QVERIFY(q.prepare(QLatin1String("insert into %1 (id, name, name2) values (:id, :name, :id)")
.arg(qtest_prepare)));
- for (i = 107; i < 109; ++i) {
+ for (int i = 107; i < 109; ++i) {
q.bindValue(":id", i);
q.bindValue(":name", "name");
QVERIFY(q.exec());
@@ -2530,12 +2384,12 @@ void tst_QSqlQuery::sqlServerLongStrings()
if (tst_Databases::getDatabaseType(db) != QSqlDriver::MSSqlServer)
QSKIP("Test is specific to SQL Server");
+ TableScope ts(db, "qtest_longstr", __FILE__);
QSqlQuery q(db);
- const QString tableName = qTableName("qtest_longstr", __FILE__, db);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id int primary key, longstring ntext)")
- .arg(tableName)));
- QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 VALUES (?, ?)").arg(tableName)));
+ .arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 VALUES (?, ?)").arg(ts.tableName())));
q.addBindValue(0);
q.addBindValue(u"bubu"_s);
@@ -2546,7 +2400,7 @@ void tst_QSqlQuery::sqlServerLongStrings()
q.addBindValue(1);
q.addBindValue(testStr);
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec("select * from " + tableName));
+ QVERIFY_SQL(q, exec("select * from " + ts.tableName()));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 0);
@@ -2591,9 +2445,8 @@ void tst_QSqlQuery::batchExec()
CHECK_DATABASE(db);
QSqlQuery q(db);
- const QString tableName = qTableName("qtest_batch", __FILE__, db);
- tst_Databases::safeDropTable(db, tableName);
-
+ TableScope ts(db, "qtest_batch", __FILE__);
+ const auto &tableName = ts.tableName();
const auto dbType = tst_Databases::getDatabaseType(db);
QLatin1String timeStampString(dbType == QSqlDriver::Interbase ? "TIMESTAMP" : "TIMESTAMP (3)");
@@ -2633,7 +2486,7 @@ void tst_QSqlQuery::batchExec()
QCOMPARE(q.value(0).toInt(), intCol.at(i));
QCOMPARE(q.value(1).toString(), charCol.at(i));
QCOMPARE(q.value(2).toDate(), dateCol.at(i));
- QCOMPARE(q.value(3).toDouble(), numCol.at(i));
+ QVERIFY(qFuzzyCompare(q.value(3).toDouble(), numCol.at(i).toDouble()));
if (tst_Databases::getDatabaseType(db) == QSqlDriver::MySqlServer
&& timeStampCol.at(i).isNull()) {
QEXPECT_FAIL("", "This appears to be a bug in MySQL as it converts null datetimes to "
@@ -2665,7 +2518,7 @@ void tst_QSqlQuery::batchExec()
QCOMPARE(q.value(0).toInt(), intCol.at(i));
QCOMPARE(q.value(1).toString(), charCol.at(i));
QCOMPARE(q.value(2).toDate(), dateCol.at(i));
- QCOMPARE(q.value(3).toDouble(), numCol.at(i));
+ QVERIFY(qFuzzyCompare(q.value(3).toDouble(), numCol.at(i).toDouble()));
if (tst_Databases::getDatabaseType(db) == QSqlDriver::MySqlServer
&& timeStampCol.at(i).isNull()) {
QEXPECT_FAIL("", "This appears to be a bug in MySQL as it converts null datetimes to "
@@ -2677,8 +2530,9 @@ void tst_QSqlQuery::batchExec()
}
// Only test the prepared stored procedure approach where the driver has support
- // for batch operations as this will not work without it
- if (db.driver()->hasFeature(QSqlDriver::BatchOperations)) {
+ // for batch operations as this will not work without it.
+ // Currently Mimer SQL cannot use output parameters with procedures in batch operations.
+ if (dbType != QSqlDriver::MimerSQL && db.driver()->hasFeature(QSqlDriver::BatchOperations)) {
const QString procName = qTableName("qtest_batch_proc", __FILE__, db);
QVERIFY_SQL(q, exec(QLatin1String(
"create or replace procedure %1 (x in timestamp, y out timestamp) "
@@ -2703,19 +2557,19 @@ void tst_QSqlQuery::QTBUG_43874()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "bug43874", __FILE__);
QSqlQuery q(db);
- const QString tableName = qTableName("bug43874", __FILE__, db);
- QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INT)").arg(tableName)));
- QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 (id) VALUES (?)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INT)").arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 (id) VALUES (?)").arg(ts.tableName())));
for (int i = 0; i < 2; ++i) {
const QVariantList ids = { i };
q.addBindValue(ids);
QVERIFY_SQL(q, execBatch());
}
- QVERIFY_SQL(q, exec(QLatin1String("SELECT id FROM %1 ORDER BY id").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT id FROM %1 ORDER BY id").arg(ts.tableName())));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 0);
@@ -2810,14 +2664,14 @@ void tst_QSqlQuery::record_sqlite()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "record_sqlite");
QSqlQuery q(db);
- const QString tableName = qTableName("record_sqlite", __FILE__, db);
QVERIFY_SQL(q, exec(QLatin1String(
"create table %1(id integer primary key, name varchar, title int)")
- .arg(tableName)));
+ .arg(ts.tableName())));
- QSqlRecord rec = db.record(tableName);
+ QSqlRecord rec = db.record(ts.tableName());
QCOMPARE(rec.count(), 3);
QCOMPARE(rec.field(0).metaType().id(), QMetaType::Int);
@@ -2825,7 +2679,7 @@ void tst_QSqlQuery::record_sqlite()
QCOMPARE(rec.field(2).metaType().id(), QMetaType::Int);
// Important - select from an empty table:
- QVERIFY_SQL(q, exec("select id, name, title from " + tableName));
+ QVERIFY_SQL(q, exec("select id, name, title from " + ts.tableName()));
rec = q.record();
QCOMPARE(rec.count(), 3);
@@ -2840,20 +2694,19 @@ void tst_QSqlQuery::oraLong()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QSqlQuery q(db);
-
QString aLotOfText(127000, QLatin1Char('H'));
- const QString tableName = qTableName("qtest_longstr", __FILE__, db);
+ TableScope ts(db, "qtest_longstr", __FILE__);
+ QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int primary key, astr long)")
- .arg(tableName)));
+ .arg(ts.tableName())));
QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 (id, astr) values (?, ?)")
- .arg(tableName)));
+ .arg(ts.tableName())));
q.addBindValue(1);
q.addBindValue(aLotOfText);
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec("select id,astr from " + tableName));
+ QVERIFY_SQL(q, exec("select id,astr from " + ts.tableName()));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 1);
@@ -2866,12 +2719,11 @@ void tst_QSqlQuery::execErrorRecovery()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QSqlQuery q(db);
+ TableScope ts(db, "qtest_exerr", __FILE__);
- const QString tbl = qTableName("qtest_exerr", __FILE__, db);
- q.exec("drop table " + tbl);
- QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int not null primary key)").arg(tbl)));
- QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values (?)").arg(tbl)));
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int not null primary key)").arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values (?)").arg(ts.tableName())));
q.addBindValue(1);
QVERIFY_SQL(q, exec());
@@ -2928,13 +2780,12 @@ void tst_QSqlQuery::lastInsertId()
// PostgreSQL >= 8.1 relies on lastval() which does not work if a value is
// manually inserted to the serial field, so we create a table specifically
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) {
- const auto tst_lastInsertId = qTableName("tst_lastInsertId", __FILE__, db);
- tst_Databases::safeDropTable(db, tst_lastInsertId);
+ TableScope ts(db, "tst_lastInsertId", __FILE__);
QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id serial not null, t_varchar "
"varchar(20), t_char char(20), primary key(id))")
- .arg(tst_lastInsertId)));
+ .arg(ts.tableName())));
QVERIFY_SQL(q, exec(QLatin1String("insert into %1 (t_varchar, t_char) values "
- "('VarChar41', 'Char41')").arg(tst_lastInsertId)));
+ "('VarChar41', 'Char41')").arg(ts.tableName())));
} else {
QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (41, 'VarChar41', 'Char41')")
.arg(qtest)));
@@ -2980,18 +2831,18 @@ void tst_QSqlQuery::psql_bindWithDoubleColonCastOperator()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString tablename(qTableName("bindtest", __FILE__, db));
+ TableScope ts(db, "bindtest", __FILE__);
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String(
"create table %1 (id1 int, id2 int, id3 int, fld1 int, fld2 int)")
- .arg(tablename)));
- QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, 2, 3, 10, 5)").arg(tablename)));
+ .arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, 2, 3, 10, 5)").arg(ts.tableName())));
// Insert tableName last to let the other %-tokens' numbering match what they're replaced with:
const auto queryTemplate = QLatin1String("select sum((fld1 - fld2)::int) from %4 where "
"id1 = %1 and id2 =%2 and id3=%3");
- const QString query = queryTemplate.arg(":myid1", ":myid2", ":myid3", tablename);
+ const QString query = queryTemplate.arg(":myid1", ":myid2", ":myid3", ts.tableName());
QVERIFY_SQL(q, prepare(query));
q.bindValue(":myid1", 1);
q.bindValue(":myid2", 2);
@@ -3002,7 +2853,7 @@ void tst_QSqlQuery::psql_bindWithDoubleColonCastOperator()
// The positional placeholders are converted to named placeholders in executedQuery()
const QString expected = db.driver()->hasFeature(QSqlDriver::PreparedQueries)
- ? query : queryTemplate.arg("1", "2", "3", tablename);
+ ? query : queryTemplate.arg("1", "2", "3", ts.tableName());
QCOMPARE(q.executedQuery(), expected);
}
@@ -3018,9 +2869,9 @@ void tst_QSqlQuery::psql_specialFloatValues()
CHECK_DATABASE(db);
QSqlQuery query(db);
- const QString tableName = qTableName("floattest", __FILE__, db);
- QVERIFY_SQL(query, exec(QLatin1String("create table %1 (value float)").arg(tableName)));
- QVERIFY_SQL(query, prepare(QLatin1String("insert into %1 values(:value)").arg(tableName)));
+ TableScope ts(db, "floattest", __FILE__);
+ QVERIFY_SQL(query, exec(QLatin1String("create table %1 (value float)").arg(ts.tableName())));
+ QVERIFY_SQL(query, prepare(QLatin1String("insert into %1 values(:value)").arg(ts.tableName())));
const QVariant data[] = {
QVariant(double(42.42)),
@@ -3035,8 +2886,6 @@ void tst_QSqlQuery::psql_specialFloatValues()
query.bindValue(":value", v);
QVERIFY_SQL(query, exec());
}
-
- QVERIFY_SQL(query, exec("drop table " + tableName));
}
/* For task 157397: Using QSqlQuery with an invalid QSqlDatabase
@@ -3185,11 +3034,10 @@ void tst_QSqlQuery::sqlite_finish()
db2.setDatabaseName(db.databaseName());
QVERIFY_SQL(db2, open());
- const QString tableName(qTableName("qtest_lockedtable", __FILE__, db));
- const auto wrapup = qScopeGuard([&]() { tst_Databases::safeDropTable(db, tableName); });
+ TableScope ts(db, "qtest_lockedtable", __FILE__);
+ const auto &tableName = ts.tableName();
QSqlQuery q(db);
- tst_Databases::safeDropTable(db, tableName);
q.exec(QLatin1String("CREATE TABLE %1 (pk_id INTEGER PRIMARY KEY, whatever TEXT)")
.arg(tableName));
q.exec(QLatin1String("INSERT INTO %1 values(1, 'whatever')").arg(tableName));
@@ -3222,7 +3070,8 @@ void tst_QSqlQuery::nextResult()
QSKIP("DBMS does not support multiple result sets");
QSqlQuery q(db);
- const QString tableName(qTableName("more_results", __FILE__, db));
+ TableScope ts(db, "more_results", __FILE__);
+ const auto &tableName = ts.tableName();
QVERIFY_SQL(q, exec(QLatin1String(
"CREATE TABLE %1 (id integer, text varchar(20), "
@@ -3449,7 +3298,7 @@ void tst_QSqlQuery::blobsPreparedQuery()
QSKIP("DBMS does not support BLOBs or prepared queries");
}
- const QString tableName(qTableName("blobstest", __FILE__, db));
+ TableScope ts(db, "blobstest", __FILE__);
QSqlQuery q(db);
q.setForwardOnly(true); // This is needed to make the test work with DB2.
@@ -3463,8 +3312,8 @@ void tst_QSqlQuery::blobsPreparedQuery()
: dbType == QSqlDriver::MSSqlServer ? "IMAGE" : "BLOB");
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1(id INTEGER, data %2)")
- .arg(tableName, typeName)));
- q.prepare(QLatin1String("INSERT INTO %1(id, data) VALUES(:id, :data)").arg(tableName));
+ .arg(ts.tableName(), typeName)));
+ q.prepare(QLatin1String("INSERT INTO %1(id, data) VALUES(:id, :data)").arg(ts.tableName()));
q.bindValue(":id", 1);
q.bindValue(":data", shortBLOB);
QVERIFY_SQL(q, exec());
@@ -3474,7 +3323,7 @@ void tst_QSqlQuery::blobsPreparedQuery()
QVERIFY_SQL(q, exec());
// Two executions and result sets
- q.prepare(QLatin1String("SELECT data FROM %1 WHERE id = ?").arg(tableName));
+ q.prepare(QLatin1String("SELECT data FROM %1 WHERE id = ?").arg(ts.tableName()));
q.bindValue(0, QVariant(1));
QVERIFY_SQL(q, exec());
QVERIFY_SQL(q, next());
@@ -3486,7 +3335,7 @@ void tst_QSqlQuery::blobsPreparedQuery()
QCOMPARE(q.value(0).toString().toUtf8(), longerBLOB.toUtf8());
// Only one execution and result set
- q.prepare(QLatin1String("SELECT id, data FROM %1 ORDER BY id").arg(tableName));
+ q.prepare(QLatin1String("SELECT id, data FROM %1 ORDER BY id").arg(ts.tableName()));
QVERIFY_SQL(q, exec());
QVERIFY_SQL(q, next());
QCOMPARE(q.value(1).toString(), shortBLOB);
@@ -3502,11 +3351,11 @@ void tst_QSqlQuery::emptyTableNavigate()
CHECK_DATABASE(db);
{
+ TableScope ts(db, "qtest_empty", __FILE__);
QSqlQuery q(db);
- const QString tbl = qTableName("qtest_empty", __FILE__, db);
- q.exec("drop table " + tbl);
- QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id char(10))").arg(tbl)));
- QVERIFY_SQL(q, prepare("select * from " + tbl));
+ q.exec("drop table " + ts.tableName());
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id char(10))").arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare("select * from " + ts.tableName()));
QVERIFY_SQL(q, exec());
QVERIFY(!q.next());
QVERIFY(!q.lastError().isValid());
@@ -3518,8 +3367,7 @@ void tst_QSqlQuery::timeStampParsing()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString tableName(qTableName("timeStampParsing", __FILE__, db));
- tst_Databases::safeDropTable(db, tableName);
+ TableScope ts(db, "timeStampParsing", __FILE__);
QSqlQuery q(db);
QLatin1String creator;
switch (tst_Databases::getDatabaseType(db)) {
@@ -3535,16 +3383,30 @@ void tst_QSqlQuery::timeStampParsing()
// Since there is no auto-increment feature in Interbase we allow it to be null
creator = QLatin1String("CREATE TABLE %1(id integer, datefield timestamp);");
break;
+ case QSqlDriver::MimerSQL:
+ creator = QLatin1String("CREATE UNIQUE SEQUENCE timeStampParsing_seq");
+ QVERIFY_SQL(q, exec(creator));
+ creator = QLatin1String("CREATE TABLE %1(id integer NOT NULL default next value "
+ "for timeStampParsing_seq, "
+ "datefield timestamp, primary key(id));");
+ break;
default:
creator = QLatin1String("CREATE TABLE %1("
"\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "
"\"datefield\" timestamp);");
break;
}
- QVERIFY_SQL(q, exec(creator.arg(tableName)));
- QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (datefield) VALUES (current_timestamp);")
- .arg(tableName)));
- QVERIFY_SQL(q, exec(QLatin1String("SELECT * FROM ") + tableName));
+ QVERIFY_SQL(q, exec(creator.arg(ts.tableName())));
+ QLatin1String currentTimestamp;
+ if (tst_Databases::getDatabaseType(db) == QSqlDriver::MimerSQL)
+ currentTimestamp = QLatin1String("localtimestamp");
+ else
+ currentTimestamp = QLatin1String("current_timestamp");
+ QVERIFY_SQL(q,
+ exec(QLatin1String("INSERT INTO %1 (datefield) VALUES (%2);")
+ .arg(ts.tableName())
+ .arg(currentTimestamp)));
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT * FROM ") + ts.tableName()));
while (q.next())
QVERIFY(q.value(1).toDateTime().isValid());
}
@@ -3554,10 +3416,10 @@ void tst_QSqlQuery::task_217003()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QSqlQuery q(db);
- const QString planets = qTableName("Planet", __FILE__, db);
+ TableScope ts(db, "Planet", __FILE__);
+ const auto &planets = ts.tableName();
- q.exec("drop table " + planets);
+ QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("create table %1 (Name varchar(20))").arg(planets)));
QVERIFY_SQL(q, exec(QLatin1String("insert into %1 VALUES ('Mercury')").arg(planets)));
QVERIFY_SQL(q, exec(QLatin1String("insert into %1 VALUES ('Venus')").arg(planets)));
@@ -3583,11 +3445,10 @@ void tst_QSqlQuery::task_250026()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QSqlQuery q(db);
+ TableScope ts(db, "task_250026", __FILE__);
- const QString tableName(qTableName("task_250026", __FILE__, db));
-
- if (!q.exec(QLatin1String("create table %1 (longfield varchar(1100))").arg(tableName))) {
+ QSqlQuery q(db);
+ if (!q.exec(QLatin1String("create table %1 (longfield varchar(1100))").arg(ts.tableName()))) {
qDebug() << "Error" << q.lastError();
QSKIP("Db doesn't support \"1100\" as a size for fields");
}
@@ -3595,21 +3456,21 @@ void tst_QSqlQuery::task_250026()
const QString data258(258, QLatin1Char('A'));
const QString data1026(1026, QLatin1Char('A'));
QVERIFY_SQL(q, prepare(QLatin1String("insert into %1(longfield) VALUES (:longfield)")
- .arg(tableName)));
+ .arg(ts.tableName())));
q.bindValue(":longfield", data258);
QVERIFY_SQL(q, exec());
q.bindValue(":longfield", data1026);
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec("select * from " + tableName));
+ QVERIFY_SQL(q, exec("select * from " + ts.tableName()));
QVERIFY_SQL(q, next());
- QCOMPARE(q.value(0).toString().length(), data258.length());
+ QCOMPARE(q.value(0).toString().size(), data258.size());
QVERIFY_SQL(q, next());
- QCOMPARE(q.value(0).toString().length(), data1026.length());
+ QCOMPARE(q.value(0).toString().size(), data1026.size());
}
void tst_QSqlQuery::crashQueryOnCloseDatabase()
{
- for (const auto &dbName : qAsConst(dbs.dbNames)) {
+ for (const auto &dbName : std::as_const(dbs.dbNames)) {
const auto tidier = qScopeGuard([]() { QSqlDatabase::removeDatabase("crashTest"); });
// Note: destruction of clonedDb needs to happen before we call removeDatabase.
QSqlDatabase clonedDb = QSqlDatabase::cloneDatabase(
@@ -3621,19 +3482,19 @@ void tst_QSqlQuery::crashQueryOnCloseDatabase()
}
}
-void tst_QSqlQuery::task_233829()
+void tst_QSqlQuery::testNaN()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "testNaN", __FILE__);
QSqlQuery q(db);
- const QString tableName(qTableName("task_233829", __FILE__, db));
QVERIFY_SQL(q, exec(QLatin1String(
"CREATE TABLE %1(dbl1 double precision,dbl2 double precision) "
- "without oids;").arg(tableName)));
+ "without oids;").arg(ts.tableName())));
const QString queryString =
- QLatin1String("INSERT INTO %1(dbl1, dbl2) VALUES(?,?)").arg(tableName);
+ QLatin1String("INSERT INTO %1(dbl1, dbl2) VALUES(?,?)").arg(ts.tableName());
const double nan = qQNaN();
QVERIFY_SQL(q, prepare(queryString));
@@ -3642,13 +3503,11 @@ void tst_QSqlQuery::task_233829()
QVERIFY_SQL(q, exec());
}
-void tst_QSqlQuery::QTBUG_12477()
+void tst_QSqlQuery::psqlNumericMetadata()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- if (!db.driverName().startsWith("QPSQL"))
- QSKIP("PostgreSQL-specific test");
QSqlQuery q(db);
QVERIFY_SQL(q, exec("SELECT 1::bit, '10101010000111101101'::varbit, "
@@ -3691,11 +3550,10 @@ void tst_QSqlQuery::sqlServerReturn0()
if (tst_Databases::getDatabaseType(db) != QSqlDriver::MSSqlServer)
QSKIP("Test is specific to SQL Server");
- const QString tableName(qTableName("test141895", __FILE__, db));
- const QString procName(qTableName("test141895_proc", __FILE__, db));
+ ProcScope ps(db, "test141895_proc", __FILE__);
+ TableScope ts(db, "test141895", __FILE__);
+ const auto &tableName = ts.tableName();
QSqlQuery q(db);
- q.exec("DROP TABLE " + tableName);
- q.exec("DROP PROCEDURE " + procName);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id integer)").arg(tableName)));
QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id) VALUES (1)").arg(tableName)));
QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id) VALUES (2)").arg(tableName)));
@@ -3703,10 +3561,10 @@ void tst_QSqlQuery::sqlServerReturn0()
QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id) VALUES (3)").arg(tableName)));
QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id) VALUES (1)").arg(tableName)));
QVERIFY_SQL(q, exec(QLatin1String("CREATE PROCEDURE %1 AS "
- "SELECT * FROM %1 WHERE ID = 2 "
- "RETURN 0").arg(tableName)));
+ "SELECT * FROM %2 WHERE ID = 2 "
+ "RETURN 0").arg(ps.name(), ts.tableName())));
- QVERIFY_SQL(q, exec(QLatin1String("{CALL %1}").arg(procName)));
+ QVERIFY_SQL(q, exec(QLatin1String("{CALL %1}").arg(ps.name())));
QVERIFY_SQL(q, next());
}
@@ -3804,24 +3662,21 @@ void tst_QSqlQuery::QTBUG_18435()
if (dbType != QSqlDriver::MSSqlServer || !db.driverName().startsWith("QODBC"))
QSKIP("Test is specific to SQL Server");
+ ProcScope ps(db, "qtbug_18435_proc", __FILE__);
QSqlQuery q(db);
- QString procName(qTableName("qtbug_18435_proc", __FILE__, db));
- q.exec("DROP PROCEDURE " + procName);
const QString stmt = QLatin1String("CREATE PROCEDURE %1 @key nvarchar(50) OUTPUT AS\n"
"BEGIN\n"
" SET NOCOUNT ON\n"
" SET @key = 'TEST'\n"
- "END\n").arg(procName);
+ "END\n").arg(ps.name());
QVERIFY_SQL(q, exec(stmt));
- QVERIFY_SQL(q, prepare(QLatin1String("{CALL %1(?)}").arg(procName)));
+ QVERIFY_SQL(q, prepare(QLatin1String("{CALL %1(?)}").arg(ps.name())));
const QString testStr = "0123";
q.bindValue(0, testStr, QSql::Out);
QVERIFY_SQL(q, exec());
QCOMPARE(q.boundValue(0).toString(), QLatin1String("TEST"));
-
- QVERIFY_SQL(q, exec("DROP PROCEDURE " + procName));
}
void tst_QSqlQuery::QTBUG_5251()
@@ -3831,15 +3686,14 @@ void tst_QSqlQuery::QTBUG_5251()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString timetest(qTableName("timetest", __FILE__, db));
- tst_Databases::safeDropTable(db, timetest);
+ TableScope ts(db, "timetest", __FILE__);
QSqlQuery q(db);
- QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (t TIME)").arg(timetest)));
- QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO VALUES ('1:2:3.666')").arg(timetest)));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (t TIME)").arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 VALUES ('1:2:3.666')").arg(ts.tableName())));
QSqlTableModel timetestModel(0, db);
timetestModel.setEditStrategy(QSqlTableModel::OnManualSubmit);
- timetestModel.setTable(timetest);
+ timetestModel.setTable(ts.tableName());
QVERIFY_SQL(timetestModel, select());
QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"),
@@ -3851,7 +3705,7 @@ void tst_QSqlQuery::QTBUG_5251()
QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"),
u"00:12:34.500");
- QVERIFY_SQL(q, exec(QLatin1String("UPDATE %1 SET t = '0:11:22.33'").arg(timetest)));
+ QVERIFY_SQL(q, exec(QLatin1String("UPDATE %1 SET t = '0:11:22.33'").arg(ts.tableName())));
QVERIFY_SQL(timetestModel, select());
QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"),
u"00:11:22.330");
@@ -3862,9 +3716,10 @@ void tst_QSqlQuery::QTBUG_6421()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ const QString tableName(qTableName("bug6421", __FILE__, db).toUpper());
+ TableScope ts(db, tableName);
QSqlQuery q(db);
- const QString tableName(qTableName("bug6421", __FILE__, db).toUpper());
QVERIFY_SQL(q, exec(QLatin1String(
"create table %1(COL1 char(10), COL2 char(10), COL3 char(10))")
@@ -3892,9 +3747,8 @@ void tst_QSqlQuery::QTBUG_6618()
if (tst_Databases::getDatabaseType(db) != QSqlDriver::MSSqlServer)
QSKIP("Test is specific to SQL Server");
+ ProcScope ps(db, "tst_raiseError", __FILE__);
QSqlQuery q(db);
- const QString procedureName = qTableName("tst_raiseError", __FILE__, db);
- q.exec("drop procedure " + procedureName); // non-fatal
QString errorString;
for (int i = 0; i < 110; ++i)
errorString += "reallylong";
@@ -3902,8 +3756,8 @@ void tst_QSqlQuery::QTBUG_6618()
QVERIFY_SQL(q, exec(QLatin1String("create procedure %1 as\n"
"begin\n"
" raiserror('%2', 16, 1)\n"
- "end\n").arg(procedureName, errorString)));
- q.exec(QLatin1String("{call %1}").arg(procedureName));
+ "end\n").arg(ps.name(), errorString)));
+ q.exec(QLatin1String("{call %1}").arg(ps.name()));
QVERIFY(q.lastError().text().contains(errorString));
}
@@ -3912,11 +3766,11 @@ void tst_QSqlQuery::QTBUG_6852()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QSqlQuery q(db);
- const QString tableName(qTableName("bug6852", __FILE__, db));
- const QString procName(qTableName("bug6852_proc", __FILE__, db));
+ TableScope ts(db, "bug6852", __FILE__);
+ const auto &tableName = ts.tableName();
+ ProcScope ps(db, "bug6852_proc", __FILE__);
- QVERIFY_SQL(q, exec("DROP PROCEDURE IF EXISTS " + procName));
+ QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1(\n"
"MainKey INT NOT NULL,\n"
"OtherTextCol VARCHAR(45) NOT NULL,\n"
@@ -3931,9 +3785,9 @@ void tst_QSqlQuery::QTBUG_6852()
" SET @st = 'SELECT MainKey, OtherTextCol from %2';\n"
" PREPARE stmt from @st;\n"
" EXECUTE stmt;\n"
- "END;").arg(procName, tableName)));
+ "END;").arg(ps.name(), tableName)));
- QVERIFY_SQL(q, exec(QLatin1String("CALL %1()").arg(procName)));
+ QVERIFY_SQL(q, exec(QLatin1String("CALL %1()").arg(ps.name())));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 0);
QCOMPARE(q.value(1).toString(), QLatin1String("Disabled"));
@@ -3944,19 +3798,19 @@ void tst_QSqlQuery::QTBUG_5765()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QSqlQuery q(db);
- const QString tableName(qTableName("bug5765", __FILE__, db));
+ TableScope ts(db, "bug5765", __FILE__);
+ QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1(testval TINYINT(1) DEFAULT 0)")
- .arg(tableName)));
- q.prepare(QLatin1String("INSERT INTO %1 SET testval = :VALUE").arg(tableName));
+ .arg(ts.tableName())));
+ q.prepare(QLatin1String("INSERT INTO %1 SET testval = :VALUE").arg(ts.tableName()));
q.bindValue(":VALUE", 1);
QVERIFY_SQL(q, exec());
q.bindValue(":VALUE", 12);
QVERIFY_SQL(q, exec());
q.bindValue(":VALUE", 123);
QVERIFY_SQL(q, exec());
- QString sql = "select testval from " + tableName;
+ QString sql = "select testval from " + ts.tableName();
QVERIFY_SQL(q, exec(sql));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 1);
@@ -3983,9 +3837,10 @@ void tst_QSqlQuery::QTBUG_21884()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "bug21884", __FILE__);
+ const auto &tableName = ts.tableName();
QSqlQuery q(db);
- QString tableName(qTableName("bug21884", __FILE__, db));
{
const QString good[] = {
@@ -4025,8 +3880,6 @@ void tst_QSqlQuery::QTBUG_21884()
*/
void tst_QSqlQuery::QTBUG_16967()
{
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
QSqlQuery q2;
QFETCH(QString, dbName);
{
@@ -4039,7 +3892,7 @@ QT_WARNING_DISABLE_DEPRECATED
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlQuery q(db);
- q2 = q;
+ q2 = QSqlQuery(q.lastQuery(), db);
q.prepare("CREATE TABLE t1 (id INTEGER PRIMARY KEY, str TEXT);");
db.close();
QCOMPARE(db.lastError().type(), QSqlError::NoError);
@@ -4048,7 +3901,7 @@ QT_WARNING_DISABLE_DEPRECATED
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlQuery q(db);
- q2 = q;
+ q2 = QSqlQuery(q.lastQuery(), db);
q2.prepare("CREATE TABLE t1 (id INTEGER PRIMARY KEY, str TEXT);");
q2.exec();
db.close();
@@ -4058,7 +3911,7 @@ QT_WARNING_DISABLE_DEPRECATED
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlQuery q(db);
- q2 = q;
+ q2 = QSqlQuery(q.lastQuery(), db);
q.exec("INSERT INTO t1 (id, str) VALUES(1, \"test1\");");
db.close();
QCOMPARE(db.lastError().type(), QSqlError::NoError);
@@ -4067,12 +3920,11 @@ QT_WARNING_DISABLE_DEPRECATED
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlQuery q(db);
- q2 = q;
+ q2 = QSqlQuery(q.lastQuery(), db);
q.exec("SELECT * FROM t1;");
db.close();
QCOMPARE(db.lastError().type(), QSqlError::NoError);
}
-QT_WARNING_POP
}
/* In SQLite, when a boolean value is bound to a placeholder, it should be
@@ -4085,10 +3937,11 @@ void tst_QSqlQuery::QTBUG_23895()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "bug23895", __FILE__);
+ const auto &tableName = ts.tableName();
QSqlQuery q(db);
- QString tableName(qTableName("bug23895", __FILE__, db));
q.prepare(QLatin1String("create table %1(id integer primary key, val1 bool, val2 boolean)")
.arg(tableName));
QVERIFY_SQL(q, exec());
@@ -4139,19 +3992,16 @@ void tst_QSqlQuery::QTBUG_14904()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "bug14904", __FILE__);
QSqlQuery q(db);
-
- QString tableName(qTableName("bug14904", __FILE__, db));
- tst_Databases::safeDropTable(db, tableName);
-
- q.prepare(QLatin1String("create table %1(val1 bool)").arg(tableName));
+ q.prepare(QLatin1String("create table %1(val1 bool)").arg(ts.tableName()));
QVERIFY_SQL(q, exec());
- q.prepare(QLatin1String("insert into %1(val1) values(?);").arg(tableName));
+ q.prepare(QLatin1String("insert into %1(val1) values(?);").arg(ts.tableName()));
q.addBindValue(true);
QVERIFY_SQL(q, exec());
- QString sql = "select val1 AS value1 from " + tableName;
+ QString sql = "select val1 AS value1 from " + ts.tableName();
QVERIFY_SQL(q, exec(sql));
QVERIFY_SQL(q, next());
@@ -4159,7 +4009,7 @@ void tst_QSqlQuery::QTBUG_14904()
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::Bool);
QVERIFY(q.value(0).toBool());
- sql = "select val1 AS 'value.one' from " + tableName;
+ sql = "select val1 AS 'value.one' from " + ts.tableName();
QVERIFY_SQL(q, exec(sql));
QVERIFY_SQL(q, next());
QCOMPARE(q.record().indexOf("value.one"), 0); // Was -1 before bug fix.
@@ -4173,19 +4023,17 @@ void tst_QSqlQuery::QTBUG_2192()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
{
- const QString tableName(qTableName("bug2192", __FILE__, db));
- tst_Databases::safeDropTable(db, tableName);
-
+ TableScope ts(db, "bug2192", __FILE__);
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (dt %2)")
- .arg(tableName, tst_Databases::dateTimeTypeName(db))));
+ .arg(ts.tableName(), tst_Databases::dateTimeTypeName(db))));
QDateTime dt = QDateTime(QDate(2012, 7, 4), QTime(23, 59, 59, 999));
- QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 (dt) VALUES (?)").arg(tableName)));
+ QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 (dt) VALUES (?)").arg(ts.tableName())));
q.bindValue(0, dt);
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec("SELECT dt FROM " + tableName));
+ QVERIFY_SQL(q, exec("SELECT dt FROM " + ts.tableName()));
QVERIFY_SQL(q, next());
// Check if retrieved value preserves reported precision
@@ -4202,12 +4050,10 @@ void tst_QSqlQuery::QTBUG_36211()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) {
- const QString tableName(qTableName("bug36211", __FILE__, db));
- tst_Databases::safeDropTable(db, tableName);
-
+ TableScope ts(db, "bug36211", __FILE__);
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (dtwtz timestamptz, dtwotz timestamp)")
- .arg(tableName)));
+ .arg(ts.tableName())));
#if QT_CONFIG(timezone)
QTimeZone l_tzBrazil("America/Sao_Paulo");
@@ -4216,7 +4062,7 @@ void tst_QSqlQuery::QTBUG_36211()
QVERIFY(l_tzChina.isValid());
QDateTime dt = QDateTime(QDate(2014, 10, 30), QTime(14, 12, 02, 357));
QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 (dtwtz, dtwotz) VALUES (:dt, :dt)")
- .arg(tableName)));
+ .arg(ts.tableName())));
q.bindValue(":dt", dt);
QVERIFY_SQL(q, exec());
q.bindValue(":dt", dt.toTimeZone(l_tzBrazil));
@@ -4224,7 +4070,7 @@ void tst_QSqlQuery::QTBUG_36211()
q.bindValue(":dt", dt.toTimeZone(l_tzChina));
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec("SELECT dtwtz, dtwotz FROM " + tableName));
+ QVERIFY_SQL(q, exec("SELECT dtwtz, dtwotz FROM " + ts.tableName()));
for (int i = 0; i < 3; ++i) {
QVERIFY_SQL(q, next());
@@ -4250,23 +4096,21 @@ void tst_QSqlQuery::QTBUG_53969()
CHECK_DATABASE(db);
tableValues.reserve(values.size());
if (tst_Databases::getDatabaseType(db) == QSqlDriver::MySqlServer) {
- const QString tableName(qTableName("bug53969", __FILE__, db));
- tst_Databases::safeDropTable(db, tableName);
-
+ TableScope ts(db, "bug53969", __FILE__);
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INT AUTO_INCREMENT PRIMARY KEY, "
"test_number TINYINT(3) UNSIGNED)")
- .arg(tableName)));
+ .arg(ts.tableName())));
QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 (test_number) VALUES (:value)")
- .arg(tableName)));
+ .arg(ts.tableName())));
for (int value : values) {
q.bindValue(":value", value);
QVERIFY_SQL(q, exec());
}
- QVERIFY_SQL(q, prepare("SELECT test_number FROM " + tableName));
+ QVERIFY_SQL(q, prepare("SELECT test_number FROM " + ts.tableName()));
QVERIFY_SQL(q, exec());
while (q.next()) {
@@ -4283,17 +4127,16 @@ void tst_QSqlQuery::gisPointDatatype()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "qtbug72140", __FILE__);
QSqlQuery sqlQuery(db);
- const auto tableName = qTableName("qtbug72140", __FILE__, db);
- tst_Databases::safeDropTable(db, tableName);
QVERIFY(sqlQuery.exec(QLatin1String(
"CREATE TABLE %1 (`lonlat_point` POINT NULL) ENGINE = InnoDB;")
- .arg(tableName)));
+ .arg(ts.tableName())));
QVERIFY(sqlQuery.exec(QLatin1String(
"INSERT INTO %1(lonlat_point) VALUES(ST_GeomFromText('POINT(1 1)'));")
- .arg(tableName)));
- QVERIFY(sqlQuery.exec(QLatin1String("SELECT * FROM %1;").arg(tableName)));
+ .arg(ts.tableName())));
+ QVERIFY(sqlQuery.exec(QLatin1String("SELECT * FROM %1;").arg(ts.tableName())));
QCOMPARE(sqlQuery.record().field(0).metaType().id(), QMetaType::QByteArray);
QVERIFY(sqlQuery.next());
}
@@ -4303,13 +4146,13 @@ void tst_QSqlQuery::oraOCINumber()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString qtest_oraOCINumber(qTableName("qtest_oraOCINumber", __FILE__, db));
+ TableScope ts(db, "qtest_oraOCINumber", __FILE__);
QSqlQuery q(db);
q.setForwardOnly(true);
QVERIFY_SQL(q, exec(QLatin1String("create table %1 (col1 number(20), col2 number(20))")
- .arg(qtest_oraOCINumber)));
- QVERIFY(q.prepare(QLatin1String("insert into %1 values (?, ?)").arg(qtest_oraOCINumber)));
+ .arg(ts.tableName())));
+ QVERIFY(q.prepare(QLatin1String("insert into %1 values (?, ?)").arg(ts.tableName())));
const QVariantList col1Values = {
qulonglong(1), qulonglong(0), qulonglong(INT_MAX), qulonglong(UINT_MAX),
@@ -4326,7 +4169,7 @@ void tst_QSqlQuery::oraOCINumber()
QVERIFY(q.execBatch());
QVERIFY(q.prepare(QLatin1String(
"select * from %1 where col1 = :bindValue0 AND col2 = :bindValue1")
- .arg(qtest_oraOCINumber)));
+ .arg(ts.tableName())));
q.bindValue(":bindValue0", qulonglong(1), QSql::InOut);
q.bindValue(":bindValue1", qlonglong(1), QSql::InOut);
@@ -4398,8 +4241,6 @@ void tst_QSqlQuery::sqlite_constraint()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- if (tst_Databases::getDatabaseType(db) != QSqlDriver::SQLite)
- QSKIP("SQLite3-specific test");
QSqlQuery q(db);
const QString trigger(qTableName("test_constraint", __FILE__, db));
@@ -4419,30 +4260,64 @@ void tst_QSqlQuery::sqlite_real()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString tableName(qTableName("sqliterealtype", __FILE__, db));
- tst_Databases::safeDropTable(db, tableName);
+ TableScope ts(db, "sqliterealtype", __FILE__);
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INTEGER, realVal REAL)")
- .arg(tableName)));
+ .arg(ts.tableName())));
QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id, realVal) VALUES (1, 2.3)")
- .arg(tableName)));
- QVERIFY_SQL(q, exec("SELECT realVal FROM " + tableName));
+ .arg(ts.tableName())));
+ QVERIFY_SQL(q, exec("SELECT realVal FROM " + ts.tableName()));
QVERIFY(q.next());
QCOMPARE(q.value(0).toDouble(), 2.3);
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::Double);
- q.prepare(QLatin1String("INSERT INTO %1 (id, realVal) VALUES (?, ?)").arg(tableName));
+ q.prepare(QLatin1String("INSERT INTO %1 (id, realVal) VALUES (?, ?)").arg(ts.tableName()));
QVariant var((double)5.6);
q.addBindValue(4);
q.addBindValue(var);
QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec(QLatin1String("SELECT realVal FROM %1 WHERE ID=4").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT realVal FROM %1 WHERE ID=4").arg(ts.tableName())));
QVERIFY(q.next());
QCOMPARE(q.value(0).toDouble(), 5.6);
}
+void tst_QSqlQuery::prepared_query_json_row()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ if (tst_Databases::getDatabaseType(db) != QSqlDriver::MySqlServer &&
+ tst_Databases::getDatabaseType(db) != QSqlDriver::PostgreSQL) {
+ QSKIP("PostgreSQL / MySQL specific test");
+ }
+
+ TableScope ts(db, "tableWithJsonRow", __FILE__);
+ QSqlQuery q(db);
+ const QLatin1String vals[] = {QLatin1String("{\"certificateNumber\": \"CERT-001\"}"),
+ QLatin1String("{\"certificateNumber\": \"CERT-002\"}")};
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INTEGER, value JSON)").arg(ts.tableName())));
+ for (const QLatin1String &json : vals) {
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id, value) VALUES (1, '%2')")
+ .arg(ts.tableName(), json)));
+ }
+
+ QVERIFY_SQL(q, prepare(QLatin1String("SELECT id, value FROM %1 WHERE id = ?").arg(ts.tableName())));
+ q.addBindValue(1);
+ QVERIFY_SQL(q, exec());
+
+ size_t iCount = 0;
+ while (q.next()) {
+ QVERIFY(iCount < sizeof(vals));
+ const int id = q.value(0).toInt();
+ const QByteArray json = q.value(1).toByteArray();
+ QCOMPARE(id, 1);
+ QCOMPARE(json, vals[iCount].data());
+ ++iCount;
+ }
+}
+
void tst_QSqlQuery::aggregateFunctionTypes()
{
QFETCH(QString, dbName);
@@ -4453,7 +4328,8 @@ void tst_QSqlQuery::aggregateFunctionTypes()
int countType = intType;
// QPSQL uses LongLong for manipulation of integers
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::Interbase) {
+ if (dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::Interbase
+ || dbType == QSqlDriver::MimerSQL) {
sumType = countType = QMetaType::LongLong;
} else if (dbType == QSqlDriver::Oracle) {
intType = sumType = countType = QMetaType::Double;
@@ -4462,8 +4338,8 @@ void tst_QSqlQuery::aggregateFunctionTypes()
countType = QMetaType::LongLong;
}
{
- const QString tableName(qTableName("numericFunctionsWithIntValues", __FILE__, db));
- tst_Databases::safeDropTable(db, tableName);
+ TableScope ts(db, "numericFunctionsWithIntValues", __FILE__);
+ const auto &tableName = ts.tableName();
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INTEGER)").arg(tableName)));
@@ -4512,8 +4388,8 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QCOMPARE(q.record().field(0).metaType().id(), intType);
}
{
- const QString tableName(qTableName("numericFunctionsWithDoubleValues", __FILE__, db));
- tst_Databases::safeDropTable(db, tableName);
+ TableScope ts(db, "numericFunctionsWithDoubleValues", __FILE__);
+ const auto &tableName = ts.tableName();
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id REAL)").arg(tableName)));
@@ -4576,15 +4452,15 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::Double);
}
{
- const QString tableName(qTableName("stringFunctions", __FILE__, db));
- tst_Databases::safeDropTable(db, tableName);
+ TableScope ts(db, "stringFunctions", __FILE__);
+ const auto &tableName = ts.tableName();
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INTEGER, txt VARCHAR(50))")
.arg(tableName)));
QVERIFY_SQL(q, exec("SELECT MAX(txt) FROM " + tableName));
- QVERIFY(q.next());
+ QVERIFY_SQL(q, next());
if (dbType == QSqlDriver::SQLite)
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::UnknownType);
else
@@ -4599,6 +4475,19 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY(q.next());
QCOMPARE(q.value(0).toString(), QLatin1String("upper"));
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::QString);
+
+ QVERIFY_SQL(q, exec(QLatin1String("DELETE FROM %1").arg(tableName)));
+ QVERIFY_SQL(q, exec(QString::fromUtf8("INSERT INTO %1 (id, txt) VALUES (1, 'löW€RÄ')")
+ .arg(tableName)));
+ QVERIFY_SQL(q, exec("SELECT LOWER(txt) FROM " + tableName));
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toString(), QString::fromUtf8("löw€rä"));
+ QCOMPARE(q.record().field(0).metaType().id(), QMetaType::QString);
+
+ QVERIFY_SQL(q, exec("SELECT UPPER(txt) FROM " + tableName));
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toString(), QString::fromUtf8("LÖW€RÄ"));
+ QCOMPARE(q.record().field(0).metaType().id(), QMetaType::QString);
}
}
@@ -4608,9 +4497,9 @@ void runIntegralTypesMysqlTest(QSqlDatabase &db, const QString &tableName, const
{
QList<QVariant> variantValues;
variantValues.reserve(values.size());
+ TableScope ts(db, tableName);
QSqlQuery q(db);
- QVERIFY_SQL(q, exec("DROP TABLE IF EXISTS " + tableName));
QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %2 (id %1)").arg(type, tableName)));
if (withPreparedStatement) {
@@ -4696,29 +4585,35 @@ void tst_QSqlQuery::integralTypesMysql()
runIntegralTypesMysqlTest<qint64>(db, "bigIntTest", "BIGINT", withPreparedStatement);
runIntegralTypesMysqlTest<quint64>(db, "unsignedBigIntTest", "BIGINT UNSIGNED",
withPreparedStatement);
+ runIntegralTypesMysqlTest<quint64>(db, "bitmask_7", "BIT(7)", withPreparedStatement, 0,
+ (1LL << 7) - 1);
+ runIntegralTypesMysqlTest<quint64>(db, "bitmask_31", "BIT(31)", withPreparedStatement, 0,
+ (1LL << 31) - 1);
+ runIntegralTypesMysqlTest<quint64>(db, "bitmask_33", "BIT(33)", withPreparedStatement, 0,
+ (1LL << 33) - 1);
+ runIntegralTypesMysqlTest<quint64>(db, "bitmask_64", "BIT(64)", withPreparedStatement);
}
}
void tst_QSqlQuery::QTBUG_57138()
{
- const QDateTime utc = QDateTime(QDate(2150, 1, 5), QTime(14, 0, 0, 123), Qt::UTC);
- const QDateTime localtime = QDateTime(QDate(2150, 1, 5), QTime(14, 0, 0, 123), Qt::LocalTime);
- const QDateTime tzoffset = QDateTime(QDate(2150, 1, 5), QTime(14, 0, 0, 123),
- Qt::OffsetFromUTC, 3600);
+ const QDateTime utc(QDate(2150, 1, 5), QTime(14, 0, 0, 123), QTimeZone::UTC);
+ const QDateTime localtime(QDate(2150, 1, 5), QTime(14, 0, 0, 123));
+ const QDateTime tzoffset(QDate(2150, 1, 5), QTime(14, 0, 0, 123),
+ QTimeZone::fromSecondsAheadOfUtc(3600));
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "qtbug57138", __FILE__);
QSqlQuery create(db);
- QString tableName = qTableName("qtbug57138", __FILE__, db);
- tst_Databases::safeDropTable(db, tableName);
QVERIFY_SQL(create, exec(QLatin1String(
"create table %1 (id int, dt_utc datetime, dt_lt datetime, "
- "dt_tzoffset datetime)").arg(tableName)));
+ "dt_tzoffset datetime)").arg(ts.tableName())));
QVERIFY_SQL(create, prepare(QLatin1String("insert into %1 (id, dt_utc, dt_lt, dt_tzoffset) "
- "values (?, ?, ?, ?)").arg(tableName)));
+ "values (?, ?, ?, ?)").arg(ts.tableName())));
create.addBindValue(0);
create.addBindValue(utc);
@@ -4728,7 +4623,7 @@ void tst_QSqlQuery::QTBUG_57138()
QSqlQuery q(db);
q.prepare(QLatin1String("SELECT dt_utc, dt_lt, dt_tzoffset FROM %1 WHERE id = ?")
- .arg(tableName));
+ .arg(ts.tableName()));
q.addBindValue(0);
QVERIFY_SQL(q, exec());
@@ -4744,17 +4639,15 @@ void tst_QSqlQuery::QTBUG_73286()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ TableScope ts(db, "qtbug73286", __FILE__);
QSqlQuery create(db);
- QString tableName = qTableName("qtbug73286", __FILE__, db);
- tst_Databases::safeDropTable(db, tableName);
-
QVERIFY_SQL(create, exec(QLatin1String(
"create table %1 (dec2 decimal(4,2), dec0 decimal(20,0), "
- "dec3 decimal(20,3))").arg(tableName)));
+ "dec3 decimal(20,3))").arg(ts.tableName())));
QVERIFY_SQL(create, prepare(QLatin1String(
"insert into %1 (dec2, dec0, dec3) values (?, ?, ?)")
- .arg(tableName)));
+ .arg(ts.tableName())));
create.addBindValue("99.99");
create.addBindValue("12345678901234567890");
@@ -4763,7 +4656,7 @@ void tst_QSqlQuery::QTBUG_73286()
QVERIFY_SQL(create, exec());
QSqlQuery q(db);
- q.prepare("SELECT dec2, dec0, dec3 FROM " + tableName);
+ q.prepare("SELECT dec2, dec0, dec3 FROM " + ts.tableName());
q.setNumericalPrecisionPolicy(QSql::HighPrecision);
QVERIFY_SQL(q, exec());
@@ -4774,6 +4667,22 @@ void tst_QSqlQuery::QTBUG_73286()
QCOMPARE(q.value(2).toString(), "12345678901234567.890");
}
+void tst_QSqlQuery::insertVarChar1()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlQuery q(db);
+ TableScope ts(db, "testtable", __FILE__);
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (smallcol VARCHAR(1))").arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 (smallcol) VALUES (?)").arg(ts.tableName())));
+ QSqlField smallCol("smallcol");
+ smallCol.setValue(QVariant(QString(QChar('F'))));
+ q.bindValue(0, smallCol.value());
+ QVERIFY_SQL(q, exec());
+}
+
void tst_QSqlQuery::dateTime_data()
{
if (dbs.dbNames.isEmpty())
@@ -4825,13 +4734,11 @@ void tst_QSqlQuery::dateTime_data()
#endif
};
- for (const QString &dbName : qAsConst(dbs.dbNames)) {
+ for (const QString &dbName : std::as_const(dbs.dbNames)) {
QSqlDatabase db = QSqlDatabase::database(dbName);
if (!db.isValid())
continue;
const QString tableNameTSWithTimeZone(qTableName("dateTimeTSWithTimeZone", __FILE__, db));
- const QString tableNameTSWithLocalTimeZone(qTableName("dateTimeTSWithLocalTimeZone",
- __FILE__, db));
const QString tableNameTS(qTableName("dateTimeTS", __FILE__, db));
const QString tableNameDate(qTableName("dateTimeDate", __FILE__, db));
QTest::newRow(QString(dbName + " timestamp with time zone").toLatin1())
@@ -4864,17 +4771,93 @@ void tst_QSqlQuery::dateTime()
QFETCH(QList<QDateTime>, initialDateTimes);
QFETCH(QList<QDateTime>, expectedDateTimes);
- tst_Databases::safeDropTable(db, tableName);
+ TableScope ts(db, tableName);
QSqlQuery q(db);
QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + createTableString));
- for (const QDateTime &dt : qAsConst(initialDateTimes)) {
+ for (const QDateTime &dt : std::as_const(initialDateTimes)) {
QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 values(:dt)").arg(tableName)));
q.bindValue(":dt", dt);
QVERIFY_SQL(q, exec());
}
QVERIFY_SQL(q, exec("SELECT * FROM " + tableName));
- for (const QDateTime &dt : qAsConst(expectedDateTimes)) {
+ for (const QDateTime &dt : std::as_const(expectedDateTimes)) {
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toDateTime(), dt);
+ }
+}
+
+void tst_QSqlQuery::ibaseDateTimeWithTZ_data()
+{
+ if (dbs.dbNames.isEmpty())
+ QSKIP("No database drivers are available in this Qt configuration");
+
+ QTest::addColumn<QString>("dbName");
+ QTest::addColumn<QString>("tableName");
+ QTest::addColumn<QList<QDateTime> >("initialDateTimes");
+ QTest::addColumn<QList<QDateTime> >("expectedDateTimes");
+
+#if QT_CONFIG(timezone)
+ const QTimeZone afterUTCTimeZone("Asia/Hong_Kong");
+ const QTimeZone beforeUTCTimeZone("America/Los_Angeles");
+ const QDateTime dtWithAfterTZ(QDate(2015, 5, 18), QTime(4, 26, 30, 500), afterUTCTimeZone);
+ const QDateTime dtWithBeforeTZ(QDate(2015, 5, 18), QTime(4, 26, 30, 500), beforeUTCTimeZone);
+ const QTimeZone utcTimeZone("UTC");
+ const QDateTime dtWithUTCTZ(QDate(2015, 5, 18), QTime(4, 26, 30, 500), utcTimeZone);
+#endif // QT_CONFIG(timezone)
+ const QDateTime dtLocalTZ(QDateTime::currentDateTime());
+
+ const QList<QDateTime> dateTimes = {
+#if QT_CONFIG(timezone)
+ dtWithAfterTZ,
+ dtWithBeforeTZ,
+ dtWithUTCTZ,
+#endif // QT_CONFIG(timezone)
+ dtLocalTZ
+ };
+
+ for (const QString &dbName : std::as_const(dbs.dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ if (!db.isValid())
+ continue;
+
+ const QString tableNameTSWithTimeZone(qTableName("dateTimeTSWithTZ", __FILE__, db));
+
+ QTest::newRow(QString(dbName + " timestamp with time zone").toLatin1())
+ << dbName
+ << tableNameTSWithTimeZone
+ << dateTimes
+ << dateTimes;
+ }
+}
+
+void tst_QSqlQuery::ibaseDateTimeWithTZ()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ if (tst_Databases::getDatabaseType(db) != QSqlDriver::Interbase)
+ QSKIP("Implemented only for Interbase");
+
+ if (tst_Databases::getIbaseEngineVersion(db).majorVersion() < 4)
+ QSKIP("Time zone support only implemented for firebird engine version 4 and greater");
+
+ QFETCH(QString, tableName);
+ TableScope ts(db, tableName);
+
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE " + tableName + "(dt timestamp with time zone)")));
+
+ QFETCH(QList<QDateTime>, initialDateTimes);
+ QFETCH(QList<QDateTime>, expectedDateTimes);
+
+ for (const QDateTime &dt : std::as_const(initialDateTimes)) {
+ QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 values(:dt)").arg(tableName)));
+ q.bindValue(":dt", dt);
+ QVERIFY_SQL(q, exec());
+ }
+ QVERIFY_SQL(q, exec("SELECT * FROM " + tableName));
+ for (const QDateTime &dt : std::as_const(expectedDateTimes)) {
QVERIFY(q.next());
QCOMPARE(q.value(0).toDateTime(), dt);
}
@@ -4930,8 +4913,8 @@ void tst_QSqlQuery::mysql_timeType()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const auto tableName = qTableName("mysqlTimeType", __FILE__, db);
- tst_Databases::safeDropTables(db, { tableName });
+ TableScope ts(db, "mysqlTimeType", __FILE__);
+ const auto &tableName = ts.tableName();
QSqlQuery qry(db);
QVERIFY_SQL(qry, exec(QLatin1String("create table %1 (t time(6))").arg(tableName)));
@@ -4992,14 +4975,13 @@ void tst_QSqlQuery::ibaseArray()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const auto arrayTable = qTableName("ibasearray", __FILE__, db);
- tst_Databases::safeDropTable(db, arrayTable);
+ TableScope ts(db, "ibasearray", __FILE__);
QSqlQuery qry(db);
QVERIFY_SQL(qry, exec(QLatin1String(
"create table %1 (intData int[0:4], longData bigint[5], "
- "charData varchar(255)[5], boolData boolean[2])").arg(arrayTable)));
+ "charData varchar(255)[5], boolData boolean[2])").arg(ts.tableName())));
QVERIFY_SQL(qry, prepare(QLatin1String("insert into %1 (intData, longData, charData, boolData)"
- " values(?, ?, ?, ?)").arg(arrayTable)));
+ " values(?, ?, ?, ?)").arg(ts.tableName())));
const auto intArray = QVariant{QVariantList{1, 2, 3, 4711, 815}};
const auto charArray = QVariant{QVariantList{"AAA", "BBB", "CCC", "DDD", "EEE"}};
const auto boolArray = QVariant{QVariantList{true, false}};
@@ -5008,7 +4990,7 @@ void tst_QSqlQuery::ibaseArray()
qry.bindValue(2, charArray);
qry.bindValue(3, boolArray);
QVERIFY_SQL(qry, exec());
- QVERIFY_SQL(qry, exec("select * from " + arrayTable));
+ QVERIFY_SQL(qry, exec("select * from " + ts.tableName()));
QVERIFY(qry.next());
QCOMPARE(qry.value(0).toList(), intArray.toList());
QCOMPARE(qry.value(1).toList(), intArray.toList());
@@ -5016,6 +4998,42 @@ void tst_QSqlQuery::ibaseArray()
QCOMPARE(qry.value(3).toList(), boolArray.toList());
}
+void tst_QSqlQuery::ibaseTimeStampTzArray()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ if (tst_Databases::getIbaseEngineVersion(db).majorVersion() < 4)
+ QSKIP("Time zone support only implemented for firebird engine version 4 and greater");
+
+ TableScope ts(db, "ibasetstzarray", __FILE__);
+ QSqlQuery qry(db);
+ QVERIFY_SQL(qry, exec(QLatin1String(
+ "create table %1 (timeStampData timestamp with time zone[0:4])").arg(ts.tableName())));
+ QVERIFY_SQL(qry, prepare(QLatin1String("insert into %1 (timeStampData)"
+ " values(?)").arg(ts.tableName())));
+#if QT_CONFIG(timezone)
+ const QDateTime dtWithAfterTZ(QDate(2015, 5, 18), QTime(4, 26, 30, 500), QTimeZone("Asia/Hong_Kong"));
+ const QDateTime dtWithBeforeTZ(QDate(2015, 5, 18), QTime(4, 26, 30, 500), QTimeZone("America/Los_Angeles"));
+ const QDateTime dtWithUTCTZ(QDate(2015, 5, 18), QTime(4, 26, 30, 500), QTimeZone("UTC"));
+ const QDateTime dtLocalTZ(QDateTime::currentDateTime());
+ const QDateTime dtWithMETTZ(QDate(2015, 5, 18), QTime(4, 26, 30, 500), QTimeZone("MET"));
+
+
+ const auto timeStampData = QVariant{QVariantList{dtWithAfterTZ,
+ dtWithBeforeTZ,
+ dtWithUTCTZ,
+ dtLocalTZ,
+ dtWithMETTZ}};
+ qry.bindValue(0, timeStampData);
+ QVERIFY_SQL(qry, exec());
+ QVERIFY_SQL(qry, exec("select * from " + ts.tableName()));
+ QVERIFY(qry.next());
+ QCOMPARE(qry.value(0).toList(), timeStampData.toList());
+#endif // QT_CONFIG(timezone)
+}
+
void tst_QSqlQuery::ibase_executeBlock()
{
QFETCH(QString, dbName);
@@ -5036,5 +5054,83 @@ void tst_QSqlQuery::ibase_executeBlock()
QCOMPARE(qry.value(0).toInt(), 4);
}
+void tst_QSqlQuery::positionalBindingEnabled()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "positionalBinding", __FILE__);
+ const QString &tableName = ts.tableName();
+
+ QSqlQuery qry(db);
+ QVERIFY_SQL(qry, exec("CREATE TABLE " + tableName + " (integer_col integer)"));
+ QVERIFY_SQL(qry, exec("INSERT INTO " + tableName + "(integer_col) VALUES(42)"));
+
+ qry.setPositionalBindingEnabled(true);
+ QCOMPARE(qry.isPositionalBindingEnabled(), true);
+ QVERIFY_SQL(qry, prepare("SELECT integer_col FROM " + tableName + " WHERE integer_col = :integer_val"));
+ qry.bindValue(":integer_val", 42);
+ QVERIFY_SQL(qry, exec());
+ QVERIFY_SQL(qry, next());
+ QCOMPARE(qry.value(0).toInt(), 42);
+ QVERIFY_SQL(qry, prepare("SELECT integer_col FROM " + tableName + " WHERE integer_col = ?"));
+ qry.bindValue(0, 42);
+ QVERIFY_SQL(qry, exec());
+ QVERIFY_SQL(qry, next());
+ QCOMPARE(qry.value(0).toInt(), 42);
+
+ qry.setPositionalBindingEnabled(false);
+ QCOMPARE(qry.isPositionalBindingEnabled(), false);
+ QVERIFY_SQL(qry, prepare("SELECT integer_col FROM " + tableName + " WHERE integer_col = :integer_val"));
+ qry.bindValue(":integer_val", 42);
+ QVERIFY_SQL(qry, exec());
+ QVERIFY_SQL(qry, next());
+ QCOMPARE(qry.value(0).toInt(), 42);
+ // the next query will only work when the underlying database support question mark notation natively
+ if (dbType == QSqlDriver::PostgreSQL) {
+ QVERIFY(!qry.prepare("SELECT integer_col FROM " + tableName + " WHERE integer_col = ?"));
+ qry.bindValue(0, 42);
+ QVERIFY(!qry.exec());
+ QVERIFY(!qry.next());
+ } else {
+ QVERIFY_SQL(qry, prepare("SELECT integer_col FROM " + tableName + " WHERE integer_col = ?"));
+ qry.bindValue(0, 42);
+ QVERIFY_SQL(qry, exec());
+ QVERIFY_SQL(qry, next());
+ QCOMPARE(qry.value(0).toInt(), 42);
+ }
+}
+
+void tst_QSqlQuery::psqlJsonOperator()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "qTableName", __FILE__);
+ const QString &tableName = ts.tableName();
+
+ QSqlQuery qry(db);
+ qry.setPositionalBindingEnabled(false); // don't allow / handle '?' as placeholder
+ QVERIFY_SQL(qry, exec("CREATE TABLE " + tableName + " (integer_col integer, json_col jsonb)"));
+ QVERIFY_SQL(qry, exec("INSERT INTO " + tableName + "(integer_col, json_col) VALUES(42, '{\"a\": [1, 2]}')"));
+ QVERIFY_SQL(qry, exec("INSERT INTO " + tableName + "(integer_col, json_col) VALUES(43, '{\"b\": [3, 4]}')"));
+
+ QVERIFY_SQL(qry, prepare("SELECT integer_col, json_col FROM " + tableName + " WHERE json_col @? '$.a[*] ? (@ == 1)' and integer_col = :int"));
+ qry.bindValue(":int", 42);
+ QVERIFY_SQL(qry, exec());
+ QVERIFY_SQL(qry, next());
+ QCOMPARE(qry.value(0).toInt(), 42);
+ QCOMPARE(qry.value(1).toByteArray(), "{\"a\": [1, 2]}");
+
+ QVERIFY_SQL(qry, prepare("SELECT integer_col, json_col FROM " + tableName + " WHERE json_col ? 'b' and integer_col = :int"));
+ qry.bindValue(":int", 43);
+ QVERIFY_SQL(qry, exec());
+ QVERIFY_SQL(qry, next());
+ QCOMPARE(qry.value(0).toInt(), 43);
+ QCOMPARE(qry.value(1).toByteArray(), "{\"b\": [3, 4]}");
+}
+
+
QTEST_MAIN(tst_QSqlQuery)
#include "tst_qsqlquery.moc"
diff --git a/tests/auto/sql/kernel/qsqlrecord/CMakeLists.txt b/tests/auto/sql/kernel/qsqlrecord/CMakeLists.txt
index 72eb1c0727..18d46669db 100644
--- a/tests/auto/sql/kernel/qsqlrecord/CMakeLists.txt
+++ b/tests/auto/sql/kernel/qsqlrecord/CMakeLists.txt
@@ -1,12 +1,19 @@
-# Generated from qsqlrecord.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqlrecord Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqlrecord LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqlrecord
SOURCES
tst_qsqlrecord.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Sql
)
diff --git a/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp b/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
index 478dec6ac4..6aeae86d7d 100644
--- a/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
+++ b/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.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>
@@ -14,12 +14,7 @@
class tst_QSqlRecord : public QObject
{
-Q_OBJECT
-
-public:
- tst_QSqlRecord();
- virtual ~tst_QSqlRecord();
-
+ Q_OBJECT
public slots:
void init();
@@ -45,28 +40,14 @@ private slots:
void clearValues();
void clear();
void append();
+ void moveSemantics();
private:
- QSqlRecord* rec;
- QSqlField* fields[ NUM_FIELDS ];
+ std::unique_ptr<QSqlRecord> rec;
+ std::array<std::unique_ptr<QSqlField>, NUM_FIELDS> fields;
void createTestRecord();
};
-tst_QSqlRecord::tst_QSqlRecord()
-{
- rec = 0;
- for ( int i = 0; i < NUM_FIELDS; ++i )
- fields[ i ] = 0;
-}
-
-tst_QSqlRecord::~tst_QSqlRecord()
-{
- delete rec;
- for ( int i = 0; i < NUM_FIELDS; ++i )
- delete fields[ i ];
- rec = 0;
-}
-
void tst_QSqlRecord::init()
{
cleanup();
@@ -74,31 +55,26 @@ void tst_QSqlRecord::init()
void tst_QSqlRecord::cleanup()
{
- delete rec;
- for ( int i = 0; i < NUM_FIELDS; ++i ) {
- delete fields[ i ];
- fields[ i ] = 0;
- }
- rec = 0;
+ rec = nullptr;
+ for (auto &field : fields)
+ field = nullptr;
}
void tst_QSqlRecord::createTestRecord()
{
- delete rec;
- rec = new QSqlRecord();
- fields[0] = new QSqlField(QStringLiteral("string"), QMetaType(QMetaType::QString), QStringLiteral("stringtable"));
- fields[1] = new QSqlField(QStringLiteral("int"), QMetaType(QMetaType::Int), QStringLiteral("inttable"));
- fields[2] = new QSqlField(QStringLiteral("double"), QMetaType(QMetaType::Double), QStringLiteral("doubletable"));
- fields[3] = new QSqlField(QStringLiteral("bool"), QMetaType(QMetaType::Bool));
- for ( int i = 0; i < NUM_FIELDS; ++i )
- rec->append( *(fields[ i ] ) );
+ rec = std::make_unique<QSqlRecord>();
+ fields[0] = std::make_unique<QSqlField>(QStringLiteral("string"), QMetaType(QMetaType::QString), QStringLiteral("stringtable"));
+ fields[1] = std::make_unique<QSqlField>(QStringLiteral("int"), QMetaType(QMetaType::Int), QStringLiteral("inttable"));
+ fields[2] = std::make_unique<QSqlField>(QStringLiteral("double"), QMetaType(QMetaType::Double), QStringLiteral("doubletable"));
+ fields[3] = std::make_unique<QSqlField>(QStringLiteral("bool"), QMetaType(QMetaType::Bool));
+ for (const auto &field : fields)
+ rec->append(*field);
}
void tst_QSqlRecord::append()
{
- delete rec;
- rec = new QSqlRecord();
+ rec = std::make_unique<QSqlRecord>();
rec->append(QSqlField("string", QMetaType(QMetaType::QString), QStringLiteral("stringtable")));
QCOMPARE( rec->field( 0 ).name(), (QString) "string" );
QCOMPARE(rec->field(0).tableName(), QStringLiteral("stringtable"));
@@ -157,10 +133,7 @@ void tst_QSqlRecord::clearValues()
QFETCH( double, dval );
QFETCH( int, bval );
- if(rec)
- delete rec;
-
- rec = new QSqlRecord();
+ rec = std::make_unique<QSqlRecord>();
rec->append( QSqlField( "string", QMetaType(QMetaType::QString) ) );
QCOMPARE( rec->field(0).name(), (QString) "string" );
QVERIFY( !rec->isEmpty() );
@@ -200,8 +173,8 @@ void tst_QSqlRecord::clearValues()
void tst_QSqlRecord::contains()
{
createTestRecord();
- for ( int i = 0; i < NUM_FIELDS; ++i )
- QVERIFY( rec->contains( fields[ i ]->name() ) );
+ for (const auto &field : fields)
+ QVERIFY(rec->contains(field->name()));
QVERIFY( !rec->contains( "__Harry__" ) );
}
@@ -233,8 +206,8 @@ void tst_QSqlRecord::fieldName()
{
createTestRecord();
- for ( int i = 0; i < NUM_FIELDS; ++i )
- QVERIFY( rec->field( (fields[ i ] )->name() ) == *( fields[ i ] ) );
+ for (const auto &field : fields)
+ QVERIFY(rec->field(field->name()) == *field);
QVERIFY( rec->fieldName( NUM_FIELDS ).isNull() );
}
@@ -412,8 +385,7 @@ void tst_QSqlRecord::setValue()
{
int i;
- delete rec;
- rec = new QSqlRecord();
+ rec = std::make_unique<QSqlRecord>();
rec->append( QSqlField( "string", QMetaType(QMetaType::QString) ) );
QCOMPARE( rec->field( 0 ).name(), (QString) "string" );
QVERIFY( !rec->isEmpty() );
@@ -478,5 +450,24 @@ void tst_QSqlRecord::value()
QCOMPARE(rec2.value("string").toString(), QLatin1String("Harry"));
}
+void tst_QSqlRecord::moveSemantics()
+{
+ QSqlRecord rec, empty;
+ rec.append(QSqlField("string", QMetaType(QMetaType::QString)));
+ rec.setValue("string", "Harry");
+ auto moved = std::move(rec);
+ // `rec` is not partially-formed
+
+ // moving transfers state:
+ QCOMPARE(moved.value("string").toString(), QLatin1String("Harry"));
+
+ // moved-from objects can be assigned-to:
+ rec = empty;
+ QVERIFY(rec.value("string").isNull());
+
+ // moved-from object can be destroyed:
+ moved = std::move(rec);
+}
+
QTEST_MAIN(tst_QSqlRecord)
#include "tst_qsqlrecord.moc"
diff --git a/tests/auto/sql/kernel/qsqlresult/CMakeLists.txt b/tests/auto/sql/kernel/qsqlresult/CMakeLists.txt
index 1dc3394770..1fc475b144 100644
--- a/tests/auto/sql/kernel/qsqlresult/CMakeLists.txt
+++ b/tests/auto/sql/kernel/qsqlresult/CMakeLists.txt
@@ -1,14 +1,21 @@
-# Generated from qsqlresult.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqlresult Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqlresult LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqlresult
SOURCES
testsqldriver.h
tst_qsqlresult.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Sql
Qt::SqlPrivate
diff --git a/tests/auto/sql/kernel/qsqlresult/testsqldriver.h b/tests/auto/sql/kernel/qsqlresult/testsqldriver.h
index 79be0dc230..072e683d68 100644
--- a/tests/auto/sql/kernel/qsqlresult/testsqldriver.h
+++ b/tests/auto/sql/kernel/qsqlresult/testsqldriver.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
#ifndef TESTSQLDRIVER_H
#define TESTSQLDRIVER_H
diff --git a/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp b/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp
index b8fd27bc50..da438dcfd6 100644
--- a/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp
+++ b/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.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>
#include <QtSql/QtSql>
@@ -29,7 +29,7 @@ void tst_QSqlResult::positionalToNamedBinding()
TestSqlDriverResult result(&testDriver);
QString query("INSERT INTO MYTABLE (ID, NAME, BIRTH) VALUES(?, ?, ?)");
QVERIFY(result.savePrepare(query));
- QCOMPARE(result.boundValues().count(), 3);
+ QCOMPARE(result.boundValues().size(), 3);
}
void tst_QSqlResult::parseOfBoundValues()
@@ -37,43 +37,43 @@ void tst_QSqlResult::parseOfBoundValues()
TestSqlDriver testDriver;
TestSqlDriverResult result(&testDriver);
QVERIFY(result.savePrepare("SELECT :1 AS \":2\""));
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT :1 AS ':2'"));
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT :1 AS [:2]"));
if (testDriver.dbmsType() == QSqlDriver::PostgreSQL)
- QCOMPARE(result.boundValues().count(), 2);
+ QCOMPARE(result.boundValues().size(), 2);
else
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT :1 AS [:2]]]"));
if (testDriver.dbmsType() == QSqlDriver::PostgreSQL)
- QCOMPARE(result.boundValues().count(), 2);
+ QCOMPARE(result.boundValues().size(), 2);
else
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT :1 AS [:2]]]]]"));
if (testDriver.dbmsType() == QSqlDriver::PostgreSQL)
- QCOMPARE(result.boundValues().count(), 2);
+ QCOMPARE(result.boundValues().size(), 2);
else
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT ? AS \"?\""));
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT ? AS '?'"));
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT ? AS [?]"));
if (testDriver.dbmsType() == QSqlDriver::PostgreSQL)
- QCOMPARE(result.boundValues().count(), 2);
+ QCOMPARE(result.boundValues().size(), 2);
else
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT ? AS \"'?\""));
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT ? AS '?\"'"));
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT ? AS '?''?'"));
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
QVERIFY(result.savePrepare("SELECT ? AS [\"?']"));
- QCOMPARE(result.boundValues().count(), 1);
+ QCOMPARE(result.boundValues().size(), 1);
}
QTEST_MAIN( tst_QSqlResult )
diff --git a/tests/auto/sql/kernel/qsqlthread/CMakeLists.txt b/tests/auto/sql/kernel/qsqlthread/CMakeLists.txt
index 6cdeec3162..98108528e6 100644
--- a/tests/auto/sql/kernel/qsqlthread/CMakeLists.txt
+++ b/tests/auto/sql/kernel/qsqlthread/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qsqlthread.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqlthread Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqlthread LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqlthread
SOURCES
tst_qsqlthread.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Sql
Qt::SqlPrivate
diff --git a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
index d868cf0197..0bebb7edd5 100644
--- a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
+++ b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.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>
@@ -258,18 +258,16 @@ void tst_QSqlThread::generic_data(const QString& engine)
void tst_QSqlThread::dropTestTables()
{
- for (int i = 0; i < dbs.dbNames.count(); ++i) {
- QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i));
- QSqlQuery q(db);
-
- tst_Databases::safeDropTables(db, QStringList() << qtest << qTableName("qtest2", __FILE__, db) << qTableName("emptytable", __FILE__, db));
+ for (const auto &dbName : dbs.dbNames) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ tst_Databases::safeDropTables(db, { qtest, qTableName("qtest2", __FILE__, db), qTableName("emptytable", __FILE__, db) });
}
}
void tst_QSqlThread::createTestTables()
{
- for (int i = 0; i < dbs.dbNames.count(); ++i) {
- QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i));
+ for (const auto &dbName : dbs.dbNames) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
QSqlQuery q(db);
QVERIFY_SQL(q, exec("create table " + qtest
@@ -285,8 +283,8 @@ void tst_QSqlThread::createTestTables()
void tst_QSqlThread::repopulateTestTables()
{
- for (int i = 0; i < dbs.dbNames.count(); ++i) {
- QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i));
+ for (const auto &dbName : dbs.dbNames) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
QSqlQuery q(db);
QVERIFY_SQL(q, exec("delete from " + qtest));
diff --git a/tests/auto/sql/kernel/qvfssql/CMakeLists.txt b/tests/auto/sql/kernel/qvfssql/CMakeLists.txt
new file mode 100644
index 0000000000..7c66f055a6
--- /dev/null
+++ b/tests/auto/sql/kernel/qvfssql/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsqlfield Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qvfssql LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qvfssql
+ SOURCES
+ tst_qvfssql.cpp
+ LIBRARIES
+ Qt::SqlPrivate
+)
+
+set(qvfssql_resource_files
+ "sample.db"
+)
+
+qt_internal_add_resource(tst_qvfssql "tst_qvfssql"
+ PREFIX
+ "/ro/"
+ FILES
+ ${qvfssql_resource_files}
+)
diff --git a/tests/auto/sql/kernel/qvfssql/sample.db b/tests/auto/sql/kernel/qvfssql/sample.db
new file mode 100644
index 0000000000..56e6427e3c
--- /dev/null
+++ b/tests/auto/sql/kernel/qvfssql/sample.db
Binary files differ
diff --git a/tests/auto/sql/kernel/qvfssql/tst_qvfssql.cpp b/tests/auto/sql/kernel/qvfssql/tst_qvfssql.cpp
new file mode 100644
index 0000000000..0dbdf7e60a
--- /dev/null
+++ b/tests/auto/sql/kernel/qvfssql/tst_qvfssql.cpp
@@ -0,0 +1,94 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <qsqldatabase.h>
+#include <qstandardpaths.h>
+
+#include "../qsqldatabase/tst_databases.h"
+
+using namespace Qt::StringLiterals;
+
+class tst_QVfsSql : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testRoDb();
+ void testRwDb();
+};
+
+void tst_QVfsSql::testRoDb()
+{
+ QVERIFY(QSqlDatabase::drivers().contains("QSQLITE"_L1));
+ QSqlDatabase::addDatabase("QSQLITE"_L1, "ro_db"_L1);
+ QSqlDatabase db = QSqlDatabase::database("ro_db"_L1, false);
+ QVERIFY_SQL(db, isValid());
+ db.setDatabaseName(":/ro/sample.db"_L1);
+
+ db.setConnectOptions("QSQLITE_USE_QT_VFS"_L1);
+ QVERIFY(!db.open()); // can not open as the QSQLITE_OPEN_READONLY attribute is missing
+
+ db.setConnectOptions("QSQLITE_USE_QT_VFS;QSQLITE_OPEN_READONLY"_L1);
+ QVERIFY_SQL(db, open());
+
+ QStringList tables = db.tables();
+ QSqlQuery q{db};
+ for (auto table : {"reltest1"_L1, "reltest2"_L1, "reltest3"_L1, "reltest4"_L1, "reltest5"_L1}) {
+ QVERIFY(tables.contains(table));
+ QVERIFY_SQL(q, exec("select * from " + table));
+ QVERIFY(q.next());
+ }
+ QVERIFY_SQL(q, exec("select * from reltest1 where id = 4"_L1));
+ QVERIFY_SQL(q, first());
+ QVERIFY(q.value(0).toInt() == 4);
+ QVERIFY(q.value(1).toString() == "boris"_L1);
+ QVERIFY(q.value(2).toInt() == 2);
+ QVERIFY(q.value(3).toInt() == 2);
+}
+
+void tst_QVfsSql::testRwDb()
+{
+ QSqlDatabase::addDatabase("QSQLITE"_L1, "rw_db"_L1);
+ QSqlDatabase db = QSqlDatabase::database("rw_db"_L1, false);
+ QVERIFY_SQL(db, isValid());
+ const auto dbPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/test_qt_vfs.db"_L1;
+ db.setDatabaseName(dbPath);
+ QFile::remove(dbPath);
+
+ db.setConnectOptions("QSQLITE_USE_QT_VFS;QSQLITE_OPEN_READONLY"_L1);
+ QVERIFY(!db.open()); // can not open as the QSQLITE_OPEN_READONLY attribute is set and the file is missing
+
+ db.setConnectOptions("QSQLITE_USE_QT_VFS"_L1);
+ QVERIFY_SQL(db, open());
+
+ QVERIFY(db.tables().isEmpty());
+ QSqlQuery q{db};
+ QVERIFY_SQL(q, exec("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, val INTEGER)"_L1));
+ QVERIFY_SQL(q, exec("BEGIN"_L1));
+ for (int i = 0; i < 1000; ++i) {
+ q.prepare("INSERT INTO test (val) VALUES (:val)"_L1);
+ q.bindValue(":val"_L1, i);
+ QVERIFY_SQL(q, exec());
+ }
+ QVERIFY_SQL(q, exec("COMMIT"_L1));
+ QVERIFY_SQL(q, exec("SELECT val FROM test ORDER BY val"_L1));
+ for (int i = 0; i < 1000; ++i) {
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt() , i);
+ }
+ QVERIFY_SQL(q, exec("DELETE FROM test WHERE val < 500"_L1));
+ auto fileSize = QFileInfo{dbPath}.size();
+ QVERIFY_SQL(q, exec("VACUUM"_L1));
+ QVERIFY(QFileInfo{dbPath}.size() < fileSize); // TEST xTruncate VFS
+ QVERIFY_SQL(q, exec("SELECT val FROM test ORDER BY val"_L1));
+ for (int i = 500; i < 1000; ++i) {
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt() , i);
+ }
+ db.close();
+ QFile::remove(dbPath);
+}
+
+QTEST_MAIN(tst_QVfsSql)
+#include "tst_qvfssql.moc"
diff --git a/tests/auto/sql/models/CMakeLists.txt b/tests/auto/sql/models/CMakeLists.txt
index ce44f587de..0ab804abe3 100644
--- a/tests/auto/sql/models/CMakeLists.txt
+++ b/tests/auto/sql/models/CMakeLists.txt
@@ -1,4 +1,5 @@
-# Generated from models.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(qsqlrelationaltablemodel)
add_subdirectory(qsqltablemodel)
diff --git a/tests/auto/sql/models/qsqlquerymodel/CMakeLists.txt b/tests/auto/sql/models/qsqlquerymodel/CMakeLists.txt
index e38c51b4be..d148ce43e2 100644
--- a/tests/auto/sql/models/qsqlquerymodel/CMakeLists.txt
+++ b/tests/auto/sql/models/qsqlquerymodel/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qsqlquerymodel.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqlquerymodel Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqlquerymodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqlquerymodel
SOURCES
tst_qsqlquerymodel.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::Sql
diff --git a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
index 8b7476b3e7..a669c72a1e 100644
--- a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
+++ b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.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>
@@ -62,9 +62,9 @@ private slots:
void task_QTBUG_4963_setHeaderDataWithProxyModel();
private:
- void generic_data(const QString &engine=QString());
- void dropTestTables(QSqlDatabase db);
- void createTestTables(QSqlDatabase db);
+ void generic_data(const QString &engine = QString());
+ void dropTestTables(const QSqlDatabase &db);
+ void createTestTables(const QSqlDatabase &db);
void populateTestTables(QSqlDatabase db);
tst_Databases dbs;
};
@@ -73,8 +73,8 @@ private:
class DBTestModel: public QSqlQueryModel
{
public:
- DBTestModel(QObject *parent = nullptr): QSqlQueryModel(parent) {}
- QModelIndex indexInQuery(const QModelIndex &item) const override { return QSqlQueryModel::indexInQuery(item); }
+ using QSqlQueryModel::QSqlQueryModel;
+ using QSqlQueryModel::indexInQuery;
};
tst_QSqlQueryModel::tst_QSqlQueryModel()
@@ -88,8 +88,8 @@ tst_QSqlQueryModel::~tst_QSqlQueryModel()
void tst_QSqlQueryModel::initTestCase()
{
QVERIFY(dbs.open());
- for (QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it) {
- QSqlDatabase db = QSqlDatabase::database((*it));
+ for (const auto &dbName : std::as_const(dbs.dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
dropTestTables(db); //in case of leftovers
createTestTables(db);
@@ -99,15 +99,15 @@ void tst_QSqlQueryModel::initTestCase()
void tst_QSqlQueryModel::cleanupTestCase()
{
- for (QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it) {
- QSqlDatabase db = QSqlDatabase::database((*it));
+ for (const auto &dbName : std::as_const(dbs.dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
dropTestTables(db);
}
dbs.close();
}
-void tst_QSqlQueryModel::dropTestTables(QSqlDatabase db)
+void tst_QSqlQueryModel::dropTestTables(const QSqlDatabase &db)
{
QStringList tableNames;
tableNames << qTableName("test", __FILE__, db)
@@ -117,7 +117,7 @@ void tst_QSqlQueryModel::dropTestTables(QSqlDatabase db)
tst_Databases::safeDropTables(db, tableNames);
}
-void tst_QSqlQueryModel::createTestTables(QSqlDatabase db)
+void tst_QSqlQueryModel::createTestTables(const QSqlDatabase &db)
{
dropTestTables(db);
QSqlQuery q(db);
@@ -202,7 +202,7 @@ void tst_QSqlQueryModel::removeColumn()
QCOMPARE(model.columnCount(), 3);
QVERIFY(model.removeColumn(0));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QVERIFY(*(QModelIndex *)spy.at(0).at(0).constData() == QModelIndex());
QCOMPARE(spy.at(0).at(1).toInt(), 0);
QCOMPARE(spy.at(0).at(2).toInt(), 0);
@@ -232,7 +232,7 @@ void tst_QSqlQueryModel::removeColumn()
QVERIFY(model.removeColumn(2));
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
QVERIFY(*(QModelIndex *)spy.at(1).at(0).constData() == QModelIndex());
QCOMPARE(spy.at(1).at(1).toInt(), 2);
QCOMPARE(spy.at(1).at(2).toInt(), 2);
@@ -245,7 +245,7 @@ void tst_QSqlQueryModel::removeColumn()
QVERIFY(model.removeColumn(1));
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
QVERIFY(*(QModelIndex *)spy.at(2).at(0).constData() == QModelIndex());
QCOMPARE(spy.at(2).at(1).toInt(), 1);
QCOMPARE(spy.at(2).at(2).toInt(), 1);
@@ -259,7 +259,7 @@ void tst_QSqlQueryModel::removeColumn()
QVERIFY(model.removeColumn(0));
- QCOMPARE(spy.count(), 4);
+ QCOMPARE(spy.size(), 4);
QVERIFY(*(QModelIndex *)spy.at(3).at(0).constData() == QModelIndex());
QCOMPARE(spy.at(3).at(1).toInt(), 0);
QCOMPARE(spy.at(3).at(2).toInt(), 0);
@@ -301,7 +301,7 @@ void tst_QSqlQueryModel::insertColumn()
QVERIFY(model.insertColumn(1));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QVERIFY(*(QModelIndex *)spy.at(0).at(0).constData() == QModelIndex());
QCOMPARE(spy.at(0).at(1).toInt(), 1);
QCOMPARE(spy.at(0).at(2).toInt(), 1);
@@ -330,7 +330,7 @@ void tst_QSqlQueryModel::insertColumn()
QVERIFY(model.insertColumn(0));
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
QVERIFY(*(QModelIndex *)spy.at(1).at(0).constData() == QModelIndex());
QCOMPARE(spy.at(1).at(1).toInt(), 0);
QCOMPARE(spy.at(1).at(2).toInt(), 0);
@@ -345,7 +345,7 @@ void tst_QSqlQueryModel::insertColumn()
QVERIFY(!model.insertColumn(6));
QVERIFY(model.insertColumn(5));
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
QVERIFY(*(QModelIndex *)spy.at(2).at(0).constData() == QModelIndex());
QCOMPARE(spy.at(2).at(1).toInt(), 5);
QCOMPARE(spy.at(2).at(2).toInt(), 5);
@@ -424,7 +424,7 @@ void tst_QSqlQueryModel::setHeaderData()
QSignalSpy spy(&model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)));
QVERIFY(model.setHeaderData(2, Qt::Horizontal, "bar"));
QCOMPARE(model.headerData(2, Qt::Horizontal).toString(), QString("bar"));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(qvariant_cast<Qt::Orientation>(spy.value(0).value(0)), Qt::Horizontal);
QCOMPARE(spy.value(0).value(1).toInt(), 2);
QCOMPARE(spy.value(0).value(2).toInt(), 2);
@@ -452,8 +452,8 @@ void tst_QSqlQueryModel::fetchMore()
model.setQuery(QSqlQuery("select * from " + qTableName("many", __FILE__, db), db));
int rowCount = model.rowCount();
- QCOMPARE(modelAboutToBeResetSpy.count(), 1);
- QCOMPARE(modelResetSpy.count(), 1);
+ QCOMPARE(modelAboutToBeResetSpy.size(), 1);
+ QCOMPARE(modelResetSpy.size(), 1);
// If the driver doesn't return the query size fetchMore() causes the
// model to grow and new signals are emitted
@@ -499,11 +499,11 @@ void tst_QSqlQueryModel::withSortFilterProxyModel()
QCOMPARE(proxy.rowCount(), 511);
// setQuery() resets the model accompanied by begin and end signals
- QCOMPARE(modelAboutToBeResetSpy.count(), 1);
- QCOMPARE(modelResetSpy.count(), 1);
+ QCOMPARE(modelAboutToBeResetSpy.size(), 1);
+ QCOMPARE(modelResetSpy.size(), 1);
// The call to scrollToBottom() forces the model to fetch additional rows.
- QCOMPARE(modelRowsInsertedSpy.count(), 1);
+ QCOMPARE(modelRowsInsertedSpy.size(), 1);
QCOMPARE(modelRowsInsertedSpy.value(0).value(1).toInt(), 256);
QCOMPARE(modelRowsInsertedSpy.value(0).value(2).toInt(), 510);
}
@@ -523,14 +523,14 @@ void tst_QSqlQueryModel::setQuerySignalEmission()
// First select, the model was empty and no rows had to be removed, but model resets anyway.
model.setQuery(QSqlQuery("SELECT * FROM " + qTableName("test", __FILE__, db), db));
- QCOMPARE(modelAboutToBeResetSpy.count(), 1);
- QCOMPARE(modelResetSpy.count(), 1);
+ QCOMPARE(modelAboutToBeResetSpy.size(), 1);
+ QCOMPARE(modelResetSpy.size(), 1);
// Second select, the model wasn't empty and two rows had to be removed!
// setQuery() resets the model accompanied by begin and end signals
model.setQuery(QSqlQuery("SELECT * FROM " + qTableName("test", __FILE__, db), db));
- QCOMPARE(modelAboutToBeResetSpy.count(), 2);
- QCOMPARE(modelResetSpy.count(), 2);
+ QCOMPARE(modelAboutToBeResetSpy.size(), 2);
+ QCOMPARE(modelResetSpy.size(), 2);
}
// For task 170783: When the query's result set is empty no rows should be inserted,
@@ -549,8 +549,8 @@ void tst_QSqlQueryModel::setQueryWithNoRowsInResultSet()
QSqlQuery query(db);
QVERIFY_SQL(query, exec("SELECT * FROM " + qTableName("test", __FILE__, db) + " where 0 = 1"));
model.setQuery(std::move(query));
- QCOMPARE(modelRowsAboutToBeInsertedSpy.count(), 0);
- QCOMPARE(modelRowsInsertedSpy.count(), 0);
+ QCOMPARE(modelRowsAboutToBeInsertedSpy.size(), 0);
+ QCOMPARE(modelRowsInsertedSpy.size(), 0);
}
class NestedResetsTest: public QSqlQueryModel
diff --git a/tests/auto/sql/models/qsqlrelationaldelegate/CMakeLists.txt b/tests/auto/sql/models/qsqlrelationaldelegate/CMakeLists.txt
index b76a3f7b9c..ea2dc6131d 100644
--- a/tests/auto/sql/models/qsqlrelationaldelegate/CMakeLists.txt
+++ b/tests/auto/sql/models/qsqlrelationaldelegate/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qsqlrelationaldelegate.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqlrelationaldelegate Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqlrelationaldelegate LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqlrelationaldelegate
SOURCES
tst_qsqlrelationaldelegate.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Sql
Qt::SqlPrivate
diff --git a/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp b/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp
index 5c49600b8f..5977689ab6 100644
--- a/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp
+++ b/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2018 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>
@@ -77,16 +77,17 @@ void tst_QSqlRelationalDelegate::recreateTestTables(QSqlDatabase db)
void tst_QSqlRelationalDelegate::initTestCase()
{
- foreach (const QString &dbname, dbs.dbNames) {
- QSqlDatabase db=QSqlDatabase::database(dbname);
+ for (const QString &dbName : std::as_const(dbs.dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ QSqlQuery q(db);
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::Interbase) {
- db.exec("SET DIALECT 3");
+ q.exec("SET DIALECT 3");
} else if (dbType == QSqlDriver::MSSqlServer) {
- db.exec("SET ANSI_DEFAULTS ON");
- db.exec("SET IMPLICIT_TRANSACTIONS OFF");
+ q.exec("SET ANSI_DEFAULTS ON");
+ q.exec("SET IMPLICIT_TRANSACTIONS OFF");
} else if (dbType == QSqlDriver::PostgreSQL) {
- db.exec("set client_min_messages='warning'");
+ q.exec("set client_min_messages='warning'");
}
recreateTestTables(db);
}
@@ -94,7 +95,7 @@ void tst_QSqlRelationalDelegate::initTestCase()
void tst_QSqlRelationalDelegate::cleanupTestCase()
{
- foreach (const QString &dbName, dbs.dbNames) {
+ for (const QString &dbName : std::as_const(dbs.dbNames)) {
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
dropTestTables(QSqlDatabase::database(dbName));
@@ -146,7 +147,7 @@ void tst_QSqlRelationalDelegate::comboBoxEditor()
tv.setCurrentIndex(index);
tv.edit(index);
QList<QComboBox*> comboBoxes = tv.viewport()->findChildren<QComboBox *>();
- QCOMPARE(comboBoxes.count(), 1);
+ QCOMPARE(comboBoxes.size(), 1);
QComboBox *editor = comboBoxes.at(0);
QCOMPARE(editor->currentText(), "herr");
diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/CMakeLists.txt b/tests/auto/sql/models/qsqlrelationaltablemodel/CMakeLists.txt
index 736412731e..dc85845987 100644
--- a/tests/auto/sql/models/qsqlrelationaltablemodel/CMakeLists.txt
+++ b/tests/auto/sql/models/qsqlrelationaltablemodel/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qsqlrelationaltablemodel.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqlrelationaltablemodel Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqlrelationaltablemodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqlrelationaltablemodel
SOURCES
tst_qsqlrelationaltablemodel.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Sql
Qt::SqlPrivate
diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
index 4f824cce66..5e3643ec8e 100644
--- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
+++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.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>
@@ -7,21 +7,12 @@
#include "../../kernel/qsqldatabase/tst_databases.h"
-QString reltest1;
-QString reltest2;
-QString reltest3;
-QString reltest4;
-QString reltest5;
-
class tst_QSqlRelationalTableModel : public QObject
{
Q_OBJECT
public:
- void recreateTestTables(QSqlDatabase);
- tst_QSqlRelationalTableModel();
-
- tst_Databases dbs;
+ using QObject::QObject;
public slots:
void initTestCase_data();
@@ -56,25 +47,43 @@ private slots:
void setRelation();
private:
- void dropTestTables( QSqlDatabase db );
+ void fixupTableNamesForDb(const QSqlDatabase &db);
+ void recreateTestTables(const QSqlDatabase &db);
+ void dropTestTables(const QSqlDatabase &db);
+ static QString escapeTableName(const QSqlDatabase &db, const QString &name)
+ {
+ QString _name = name;
+ const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ if (dbType == QSqlDriver::Oracle ||
+ dbType == QSqlDriver::DB2)
+ _name = name.toUpper();
+ return db.driver()->escapeIdentifier(_name, QSqlDriver::TableName);
+ }
+ static QString escapeFieldName(const QSqlDatabase &db, const QString &name)
+ {
+ QString _name = name;
+ const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ if (dbType == QSqlDriver::Interbase ||
+ dbType == QSqlDriver::Oracle ||
+ dbType == QSqlDriver::DB2)
+ _name = name.toUpper();
+ return db.driver()->escapeIdentifier(_name, QSqlDriver::FieldName);
+ }
+ QString reltest1;
+ QString reltest2;
+ QString reltest3;
+ QString reltest4;
+ QString reltest5;
+ tst_Databases dbs;
};
-tst_QSqlRelationalTableModel::tst_QSqlRelationalTableModel()
+void tst_QSqlRelationalTableModel::fixupTableNamesForDb(const QSqlDatabase &db)
{
- static QSqlDatabase static_qtest_db_1 = QSqlDatabase();
- reltest1 = qTableName("reltest1", __FILE__, static_qtest_db_1);
-
- static QSqlDatabase static_qtest_db_2 = QSqlDatabase();
- reltest2 = qTableName("reltest2", __FILE__, static_qtest_db_2);
-
- static QSqlDatabase static_qtest_db_3 = QSqlDatabase();
- reltest3 = qTableName("reltest3", __FILE__, static_qtest_db_3);
-
- static QSqlDatabase static_qtest_db_4 = QSqlDatabase();
- reltest4 = qTableName("reltest4", __FILE__, static_qtest_db_4);
-
- static QSqlDatabase static_qtest_db_5 = QSqlDatabase();
- reltest5 = qTableName("reltest5", __FILE__, static_qtest_db_5);
+ reltest1 = qTableName("reltest1", __FILE__, db);
+ reltest2 = qTableName("reltest2", __FILE__, db);
+ reltest3 = qTableName("reltest3", __FILE__, db);
+ reltest4 = qTableName("reltest4", __FILE__, db);
+ reltest5 = qTableName("reltest5", __FILE__, db);
}
void tst_QSqlRelationalTableModel::initTestCase_data()
@@ -84,7 +93,7 @@ void tst_QSqlRelationalTableModel::initTestCase_data()
QSKIP("No database drivers are available in this Qt configuration");
}
-void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db)
+void tst_QSqlRelationalTableModel::recreateTestTables(const QSqlDatabase &db)
{
dropTestTables(db);
@@ -114,32 +123,36 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db)
QVERIFY_SQL( q, exec("insert into " + reltest5 + " values('herr', 'Hr')"));
QVERIFY_SQL( q, exec("insert into " + reltest5 + " values('mister', 'Mr')"));
- if (testWhiteSpaceNames(db.driverName())) {
- const auto reltest6 = qTableName("rel test6", __FILE__, db);
- QVERIFY_SQL( q, exec("create table " + reltest6 + " (id int not null primary key, " + db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName) +
- " int, " + db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName) + " int)"));
- QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(1, 1,9)"));
- QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(2, 2,8)"));
-
- const auto reltest7 = qTableName("rel test7", __FILE__, db);
- QVERIFY_SQL( q, exec("create table " + reltest7 + " (" + db.driver()->escapeIdentifier("city id", QSqlDriver::TableName) + " int not null primary key, " + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName) + " varchar(20))"));
- QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(1, 'New York')"));
- QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(2, 'Washington')"));
- }
+ const auto reltest6 = qTableName("rel test6", __FILE__, db);
+ const auto cityKeyStr = db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName);
+ const auto extraFieldStr = db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName);
+ QVERIFY_SQL( q, exec("create table " + reltest6 + " (id int not null primary key, " + cityKeyStr +
+ " int, " + extraFieldStr + " int)"));
+ QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(1, 1,9)"));
+ QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(2, 2,8)"));
+
+ const auto reltest7 = qTableName("rel test7", __FILE__, db);
+ const auto cityIdStr = db.driver()->escapeIdentifier("city id", QSqlDriver::TableName);
+ const auto cityNameStr = db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName);
+ QVERIFY_SQL( q, exec("create table " + reltest7 + " (" + cityIdStr + " int not null primary key, " +
+ cityNameStr + " varchar(20))"));
+ QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(1, 'New York')"));
+ QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(2, 'Washington')"));
}
void tst_QSqlRelationalTableModel::initTestCase()
{
- foreach (const QString &dbname, dbs.dbNames) {
- QSqlDatabase db=QSqlDatabase::database(dbname);
+ for (const QString &dbName : std::as_const(dbs.dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ QSqlQuery q(db);
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::Interbase) {
- db.exec("SET DIALECT 3");
+ q.exec("SET DIALECT 3");
} else if (dbType == QSqlDriver::MSSqlServer) {
- db.exec("SET ANSI_DEFAULTS ON");
- db.exec("SET IMPLICIT_TRANSACTIONS OFF");
+ q.exec("SET ANSI_DEFAULTS ON");
+ q.exec("SET IMPLICIT_TRANSACTIONS OFF");
} else if (dbType == QSqlDriver::PostgreSQL) {
- db.exec("set client_min_messages='warning'");
+ q.exec("set client_min_messages='warning'");
}
recreateTestTables(db);
}
@@ -147,30 +160,27 @@ void tst_QSqlRelationalTableModel::initTestCase()
void tst_QSqlRelationalTableModel::cleanupTestCase()
{
- foreach (const QString &dbName, dbs.dbNames) {
+ for (const QString &dbName : std::as_const(dbs.dbNames)) {
QSqlDatabase db = QSqlDatabase::database(dbName);
- CHECK_DATABASE( db );
- dropTestTables( QSqlDatabase::database(dbName) );
+ CHECK_DATABASE(db);
+ dropTestTables(db);
}
dbs.close();
}
-void tst_QSqlRelationalTableModel::dropTestTables( QSqlDatabase db )
+void tst_QSqlRelationalTableModel::dropTestTables(const QSqlDatabase &db)
{
- QStringList tableNames;
- tableNames << reltest1
- << reltest2
- << reltest3
- << reltest4
- << reltest5
- << qTableName("rel test6", __FILE__, db)
- << qTableName("rel test7", __FILE__, db)
- << qTableName("CASETEST1", db)
- << qTableName("casetest1", db);
+ fixupTableNamesForDb(db);
+ QStringList tableNames{reltest1, reltest2, reltest3, reltest4, reltest5,
+ qTableName("rel test6", __FILE__, db),
+ qTableName("rel test7", __FILE__, db),
+ qTableName("CASETEST1", __FILE__, db),
+ qTableName("casetest1", __FILE__, db)};
tst_Databases::safeDropTables( db, tableNames );
- db.exec("DROP SCHEMA " + qTableName("QTBUG_5373", __FILE__, db) + " CASCADE");
- db.exec("DROP SCHEMA " + qTableName("QTBUG_5373_s2", __FILE__, db) + " CASCADE");
+ QSqlQuery q(db);
+ q.exec("DROP SCHEMA " + qTableName("QTBUG_5373", __FILE__, db) + " CASCADE");
+ q.exec("DROP SCHEMA " + qTableName("QTBUG_5373_s2", __FILE__, db) + " CASCADE");
}
void tst_QSqlRelationalTableModel::init()
@@ -186,6 +196,7 @@ void tst_QSqlRelationalTableModel::data()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
QSqlRelationalTableModel model(0, db);
@@ -227,6 +238,7 @@ void tst_QSqlRelationalTableModel::setData()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
// set the values using OnRowChange Strategy
@@ -434,6 +446,7 @@ void tst_QSqlRelationalTableModel::insertRecord()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
QSqlRelationalTableModel model(0, db);
@@ -544,6 +557,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
QSqlRelationalTableModel model(0, db);
@@ -652,56 +666,33 @@ void tst_QSqlRelationalTableModel::removeColumn()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- recreateTestTables(db);
- QSqlRelationalTableModel model(0, db);
-
- model.setTable(reltest1);
- model.setRelation(2, QSqlRelation(reltest2, "id", "title"));
- QVERIFY_SQL(model, select());
-
- QVERIFY_SQL(model, removeColumn(3));
- QVERIFY_SQL(model, select());
-
- QCOMPARE(model.columnCount(), 3);
-
- QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
- QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
- QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
- QCOMPARE(model.data(model.index(0, 3)), QVariant());
-
- // try removing more than one column
- QVERIFY_SQL(model, removeColumns(1, 2));
- QCOMPARE(model.columnCount(), 1);
- QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
- QCOMPARE(model.data(model.index(0, 1)), QVariant());
-
- // try in LeftJoin mode the same tests
- CHECK_DATABASE(db);
- recreateTestTables(db);
+ for (const auto mode : {QSqlRelationalTableModel::InnerJoin, QSqlRelationalTableModel::LeftJoin}) {
+ recreateTestTables(db);
- QSqlRelationalTableModel lmodel(0, db);
+ QSqlRelationalTableModel model(0, db);
- lmodel.setTable(reltest1);
- lmodel.setRelation(2, QSqlRelation(reltest2, "id", "title"));
- lmodel.setJoinMode(QSqlRelationalTableModel::LeftJoin);
- QVERIFY_SQL(lmodel, select());
+ model.setTable(reltest1);
+ model.setRelation(2, QSqlRelation(reltest2, "id", "title"));
+ model.setJoinMode(mode);
+ QVERIFY_SQL(model, select());
- QVERIFY_SQL(lmodel, removeColumn(3));
- QVERIFY_SQL(lmodel, select());
+ QVERIFY_SQL(model, removeColumn(3));
+ QVERIFY_SQL(model, select());
- QCOMPARE(lmodel.columnCount(), 3);
+ QCOMPARE(model.columnCount(), 3);
- QCOMPARE(lmodel.data(lmodel.index(0, 0)).toInt(), 1);
- QCOMPARE(lmodel.data(lmodel.index(0, 1)).toString(), QString("harry"));
- QCOMPARE(lmodel.data(lmodel.index(0, 2)).toString(), QString("herr"));
- QCOMPARE(lmodel.data(lmodel.index(0, 3)), QVariant());
+ QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
+ QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
+ QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
+ QCOMPARE(model.data(model.index(0, 3)), QVariant());
- // try removing more than one column
- QVERIFY_SQL(lmodel, removeColumns(1, 2));
- QCOMPARE(lmodel.columnCount(), 1);
- QCOMPARE(lmodel.data(lmodel.index(0, 0)).toInt(), 1);
- QCOMPARE(lmodel.data(lmodel.index(0, 1)), QVariant());
+ // try removing more than one column
+ QVERIFY_SQL(model, removeColumns(1, 2));
+ QCOMPARE(model.columnCount(), 1);
+ QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
+ QCOMPARE(model.data(model.index(0, 1)), QVariant());
+ }
}
void tst_QSqlRelationalTableModel::filter()
@@ -736,6 +727,7 @@ void tst_QSqlRelationalTableModel::sort()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
QSqlRelationalTableModel model(0, db);
@@ -781,7 +773,7 @@ void tst_QSqlRelationalTableModel::sort()
QStringList stringsInDatabaseOrder;
// PostgreSQL puts the null ones (from the table with the original value) first in descending order
// which translate to empty strings in the related table
- if (dbType == QSqlDriver::PostgreSQL)
+ if (dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::MimerSQL)
stringsInDatabaseOrder << "" << "" << "mister" << "mister" << "herr" << "herr";
else
stringsInDatabaseOrder << "mister" << "mister" << "herr" << "herr" << "" << "";
@@ -794,7 +786,7 @@ void tst_QSqlRelationalTableModel::sort()
// PostgreSQL puts the null ones (from the table with the original value) first in descending order
// which translate to empty strings in the related table
stringsInDatabaseOrder.clear();
- if (dbType == QSqlDriver::PostgreSQL)
+ if (dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::MimerSQL)
stringsInDatabaseOrder << "herr" << "mister" << "mister" << "mister" << "mister" << "";
else if (dbType != QSqlDriver::Sybase)
stringsInDatabaseOrder << "" << "herr" << "mister" << "mister" << "mister" << "mister";
@@ -873,6 +865,7 @@ void tst_QSqlRelationalTableModel::revert()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
QSqlRelationalTableModel model(0, db);
@@ -910,6 +903,7 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
QSqlRelationalTableModel model(0, db);
@@ -964,6 +958,7 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
QSqlRelationalTableModel model(0, db);
@@ -975,13 +970,12 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames()
model.setRelation(2, QSqlRelation(reltest4, "id", "name"));
QVERIFY_SQL(model, select());
- if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) {
- QCOMPARE(model.record(1).value((reltest4+QLatin1String("_name_2")).toUpper()).toString(),
- QString("Trondheim"));
- } else {
- QCOMPARE(model.record(1).value((reltest4+QLatin1String("_name_2"))).toString(),
- QString("Trondheim"));
- }
+ QString reltest4Unescaped = qTableName("reltest4", __FILE__, db, false);
+ QString fieldName = reltest4Unescaped + QLatin1String("_name_2");
+ if (dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2)
+ fieldName = fieldName.toUpper();
+ fieldName.truncate(db.driver()->maximumIdentifierLength(QSqlDriver::TableName));
+ QCOMPARE(model.record(1).value(fieldName).toString(), QLatin1String("Trondheim"));
QSqlRecord rec = model.record();
rec.setValue(0, 3);
@@ -997,10 +991,7 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames()
}
// The duplicate field names is aliased because it's comes from the relation's display column.
- if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2)
- QCOMPARE(rec.fieldName(2), (reltest4+QLatin1String("_name_2")).toUpper());
- else
- QCOMPARE(rec.fieldName(2), reltest4+QLatin1String("_name_2"));
+ QCOMPARE(rec.fieldName(2), fieldName);
QVERIFY(model.insertRecord(-1, rec));
QCOMPARE(model.data(model.index(2, 2)).toString(), QString("Oslo"));
@@ -1013,6 +1004,7 @@ void tst_QSqlRelationalTableModel::invalidData()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
@@ -1043,6 +1035,7 @@ void tst_QSqlRelationalTableModel::relationModel()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
@@ -1086,60 +1079,64 @@ void tst_QSqlRelationalTableModel::casing()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::SQLite || dbType == QSqlDriver::MSSqlServer)
+ if (dbType == QSqlDriver::SQLite || dbType == QSqlDriver::MSSqlServer)
QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities");
QSqlQuery q(db);
- QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db).toUpper() +
+ const QString caseTestUpper = qTableName("CASETEST1", __FILE__, db).toUpper();
+ const QString caseTestLower = qTableName("casetest1", __FILE__, db);
+ tst_Databases::safeDropTables(db, {caseTestUpper, caseTestLower});
+ QVERIFY_SQL( q, exec("create table " + caseTestUpper +
" (id int not null primary key, name varchar(20), title_key int, another_title_key int)"));
- if (!q.exec("create table " + qTableName("casetest1", db) +
+ if (!q.exec("create table " + caseTestLower +
" (ident int not null primary key, name varchar(20), title_key int)"))
QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities");
- QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db).toUpper() + " values(1, 'harry', 1, 2)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db).toUpper() + " values(2, 'trond', 2, 1)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db).toUpper() + " values(3, 'vohi', 1, 2)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db).toUpper() + " values(4, 'boris', 2, 2)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db) + " values(1, 'jerry', 1)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db) + " values(2, 'george', 2)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db) + " values(4, 'kramer', 2)"));
+ QVERIFY_SQL( q, exec("insert into " + caseTestUpper + " values(1, 'harry', 1, 2)"));
+ QVERIFY_SQL( q, exec("insert into " + caseTestUpper + " values(2, 'trond', 2, 1)"));
+ QVERIFY_SQL( q, exec("insert into " + caseTestUpper + " values(3, 'vohi', 1, 2)"));
+ QVERIFY_SQL( q, exec("insert into " + caseTestUpper + " values(4, 'boris', 2, 2)"));
+ QVERIFY_SQL( q, exec("insert into " + caseTestLower + " values(1, 'jerry', 1)"));
+ QVERIFY_SQL( q, exec("insert into " + caseTestLower + " values(2, 'george', 2)"));
+ QVERIFY_SQL( q, exec("insert into " + caseTestLower + " values(4, 'kramer', 2)"));
if (dbType == QSqlDriver::Oracle) {
//try an owner that doesn't exist
- QSqlRecord rec = db.driver()->record("doug." + qTableName("CASETEST1", db).toUpper());
+ QSqlRecord rec = db.driver()->record("doug." + caseTestUpper);
QCOMPARE( rec.count(), 0);
//try an owner that does exist
- rec = db.driver()->record(db.userName() + QLatin1Char('.') + qTableName("CASETEST1", db).toUpper());
+ rec = db.driver()->record(db.userName() + QLatin1Char('.') + caseTestUpper);
QCOMPARE( rec.count(), 4);
}
- QSqlRecord rec = db.driver()->record(qTableName("CASETEST1", db).toUpper());
+ QSqlRecord rec = db.driver()->record(caseTestUpper);
QCOMPARE( rec.count(), 4);
- rec = db.driver()->record(qTableName("casetest1", db));
+ rec = db.driver()->record(caseTestLower);
QCOMPARE( rec.count(), 3);
QSqlTableModel upperCaseModel(0, db);
- upperCaseModel.setTable(qTableName("CASETEST1", db).toUpper());
+ upperCaseModel.setTable(caseTestUpper);
- QCOMPARE(upperCaseModel.tableName(), qTableName("CASETEST1", db).toUpper());
+ QCOMPARE(upperCaseModel.tableName(), caseTestUpper);
QVERIFY_SQL(upperCaseModel, select());
QCOMPARE(upperCaseModel.rowCount(), 4);
QSqlTableModel lowerCaseModel(0, db);
- lowerCaseModel.setTable(qTableName("casetest1", db));
- QCOMPARE(lowerCaseModel.tableName(), qTableName("casetest1", db));
+ lowerCaseModel.setTable(caseTestLower);
+ QCOMPARE(lowerCaseModel.tableName(), caseTestLower);
QVERIFY_SQL(lowerCaseModel, select());
QCOMPARE(lowerCaseModel.rowCount(), 3);
QSqlRelationalTableModel model(0, db);
- model.setTable(qTableName("CASETEST1", db).toUpper());
+ model.setTable(caseTestUpper);
model.setRelation(2, QSqlRelation(reltest2, "id", "title"));
QVERIFY_SQL(model, select());
@@ -1153,7 +1150,7 @@ void tst_QSqlRelationalTableModel::escapedRelations()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ fixupTableNamesForDb(db);
recreateTestTables(db);
@@ -1161,16 +1158,7 @@ void tst_QSqlRelationalTableModel::escapedRelations()
model.setTable(reltest1);
//try with relation table name quoted
- if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) {
- model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(reltest2.toUpper(),QSqlDriver::TableName),
- "id",
- "title"));
- } else {
- model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(reltest2,QSqlDriver::TableName),
- "id",
- "title"));
-
- }
+ model.setRelation(2, QSqlRelation(escapeTableName(db, reltest2), "id", "title"));
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
@@ -1185,16 +1173,8 @@ void tst_QSqlRelationalTableModel::escapedRelations()
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
//try with index column quoted
+ model.setRelation(2, QSqlRelation(reltest2, escapeFieldName(db, "id"), "title"));
model.setJoinMode(QSqlRelationalTableModel::InnerJoin);
- if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) {
- model.setRelation(2, QSqlRelation(reltest2,
- db.driver()->escapeIdentifier("id", QSqlDriver::FieldName).toUpper(),
- "title"));
- } else {
- model.setRelation(2, QSqlRelation(reltest2,
- db.driver()->escapeIdentifier("id", QSqlDriver::FieldName),
- "title"));
- }
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
@@ -1209,18 +1189,8 @@ void tst_QSqlRelationalTableModel::escapedRelations()
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
//try with display column quoted
+ model.setRelation(2, QSqlRelation(reltest2, "id", escapeFieldName(db, "title")));
model.setJoinMode(QSqlRelationalTableModel::InnerJoin);
- if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) {
-
- model.setRelation(2, QSqlRelation(reltest2,
- "id",
- db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper()));
- } else {
- model.setRelation(2, QSqlRelation(reltest2,
- "id",
- db.driver()->escapeIdentifier("title", QSqlDriver::FieldName)));
- }
-
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
@@ -1235,16 +1205,10 @@ void tst_QSqlRelationalTableModel::escapedRelations()
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
//try with tablename and index and display columns quoted in the relation
+ model.setRelation(2, QSqlRelation(escapeTableName(db, reltest2),
+ escapeFieldName(db, "id"),
+ escapeFieldName(db, "title")));
model.setJoinMode(QSqlRelationalTableModel::InnerJoin);
- if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) {
- model.setRelation(2, QSqlRelation(reltest2,
- "id",
- db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper()));
- } else {
- model.setRelation(2, QSqlRelation(reltest2,
- "id",
- db.driver()->escapeIdentifier("title", QSqlDriver::FieldName)));
- }
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
@@ -1264,17 +1228,13 @@ void tst_QSqlRelationalTableModel::escapedTableName()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ fixupTableNamesForDb(db);
// set the values using OnRowChange Strategy with an escaped tablename
{
QSqlRelationalTableModel model(0, db);
- if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) {
- model.setTable(db.driver()->escapeIdentifier(reltest1.toUpper(), QSqlDriver::TableName));
- } else {
- model.setTable(db.driver()->escapeIdentifier(reltest1, QSqlDriver::TableName));
- }
+ model.setTable(escapeTableName(db, reltest1));
model.setSort(0, Qt::AscendingOrder);
model.setRelation(2, QSqlRelation(reltest2, "id", "title"));
QVERIFY_SQL(model, select());
@@ -1317,11 +1277,7 @@ void tst_QSqlRelationalTableModel::escapedTableName()
{
QSqlRelationalTableModel model(0, db);
- if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) {
- model.setTable(db.driver()->escapeIdentifier(reltest1.toUpper(), QSqlDriver::TableName));
- } else {
- model.setTable(db.driver()->escapeIdentifier(reltest1, QSqlDriver::TableName));
- }
+ model.setTable(escapeTableName(db, reltest1));
model.setSort(0, Qt::AscendingOrder);
model.setRelation(2, QSqlRelation(reltest2, "id", "title"));
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
@@ -1368,9 +1324,8 @@ void tst_QSqlRelationalTableModel::whiteSpaceInIdentifiers()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
- if (!testWhiteSpaceNames(db.driverName()))
- QSKIP("White space test irrelevant for driver");
QSqlRelationalTableModel model(0, db);
model.setTable(qTableName("rel test6", __FILE__, db));
model.setSort(0, Qt::DescendingOrder);
@@ -1453,6 +1408,7 @@ void tst_QSqlRelationalTableModel::psqlSchemaTest()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType != QSqlDriver::PostgreSQL)
@@ -1480,6 +1436,7 @@ void tst_QSqlRelationalTableModel::selectAfterUpdate()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
@@ -1505,6 +1462,7 @@ void tst_QSqlRelationalTableModel::relationOnFirstColumn()
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ fixupTableNamesForDb(db);
QString testTable1 = qTableName("QTBUG_20038_test1", __FILE__, db);
QString testTable2 = qTableName("QTBUG_20038_test2", __FILE__, db);
@@ -1519,7 +1477,14 @@ void tst_QSqlRelationalTableModel::relationOnFirstColumn()
QVERIFY_SQL(q, exec("INSERT INTO " + testTable1 + " (id1, val1) VALUES(3, 30);"));
//prepare test2 table
- QVERIFY_SQL(q, exec("CREATE TABLE " + testTable2 + " (id INTEGER PRIMARY KEY, name TEXT);"));
+ if (tst_Databases::getDatabaseType(db) == QSqlDriver::MimerSQL) {
+ QVERIFY_SQL(q,
+ exec("CREATE TABLE " + testTable2
+ + " (id INTEGER PRIMARY KEY, name NVARCHAR(100));"));
+ } else {
+ QVERIFY_SQL(q,
+ exec("CREATE TABLE " + testTable2 + " (id INTEGER PRIMARY KEY, name VARCHAR(100));"));
+ }
QVERIFY_SQL(q, exec("DELETE FROM " + testTable2 + QLatin1Char(';')));
QVERIFY_SQL(q, exec("INSERT INTO " + testTable2 + " (id, name) VALUES (10, 'Hervanta');"));
QVERIFY_SQL(q, exec("INSERT INTO " + testTable2 + " (id, name) VALUES (20, 'Keskusta');"));
diff --git a/tests/auto/sql/models/qsqltablemodel/CMakeLists.txt b/tests/auto/sql/models/qsqltablemodel/CMakeLists.txt
index 4cbd667ec4..15cbe24ef7 100644
--- a/tests/auto/sql/models/qsqltablemodel/CMakeLists.txt
+++ b/tests/auto/sql/models/qsqltablemodel/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qsqltablemodel.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsqltablemodel Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsqltablemodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsqltablemodel
SOURCES
tst_qsqltablemodel.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Sql
Qt::SqlPrivate
diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
index ebddefb5fd..9c93fc2b18 100644
--- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.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>
@@ -116,6 +116,8 @@ private slots:
void submitAllOnInvalidTable();
void insertRecordsInLoop_data() { generic_data(); }
void insertRecordsInLoop();
+ void sqlite_escaped_delimiters_data() { generic_data("QSQLITE"); }
+ void sqlite_escaped_delimiters();
void sqlite_attachedDatabase_data() { generic_data("QSQLITE"); }
void sqlite_attachedDatabase(); // For task 130799
void tableModifyWithBlank_data() { generic_data(); }
@@ -148,25 +150,22 @@ tst_QSqlTableModel::~tst_QSqlTableModel()
void tst_QSqlTableModel::dropTestTables()
{
- for (int i = 0; i < dbs.dbNames.count(); ++i) {
+ for (int i = 0; i < dbs.dbNames.size(); ++i) {
QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i));
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
QSqlQuery q(db);
if (dbType == QSqlDriver::PostgreSQL)
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
- QStringList tableNames;
- tableNames << qTableName("test1", __FILE__, db)
- << qTableName("test2", __FILE__, db)
- << qTableName("test3", __FILE__, db)
- << qTableName("test4", __FILE__, db)
- << qTableName("emptytable", __FILE__, db)
- << qTableName("bigtable", __FILE__, db)
- << qTableName("foo", __FILE__, db)
- << qTableName("pktest", __FILE__, db);
- if (testWhiteSpaceNames(db.driverName()))
- tableNames << qTableName("qtestw hitespace", db);
-
+ QStringList tableNames{qTableName("test1", __FILE__, db),
+ qTableName("test2", __FILE__, db),
+ qTableName("test3", __FILE__, db),
+ qTableName("test4", __FILE__, db),
+ qTableName("emptytable", __FILE__, db),
+ qTableName("bigtable", __FILE__, db),
+ qTableName("foo", __FILE__, db),
+ qTableName("pktest", __FILE__, db),
+ qTableName("qtestw hitespace", __FILE__, db)};
tst_Databases::safeDropTables(db, tableNames);
if (db.driverName().startsWith("QPSQL")) {
@@ -177,7 +176,7 @@ void tst_QSqlTableModel::dropTestTables()
void tst_QSqlTableModel::createTestTables()
{
- for (int i = 0; i < dbs.dbNames.count(); ++i) {
+ for (int i = 0; i < dbs.dbNames.size(); ++i) {
QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i));
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
QSqlQuery q(db);
@@ -196,10 +195,8 @@ void tst_QSqlTableModel::createTestTables()
QVERIFY_SQL(q, exec("create table " + qTableName("emptytable", __FILE__, db) + "(id int)"));
- if (testWhiteSpaceNames(db.driverName())) {
- QString qry = "create table " + qTableName("qtestw hitespace", db) + " ("+ db.driver()->escapeIdentifier("a field", QSqlDriver::FieldName) + " int)";
- QVERIFY_SQL( q, exec(qry));
- }
+ const auto fieldStr = db.driver()->escapeIdentifier("a field", QSqlDriver::FieldName);
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtestw hitespace", __FILE__, db) + " ("+ fieldStr + " int)"));
QVERIFY_SQL(q, exec("create table " + qTableName("pktest", __FILE__, db) + "(id int not null primary key, a varchar(20))"));
}
@@ -207,7 +204,7 @@ void tst_QSqlTableModel::createTestTables()
void tst_QSqlTableModel::repopulateTestTables()
{
- for (int i = 0; i < dbs.dbNames.count(); ++i) {
+ for (int i = 0; i < dbs.dbNames.size(); ++i) {
QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i));
QSqlQuery q(db);
const auto test = qTableName("test1", __FILE__, db);
@@ -430,8 +427,7 @@ void tst_QSqlTableModel::insertColumns()
{
// Just like the select test, with extra stuff
QFETCH(QString, dbName);
- QFETCH(int, submitpolicy_i);
- QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
+ QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
const auto test = qTableName("test1", __FILE__, db);
@@ -581,13 +577,13 @@ void tst_QSqlTableModel::setRecord()
CHECK_DATABASE(db);
const auto test3 = qTableName("test3", __FILE__, db);
- QList<QSqlTableModel::EditStrategy> policies = QList<QSqlTableModel::EditStrategy>() << QSqlTableModel::OnFieldChange << QSqlTableModel::OnRowChange << QSqlTableModel::OnManualSubmit;
+ const auto policies = { QSqlTableModel::OnFieldChange, QSqlTableModel::OnRowChange, QSqlTableModel::OnManualSubmit };
QString Xsuffix;
- foreach( QSqlTableModel::EditStrategy submitpolicy, policies) {
+ for (QSqlTableModel::EditStrategy submitpolicy : policies) {
QSqlTableModel model(0, db);
- model.setEditStrategy((QSqlTableModel::EditStrategy)submitpolicy);
+ model.setEditStrategy(submitpolicy);
model.setTable(test3);
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
@@ -601,23 +597,23 @@ void tst_QSqlTableModel::setRecord()
QVERIFY(model.setRecord(i, rec));
// dataChanged() emitted by setData() for each *changed* column
- if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnManualSubmit) {
- QCOMPARE(spy.count(), 2);
- QCOMPARE(spy.at(0).count(), 2);
+ if (submitpolicy == QSqlTableModel::OnManualSubmit) {
+ QCOMPARE(spy.size(), 2);
+ QCOMPARE(spy.at(0).size(), 2);
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(0).at(0)), model.index(i, 1));
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(0).at(1)), model.index(i, 1));
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(1).at(0)), model.index(i, 2));
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(1).at(1)), model.index(i, 2));
QVERIFY(model.submitAll());
- } else if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnRowChange && i == model.rowCount() -1)
+ } else if (submitpolicy == QSqlTableModel::OnRowChange && i == model.rowCount() -1)
model.submit();
else {
- if ((QSqlTableModel::EditStrategy)submitpolicy != QSqlTableModel::OnManualSubmit)
+ if (submitpolicy != QSqlTableModel::OnManualSubmit)
// dataChanged() also emitted by selectRow()
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
else
- QCOMPARE(spy.count(), 2);
- QCOMPARE(spy.at(0).count(), 2);
+ QCOMPARE(spy.size(), 2);
+ QCOMPARE(spy.at(0).size(), 2);
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(0).at(0)), model.index(i, 1));
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(0).at(1)), model.index(i, 1));
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(1).at(0)), model.index(i, 2));
@@ -714,8 +710,7 @@ void tst_QSqlTableModel::recordReimpl()
void tst_QSqlTableModel::insertRow()
{
QFETCH(QString, dbName);
- QFETCH(int, submitpolicy_i);
- QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
+ QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
const auto test = qTableName("test1", __FILE__, db);
@@ -824,8 +819,7 @@ void tst_QSqlTableModel::insertRowFailure()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
- QFETCH(int, submitpolicy_i);
- QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
+ QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
CHECK_DATABASE(db);
QSqlTableModel model(0, db);
@@ -974,8 +968,7 @@ void tst_QSqlTableModel::insertMultiRecords()
void tst_QSqlTableModel::insertWithAutoColumn()
{
QFETCH(QString, dbName);
- QFETCH(int, submitpolicy_i);
- QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
+ QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
@@ -1092,7 +1085,7 @@ void tst_QSqlTableModel::removeRow()
QSignalSpy headerDataChangedSpy(&model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)));
QVERIFY(model.removeRow(1));
- QCOMPARE(headerDataChangedSpy.count(), 1);
+ QCOMPARE(headerDataChangedSpy.size(), 1);
QCOMPARE(*static_cast<const Qt::Orientation *>(headerDataChangedSpy.at(0).value(0).constData()), Qt::Vertical);
QCOMPARE(headerDataChangedSpy.at(0).at(1).toInt(), 1);
QCOMPARE(headerDataChangedSpy.at(0).at(2).toInt(), 1);
@@ -1112,7 +1105,7 @@ void tst_QSqlTableModel::removeRow()
headerDataChangedSpy.clear();
QVERIFY(model.removeRow(1));
- QCOMPARE(headerDataChangedSpy.count(), 1);
+ QCOMPARE(headerDataChangedSpy.size(), 1);
QCOMPARE(model.rowCount(), 3);
QVERIFY_SQL(model, select());
@@ -1148,7 +1141,7 @@ void tst_QSqlTableModel::removeRows()
QVERIFY_SQL(model, removeRows(0, 1));
QVERIFY_SQL(model, removeRows(1, 1));
- QCOMPARE(beforeDeleteSpy.count(), 2);
+ QCOMPARE(beforeDeleteSpy.size(), 2);
QCOMPARE(beforeDeleteSpy.at(0).at(0).toInt(), 0);
QCOMPARE(beforeDeleteSpy.at(1).at(0).toInt(), 1);
// deleted rows shown as empty until select
@@ -1179,15 +1172,15 @@ void tst_QSqlTableModel::removeRows()
qRegisterMetaType<Qt::Orientation>("Qt::Orientation");
QSignalSpy headerDataChangedSpy(&model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)));
QVERIFY(model.removeRows(0, 2, QModelIndex()));
- QCOMPARE(headerDataChangedSpy.count(), 2);
+ QCOMPARE(headerDataChangedSpy.size(), 2);
QCOMPARE(headerDataChangedSpy.at(0).at(1).toInt(), 1);
QCOMPARE(headerDataChangedSpy.at(0).at(2).toInt(), 1);
QCOMPARE(headerDataChangedSpy.at(1).at(1).toInt(), 0);
QCOMPARE(headerDataChangedSpy.at(1).at(2).toInt(), 0);
QCOMPARE(model.rowCount(), 3);
- QCOMPARE(beforeDeleteSpy.count(), 0);
+ QCOMPARE(beforeDeleteSpy.size(), 0);
QVERIFY(model.submitAll());
- QCOMPARE(beforeDeleteSpy.count(), 2);
+ QCOMPARE(beforeDeleteSpy.size(), 2);
QCOMPARE(beforeDeleteSpy.at(0).at(0).toInt(), 0);
QCOMPARE(beforeDeleteSpy.at(1).at(0).toInt(), 1);
QCOMPARE(model.rowCount(), 1);
@@ -1197,8 +1190,7 @@ void tst_QSqlTableModel::removeRows()
void tst_QSqlTableModel::removeInsertedRow()
{
QFETCH(QString, dbName);
- QFETCH(int, submitpolicy_i);
- QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
+ QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
const auto test = qTableName("test1", __FILE__, db);
@@ -1382,8 +1374,7 @@ void tst_QSqlTableModel::removeInsertedRows()
void tst_QSqlTableModel::revert()
{
QFETCH(QString, dbName);
- QFETCH(int, submitpolicy_i);
- QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
+ QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
@@ -1459,8 +1450,7 @@ void tst_QSqlTableModel::revert()
void tst_QSqlTableModel::isDirty()
{
QFETCH(QString, dbName);
- QFETCH(int, submitpolicy_i);
- QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
+ QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
const auto test = qTableName("test1", __FILE__, db);
@@ -1665,11 +1655,11 @@ void tst_QSqlTableModel::emptyTable()
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"));
+ QCOMPARE(model.headerData(0, Qt::Horizontal).toString().toLower(), QString("id"));
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
model.insertRow(0);
QCOMPARE(model.rowCount(), 1);
- QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("id"));
+ QCOMPARE(model.headerData(0, Qt::Horizontal).toString().toLower(), QString("id"));
model.revertAll();
}
@@ -1700,10 +1690,7 @@ void tst_QSqlTableModel::whitespaceInIdentifiers()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- if (!testWhiteSpaceNames(db.driverName()))
- QSKIP("DBMS doesn't support whitespaces in identifiers");
-
- QString tableName = qTableName("qtestw hitespace", db);
+ QString tableName = qTableName("qtestw hitespace", __FILE__, db);
QSqlTableModel model(0, db);
model.setTable(tableName);
@@ -1784,8 +1771,8 @@ void tst_QSqlTableModel::setFilter()
model.setFilter("id = 2");
// check the signals
- QCOMPARE(modelAboutToBeResetSpy.count(), 1);
- QCOMPARE(modelResetSpy.count(), 1);
+ QCOMPARE(modelAboutToBeResetSpy.size(), 1);
+ QCOMPARE(modelResetSpy.size(), 1);
QCOMPARE(model.rowCount(), 1);
QCOMPARE(model.data(model.index(0, 0)).toInt(), 2);
@@ -1928,13 +1915,82 @@ void tst_QSqlTableModel::insertRecordsInLoop()
model.submitAll(); // submitAll() calls select() which clears and repopulates the table
// model emits reset signals
- QCOMPARE(modelAboutToBeResetSpy.count(), 1);
- QCOMPARE(modelResetSpy.count(), 1);
+ QCOMPARE(modelAboutToBeResetSpy.size(), 1);
+ QCOMPARE(modelResetSpy.size(), 1);
QCOMPARE(model.rowCount(), 13);
QCOMPARE(model.columnCount(), 3);
}
+void tst_QSqlTableModel::sqlite_escaped_delimiters()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ if (db.databaseName() == ":memory:")
+ QSKIP(":memory: database, skipping test");
+
+ auto attachedDb = QSqlDatabase::cloneDatabase(db, db.driverName() + QLatin1String("attached"));
+ attachedDb.setDatabaseName(db.databaseName() + QLatin1String("attached.dat"));
+ QVERIFY_SQL(attachedDb, open());
+ QSqlQuery q(attachedDb);
+ TableScope tsAttached(attachedDb, "attachedTestTable", __FILE__);
+ QVERIFY_SQL(q,
+ exec("CREATE TABLE attachedTestTable("
+ "id int, \"attachedCol [unit]\" varchar(20))"));
+ QVERIFY_SQL(q,
+ exec("INSERT INTO attachedTestTable VALUES("
+ "1, 'attachTestData')"));
+
+ QSqlQuery q2(db);
+ TableScope ts(db, "testTable", __FILE__);
+ QVERIFY_SQL(q2, exec("CREATE TABLE testTable(id int, \"col [unit]\" varchar(20))"));
+ QVERIFY_SQL(q2, exec("INSERT INTO testTable VALUES(2, 'testData')"));
+ QVERIFY_SQL(q2, exec("ATTACH DATABASE \"" + attachedDb.databaseName() + "\" AS attachedDb"));
+
+ const std::array<std::pair<QLatin1Char, QLatin1Char>, 3> escapingPairs{
+ std::make_pair(QLatin1Char{'"'}, QLatin1Char{'"'}),
+ std::make_pair(QLatin1Char{'`'}, QLatin1Char{'`'}),
+ std::make_pair(QLatin1Char{'['}, QLatin1Char{']'})
+ };
+
+ QSqlTableModel model(nullptr, db);
+ model.setTable("testTable");
+ QVERIFY_SQL(model, select());
+ for (const auto &escapingPair : escapingPairs) {
+ model.setTable(escapingPair.first + "testTable" + escapingPair.second);
+ QVERIFY_SQL(model, select());
+ }
+
+ model.setTable("attachedDb.attachedTestTable");
+ QFAIL_SQL(model, select());
+ for (const auto &escapingPair : escapingPairs) {
+ model.setTable(escapingPair.first + "attachedDb.attachedTestTable" + escapingPair.second);
+ QFAIL_SQL(model, select());
+ model.setTable(escapingPair.first + "attachedDb" + escapingPair.first + ".a"
+ + escapingPair.second + "ttachedTestTable" + escapingPair.second);
+ QFAIL_SQL(model, select());
+ }
+
+ for (std::size_t i = 0; i <= escapingPairs.size(); ++i) {
+ for (std::size_t j = 0; j <= escapingPairs.size(); ++j) {
+ if (i == escapingPairs.size() && j == escapingPairs.size())
+ continue;
+
+ QString leftName = "attachedDb";
+ if (i != escapingPairs.size())
+ leftName = escapingPairs.at(i).first + leftName + escapingPairs.at(i).second;
+ QString rightName = "attachedTestTable";
+ if (j != escapingPairs.size())
+ rightName = escapingPairs.at(j).first + rightName + escapingPairs.at(j).second;
+ model.setTable(leftName + "." + rightName);
+ QVERIFY_SQL(model, select());
+ }
+ }
+
+ attachedDb.close();
+}
+
void tst_QSqlTableModel::sqlite_attachedDatabase()
{
QFETCH(QString, dbName);
@@ -1947,21 +2003,23 @@ void tst_QSqlTableModel::sqlite_attachedDatabase()
attachedDb.setDatabaseName(db.databaseName()+QLatin1String("attached.dat"));
QVERIFY_SQL(attachedDb, open());
QSqlQuery q(attachedDb);
- tst_Databases::safeDropTables(attachedDb, QStringList() << "atest" << "atest2");
+ TableScope ts(db, "atest", __FILE__);
+ TableScope tsAttached(attachedDb, "atest", __FILE__);
+ TableScope tsAttached2(attachedDb, "atest2", __FILE__);
+
QVERIFY_SQL( q, exec("CREATE TABLE atest(id int, text varchar(20))"));
QVERIFY_SQL( q, exec("CREATE TABLE atest2(id int, text varchar(20))"));
QVERIFY_SQL( q, exec("INSERT INTO atest VALUES(1, 'attached-atest')"));
QVERIFY_SQL( q, exec("INSERT INTO atest2 VALUES(2, 'attached-atest2')"));
QSqlQuery q2(db);
- tst_Databases::safeDropTable(db, "atest");
QVERIFY_SQL(q2, exec("CREATE TABLE atest(id int, text varchar(20))"));
QVERIFY_SQL(q2, exec("INSERT INTO atest VALUES(3, 'main')"));
QVERIFY_SQL(q2, exec("ATTACH DATABASE \""+attachedDb.databaseName()+"\" as adb"));
// This should query the table in the attached database (schema supplied)
QSqlTableModel model(0, db);
- model.setTable("adb.atest");
+ model.setTable("\"adb\".\"atest\"");
QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 1);
QCOMPARE(model.data(model.index(0, 0), Qt::DisplayRole).toInt(), 1);
@@ -2145,29 +2203,27 @@ void tst_QSqlTableModel::sqlite_selectFromIdentifierWithDot()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
+ TableScope fieldDot(db, "fieldDot", __FILE__);
+ TableScope tableDot(db, u'[' + qTableName("table.dot", __FILE__, db) + u']');
CHECK_DATABASE(db);
{
- const auto fieldDot = qTableName("fieldDot", __FILE__, db);
- tst_Databases::safeDropTable(db, fieldDot);
QSqlQuery qry(db);
- QVERIFY_SQL(qry, exec("create table " + fieldDot + " (id int primary key, "
+ QVERIFY_SQL(qry, exec("create table " + fieldDot.tableName() + " (id int primary key, "
"\"person.firstname\" varchar(20))"));
- QVERIFY_SQL(qry, exec("insert into " + fieldDot + " values(1, 'Andy')"));
+ QVERIFY_SQL(qry, exec("insert into " + fieldDot.tableName() + " values(1, 'Andy')"));
QSqlTableModel model(0, db);
- model.setTable(fieldDot);
+ model.setTable(fieldDot.tableName());
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Andy"));
}
- const auto tableDot = QLatin1Char('[') + qTableName("table.dot", __FILE__, db) + QLatin1Char(']');
{
- tst_Databases::safeDropTable(db, tableDot);
QSqlQuery qry(db);
- QVERIFY_SQL(qry, exec("create table " + tableDot + " (id int primary key, "
+ QVERIFY_SQL(qry, exec("create table " + tableDot.tableName() + " (id int primary key, "
"\"person.firstname\" varchar(20))"));
- QVERIFY_SQL(qry, exec("insert into " + tableDot + " values(1, 'Andy')"));
+ QVERIFY_SQL(qry, exec("insert into " + tableDot.tableName() + " values(1, 'Andy')"));
QSqlTableModel model(0, db);
- model.setTable(tableDot);
+ model.setTable(tableDot.tableName());
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Andy"));
@@ -2179,7 +2235,7 @@ void tst_QSqlTableModel::sqlite_selectFromIdentifierWithDot()
QSqlQuery qry(attachedDb);
QVERIFY_SQL(qry, exec(QString("attach '%1' AS 'attached'").arg(db.databaseName())));
QSqlTableModel model(0, attachedDb);
- model.setTable(QString("attached.%1").arg(tableDot));
+ model.setTable(QString("attached.%1").arg(tableDot.tableName()));
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Andy"));