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.cpp57
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_databases.h450
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp629
-rw-r--r--tests/auto/sql/kernel/qsqldriver/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp97
-rw-r--r--tests/auto/sql/kernel/qsqlerror/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp39
-rw-r--r--tests/auto/sql/kernel/qsqlfield/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlfield/tst_qsqlfield.cpp49
-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.cpp5246
-rw-r--r--tests/auto/sql/kernel/qsqlrecord/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp118
-rw-r--r--tests/auto/sql/kernel/qsqlresult/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlresult/testsqldriver.h29
-rw-r--r--tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp63
-rw-r--r--tests/auto/sql/kernel/qsqlthread/CMakeLists.txt11
-rw-r--r--tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp45
-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.cpp91
-rw-r--r--tests/auto/sql/models/qsqlrelationaldelegate/CMakeLists.txt11
-rw-r--r--tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp46
-rw-r--r--tests/auto/sql/models/qsqlrelationaltablemodel/CMakeLists.txt11
-rw-r--r--tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp374
-rw-r--r--tests/auto/sql/models/qsqltablemodel/CMakeLists.txt11
-rw-r--r--tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp310
36 files changed, 4144 insertions, 3924 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 a8eca14f49..7b6e260ebf 100644
--- a/tests/auto/sql/kernel/qsql/tst_qsql.cpp
+++ b/tests/auto/sql/kernel/qsql/tst_qsql.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -44,11 +19,6 @@ class tst_QSql : public QObject
{
Q_OBJECT
-public:
- tst_QSql();
- virtual ~tst_QSql();
-
-
public slots:
void initTestCase();
void cleanupTestCase();
@@ -66,15 +36,6 @@ private slots:
};
/****************** General Qt SQL Module tests *****************/
-
-tst_QSql::tst_QSql()
-{
-}
-
-tst_QSql::~tst_QSql()
-{
-}
-
void tst_QSql::initTestCase()
{
}
@@ -105,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());
@@ -150,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());
@@ -175,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))
@@ -207,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 74fa06ab29..f81fe5548b 100644
--- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
+++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
/* possible connection parameters */
#ifndef TST_DATABASES_H
@@ -34,6 +9,7 @@
#include <QSqlDriver>
#include <QSqlError>
#include <QSqlQuery>
+#include <QSqlRecord>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QDir>
@@ -44,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" ); }
@@ -56,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();
@@ -145,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()
@@ -256,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(),
@@ -269,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;
@@ -287,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;
}
@@ -308,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);
@@ -366,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;
@@ -375,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
@@ -414,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)
@@ -450,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)
@@ -477,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 );
@@ -532,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()
@@ -571,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 0ef4caeafa..19afacf6f9 100644
--- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
+++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -53,8 +28,7 @@ class tst_QSqlDatabase : public QObject
Q_OBJECT
public:
- tst_QSqlDatabase();
- virtual ~tst_QSqlDatabase();
+ using QObject::QObject;
public slots:
void initTestCase();
@@ -75,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();
@@ -87,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"); }
@@ -134,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();
@@ -162,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
@@ -207,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;
};
@@ -235,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);
@@ -248,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;
@@ -283,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;
@@ -325,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;
@@ -346,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) {
@@ -378,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) {
@@ -393,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;
@@ -465,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);
@@ -534,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())));
@@ -587,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()
@@ -622,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;
@@ -636,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
@@ -675,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(
@@ -695,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);
@@ -713,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;
@@ -896,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),
@@ -1193,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);
@@ -1238,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);
@@ -1267,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);
}
@@ -1400,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;
@@ -1431,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());
@@ -1445,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();
@@ -1458,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");
@@ -1561,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());
@@ -1577,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()));
@@ -1600,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"));
@@ -1624,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));
@@ -1644,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);
@@ -1662,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)));
@@ -1735,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)));
@@ -1767,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()
@@ -1781,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)"
@@ -1797,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());
@@ -1812,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()
@@ -1870,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());
@@ -1885,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);
@@ -1899,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);
@@ -1929,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);
}
@@ -1954,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);
@@ -2004,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);
@@ -2083,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());
@@ -2099,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);
}
@@ -2125,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);
}
@@ -2195,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);
@@ -2234,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);
@@ -2248,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()
@@ -2275,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
@@ -2391,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());
@@ -2441,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);
@@ -2459,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());
@@ -2500,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());
@@ -2529,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 70e5b43845..fb8d804843 100644
--- a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
+++ b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -60,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;
@@ -77,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();
}
@@ -136,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";
@@ -150,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();
@@ -170,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)
@@ -180,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);
@@ -194,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);
@@ -230,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 ab7489a145..2be7d08cf8 100644
--- a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp
+++ b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -133,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 09e33cebee..5e012ba39c 100644
--- a/tests/auto/sql/kernel/qsqlfield/tst_qsqlfield.cpp
+++ b/tests/auto/sql/kernel/qsqlfield/tst_qsqlfield.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -64,6 +39,7 @@ private slots:
void clear();
void setTableName_data();
void setTableName();
+ void moveSemantics();
};
// Testing get/set functions
@@ -369,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 ad7baeb9a9..56fb5cd05f 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -1,38 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 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_QSqlQuery : public QObject
@@ -41,12 +21,10 @@ class tst_QSqlQuery : public QObject
public:
tst_QSqlQuery();
- virtual ~tst_QSqlQuery();
public slots:
void initTestCase();
void cleanupTestCase();
- void init();
void cleanup();
private slots:
@@ -64,6 +42,8 @@ private slots:
void size();
void isNull_data() { generic_data(); }
void isNull();
+ void writeNull_data() { generic_data(); }
+ void writeNull();
void query_exec_data() { generic_data(); }
void query_exec();
void execErrorRecovery_data() { generic_data(); }
@@ -78,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"); }
@@ -99,9 +77,10 @@ private slots:
void psql_forwardOnlyQueryResultsLost_data() { generic_data("QPSQL"); }
void psql_forwardOnlyQueryResultsLost();
- // bug specific tests
- void tds_bitField_data() { generic_data("QTDS"); }
- void tds_bitField();
+ void positionalBindingEnabled_data() { generic_data(); }
+ void positionalBindingEnabled();
+
+ // Bug-specific tests:
void oci_nullBlob_data() { generic_data("QOCI"); }
void oci_nullBlob();
void blob_data() { generic_data(); }
@@ -194,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();
@@ -225,9 +204,9 @@ private slots:
void QTBUG_21884_data() { generic_data("QSQLITE"); }
void QTBUG_21884();
void QTBUG_16967_data() { generic_data("QSQLITE"); }
- void QTBUG_16967(); //clean close
+ void QTBUG_16967(); // clean close
void QTBUG_23895_data() { generic_data("QSQLITE"); }
- void QTBUG_23895(); //sqlite boolean type
+ void QTBUG_23895(); // sqlite boolean type
void QTBUG_14904_data() { generic_data("QSQLITE"); }
void QTBUG_14904();
@@ -249,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();
@@ -261,18 +243,33 @@ 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(); }
+ void prematureExec();
private:
// returns all database connections
void generic_data(const QString &engine=QString());
- void dropTestTables( QSqlDatabase db );
- void createTestTables( QSqlDatabase db );
- void populateTestTables( QSqlDatabase db );
+ void dropTestTables(QSqlDatabase db);
+ void createTestTables(QSqlDatabase db);
+ void populateTestTables(QSqlDatabase db);
tst_Databases dbs;
};
@@ -283,368 +280,329 @@ tst_QSqlQuery::tst_QSqlQuery()
qtest = qTableName("qtest", __FILE__, static_qtest_db);
}
-tst_QSqlQuery::~tst_QSqlQuery()
-{
-}
-
void tst_QSqlQuery::initTestCase()
{
QVERIFY(dbs.open());
- for ( QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it ) {
- QSqlDatabase db = QSqlDatabase::database(( *it ) );
- CHECK_DATABASE( db );
- dropTestTables( db ); //in case of leftovers
- createTestTables( db );
- populateTestTables( db );
+ for (const QString &name : std::as_const(dbs.dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(name);
+ CHECK_DATABASE(db);
+ dropTestTables(db); // in case of leftovers
+ createTestTables(db);
+ populateTestTables(db);
}
}
void tst_QSqlQuery::cleanupTestCase()
{
- for ( QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it ) {
- QSqlDatabase db = QSqlDatabase::database(( *it ) );
- CHECK_DATABASE( db );
- dropTestTables( db );
+ for (const QString &name : std::as_const(dbs.dbNames)) {
+ QSqlDatabase db = QSqlDatabase::database(name);
+ CHECK_DATABASE(db);
+ dropTestTables(db);
}
dbs.close();
}
-void tst_QSqlQuery::init()
-{
-}
-
void tst_QSqlQuery::cleanup()
{
if (QTest::currentTestFunction() == QLatin1String("crashQueryOnCloseDatabase"))
return;
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if ( QTest::currentTestFunction() == QLatin1String( "numRowsAffected" )
- || QTest::currentTestFunction() == QLatin1String( "transactions" )
- || QTest::currentTestFunction() == QLatin1String( "size" )
- || QTest::currentTestFunction() == QLatin1String( "isActive" )
- || QTest::currentTestFunction() == QLatin1String( "lastInsertId" ) ) {
- populateTestTables( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ if (QTest::currentTestFunction() == QLatin1String("numRowsAffected")
+ || QTest::currentTestFunction() == QLatin1String("transactions")
+ || QTest::currentTestFunction() == QLatin1String("size")
+ || QTest::currentTestFunction() == QLatin1String("isActive")
+ || QTest::currentTestFunction() == QLatin1String("lastInsertId")) {
+ populateTestTables(db);
}
- if (QTest::currentTestFailed() && (dbType == QSqlDriver::Oracle || db.driverName().startsWith("QODBC"))) {
- //since Oracle ODBC totally craps out on error, we init again
+ if (QTest::currentTestFailed() && (tst_Databases::getDatabaseType(db) == QSqlDriver::Oracle
+ || db.driverName().startsWith("QODBC"))) {
+ // Since Oracle ODBC totally craps out on error, we init again:
db.close();
db.open();
}
}
-void tst_QSqlQuery::generic_data(const QString& engine)
+void tst_QSqlQuery::generic_data(const QString &engine)
{
- if ( dbs.fillTestTable(engine) == 0 ) {
- if(engine.isEmpty())
- QSKIP( "No database drivers are available in this Qt configuration");
- else
- QSKIP( (QString("No database drivers of type %1 are available in this Qt configuration").arg(engine)).toLocal8Bit());
- }
+ if (dbs.fillTestTable(engine))
+ return;
+
+ if (engine.isEmpty())
+ QSKIP("No database drivers are available in this Qt configuration");
+
+ QSKIP(qPrintable(QLatin1String("No database drivers of type %1 "
+ "are available in this Qt configuration").arg(engine)));
}
-void tst_QSqlQuery::dropTestTables( QSqlDatabase db )
+void tst_QSqlQuery::dropTestTables(QSqlDatabase db)
{
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
QStringList tablenames;
- // drop all the table in case a testcase failed
+ // Drop all the table in case a testcase failed:
tablenames << qtest
<< qTableName("qtest_null", __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 );
+ tst_Databases::safeDropTables(db, tablenames);
if (dbType == QSqlDriver::Oracle) {
- QSqlQuery q( db );
+ QSqlQuery q(db);
q.exec("DROP PACKAGE " + qTableName("pkg", __FILE__, db));
}
}
-void tst_QSqlQuery::createTestTables( QSqlDatabase db )
+void tst_QSqlQuery::createTestTables(QSqlDatabase db)
{
- QSqlQuery q( db );
+ QSqlQuery q(db);
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::MySqlServer)
// ### stupid workaround until we find a way to hardcode this
// in the MySQL server startup script
- q.exec( "set table_type=innodb" );
+ q.exec("set table_type=innodb");
else if (dbType == QSqlDriver::PostgreSQL)
- QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
+ QVERIFY_SQL(q, exec("set client_min_messages='warning'"));
- if (dbType == QSqlDriver::PostgreSQL)
- QVERIFY_SQL( q, exec( "create table " + qtest + " (id serial NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id)) WITH OIDS" ) );
- else
- QVERIFY_SQL( q, exec( "create table " + qtest + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) );
+ 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))").arg(qtest)));
+ } else {
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create table %1 (id int %2 NOT NULL, t_varchar varchar(20), "
+ "t_char char(20), primary key(id))")
+ .arg(qtest, tst_Databases::autoFieldName(db))));
+ }
- if (dbType == QSqlDriver::MSSqlServer || dbType == QSqlDriver::Sybase)
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest_null", __FILE__, db) + " (id int null, t_varchar varchar(20) null)"));
- else
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest_null", __FILE__, db) + " (id int, t_varchar varchar(20))"));
+ QLatin1String creator(dbType == QSqlDriver::MSSqlServer || dbType == QSqlDriver::Sybase
+ ? "create table %1 (id int null, t_varchar varchar(20) null)"
+ : "create table %1 (id int, t_varchar varchar(20))");
+ QVERIFY_SQL(q, exec(creator.arg(qTableName("qtest_null", __FILE__, db))));
}
-void tst_QSqlQuery::populateTestTables( QSqlDatabase db )
+void tst_QSqlQuery::populateTestTables(QSqlDatabase db)
{
- QSqlQuery q( db );
- const QString qtest_null(qTableName( "qtest_null", __FILE__, db));
- q.exec( "delete from " + qtest );
- QVERIFY_SQL( q, exec( "insert into " + qtest + " values (1, 'VarChar1', 'Char1')" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest + " values (2, 'VarChar2', 'Char2')" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest + " values (3, 'VarChar3', 'Char3')" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest + " values (4, 'VarChar4', 'Char4')" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest + " values (5, 'VarChar5', 'Char5')" ) );
-
- q.exec( "delete from " + qtest_null );
- QVERIFY_SQL( q, exec( "insert into " + qtest_null + " values (0, NULL)" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest_null + " values (1, 'n')" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest_null + " values (2, 'i')" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest_null + " values (3, NULL)" ) );
+ QSqlQuery q(db);
+ const QString qtest_null(qTableName("qtest_null", __FILE__, db));
+ q.exec("delete from " + qtest);
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, 'VarChar1', 'Char1')")
+ .arg(qtest)));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (2, 'VarChar2', 'Char2')")
+ .arg(qtest)));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (3, 'VarChar3', 'Char3')")
+ .arg(qtest)));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (4, 'VarChar4', 'Char4')")
+ .arg(qtest)));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (5, 'VarChar5', 'Char5')")
+ .arg(qtest)));
+
+ q.exec("delete from " + qtest_null);
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (0, NULL)").arg(qtest_null)));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (1, 'n')").arg(qtest_null)));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (2, 'i')").arg(qtest_null)));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (3, NULL)").arg(qtest_null)));
}
// There were problems with char fields of size 1
void tst_QSqlQuery::char1Select()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
{
- QSqlQuery q( db );
- const QString tbl = qTableName("char1Select", __FILE__, db);
- q.exec( "drop table " + tbl);
- QVERIFY_SQL(q, exec("create table " + tbl + " (id char(1))"));
- QVERIFY_SQL(q, exec("insert into " + tbl + " values ('a')"));
- QVERIFY_SQL(q, exec("select * from " + tbl));
- QVERIFY( q.next() );
- QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType == QSqlDriver::Interbase)
- QCOMPARE( q.value( 0 ).toString().left( 1 ), QString( "a" ) );
+ TableScope ts(db, "char1Select", __FILE__);
+ QSqlQuery q(db);
+ 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");
else
- QCOMPARE( q.value( 0 ).toString(), QString( "a" ) );
+ QCOMPARE(q.value(0).toString(), u"a");
- QVERIFY( !q.next() );
+ QVERIFY(!q.next());
}
}
void tst_QSqlQuery::char1SelectUnicode()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::DB2)
QSKIP("Needs someone with more Unicode knowledge than I have to fix");
- if ( db.driver()->hasFeature( QSqlDriver::Unicode ) ) {
- QString uniStr( QChar(0x0915) ); // DEVANAGARI LETTER KA
- QSqlQuery q( db );
- QString createQuery;
- const QString char1SelectUnicode(qTableName("char1SU", __FILE__, db));
-
- if (dbType == QSqlDriver::MSSqlServer)
- createQuery = "create table " + char1SelectUnicode + "(id nchar(1))";
- else if (dbType == QSqlDriver::DB2 || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::PostgreSQL)
- createQuery = "create table " + char1SelectUnicode + " (id char(3))";
- else if (dbType == QSqlDriver::Interbase)
- createQuery = "create table " + char1SelectUnicode +
- " (id char(1) character set unicode_fss)";
- else if (dbType == QSqlDriver::MySqlServer)
- createQuery = "create table " + char1SelectUnicode + " (id char(1)) "
- "default character set 'utf8'";
- else
- createQuery = "create table " + char1SelectUnicode + " (id char(1))";
-
- QVERIFY_SQL( q, exec( createQuery ) );
-
- QVERIFY_SQL( q, prepare( "insert into " + char1SelectUnicode + " values(?)" ) );
-
- q.bindValue( 0, uniStr );
+ if (!db.driver()->hasFeature(QSqlDriver::Unicode))
+ QSKIP("Database not unicode capable");
- QVERIFY_SQL( q, exec() );
-
- QVERIFY_SQL( q, exec( "select * from " + char1SelectUnicode ) );
+ QString uniStr(QChar(0x0915)); // DEVANAGARI LETTER KA
+ TableScope ts(db, "char1SU", __FILE__);
+ QSqlQuery q(db);
+ QLatin1String createQuery;
+
+ switch (dbType) {
+ case QSqlDriver::MimerSQL:
+ case QSqlDriver::MSSqlServer:
+ createQuery = QLatin1String("create table %1(id nchar(1))");
+ break;
+ case QSqlDriver::DB2:
+ case QSqlDriver::Oracle:
+ case QSqlDriver::PostgreSQL:
+ createQuery = QLatin1String("create table %1 (id char(3))");
+ break;
+ case QSqlDriver::Interbase:
+ createQuery = QLatin1String("create table %1 (id char(1) character set unicode_fss)");
+ break;
+ case QSqlDriver::MySqlServer:
+ createQuery = QLatin1String("create table %1 (id char(1)) default character set 'utf8'");
+ break;
+ default:
+ createQuery = QLatin1String("create table %1 (id char(1))");
+ break;
+ }
- QVERIFY( q.next() );
+ QVERIFY_SQL(q, exec(createQuery.arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 values(?)").arg(ts.tableName())));
- if ( !q.value( 0 ).toString().isEmpty() )
- QCOMPARE( q.value( 0 ).toString()[ 0 ].unicode(), uniStr[0].unicode() );
+ q.bindValue(0, uniStr);
+ QVERIFY_SQL(q, exec());
+ QVERIFY_SQL(q, exec("select * from " + ts.tableName()));
- QCOMPARE( q.value( 0 ).toString().trimmed(), uniStr );
+ QVERIFY(q.next());
+ if (!q.value(0).toString().isEmpty())
+ QCOMPARE(q.value(0).toString()[0].unicode(), uniStr[0].unicode());
- QVERIFY( !q.next() );
- }
- else
- QSKIP( "Database not unicode capable");
+ QCOMPARE(q.value(0).toString().trimmed(), uniStr);
+ QVERIFY(!q.next());
}
void tst_QSqlQuery::oraRowId()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- const QString oraRowId(qTableName("oraRowId", __FILE__, db));
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "oraRowId", __FILE__);
+ const auto &oraRowId = ts.tableName();
- QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "select rowid from " + qtest ) );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).metaType().id(), QMetaType::QString );
- QVERIFY( !q.value( 0 ).toString().isEmpty() );
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec("select rowid from " + qtest));
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).metaType().id(), QMetaType::QString);
+ QVERIFY(!q.value(0).toString().isEmpty());
- QVERIFY_SQL( q, exec( "create table " + oraRowId + " (id char(1))" ) );
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id char(1))").arg(oraRowId)));
- QVERIFY_SQL( q, exec( "insert into " + oraRowId + " values('a')" ) );
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values('a')").arg(oraRowId)));
QVariant v1 = q.lastInsertId();
- QVERIFY( v1.isValid() );
+ QVERIFY(v1.isValid());
- QVERIFY_SQL( q, exec( "insert into " + oraRowId + " values('b')" ) );
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values('b')").arg(oraRowId)));
QVariant v2 = q.lastInsertId();
- QVERIFY( v2.isValid() );
-
- QVERIFY_SQL( q, prepare( "select * from " + oraRowId + " where rowid = ?" ) );
- q.addBindValue( v1 );
- QVERIFY_SQL( q, exec() );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toString(), QString( "a" ) );
-
- q.addBindValue( v2 );
- QVERIFY_SQL( q, exec() );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toString(), QString( "b" ) );
+ QVERIFY(v2.isValid());
+
+ QVERIFY_SQL(q, prepare(QLatin1String("select * from %1 where rowid = ?").arg(oraRowId)));
+ q.addBindValue(v1);
+ QVERIFY_SQL(q, exec());
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toString(), u"a");
+
+ q.addBindValue(v2);
+ QVERIFY_SQL(q, exec());
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toString(), u"b");
}
void tst_QSqlQuery::mysql_outValues()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- const QString hello(qTableName("hello", __FILE__, db)), qtestproc(qTableName("qtestproc", __FILE__, db));
-
- QSqlQuery q( db );
-
- q.exec( "drop function " + hello );
-
- QVERIFY_SQL(q, exec("create function " + hello + " (s char(20)) returns varchar(50) READS SQL DATA return concat('Hello ', s)"));
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ const QString hello(qTableName("hello", __FILE__, db));
+ ProcScope ps(db, "qtestproc", __FILE__);
- QVERIFY_SQL( q, exec( "select " + hello + "('world')" ) );
- QVERIFY_SQL( q, next() );
+ QSqlQuery q(db);
- QCOMPARE( q.value( 0 ).toString(), QString( "Hello world" ) );
+ q.exec("drop function " + hello);
- QVERIFY_SQL( q, prepare( "select " + hello + "('harald')" ) );
- QVERIFY_SQL( q, exec() );
- QVERIFY_SQL( q, next() );
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create function %1 (s char(20)) returns varchar(50) "
+ "READS SQL DATA return concat('Hello ', s)").arg(hello)));
- QCOMPARE( q.value( 0 ).toString(), QString( "Hello harald" ) );
+ QVERIFY_SQL(q, exec(QLatin1String("select %1('world')").arg(hello)));
+ QVERIFY_SQL(q, next());
- QVERIFY_SQL( q, exec( "drop function " + hello ) );
+ QCOMPARE(q.value(0).toString(), u"Hello world");
- q.exec( "drop procedure " + qtestproc );
+ QVERIFY_SQL(q, prepare(QLatin1String("select %1('harald')").arg(hello)));
+ QVERIFY_SQL(q, exec());
+ QVERIFY_SQL(q, next());
- QVERIFY_SQL( q, exec( "create procedure " + qtestproc + " () "
- "BEGIN select * from " + qtest + " order by id; END" ) );
- QVERIFY_SQL( q, exec( "call " + qtestproc + "()" ) );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 1 ).toString(), QString( "VarChar1" ) );
+ QCOMPARE(q.value(0).toString(), u"Hello harald");
- QVERIFY_SQL( q, exec( "drop procedure " + qtestproc ) );
+ QVERIFY_SQL(q, exec("drop function " + hello));
- QVERIFY_SQL( q, exec( "create procedure " + qtestproc + " (OUT param1 INT) "
- "BEGIN set param1 = 42; END" ) );
+ QVERIFY_SQL(q, exec(QLatin1String("create procedure %1 () BEGIN "
+ "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( "call " + qtestproc + " (@out)" ) );
- QVERIFY_SQL( q, exec( "select @out" ) );
- QCOMPARE( q.record().fieldName( 0 ), QString( "@out" ) );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), 42 );
+ 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(ps.name())));
- QVERIFY_SQL( q, exec( "drop procedure " + 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);
}
void tst_QSqlQuery::bindBool()
{
- // QTBUG-27763: bool value got converted to int 127 by mysql driver because sizeof(bool) < sizeof(int).
- // The problem was the way the bool value from the application was handled. For our purposes here, it
- // doesn't matter whether the column type is BOOLEAN or INT. All DBMSs have INT, and this usually
- // works for this test. Postresql is an exception because its INT type does not accept BOOLEAN
- // values and its BOOLEAN columns do not accept INT values.
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ // QTBUG-27763: bool value got converted to int 127 by mysql driver because
+ // sizeof(bool) < sizeof(int). The problem was the way the bool value from
+ // the application was handled. For our purposes here, it doesn't matter
+ // whether the column type is BOOLEAN or INT. All DBMSs have INT, and this
+ // usually works for this test. Postresql is an exception because its INT
+ // type does not accept BOOLEAN values and its BOOLEAN columns do not accept
+ // INT values.
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
QSqlQuery q(db);
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
const QString tableName(qTableName("bindBool", __FILE__, db));
q.exec("DROP TABLE " + tableName);
const bool useBooleanType = (dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::Interbase);
- const QString colType = useBooleanType ? QLatin1String("BOOLEAN") : QLatin1String("INT");
- QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id INT, flag " + colType + " NOT NULL, PRIMARY KEY(id))"));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %2 (id INT, flag %1 NOT NULL, PRIMARY KEY(id))")
+ .arg(QLatin1String(useBooleanType ? "BOOLEAN" : "INT"), tableName)));
for (int i = 0; i < 2; ++i) {
bool flag = i;
- q.prepare("INSERT INTO " + tableName + " (id, flag) VALUES(:id, :flag)");
+ q.prepare(QLatin1String("INSERT INTO %1 (id, flag) VALUES(:id, :flag)").arg(tableName));
q.bindValue(":id", i);
q.bindValue(":flag", flag);
QVERIFY_SQL(q, exec());
}
- QVERIFY_SQL(q, exec("SELECT id, flag FROM " + tableName + " ORDER BY id"));
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT id, flag FROM %1 ORDER BY id").arg(tableName)));
for (int i = 0; i < 2; ++i) {
bool flag = i;
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), i);
QCOMPARE(q.value(1).toBool(), flag);
}
- QVERIFY_SQL(q, prepare("SELECT flag FROM " + tableName + " WHERE flag = :filter"));
+ QVERIFY_SQL(q, prepare(QLatin1String(
+ "SELECT flag FROM %1 WHERE flag = :filter").arg(tableName)));
const bool filter = true;
q.bindValue(":filter", filter);
QVERIFY_SQL(q, exec());
@@ -656,105 +614,112 @@ void tst_QSqlQuery::bindBool()
void tst_QSqlQuery::oraOutValues()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ 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");
+ if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries))
+ QSKIP("Test requires prepared query support");
- QSqlQuery q( db );
+ QSqlQuery q(db);
- q.setForwardOnly( true );
+ q.setForwardOnly(true);
/*** outvalue int ***/
- QVERIFY_SQL( q, exec( "create or replace procedure " + tst_outValues + "(x out int) is\n"
- "begin\n"
- " x := 42;\n"
- "end;\n" ) );
- QVERIFY( q.prepare( "call " + tst_outValues + "(?)" ) );
- q.addBindValue( 0, QSql::Out );
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValue( 0 ).toInt(), 42 );
-
- // bind a null value, make sure the OCI driver resets the null flag
- q.addBindValue( QVariant(QMetaType(QMetaType::Int)), QSql::Out );
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValue( 0 ).toInt(), 42 );
- QVERIFY( !q.boundValue( 0 ).isNull() );
+ QVERIFY_SQL(q, exec(QLatin1String("create or replace procedure %1(x out int) is\n"
+ "begin\n"
+ " x := 42;\n"
+ "end;\n").arg(tst_outValues)));
+ QVERIFY(q.prepare(QLatin1String("call %1(?)").arg(tst_outValues)));
+ q.addBindValue(0, QSql::Out);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValue(0).toInt(), 42);
+
+ // Bind a null value, make sure the OCI driver resets the null flag:
+ q.addBindValue(QVariant(QMetaType(QMetaType::Int)), QSql::Out);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValue(0).toInt(), 42);
+ QVERIFY(!q.boundValue(0).isNull());
/*** outvalue varchar ***/
- QVERIFY_SQL( q, exec( "create or replace procedure " + tst_outValues + "(x out varchar) is\n"
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create or replace procedure %1(x out varchar) is\n"
"begin\n"
" x := 'blah';\n"
- "end;\n" ) );
- QVERIFY( q.prepare( "call " + tst_outValues + "(?)" ) );
- QString s1( "12345" );
- s1.reserve( 512 );
- q.addBindValue( s1, QSql::Out );
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValue( 0 ).toString(), QString( "blah" ) );
+ "end;\n").arg(tst_outValues)));
+ QVERIFY(q.prepare(QLatin1String("call %1(?)").arg(tst_outValues)));
+ QString s1("12345");
+ s1.reserve(512);
+ q.addBindValue(s1, QSql::Out);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValue(0).toString(), u"blah");
/*** in/outvalue numeric ***/
- QVERIFY_SQL( q, exec( "create or replace procedure " + tst_outValues + "(x in out numeric) is\n"
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create or replace procedure %1(x in out numeric) is\n"
"begin\n"
" x := x + 10;\n"
- "end;\n" ) );
- QVERIFY( q.prepare( "call " + tst_outValues + "(?)" ) );
- q.addBindValue( 10, QSql::Out );
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValue( 0 ).toInt(), 20 );
+ "end;\n").arg(tst_outValues)));
+ QVERIFY(q.prepare(QLatin1String("call %1(?)").arg(tst_outValues)));
+ q.addBindValue(10, QSql::Out);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValue(0).toInt(), 20);
/*** in/outvalue varchar ***/
- QVERIFY_SQL( q, exec( "create or replace procedure " + tst_outValues + "(x in out varchar) is\n"
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create or replace procedure %1(x in out varchar) is\n"
"begin\n"
" x := 'homer';\n"
- "end;\n" ) );
- QVERIFY( q.prepare( "call " + tst_outValues + "(?)" ) );
- q.addBindValue( QString( "maggy" ), QSql::Out );
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValue( 0 ).toString(), QString( "homer" ) );
+ "end;\n").arg(tst_outValues)));
+ QVERIFY(q.prepare(QLatin1String("call %1(?)").arg(tst_outValues)));
+ q.addBindValue(u"maggy"_s, QSql::Out);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValue(0).toString(), u"homer");
/*** in/outvalue varchar ***/
- QVERIFY_SQL( q, exec( "create or replace procedure " + tst_outValues + "(x in out varchar) is\n"
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create or replace procedure %1(x in out varchar) is\n"
"begin\n"
" x := NULL;\n"
- "end;\n" ) );
- QVERIFY( q.prepare( "call " + tst_outValues + "(?)" ) );
- q.addBindValue( QString( "maggy" ), QSql::Out );
- QVERIFY_SQL( q, exec() );
- QVERIFY( q.boundValue( 0 ).isNull() );
+ "end;\n").arg(tst_outValues)));
+ QVERIFY(q.prepare(QLatin1String("call %1(?)").arg(tst_outValues)));
+ q.addBindValue(u"maggy"_s, QSql::Out);
+ QVERIFY_SQL(q, exec());
+ QVERIFY(q.boundValue(0).isNull());
/*** in/outvalue int ***/
- QVERIFY_SQL( q, exec( "create or replace procedure " + tst_outValues + "(x in out int) is\n"
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create or replace procedure %1(x in out int) is\n"
"begin\n"
" x := NULL;\n"
- "end;\n" ) );
- QVERIFY( q.prepare( "call " + tst_outValues + "(?)" ) );
- q.addBindValue( 42, QSql::Out );
- QVERIFY_SQL( q, exec() );
- QVERIFY( q.boundValue( 0 ).isNull() );
+ "end;\n").arg(tst_outValues)));
+ QVERIFY(q.prepare(QLatin1String("call %1(?)").arg(tst_outValues)));
+ q.addBindValue(42, QSql::Out);
+ QVERIFY_SQL(q, exec());
+ QVERIFY(q.boundValue(0).isNull());
/*** in/outvalue varchar ***/
- QVERIFY_SQL( q, exec( "create or replace procedure " + tst_outValues + "(x in varchar, y out varchar) is\n"
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create or replace procedure %1(x in varchar, y out varchar) is\n"
"begin\n"
" y := x||'bubulalakikikokololo';\n"
- "end;\n" ) );
- QVERIFY( q.prepare( "call " + tst_outValues + "(?, ?)" ) );
- q.addBindValue( QString( "fifi" ), QSql::In );
+ "end;\n").arg(tst_outValues)));
+ QVERIFY(q.prepare(QLatin1String("call %1(?, ?)").arg(tst_outValues)));
+ q.addBindValue(u"fifi"_s, QSql::In);
QString out;
- out.reserve( 50 );
- q.addBindValue( out, QSql::Out );
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValue( 1 ).toString(), QString( "fifibubulalakikikokololo" ) );
+ out.reserve(50);
+ q.addBindValue(out, QSql::Out);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValue(1).toString(), u"fifibubulalakikikokololo");
/*** in/outvalue date ***/
- QVERIFY_SQL(q, exec("create or replace procedure " + tst_outValues + "(x in date, y out date) is\n"
- "begin\n"
- " y := x;\n"
- "end;\n"));
- QVERIFY(q.prepare("call " + tst_outValues + "(?, ?)"));
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create or replace procedure %1(x in date, y out date) is\n"
+ "begin\n"
+ " y := x;\n"
+ "end;\n").arg(tst_outValues)));
+ QVERIFY(q.prepare(QLatin1String("call %1(?, ?)").arg(tst_outValues)));
const QDate date = QDate::currentDate();
q.addBindValue(date, QSql::In);
q.addBindValue(QVariant(QDate()), QSql::Out);
@@ -762,11 +727,12 @@ void tst_QSqlQuery::oraOutValues()
QCOMPARE(q.boundValue(1).toDate(), date);
/*** in/outvalue timestamp ***/
- QVERIFY_SQL(q, exec("create or replace procedure " + tst_outValues + "(x in timestamp, y out timestamp) is\n"
- "begin\n"
- " y := x;\n"
- "end;\n"));
- QVERIFY(q.prepare("call " + tst_outValues + "(?, ?)"));
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create or replace procedure %1(x in timestamp, y out timestamp) is\n"
+ "begin\n"
+ " y := x;\n"
+ "end;\n").arg(tst_outValues)));
+ QVERIFY(q.prepare(QLatin1String("call %1(?, ?)").arg(tst_outValues)));
const QDateTime dt = QDateTime::currentDateTime();
q.addBindValue(dt, QSql::In);
q.addBindValue(QVariant(QMetaType(QMetaType::QDateTime)), QSql::Out);
@@ -776,53 +742,57 @@ void tst_QSqlQuery::oraOutValues()
void tst_QSqlQuery::oraClob()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- const QString clobby(qTableName("clobby", __FILE__, db));
-
- QSqlQuery q( db );
-
- // simple short string
- QVERIFY_SQL( q, exec( "create table " + clobby + "(id int primary key, cl clob, bl blob)" ) );
- QVERIFY_SQL( q, prepare( "insert into " + clobby + " (id, cl, bl) values(?, ?, ?)" ) );
- q.addBindValue( 1 );
- q.addBindValue( "bubu" );
- q.addBindValue( QByteArray("bubu") );
- QVERIFY_SQL( q, exec() );
-
- QVERIFY_SQL( q, exec( "select bl, cl from " + clobby + " where id = 1" ) );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toString(), QString( "bubu" ) );
- QCOMPARE( q.value( 1 ).toString(), QString( "bubu" ) );
-
- // simple short string with binding
- QVERIFY_SQL( q, prepare( "insert into " + clobby + " (id, cl, bl) values(?, ?, ?)" ) );
- q.addBindValue( 2 );
- q.addBindValue( "lala", QSql::Binary );
- q.addBindValue( QByteArray("lala"), QSql::Binary );
- QVERIFY_SQL( q, exec() );
-
- QVERIFY_SQL( q, exec( "select bl, cl from " + clobby + " where id = 2" ) );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toString(), QString( "lala" ) );
- QCOMPARE( q.value( 1 ).toString(), QString( "lala" ) );
-
- // loooong string
- QString loong;
- loong.fill( QLatin1Char( 'A' ), 25000 );
- QVERIFY_SQL( q, prepare( "insert into " + clobby + " (id, cl, bl) values(?, ?, ?)" ) );
- q.addBindValue( 3 );
- q.addBindValue( loong, QSql::Binary );
- q.addBindValue( loong.toLatin1(), QSql::Binary );
- QVERIFY_SQL( q, exec() );
-
- QVERIFY_SQL( q, exec( "select bl, cl from " + clobby + " where id = 3" ) );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toString().count(), loong.count() );
- QVERIFY( q.value( 0 ).toString() == loong );
- QCOMPARE( q.value( 1 ).toByteArray().count(), loong.toLatin1().count() );
- QVERIFY( q.value( 1 ).toByteArray() == loong.toLatin1() );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "clobby", __FILE__);
+ const auto &clobby = ts.tableName();
+
+ QSqlQuery q(db);
+
+ // Simple short string:
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1(id int primary key, cl clob, bl blob)")
+ .arg(clobby)));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 (id, cl, bl) values(?, ?, ?)")
+ .arg(clobby)));
+ q.addBindValue(1);
+ q.addBindValue("bubu");
+ q.addBindValue("bubu"_ba);
+ QVERIFY_SQL(q, exec());
+
+ QVERIFY_SQL(q, exec(QLatin1String("select bl, cl from %1 where id = 1").arg(clobby)));
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toString(), u"bubu");
+ QCOMPARE(q.value(1).toString(), u"bubu");
+
+ // Simple short string with binding:
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 (id, cl, bl) values(?, ?, ?)")
+ .arg(clobby)));
+ q.addBindValue(2);
+ q.addBindValue(u"lala"_s, QSql::Binary);
+ q.addBindValue("lala"_ba, QSql::Binary);
+ QVERIFY_SQL(q, exec());
+
+ QVERIFY_SQL(q, exec(QLatin1String("select bl, cl from %1 where id = 2").arg(clobby)));
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toString(), u"lala");
+ QCOMPARE(q.value(1).toString(), u"lala");
+
+ // Loooong string:
+ const QString loong(25000, QLatin1Char('A'));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 (id, cl, bl) values(?, ?, ?)")
+ .arg(clobby)));
+ q.addBindValue(3);
+ q.addBindValue(loong, QSql::Binary);
+ q.addBindValue(loong.toLatin1(), QSql::Binary);
+ QVERIFY_SQL(q, exec());
+
+ QVERIFY_SQL(q, exec(QLatin1String("select bl, cl from %1 where id = 3").arg(clobby)));
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toString().size(), loong.size());
+ QVERIFY(q.value(0).toString() == loong); // Deliberately not QCOMPARE() as too long
+ QCOMPARE(q.value(1).toByteArray().size(), loong.toLatin1().size());
+ QVERIFY(q.value(1).toByteArray() == loong.toLatin1()); // ditto
}
void tst_QSqlQuery::oraClobBatch()
@@ -833,268 +803,275 @@ void tst_QSqlQuery::oraClobBatch()
const QString clobBatch(qTableName("clobBatch", __FILE__, db));
tst_Databases::safeDropTables(db, { clobBatch });
QSqlQuery q(db);
- QVERIFY_SQL(q, exec("create table " + clobBatch + "(cl clob)"));
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1(cl clob)").arg(clobBatch)));
const QString longString(USHRT_MAX + 1, QLatin1Char('A'));
- QVERIFY_SQL(q, prepare("insert into " + clobBatch + " (cl) values(:cl)"));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 (cl) values(:cl)").arg(clobBatch)));
const QVariantList vars = { longString };
q.addBindValue(vars);
QVERIFY_SQL(q, execBatch());
QVERIFY_SQL(q, exec("select cl from " + clobBatch));
QVERIFY(q.next());
- QCOMPARE(q.value(0).toString().count(), longString.size());
- QVERIFY(q.value(0).toString() == longString);
+ QCOMPARE(q.value(0).toString().size(), longString.size());
+ QVERIFY(q.value(0).toString() == longString); // As above. deliberately not QCOMPARE().
}
void tst_QSqlQuery::storedProceduresIBase()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- const auto procName = qTableName("TESTPROC", __FILE__, db);
- q.exec("drop procedure " + procName);
-
- QVERIFY_SQL(q, exec("create procedure " + procName +
- " RETURNS (x integer, y varchar(20)) "
- "AS BEGIN "
- " x = 42; "
- " y = 'Hello Anders'; "
- "END" ) );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ ProcScope ps(db, "TESTPROC", __FILE__);
- QVERIFY_SQL(q, prepare("execute procedure " + procName));
- QVERIFY_SQL( q, exec() );
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QLatin1String("create procedure %1 RETURNS (x integer, y varchar(20)) "
+ "AS BEGIN "
+ " x = 42; "
+ " y = 'Hello Anders'; "
+ "END").arg(ps.name())));
+ QVERIFY_SQL(q, prepare("execute procedure " + ps.name()));
+ QVERIFY_SQL(q, exec());
- // check for a valid result set
+ // Check for a valid result set:
QSqlRecord rec = q.record();
- QCOMPARE( rec.count(), 2 );
- QCOMPARE( rec.fieldName( 0 ).toUpper(), QString( "X" ) );
- QCOMPARE( rec.fieldName( 1 ).toUpper(), QString( "Y" ) );
+ QCOMPARE(rec.count(), 2);
+ QCOMPARE(rec.fieldName(0).toUpper(), u"X");
+ QCOMPARE(rec.fieldName(1).toUpper(), u"Y");
- // the first next shall suceed
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), 42 );
- QCOMPARE( q.value( 1 ).toString(), QString( "Hello Anders" ) );
-
- // the second next shall fail
- QVERIFY( !q.next() );
+ // The first next shall suceed:
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), 42);
+ QCOMPARE(q.value(1).toString(), u"Hello Anders");
- q.exec("drop procedure " + procName);
+ // The second next shall fail:
+ QVERIFY(!q.next());
}
void tst_QSqlQuery::outValuesDB2()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- if ( !db.driver()->hasFeature( QSqlDriver::PreparedQueries ) )
- QSKIP( "Test requires prepared query support");
+ if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries))
+ QSKIP("Test requires prepared query support");
- QSqlQuery q( db );
+ ProcScope ps(db, "tst_outValues", __FILE__);
- q.setForwardOnly( true );
+ QSqlQuery q(db);
+ q.setForwardOnly(true);
- q.exec("drop procedure " + qTableName("tst_outValues", __FILE__, db)); //non-fatal
- QVERIFY_SQL( q, exec( "CREATE PROCEDURE " + qTableName("tst_outValues", __FILE__, db) +
- " (OUT x int, OUT x2 double, OUT x3 char(20))\n"
- "LANGUAGE SQL\n"
- "P1: BEGIN\n"
- " SET x = 42;\n"
- " SET x2 = 4.2;\n"
- " SET x3 = 'Homer';\n"
- "END P1" ) );
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE PROCEDURE %1 "
+ "(OUT x int, OUT x2 double, OUT x3 char(20))\n"
+ "LANGUAGE SQL\n"
+ "P1: BEGIN\n"
+ " SET x = 42;\n"
+ " SET x2 = 4.2;\n"
+ " SET x3 = 'Homer';\n"
+ "END P1").arg(ps.name())));
- QVERIFY_SQL(q, prepare("call " + qTableName("tst_outValues", __FILE__, db) + "(?, ?, ?)"));
+ QVERIFY_SQL(q, prepare(QLatin1String("call %1(?, ?, ?)").arg(ps.name())));
- q.addBindValue( 0, QSql::Out );
- q.addBindValue( 0.0, QSql::Out );
- q.addBindValue( "Simpson", QSql::Out );
+ q.addBindValue(0, QSql::Out);
+ q.addBindValue(0.0, QSql::Out);
+ q.addBindValue("Simpson", QSql::Out);
- QVERIFY_SQL( q, exec() );
+ QVERIFY_SQL(q, exec());
- QCOMPARE( q.boundValue( 0 ).toInt(), 42 );
- QCOMPARE( q.boundValue( 1 ).toDouble(), 4.2 );
- QCOMPARE( q.boundValue( 2 ).toString().trimmed(), QString( "Homer" ) );
+ QCOMPARE(q.boundValue(0).toInt(), 42);
+ QCOMPARE(q.boundValue(1).toDouble(), 4.2);
+ QCOMPARE(q.boundValue(2).toString().trimmed(), u"Homer");
}
void tst_QSqlQuery::outValues()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- const QString tst_outValues(qTableName("tst_outValues", __FILE__, db));
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- if ( !db.driver()->hasFeature( QSqlDriver::PreparedQueries ) )
- QSKIP( "Test requires prepared query support");
+ 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 );
- QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType == QSqlDriver::Oracle) {
- QVERIFY_SQL( q, exec( "create or replace procedure " + tst_outValues + "(x out int) is\n"
+ q.setForwardOnly(true);
+ QLatin1String creator, caller;
+ switch (tst_Databases::getDatabaseType(db)) {
+ case QSqlDriver::Oracle:
+ creator = QLatin1String("create or replace procedure %1(x out int) is\n"
"begin\n"
" x := 42;\n"
- "end;\n" ) );
- QVERIFY( q.prepare( "call " + tst_outValues + "(?)" ) );
- } else if (dbType == QSqlDriver::DB2) {
- q.exec( "drop procedure " + tst_outValues ); //non-fatal
- QVERIFY_SQL( q, exec( "CREATE PROCEDURE " + tst_outValues + " (OUT x int)\n"
+ "end;\n");
+ caller = QLatin1String("call %1(?)");
+ break;
+ case QSqlDriver::DB2:
+ creator = QLatin1String("CREATE PROCEDURE %1 (OUT x int)\n"
"LANGUAGE SQL\n"
"P1: BEGIN\n"
" SET x = 42;\n"
- "END P1" ) );
- QVERIFY( q.prepare( "call " + tst_outValues + "(?)" ) );
- } else if (dbType == QSqlDriver::MSSqlServer) {
- q.exec( "drop procedure " + tst_outValues ); //non-fatal
- QVERIFY_SQL( q, exec( "create procedure " + tst_outValues + " (@x int out) as\n"
+ "END P1");
+ caller = QLatin1String("call %1(?)");
+ break;
+ case QSqlDriver::MSSqlServer:
+ creator = QLatin1String("create procedure %1 (@x int out) as\n"
"begin\n"
" set @x = 42\n"
- "end\n" ) );
- QVERIFY( q.prepare( "{call " + tst_outValues + "(?)}" ) );
- } else
- QSKIP( "Don't know how to create a stored procedure for this database server, please fix this test");
+ "end\n");
+ caller = QLatin1String("{call %1(?)}");
+ break;
+ default:
+ QSKIP("Don't know how to create a stored procedure for this database server, "
+ "please fix this test");
+ }
+ QVERIFY_SQL(q, exec(creator.arg(ps.name())));
+ QVERIFY(q.prepare(caller.arg(ps.name())));
- q.addBindValue( 0, QSql::Out );
+ q.addBindValue(0, QSql::Out);
- QVERIFY_SQL( q, exec() );
+ QVERIFY_SQL(q, exec());
- QCOMPARE( q.boundValue( 0 ).toInt(), 42 );
+ QCOMPARE(q.boundValue(0).toInt(), 42);
}
void tst_QSqlQuery::blob()
{
- static const int BLOBSIZE = 1024 * 10;
- static const int BLOBCOUNT = 2;
-
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ constexpr int BLOBSIZE = 1024 * 10;
+ constexpr int BLOBCOUNT = 2;
- if ( !db.driver()->hasFeature( QSqlDriver::BLOB ) )
- QSKIP( "DBMS not BLOB capable");
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- //don' make it too big otherwise sybase and mysql will complain
- QByteArray ba( BLOBSIZE, 0 );
+ if (!db.driver()->hasFeature(QSqlDriver::BLOB))
+ QSKIP("DBMS not BLOB capable");
+ // Don't make it too big otherwise sybase and mysql will complain:
+ QByteArray ba(BLOBSIZE, Qt::Uninitialized);
for (int i = 0; i < ba.size(); ++i)
ba[i] = i % 256;
- QSqlQuery q( db );
-
- q.setForwardOnly( true );
+ TableScope ts(db, "qtest_blob", __FILE__);
+ QSqlQuery q(db);
+ q.setForwardOnly(true);
- QString queryString = QString("create table " + qTableName("qtest_blob", __FILE__, db) +
- " (id int not null primary key, t_blob %1)" ).arg( tst_Databases::blobTypeName( db, BLOBSIZE ) );
- QVERIFY_SQL( q, exec( queryString ) );
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int not null primary key, t_blob %2)")
+ .arg(ts.tableName(), tst_Databases::blobTypeName(db, BLOBSIZE))));
- QVERIFY_SQL(q, prepare("insert into " + qTableName("qtest_blob", __FILE__, db) + " (id, t_blob) values (?, ?)"));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 (id, t_blob) values (?, ?)")
+ .arg(ts.tableName())));
for (int i = 0; i < BLOBCOUNT; ++i) {
- q.addBindValue( i );
- q.addBindValue( ba );
- QVERIFY_SQL( q, exec() );
+ q.addBindValue(i);
+ q.addBindValue(ba);
+ QVERIFY_SQL(q, exec());
}
- QVERIFY_SQL(q, exec("select * from " + qTableName("qtest_blob", __FILE__, db)));
+ QVERIFY_SQL(q, exec("select * from " + ts.tableName()));
for (int i = 0; i < BLOBCOUNT; ++i) {
- QVERIFY( q.next() );
- QByteArray res = q.value( 1 ).toByteArray();
- QVERIFY2( res.size() >= ba.size(),
- QString( "array sizes differ, expected %1, got %2" ).arg( ba.size() ).arg( res.size() ).toLatin1() );
-
- for (int i2 = 0; i2 < ba.size(); ++i2) {
- if ( res[i2] != ba[i2] )
- QFAIL( QString( "ByteArrays differ at position %1, expected %2, got %3" ).arg(
- i2 ).arg(( int )( unsigned char )ba[i2] ).arg(( int )( unsigned char )res[i2] ).toLatin1() );
+ QVERIFY(q.next());
+ QByteArray res = q.value(1).toByteArray();
+ QVERIFY2(res.size() >= ba.size(),
+ qPrintable(QString::asprintf(
+ "array sizes differ, expected (at least) %" PRIdQSIZETYPE
+ ", got %" PRIdQSIZETYPE, ba.size(), res.size())));
+
+ for (qsizetype i2 = 0; i2 < ba.size(); ++i2) {
+ if (res[i2] != ba[i2]) {
+ QFAIL(qPrintable(QString::asprintf(
+ "ByteArrays differ at position %lld, expected %hhu, got %hhu",
+ i2, ba[i2], res[i2])));
+ }
}
}
}
void tst_QSqlQuery::value()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "select id, t_varchar, t_char from " + qtest + " order by id" ) );
- int i = 1;
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QLatin1String("select id, t_varchar, t_char from %1 order by id")
+ .arg(qtest)));
- while ( q.next() ) {
- QCOMPARE( q.value( 0 ).toInt(), i );
- QCOMPARE( q.value( "id" ).toInt(), i );
+ for (int i = 1; q.next(); ++i) {
+ QCOMPARE(q.value(0).toInt(), i);
+ QCOMPARE(q.value("id").toInt(), i);
+ auto istring = QString::number(i);
if (dbType == QSqlDriver::Interbase)
- QVERIFY( q.value( 1 ).toString().startsWith( "VarChar" + QString::number( i ) ) );
- else if ( q.value( 1 ).toString().endsWith(QLatin1Char(' ')))
- QCOMPARE( q.value( 1 ).toString(), ( "VarChar" + QString::number( i ) + " " ) );
+ QVERIFY(q.value(1).toString().startsWith("VarChar" + istring));
+ else if (q.value(1).toString().endsWith(QLatin1Char(' ')))
+ QCOMPARE(q.value(1).toString(), QLatin1String("VarChar%1 ").arg(istring));
else
- QCOMPARE( q.value( 1 ).toString(), ( "VarChar" + QString::number( i ) ) );
+ QCOMPARE(q.value(1).toString(), "VarChar" + istring);
if (dbType == QSqlDriver::Interbase)
- QVERIFY( q.value( 2 ).toString().startsWith( "Char" + QString::number( i ) ) );
- else if (!q.value( 2 ).toString().endsWith(QLatin1Char(' ')))
- QCOMPARE( q.value( 2 ).toString(), ( "Char" + QString::number( i ) ) );
+ QVERIFY(q.value(2).toString().startsWith("Char" + istring));
+ else if (q.value(2).toString().endsWith(QLatin1Char(' ')))
+ QCOMPARE(q.value(2).toString(), QLatin1String("Char%1 ").arg(istring));
else
- QCOMPARE( q.value( 2 ).toString(), ( "Char" + QString::number( i ) + " " ) );
-
- i++;
+ QCOMPARE(q.value(2).toString(), "Char" + istring);
}
}
#define SETUP_RECORD_TABLE \
do { \
- QVERIFY_SQL(q, exec("CREATE TABLE " + tst_record + " (id integer, extra varchar(50))")); \
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id integer, extra varchar(50))") \
+ .arg(tst_record))); \
for (int i = 0; i < 3; ++i) \
- QVERIFY_SQL(q, exec(QString("INSERT INTO " + tst_record + " VALUES(%1, 'extra%1')").arg(i))); \
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 VALUES(%2, 'extra%2')") \
+ .arg(tst_record).arg(i))); \
} while (0)
#define CHECK_RECORD \
do { \
- QVERIFY_SQL(q, exec(QString("select %1.id, %1.t_varchar, %1.t_char, %2.id, %2.extra from %1, %2 where " \
- "%1.id = %2.id order by %1.id").arg(lowerQTest).arg(tst_record))); \
- QCOMPARE(q.record().fieldName(0).toLower(), QString("id")); \
+ QVERIFY_SQL(q, exec(QLatin1String( \
+ "select %1.id, %1.t_varchar, %1.t_char, %2.id, %2.extra " \
+ "from %1, %2 where %1.id = %2.id order by %1.id") \
+ .arg(lowerQTest, tst_record))); \
+ QCOMPARE(q.record().fieldName(0).toLower(), u"id"); \
QCOMPARE(q.record().field(0).tableName().toLower(), lowerQTest); \
- QCOMPARE(q.record().fieldName(1).toLower(), QString("t_varchar")); \
+ QCOMPARE(q.record().fieldName(1).toLower(), u"t_varchar"); \
QCOMPARE(q.record().field(1).tableName().toLower(), lowerQTest); \
- QCOMPARE(q.record().fieldName(2).toLower(), QString("t_char")); \
+ QCOMPARE(q.record().fieldName(2).toLower(), u"t_char"); \
QCOMPARE(q.record().field(2).tableName().toLower(), lowerQTest); \
- QCOMPARE(q.record().fieldName(3).toLower(), QString("id")); \
+ QCOMPARE(q.record().fieldName(3).toLower(), u"id"); \
QCOMPARE(q.record().field(3).tableName().toLower(), tst_record); \
- QCOMPARE(q.record().fieldName(4).toLower(), QString("extra")); \
+ QCOMPARE(q.record().fieldName(4).toLower(), u"extra"); \
QCOMPARE(q.record().field(4).tableName().toLower(), tst_record); \
} while (0)
void tst_QSqlQuery::record()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QVERIFY( q.record().isEmpty() );
- QVERIFY_SQL( q, exec( "select id, t_varchar, t_char from " + qtest + " order by id" ) );
- QCOMPARE( q.record().fieldName( 0 ).toLower(), QString( "id" ) );
- QCOMPARE( q.record().fieldName( 1 ).toLower(), QString( "t_varchar" ) );
- QCOMPARE( q.record().fieldName( 2 ).toLower(), QString( "t_char" ) );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlQuery q(db);
+ QVERIFY(q.record().isEmpty());
+ QVERIFY_SQL(q, exec(QLatin1String("select id, t_varchar, t_char from %1 order by id")
+ .arg(qtest)));
+ QCOMPARE(q.record().fieldName(0).toLower(), u"id");
+ QCOMPARE(q.record().fieldName(1).toLower(), u"t_varchar");
+ QCOMPARE(q.record().fieldName(2).toLower(), u"t_char");
QCOMPARE(q.record().value(0), QVariant(q.record().field(0).metaType()));
QCOMPARE(q.record().value(1), QVariant(q.record().field(1).metaType()));
QCOMPARE(q.record().value(2), QVariant(q.record().field(2).metaType()));
- QVERIFY( q.next() );
- QVERIFY( q.next() );
+ QVERIFY(q.next());
+ QVERIFY(q.next());
+ QCOMPARE(q.record().fieldName(0).toLower(), u"id");
+ QCOMPARE(q.value(0).toInt(), 2);
- QCOMPARE( q.record().fieldName( 0 ).toLower(), QString( "id" ) );
- QCOMPARE( q.value( 0 ).toInt(), 2 );
+ 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 QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType == QSqlDriver::Oracle)
- QSKIP("Getting the tablename is not supported in Oracle");
const auto lowerQTest = qtest.toLower();
for (int i = 0; i < 3; ++i)
QCOMPARE(q.record().field(i).tableName().toLower(), lowerQTest);
@@ -1104,7 +1081,7 @@ void tst_QSqlQuery::record()
CHECK_RECORD;
q.clear();
- // Recreate the tables, in a different order
+ // Recreate the tables, in a different order:
const QStringList tables = { qtest, tst_record, qTableName("qtest_null", __FILE__, db) };
tst_Databases::safeDropTables(db, tables);
SETUP_RECORD_TABLE;
@@ -1115,273 +1092,264 @@ void tst_QSqlQuery::record()
void tst_QSqlQuery::isValid()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QVERIFY( !q.isValid() );
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- QVERIFY( q.first() );
- QVERIFY( q.isValid() );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlQuery q(db);
+ QVERIFY(!q.isValid());
+ QVERIFY_SQL(q, exec("select * from " + qtest));
+ QVERIFY(q.first());
+ QVERIFY(q.isValid());
}
void tst_QSqlQuery::isActive()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QVERIFY( !q.isActive() );
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- QVERIFY( q.isActive() );
- QVERIFY( q.last() );
-
- if ( !tst_Databases::isMSAccess( db ) )
- // Access is stupid enough to let you scroll over boundaries
- QVERIFY( !q.next() );
-
- QVERIFY( q.isActive() );
-
- QVERIFY_SQL( q, exec( "insert into " + qtest + " values (41, 'VarChar41', 'Char41')" ) );
-
- QVERIFY( q.isActive() );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QVERIFY_SQL( q, exec( "update " + qtest + " set id = 42 where id = 41" ) );
+ QSqlQuery q(db);
+ QVERIFY(!q.isActive());
+ QVERIFY_SQL(q, exec("select * from " + qtest));
+ QVERIFY(q.isActive());
+ QVERIFY(q.last());
- QVERIFY( q.isActive() );
+ // Access is stupid enough to let you scroll over boundaries:
+ if (!tst_Databases::isMSAccess(db))
+ QVERIFY(!q.next());
+ QVERIFY(q.isActive());
- QVERIFY_SQL( q, exec( "delete from " + qtest + " where id = 42" ) );
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (41, 'VarChar41', 'Char41')")
+ .arg(qtest)));
+ QVERIFY(q.isActive());
- QVERIFY( q.isActive() );
+ QVERIFY_SQL(q, exec(QLatin1String("update %1 set id = 42 where id = 41").arg(qtest)));
+ QVERIFY(q.isActive());
- QVERIFY_SQL( q, exec( "delete from " + qtest + " where id = 42" ) );
+ QVERIFY_SQL(q, exec(QLatin1String("delete from %1 where id = 42").arg(qtest)));
+ QVERIFY(q.isActive());
- QVERIFY( q.isActive() );
+ QVERIFY_SQL(q, exec(QLatin1String("delete from %1 where id = 42").arg(qtest)));
+ QVERIFY(q.isActive());
}
void tst_QSqlQuery::numRowsAffected()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QSqlQuery q( db );
- QCOMPARE( q.numRowsAffected(), -1 );
+ QSqlQuery q(db);
+ QCOMPARE(q.numRowsAffected(), -1);
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- int i = 0;
+ QVERIFY_SQL(q, exec("select * from " + qtest));
- while ( q.next() )
+ int i = 0;
+ while (q.next())
++i;
- if ( q.numRowsAffected() == -1 || q.numRowsAffected() == 0 )
+ if (q.numRowsAffected() == -1 || q.numRowsAffected() == 0)
QSKIP("Database doesn't support numRowsAffected");
- if ( q.numRowsAffected() != -1 && q.numRowsAffected() != 0 && q.numRowsAffected() != i ) {
- // the value is undefined for SELECT, this check is just here for curiosity
- qDebug( "Expected numRowsAffected to be -1, 0 or %d, got %d", i, q.numRowsAffected() );
- }
+ // Value is undefined for SELECT, this check is just here for curiosity:
+ if (q.numRowsAffected() != -1 && q.numRowsAffected() != 0 && q.numRowsAffected() != i)
+ qDebug("Expected numRowsAffected to be -1, 0 or %d, got %d", i, q.numRowsAffected());
- QVERIFY_SQL( q, exec( "update " + qtest + " set id = 100 where id = 1" ) );
+ QVERIFY_SQL(q, exec(QLatin1String("update %1 set id = 100 where id = 1").arg(qtest)));
- QCOMPARE( q.numRowsAffected(), 1 );
- QCOMPARE( q.numRowsAffected(), 1 ); // yes, we check twice
+ QCOMPARE(q.numRowsAffected(), 1);
+ QCOMPARE(q.numRowsAffected(), 1); // yes, we check twice
- QVERIFY_SQL( q, exec( "update " + qtest + " set id = id + 100" ) );
- QCOMPARE( q.numRowsAffected(), i );
- QCOMPARE( q.numRowsAffected(), i ); // yes, we check twice
+ QVERIFY_SQL(q, exec(QLatin1String("update %1 set id = id + 100").arg(qtest)));
+ QCOMPARE(q.numRowsAffected(), i);
+ QCOMPARE(q.numRowsAffected(), i); // yes, we check twice
- QVERIFY_SQL( q, prepare( "update " + qtest + " set id = id + :newid" ) );
+ QVERIFY_SQL(q, prepare(QLatin1String("update %1 set id = id + :newid").arg(qtest)));
q.bindValue(":newid", 100);
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.numRowsAffected(), i );
- QCOMPARE( q.numRowsAffected(), i ); // yes, we check twice
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.numRowsAffected(), i);
+ QCOMPARE(q.numRowsAffected(), i); // yes, we check twice
- QVERIFY_SQL( q, prepare( "update " + qtest + " set id = id + :newid where NOT(1 = 1)" ) );
+ QVERIFY_SQL(q, prepare(QLatin1String("update %1 set id = id + :newid where NOT(1 = 1)")
+ .arg(qtest)));
q.bindValue(":newid", 100);
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.numRowsAffected(), 0 );
- QCOMPARE( q.numRowsAffected(), 0 ); // yes, we check twice
-
- QVERIFY_SQL( q, exec( "insert into " + qtest + " values (42000, 'homer', 'marge')" ) );
- QCOMPARE( q.numRowsAffected(), 1 );
- QCOMPARE( q.numRowsAffected(), 1 ); // yes, we check twice
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.numRowsAffected(), 0);
+ QCOMPARE(q.numRowsAffected(), 0); // yes, we check twice
- QSqlQuery q2( db );
- QVERIFY_SQL( q2, exec( "insert into " + qtest + " values (42001, 'homer', 'marge')" ) );
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (42000, 'homer', 'marge')")
+ .arg(qtest)));
+ QCOMPARE(q.numRowsAffected(), 1);
+ QCOMPARE(q.numRowsAffected(), 1); // yes, we check twice
- 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
- }
+ QSqlQuery q2(db);
+ QVERIFY_SQL(q2, exec(QLatin1String("insert into %1 values (42001, 'homer', 'marge')")
+ .arg(qtest)));
+ QCOMPARE(q2.numRowsAffected(), 1);
+ QCOMPARE(q2.numRowsAffected(), 1); // yes, we check twice
}
void tst_QSqlQuery::size()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QSqlQuery q( db );
- QCOMPARE( q.size(), -1 );
+ QSqlQuery q(db);
+ QCOMPARE(q.size(), -1);
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- int i = 0;
+ QVERIFY_SQL(q, exec("select * from " + qtest));
- while ( q.next() )
+ int i = 0;
+ while (q.next())
++i;
- if ( db.driver()->hasFeature( QSqlDriver::QuerySize ) ) {
- QCOMPARE( q.size(), i );
- QCOMPARE( q.size(), i ); // yes, twice
+ if (db.driver()->hasFeature(QSqlDriver::QuerySize)) {
+ QCOMPARE(q.size(), i);
+ QCOMPARE(q.size(), i); // yes, twice
} else {
- QCOMPARE( q.size(), -1 );
- QCOMPARE( q.size(), -1 ); // yes, twice
+ QCOMPARE(q.size(), -1);
+ QCOMPARE(q.size(), -1); // yes, twice
}
- QSqlQuery q2( "select * from " + qtest, db );
+ QSqlQuery q2("select * from " + qtest, db);
- if ( db.driver()->hasFeature( QSqlDriver::QuerySize ) )
- QCOMPARE( q.size(), i );
+ if (db.driver()->hasFeature(QSqlDriver::QuerySize))
+ QCOMPARE(q.size(), i);
else
- QCOMPARE( q.size(), -1 );
+ QCOMPARE(q.size(), -1);
q2.clear();
- QVERIFY_SQL( q, exec( "update " + qtest + " set id = 100 where id = 1" ) );
- QCOMPARE( q.size(), -1 );
- QCOMPARE( q.size(), -1 ); // yes, twice
+ QVERIFY_SQL(q, exec(QLatin1String("update %1 set id = 100 where id = 1").arg(qtest)));
+ QCOMPARE(q.size(), -1);
+ QCOMPARE(q.size(), -1); // yes, twice
}
void tst_QSqlQuery::isSelect()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- QVERIFY( q.isSelect() );
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec("select * from " + qtest));
+ QVERIFY(q.isSelect());
- QVERIFY_SQL( q, exec( "update " + qtest + " set id = 1 where id = 1" ) );
- QVERIFY( q.isSelect() == false );
+ QVERIFY_SQL(q, exec(QLatin1String("update %1 set id = 1 where id = 1").arg(qtest)));
+ QVERIFY(!q.isSelect());
}
void tst_QSqlQuery::first()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QVERIFY( q.at() == QSql::BeforeFirstRow );
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- QVERIFY( q.last() );
- QVERIFY_SQL( q, first() );
- QVERIFY( q.at() == 0 );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlQuery q(db);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY_SQL(q, exec("select * from " + qtest));
+ QVERIFY(q.last());
+ QVERIFY_SQL(q, first());
+ QCOMPARE(q.at(), 0);
}
void tst_QSqlQuery::next()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QVERIFY( q.at() == QSql::BeforeFirstRow );
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- QVERIFY( q.first() );
- QVERIFY( q.next() );
- QVERIFY( q.at() == 1 );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlQuery q(db);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY_SQL(q, exec("select * from " + qtest));
+ QVERIFY(q.first());
+ QVERIFY(q.next());
+ QCOMPARE(q.at(), 1);
}
void tst_QSqlQuery::prev()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QVERIFY( q.at() == QSql::BeforeFirstRow );
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- QVERIFY( q.first() );
- QVERIFY( q.next() );
- QVERIFY( q.previous() );
- QVERIFY( q.at() == 0 );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlQuery q(db);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY_SQL(q, exec("select * from " + qtest));
+ QVERIFY(q.first());
+ QVERIFY(q.next());
+ QVERIFY(q.previous());
+ QCOMPARE(q.at(), 0);
}
void tst_QSqlQuery::last()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QCOMPARE( q.at(), int( QSql::BeforeFirstRow ) );
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- int i = 0;
-
- while ( q.next() )
- i++;
-
- QCOMPARE( q.at(), int( QSql::AfterLastRow ) );
-
- QVERIFY( q.last() );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QSet<int> validReturns(QSet<int>() << -1 << i-1);
- QVERIFY( validReturns.contains(q.at()) );
+ QSqlQuery q(db);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY_SQL(q, exec("select * from " + qtest));
- QSqlQuery q2( "select * from " + qtest, db );
+ int i = 0;
+ while (q.next())
+ ++i;
- QVERIFY( q2.last() );
+ QCOMPARE(q.at(), QSql::AfterLastRow);
+ QVERIFY(q.last());
+ QSet<int> validReturns(QSet<int>() << -1 << i - 1);
+ QVERIFY(validReturns.contains(q.at()));
- QVERIFY( validReturns.contains(q.at()) );
+ QSqlQuery q2("select * from " + qtest, db);
+ QVERIFY(q2.last());
+ QVERIFY(validReturns.contains(q.at()));
}
void tst_QSqlQuery::seek()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- QSqlQuery q( db );
- QVERIFY( q.at() == QSql::BeforeFirstRow );
- QVERIFY_SQL( q, exec( QString( "select id from %1 order by id" ).arg( qtest ) ) );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ QSqlQuery q(db);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY_SQL(q, exec(QLatin1String("select id from %1 order by id").arg(qtest)));
// NB! The order of the calls below are important!
- QVERIFY( q.last() );
- QVERIFY( !q.seek( QSql::BeforeFirstRow ) );
- QCOMPARE( q.at(), int( QSql::BeforeFirstRow ) );
- QVERIFY( q.seek( 0 ) );
- QCOMPARE( q.at(), 0 );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
-
- QVERIFY( q.seek( 1 ) );
- QCOMPARE( q.at(), 1 );
- QCOMPARE( q.value( 0 ).toInt(), 2 );
-
- QVERIFY( q.seek( 3 ) );
- QCOMPARE( q.at(), 3 );
- QCOMPARE( q.value( 0 ).toInt(), 4 );
-
- QVERIFY( q.seek( -2, true ) );
- QCOMPARE( q.at(), 1 );
- QVERIFY( q.seek( 0 ) );
- QCOMPARE( q.at(), 0 );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
+ QVERIFY(q.last());
+ QVERIFY(!q.seek(QSql::BeforeFirstRow));
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.seek(0));
+ QCOMPARE(q.at(), 0);
+ QCOMPARE(q.value(0).toInt(), 1);
+
+ QVERIFY(q.seek(1));
+ QCOMPARE(q.at(), 1);
+ QCOMPARE(q.value(0).toInt(), 2);
+
+ QVERIFY(q.seek(3));
+ QCOMPARE(q.at(), 3);
+ QCOMPARE(q.value(0).toInt(), 4);
+
+ QVERIFY(q.seek(-2, true));
+ QCOMPARE(q.at(), 1);
+ QVERIFY(q.seek(0));
+ QCOMPARE(q.at(), 0);
+ QCOMPARE(q.value(0).toInt(), 1);
QVERIFY(!q.seek(QSql::BeforeFirstRow));
- QCOMPARE(q.at(), int(QSql::BeforeFirstRow));
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
QVERIFY(q.seek(1, true));
QCOMPARE(q.at(), 0);
QCOMPARE(q.value(0).toInt(), 1);
qint32 count = 1;
- while (q.next()) ++count;
+ while (q.next())
+ ++count;
- QCOMPARE(q.at(), int(QSql::AfterLastRow));
+ QCOMPARE(q.at(), QSql::AfterLastRow);
if (!q.isForwardOnly()) {
QVERIFY(q.seek(-1, true));
@@ -1389,134 +1357,120 @@ void tst_QSqlQuery::seek()
QCOMPARE(q.value(0).toInt(), count);
} else {
QVERIFY(!q.seek(-1, true));
- QCOMPARE(q.at(), int(QSql::AfterLastRow));
+ QCOMPARE(q.at(), QSql::AfterLastRow);
}
}
void tst_QSqlQuery::seekForwardOnlyQuery()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QSqlQuery q( db );
- q.setForwardOnly( false );
- QVERIFY( !q.isForwardOnly() );
+ QSqlQuery q(db);
+ q.setForwardOnly(false);
+ QVERIFY(!q.isForwardOnly());
- QVERIFY( q.at() == QSql::BeforeFirstRow );
- QVERIFY_SQL( q, exec( QString( "select id from %1 order by id" ).arg( qtest ) ) );
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY_SQL(q, exec(QLatin1String("select id from %1 order by id").arg(qtest)));
QSqlRecord rec;
// NB! The order of the calls below are important!
- QVERIFY( q.seek( 0 ) );
- QCOMPARE( q.at(), 0 );
+ QVERIFY(q.seek(0));
+ QCOMPARE(q.at(), 0);
rec = q.record();
- QCOMPARE( rec.value( 0 ).toInt(), 1 );
+ QCOMPARE(rec.value(0).toInt(), 1);
- QVERIFY( q.seek( 1 ) );
- QCOMPARE( q.at(), 1 );
+ QVERIFY(q.seek(1));
+ QCOMPARE(q.at(), 1);
rec = q.record();
- QCOMPARE( rec.value( 0 ).toInt(), 2 );
+ QCOMPARE(rec.value(0).toInt(), 2);
// Make a jump!
- QVERIFY( q.seek( 3 ) );
- QCOMPARE( q.at(), 3 );
+ QVERIFY(q.seek(3));
+ QCOMPARE(q.at(), 3);
rec = q.record();
- QCOMPARE( rec.value( 0 ).toInt(), 4 );
+ QCOMPARE(rec.value(0).toInt(), 4);
// Last record in result set
- QVERIFY( q.seek( 4 ) );
- QCOMPARE( q.at(), 4 );
+ QVERIFY(q.seek(4));
+ QCOMPARE(q.at(), 4);
rec = q.record();
- QCOMPARE( rec.value( 0 ).toInt(), 5 );
+ QCOMPARE(rec.value(0).toInt(), 5);
}
-// tests the forward only mode;
void tst_QSqlQuery::forwardOnly()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- q.setForwardOnly( true );
- QVERIFY( q.isForwardOnly() );
- QVERIFY( q.at() == QSql::BeforeFirstRow );
- QVERIFY_SQL( q, exec( "select * from " + qtest + " order by id" ) );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlQuery q(db);
+ q.setForwardOnly(true);
+ QVERIFY(q.isForwardOnly());
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY_SQL(q, exec(QLatin1String("select * from %1 order by id").arg(qtest)));
if (!q.isForwardOnly())
QSKIP("DBMS doesn't support forward-only queries");
- QVERIFY( q.at() == QSql::BeforeFirstRow );
- QVERIFY( q.first() );
- QCOMPARE( q.at(), 0 );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
- QVERIFY( q.next() );
- QCOMPARE( q.at(), 1 );
- QCOMPARE( q.value( 0 ).toInt(), 2 );
- QVERIFY( q.next() );
- QCOMPARE( q.at(), 2 );
- QCOMPARE( q.value( 0 ).toInt(), 3 );
-
- // lets make some mistakes to see how robust it is
- QTest::ignoreMessage( QtWarningMsg, "QSqlQuery::seek: cannot seek backwards in a forward only query" );
- QVERIFY( q.first() == false );
- QCOMPARE( q.at(), 2 );
- QCOMPARE( q.value( 0 ).toInt(), 3 );
- QTest::ignoreMessage( QtWarningMsg, "QSqlQuery::seek: cannot seek backwards in a forward only query" );
- QVERIFY( q.previous() == false );
- QCOMPARE( q.at(), 2 );
- QCOMPARE( q.value( 0 ).toInt(), 3 );
- QVERIFY( q.next() );
- QCOMPARE( q.at(), 3 );
- QCOMPARE( q.value( 0 ).toInt(), 4 );
-
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- int i = 0;
-
- while ( q.next() )
- i++;
-
- QVERIFY( q.at() == QSql::AfterLastRow );
-
- QSqlQuery q2 = q;
-
- QVERIFY( q2.isForwardOnly() );
-
- QVERIFY_SQL( q, exec( "select * from " + qtest + " order by id" ) );
-
- QVERIFY( q.isForwardOnly() );
-
- QVERIFY( q2.isForwardOnly() );
-
- QCOMPARE( q.at(), int( QSql::BeforeFirstRow ) );
-
- QVERIFY_SQL( q, seek( 3 ) );
-
- QCOMPARE( q.at(), 3 );
-
- QCOMPARE( q.value( 0 ).toInt(), 4 );
-
- QTest::ignoreMessage( QtWarningMsg, "QSqlQuery::seek: cannot seek backwards in a forward only query" );
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.first());
+ QCOMPARE(q.at(), 0);
+ QCOMPARE(q.value(0).toInt(), 1);
+ QVERIFY(q.next());
+ QCOMPARE(q.at(), 1);
+ QCOMPARE(q.value(0).toInt(), 2);
+ QVERIFY(q.next());
+ QCOMPARE(q.at(), 2);
+ QCOMPARE(q.value(0).toInt(), 3);
- QVERIFY( q.seek( 0 ) == false );
+ // Let's make some mistakes to see how robust it is:
+ QTest::ignoreMessage(QtWarningMsg,
+ "QSqlQuery::seek: cannot seek backwards in a forward only query");
+ QVERIFY(!q.first());
+ QCOMPARE(q.at(), 2);
+ QCOMPARE(q.value(0).toInt(), 3);
+ QTest::ignoreMessage(QtWarningMsg,
+ "QSqlQuery::seek: cannot seek backwards in a forward only query");
+ QVERIFY(!q.previous());
+ QCOMPARE(q.at(), 2);
+ QCOMPARE(q.value(0).toInt(), 3);
+ QVERIFY(q.next());
+ QCOMPARE(q.at(), 3);
+ QCOMPARE(q.value(0).toInt(), 4);
- QCOMPARE( q.value( 0 ).toInt(), 4 );
+ QVERIFY_SQL(q, exec("select * from " + qtest));
- QCOMPARE( q.at(), 3 );
+ int i = 0;
+ while (q.next())
+ ++i;
- QVERIFY( q.last() );
+ QCOMPARE(q.at(), QSql::AfterLastRow);
- QCOMPARE( q.at(), i-1 );
+ QVERIFY_SQL(q, exec(QLatin1String("select * from %1 order by id").arg(qtest)));
+ QVERIFY(q.isForwardOnly());
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
- QTest::ignoreMessage( QtWarningMsg, "QSqlQuery::seek: cannot seek backwards in a forward only query" );
+ QVERIFY_SQL(q, seek(3));
+ QCOMPARE(q.at(), 3);
+ QCOMPARE(q.value(0).toInt(), 4);
- QVERIFY( q.first() == false );
+ QTest::ignoreMessage(QtWarningMsg,
+ "QSqlQuery::seek: cannot seek backwards in a forward only query");
+ QVERIFY(!q.seek(0));
+ QCOMPARE(q.value(0).toInt(), 4);
+ QCOMPARE(q.at(), 3);
- QCOMPARE( q.at(), i-1 );
+ QVERIFY(q.last());
+ QCOMPARE(q.at(), i - 1);
- QVERIFY( q.next() == false );
+ QTest::ignoreMessage(QtWarningMsg,
+ "QSqlQuery::seek: cannot seek backwards in a forward only query");
+ QVERIFY(!q.first());
+ QCOMPARE(q.at(), i - 1);
- QCOMPARE( q.at(), int( QSql::AfterLastRow ) );
+ QVERIFY(!q.next());
+ QCOMPARE(q.at(), QSql::AfterLastRow);
}
void tst_QSqlQuery::forwardOnlyMultipleResultSet()
@@ -1525,36 +1479,38 @@ void tst_QSqlQuery::forwardOnlyMultipleResultSet()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
-
if (!db.driver()->hasFeature(QSqlDriver::MultipleResultSets))
QSKIP("DBMS doesn't support multiple result sets");
QSqlQuery q(db);
q.setForwardOnly(true);
- QVERIFY_SQL(q, exec("select id, t_varchar from " + qtest + " order by id;" // 1.
- "select id, t_varchar, t_char from " + qtest + " where id<4 order by id;" // 2.
- "update " + qtest + " set t_varchar='VarChar555' where id=5;" // 3.
- "select * from " + qtest + " order by id;" // 4.
- "select * from " + qtest + " where id=5 order by id;" // 5.
- "select * from " + qtest + " where id=-1 order by id;" // 6.
- "select * from " + qtest + " order by id")); // 7.
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "select id, t_varchar from %1 order by id;" // 1.
+ "select id, t_varchar, t_char from %1 where id<4 order by id;" // 2.
+ "update %1 set t_varchar='VarChar555' where id=5;" // 3.
+ "select * from %1 order by id;" // 4.
+ "select * from %1 where id=5 order by id;" // 5.
+ "select * from %1 where id=-1 order by id;" // 6.
+ "select * from %1 order by id") // 7.
+ .arg(qtest)));
if (!q.isForwardOnly())
QSKIP("DBMS doesn't support forward-only queries");
// 1. Result set with 2 columns and 5 rows
- QVERIFY(q.at() == QSql::BeforeFirstRow);
- QCOMPARE(q.isActive(), true);
- QCOMPARE(q.isSelect(), true);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.isActive());
+ QVERIFY(q.isSelect());
// Test record() of first result set
QSqlRecord record = q.record();
QCOMPARE(record.count(), 2);
QCOMPARE(record.indexOf("id"), 0);
QCOMPARE(record.indexOf("t_varchar"), 1);
- if (dbType != QSqlDriver::PostgreSQL) { // tableName() is not available in forward-only mode of QPSQL
- QCOMPARE(record.field(0).tableName(), qtest); // BUG: This fails for Microsoft SQL Server 2016 (QODBC), need fix
+ // tableName() is not available in forward-only mode of QPSQL
+ if (tst_Databases::getDatabaseType(db) != QSqlDriver::PostgreSQL) {
+ // BUG: This fails for Microsoft SQL Server 2016 (QODBC), need fix:
+ QCOMPARE(record.field(0).tableName(), qtest);
QCOMPARE(record.field(1).tableName(), qtest);
}
@@ -1571,18 +1527,21 @@ void tst_QSqlQuery::forwardOnlyMultipleResultSet()
QCOMPARE(q.at(), 3);
QCOMPARE(q.value(0).toInt(), 4);
- QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::seek: cannot seek backwards in a forward only query");
- QVERIFY(q.first() == false);
+ QTest::ignoreMessage(QtWarningMsg,
+ "QSqlQuery::seek: cannot seek backwards in a forward only query");
+ QVERIFY(!q.first());
QCOMPARE(q.at(), 3);
QCOMPARE(q.value(0).toInt(), 4);
- QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::seek: cannot seek backwards in a forward only query");
- QVERIFY(q.previous() == false);
+ QTest::ignoreMessage(QtWarningMsg,
+ "QSqlQuery::seek: cannot seek backwards in a forward only query");
+ QVERIFY(!q.previous());
QCOMPARE(q.at(), 3);
QCOMPARE(q.value(0).toInt(), 4);
- QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::seek: cannot seek backwards in a forward only query");
- QVERIFY(q.seek(1) == false);
+ QTest::ignoreMessage(QtWarningMsg,
+ "QSqlQuery::seek: cannot seek backwards in a forward only query");
+ QVERIFY(!q.seek(1));
QCOMPARE(q.at(), 3);
QCOMPARE(q.value(0).toInt(), 4);
@@ -1590,15 +1549,15 @@ void tst_QSqlQuery::forwardOnlyMultipleResultSet()
QCOMPARE(q.at(), 4);
// Try move after last row
- QVERIFY(q.next() == false);
+ QVERIFY(!q.next());
QCOMPARE(q.at(), QSql::AfterLastRow);
- QCOMPARE(q.isActive(), true);
+ QVERIFY(q.isActive());
// 2. Result set with 3 columns and 3 rows
QVERIFY(q.nextResult());
- QVERIFY(q.at() == QSql::BeforeFirstRow);
- QCOMPARE(q.isActive(), true);
- QCOMPARE(q.isSelect(), true);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.isActive());
+ QVERIFY(q.isSelect());
// Test record() of second result set
record = q.record();
@@ -1608,28 +1567,28 @@ void tst_QSqlQuery::forwardOnlyMultipleResultSet()
QCOMPARE(record.indexOf("t_char"), 2);
// Test iteration
- QVERIFY(q.at() == QSql::BeforeFirstRow);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
int index = 0;
while (q.next()) {
QCOMPARE(q.at(), index);
- QCOMPARE(q.value(0).toInt(), index+1);
- index++;
+ QCOMPARE(q.value(0).toInt(), index + 1);
+ ++index;
}
- QVERIFY(q.at() == QSql::AfterLastRow);
+ QCOMPARE(q.at(), QSql::AfterLastRow);
QCOMPARE(index, 3);
// 3. Update statement
QVERIFY(q.nextResult());
- QVERIFY(q.at() == QSql::BeforeFirstRow);
- QCOMPARE(q.isActive(), true);
- QCOMPARE(q.isSelect(), false);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.isActive());
+ QVERIFY(!q.isSelect());
QCOMPARE(q.numRowsAffected(), 1);
// 4. Result set with 5 rows
QVERIFY(q.nextResult());
- QVERIFY(q.at() == QSql::BeforeFirstRow);
- QCOMPARE(q.isActive(), true);
- QCOMPARE(q.isSelect(), true);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.isActive());
+ QVERIFY(q.isSelect());
// Test forward seek(n)
QVERIFY(q.seek(2));
@@ -1646,38 +1605,38 @@ void tst_QSqlQuery::forwardOnlyMultipleResultSet()
// 5. Result set with 1 row
QVERIFY(q.nextResult());
- QVERIFY(q.at() == QSql::BeforeFirstRow);
- QCOMPARE(q.isActive(), true);
- QCOMPARE(q.isSelect(), true);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.isActive());
+ QVERIFY(q.isSelect());
QVERIFY(q.first());
QCOMPARE(q.at(), 0);
QCOMPARE(q.value(0).toInt(), 5);
- QVERIFY(q.next() == false);
- QVERIFY(q.at() == QSql::AfterLastRow);
+ QVERIFY(!q.next());
+ QCOMPARE(q.at(), QSql::AfterLastRow);
// 6. Result set without rows
QVERIFY(q.nextResult());
- QVERIFY(q.at() == QSql::BeforeFirstRow);
- QCOMPARE(q.isActive(), true);
- QCOMPARE(q.isSelect(), true);
- QVERIFY(q.next() == false);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.isActive());
+ QVERIFY(q.isSelect());
+ QVERIFY(!q.next());
// 7. Result set with 5 rows
QVERIFY(q.nextResult());
- QVERIFY(q.at() == QSql::BeforeFirstRow);
- QCOMPARE(q.isActive(), true);
- QCOMPARE(q.isSelect(), true);
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.isActive());
+ QVERIFY(q.isSelect());
// Just skip it, so we move after last result set.
- QVERIFY(q.nextResult() == false);
- QVERIFY(q.at() == QSql::BeforeFirstRow);
- QCOMPARE(q.isActive(), false);
+ QVERIFY(!q.nextResult());
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(!q.isActive());
// See if we can execute another query
- QVERIFY_SQL(q, exec("select id from " + qtest + " where id=5"));
- QVERIFY(q.at() == QSql::BeforeFirstRow);
- QCOMPARE(q.isActive(), true);
- QCOMPARE(q.isSelect(), true);
+ QVERIFY_SQL(q, exec(QLatin1String("select id from %1 where id=5").arg(qtest)));
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.isActive());
+ QVERIFY(q.isSelect());
QVERIFY(q.first());
QCOMPARE(q.at(), 0);
QCOMPARE(q.value("id").toInt(), 5);
@@ -1693,7 +1652,7 @@ void tst_QSqlQuery::psql_forwardOnlyQueryResultsLost()
QSqlQuery q1(db);
q1.setForwardOnly(true);
- QVERIFY_SQL(q1, exec("select * from " + qtest + " where id<=3 order by id"));
+ QVERIFY_SQL(q1, exec(QLatin1String("select * from %1 where id<=3 order by id").arg(qtest)));
if (!q1.isForwardOnly())
QSKIP("DBMS doesn't support forward-only queries");
@@ -1706,7 +1665,7 @@ void tst_QSqlQuery::psql_forwardOnlyQueryResultsLost()
// will cause the query results of q1 to be lost.
QSqlQuery q2(db);
q2.setForwardOnly(true);
- QVERIFY_SQL(q2, exec("select * from " + qtest + " where id>3 order by id"));
+ QVERIFY_SQL(q2, exec(QLatin1String("select * from %1 where id>3 order by id").arg(qtest)));
QTest::ignoreMessage(QtWarningMsg, "QPSQLDriver::getResult: Query results lost - "
"probably discarded on executing another SQL query.");
@@ -1724,542 +1683,545 @@ void tst_QSqlQuery::psql_forwardOnlyQueryResultsLost()
void tst_QSqlQuery::query_exec()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QVERIFY( !q.isValid() );
- QVERIFY( !q.isActive() );
- QVERIFY_SQL( q, exec( "select * from " + qtest ) );
- QVERIFY( q.isActive() );
- QVERIFY( q.next() );
- QVERIFY( q.isValid() );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlQuery q(db);
+ QVERIFY(!q.isValid());
+ QVERIFY(!q.isActive());
+ QVERIFY_SQL(q, exec("select * from " + qtest));
+ QVERIFY(q.isActive());
+ QVERIFY(q.next());
+ QVERIFY(q.isValid());
}
void tst_QSqlQuery::isNull()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QVERIFY_SQL(q, exec("select id, t_varchar from " + qTableName("qtest_null", __FILE__, db) + " order by id"));
- QVERIFY( q.next() );
- QVERIFY( !q.isNull( 0 ) );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QLatin1String("select id, t_varchar from %1 order by id")
+ .arg(qTableName("qtest_null", __FILE__, db))));
+ QVERIFY(q.next());
+ QVERIFY(!q.isNull(0));
QVERIFY(!q.isNull("id"));
- QVERIFY( q.isNull( 1 ) );
+ QVERIFY(q.isNull(1));
QVERIFY(q.isNull("t_varchar"));
- QCOMPARE( q.value( 0 ).toInt(), 0 );
- QCOMPARE( q.value( 1 ).toString(), QString() );
- QVERIFY( !q.value( 0 ).isNull() );
- QVERIFY( q.value( 1 ).isNull() );
+ QCOMPARE(q.value(0).toInt(), 0);
+ QCOMPARE(q.value(1).toString(), QString());
+ QVERIFY(!q.value(0).isNull());
+ QVERIFY(q.value(1).isNull());
- QVERIFY( q.next() );
- QVERIFY( !q.isNull( 0 ) );
+ QVERIFY(q.next());
+ QVERIFY(!q.isNull(0));
QVERIFY(!q.isNull("id"));
- QVERIFY( !q.isNull( 1 ) );
+ QVERIFY(!q.isNull(1));
QVERIFY(!q.isNull("t_varchar"));
// For a non existent field, it should be returning true.
QVERIFY(q.isNull(2));
+ QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::isNull: unknown field name 'unknown'");
QVERIFY(q.isNull("unknown"));
}
-/*! TDS specific BIT field test */
-void tst_QSqlQuery::tds_bitField()
+void tst_QSqlQuery::writeNull()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- const QString tableName = qTableName("qtest_bittest", __FILE__, db);
- QSqlQuery q( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- QVERIFY_SQL(q, exec("create table " + tableName + " (bitty bit)"));
+ // The test data table is already used, so use a local hash to exercise the various
+ // 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 },
+ { 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 = [&](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())
+ ++size;
+ return size;
+ };
- QVERIFY_SQL(q, exec("insert into " + tableName + " values (0)"));
+ for (const auto &nullableType : nullableTypes.keys()) {
+ TableScope ts(db, "qtest_writenull", __FILE__);
+ QSqlQuery q(db);
- QVERIFY_SQL(q, exec("insert into " + tableName + " values (1)"));
+ 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 " + 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" : "",
+ 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(ts.tableName())));
+ q.bindValue(":id", expectedNullCount);
+ q.bindValue(":data", nonNullValue);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(countRowsWithNull(q, ts.tableName()), expectedNullCount);
- QVERIFY_SQL(q, exec("select bitty from " + tableName));
+ // 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(ts.tableName())));
+ q.bindValue(":id", ++expectedNullCount);
+ q.bindValue(":data", QVariant());
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(countRowsWithNull(q, ts.tableName()), expectedNullCount);
+
+ // Verify that writing a null-value (but not a null-variant) produces a
+ // null entry in the database:
+ const QMetaType nullableMetaType = nullableTypes.value(nullableType).metaType();
+ // Creating a QVariant with meta type and nullptr does create a null-QVariant. We want
+ // to explicitly create a non-null variant, so we have to pass in a default-constructed
+ // value as well (and make sure that the default value is also destroyed again,
+ // which is clumsy to do using std::unique_ptr with a custom deleter, so use another
+ // scope guard).
+ void *defaultData = nullableMetaType.create();
+ const auto defaultTypeDeleter = qScopeGuard([&]{ nullableMetaType.destroy(defaultData); });
+ const QVariant nullValueVariant(nullableMetaType, defaultData);
+ QVERIFY(!nullValueVariant.isNull());
+
+ 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(q, ts.tableName()), expectedNullCount);
- QVERIFY( q.next() );
+ // All tests passed for this type if we got here, so don't print diagnostics:
+ errorHandler.dismiss();
+ }
+}
- QVERIFY( q.value( 0 ).toInt() == 0 );
+// Oracle-specific NULL BLOB test:
+void tst_QSqlQuery::oci_nullBlob()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "qtest_nullblob", __FILE__);
- QVERIFY( q.next() );
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int primary key, bb blob)")
+ .arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (0, EMPTY_BLOB())")
+ .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(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(ts.tableName())));
- QVERIFY( q.value( 0 ).toInt() == 1 );
-}
+ QVERIFY(q.next());
+ QVERIFY(q.value(1).toByteArray().isEmpty());
+ QVERIFY(!q.isNull(1));
+ QVERIFY(q.next());
+ QVERIFY(q.value(1).toByteArray().isEmpty());
+ QVERIFY(q.isNull(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));
-
- QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "create table " + qtest_nullblob + " (id int primary key, bb blob)" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest_nullblob + " values (0, EMPTY_BLOB())" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest_nullblob + " values (1, NULL)" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest_nullblob + " values (2, 'aabbcc00112233445566')" ) );
- // necessary otherwise oracle will bombard you with internal errors
- q.setForwardOnly( true );
- QVERIFY_SQL( q, exec( "select * from " + qtest_nullblob + " order by id" ) );
-
- QVERIFY( q.next() );
- QCOMPARE(( int )q.value( 1 ).toByteArray().size(), 0 );
- QVERIFY( !q.isNull( 1 ) );
-
- QVERIFY( q.next() );
- QCOMPARE(( int )q.value( 1 ).toByteArray().size(), 0 );
- QVERIFY( q.isNull( 1 ) );
-
- QVERIFY( q.next() );
- QCOMPARE(( int )q.value( 1 ).toByteArray().size(), 10 );
- QVERIFY( !q.isNull( 1 ) );
+ QVERIFY(q.next());
+ QCOMPARE(q.value(1).toByteArray().size(), qsizetype(10));
+ QVERIFY(!q.isNull(1));
}
-/* Oracle specific RAW field test */
+/* Oracle-specific RAW field test */
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));
-
- QSqlQuery q( db );
- q.setForwardOnly( true );
- QVERIFY_SQL( q, exec( "create table " + qtest_rawtest +
- " (id int, col raw(20))" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest_rawtest + " values (0, NULL)" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtest_rawtest + " values (1, '00aa1100ddeeff')" ) );
- QVERIFY_SQL( q, exec( "select col from " + qtest_rawtest + " order by id" ) );
- QVERIFY( q.next() );
- QVERIFY( q.isNull( 0 ) );
- QCOMPARE(( int )q.value( 0 ).toByteArray().size(), 0 );
- QVERIFY( q.next() );
- QVERIFY( !q.isNull( 0 ) );
- QCOMPARE(( int )q.value( 0 ).toByteArray().size(), 7 );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(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(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(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());
+ QVERIFY(q.next());
+ QVERIFY(!q.isNull(0));
+ QCOMPARE(q.value(0).toByteArray().size(), qsizetype(7));
}
-// test whether we can fetch values with more than DOUBLE precision
+// Test whether we can fetch values with more than DOUBLE precision
// note that SQLite highest precision is that of a double, although
-// you can define field with higher precision
+// you can define field with higher precision:
void tst_QSqlQuery::precision()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::Interbase)
QSKIP("DB unable to store high precision");
- const auto oldPrecision = db.driver()->numericalPrecisionPolicy();
+ const auto tidier = qScopeGuard([db, oldPrecision = db.driver()->numericalPrecisionPolicy()]() {
+ db.driver()->setNumericalPrecisionPolicy(oldPrecision);
+ });
+
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 );
+ QSqlQuery q(db);
- q.exec("drop table " + qtest_precision);
- if (tst_Databases::isMSAccess(db))
- QVERIFY_SQL(q, exec("CREATE TABLE " + qtest_precision + " (col1 number)"));
- else
- QVERIFY_SQL(q, exec("CREATE TABLE " + qtest_precision + " (col1 numeric(21, 20))"));
+ QVERIFY_SQL(q, exec(QLatin1String(tst_Databases::isMSAccess(db)
+ ? "CREATE TABLE %1 (col1 number)"
+ : "CREATE TABLE %1 (col1 numeric(21, 20))")
+ .arg(ts.tableName())));
- QVERIFY_SQL(q, exec("INSERT INTO " + qtest_precision + " (col1) VALUES (" + precStr + ")"));
- QVERIFY_SQL(q, exec("SELECT * FROM " + qtest_precision));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (col1) VALUES (%2)")
+ .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)) {
int i = 0;
while (i < val.size() && precStr[i] != 0 && precStr[i] == val[i].toLatin1())
- i++;
+ ++i;
// TDS has crappy precisions by default
if (dbType == QSqlDriver::Sybase) {
if (i < 18)
- QWARN("TDS didn't return the right precision");
+ qWarning("TDS didn't return the right precision");
} else {
- QWARN(QString(tst_Databases::dbToString(db) + " didn't return the right precision (" +
- QString::number(i) + " out of 21), " + val).toUtf8());
+ qWarning() << tst_Databases::dbToString(db) << "didn't return the right precision ("
+ << i << "out of 21)," << val;
}
}
} // SQLITE scope
- db.driver()->setNumericalPrecisionPolicy(oldPrecision);
}
void tst_QSqlQuery::nullResult()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "select * from " + qtest + " where id > 50000" ) );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- if ( q.driver()->hasFeature( QSqlDriver::QuerySize ) )
- QCOMPARE( q.size(), 0 );
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QLatin1String("select * from %1 where id > 50000").arg(qtest)));
- QVERIFY( q.next() == false );
+ if (q.driver()->hasFeature(QSqlDriver::QuerySize))
+ QCOMPARE(q.size(), 0);
- QVERIFY( q.first() == false );
- QVERIFY( q.last() == false );
- QVERIFY( q.previous() == false );
- QVERIFY( q.seek( 10 ) == false );
- QVERIFY( q.seek( 0 ) == false );
+ QVERIFY(!q.next());
+ QVERIFY(!q.first());
+ QVERIFY(!q.last());
+ QVERIFY(!q.previous());
+ QVERIFY(!q.seek(10));
+ 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()
+void tst_QSqlQuery::joins()
{
- // 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 );
+ 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( "insert into" + qtest + " values (40, 'VarChar40', 'Char40')" ) );
-
- QVERIFY_SQL( q, exec( "select * from" + qtest + " where id = 40" ) );
-
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), 40 );
-
- QVERIFY_SQL( q, exec( "commit" ) );
-
- QVERIFY_SQL( q, exec( "select * from" + qtest + " where id = 40" ) );
-
- QVERIFY( q.next() );
-
- QCOMPARE( q.value( 0 ).toInt(), 40 );
-
- // test a rollback
- q.exec( startTransactionStr );
-
- QVERIFY_SQL( q, exec( "insert into" + qtest + " values (41, 'VarChar41', 'Char41')" ) );
-
- QVERIFY_SQL( q, exec( "select * from" + qtest + " where id = 41" ) );
-
- 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() ) );
+ 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__);
- QVERIFY_SQL( q, exec( "select * from" + qtest + " where id = 41" ) );
-
- QVERIFY( q.next() == false );
-
- // test concurrent access
- q.exec( startTransactionStr );
- QVERIFY_SQL( q, exec( "insert into" + qtest + " values (42, 'VarChar42', 'Char42')" ) );
- QVERIFY_SQL( q, exec( "select * from" + qtest + " where id = 42" ) );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), 42 );
-
- QVERIFY_SQL( q2, exec( "select * from" + qtest + " where id = 42" ) );
-
- 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( "select * from" + qtest + " where id = 42" ) );
+ QSqlQuery q(db);
- QVERIFY( q2.next() );
+ 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())));
- QCOMPARE( q2.value( 0 ).toInt(), 42 );
-}
+ 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(j1.tableName(), j2.tableName())));
-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)), qtestj2(qTableName("qtestj2", __FILE__, db));
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), 1);
+ QCOMPARE(q.value(1).toInt(), 1);
+ QCOMPARE(q.value(2).toInt(), 1);
+ QCOMPARE(q.value(3).toString(), u"trenton");
+ QCOMPARE(q.value(4).toInt(), 1);
+ QCOMPARE(q.value(5).toString(), u"trenton");
- 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");
-
- QSqlQuery q( db );
-
- QVERIFY_SQL( q, exec( "create table " + qtestj1 + " (id1 int, id2 int)" ) );
- QVERIFY_SQL( q, exec( "create table " + qtestj2 + " (id int, name varchar(20))" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtestj1 + " values (1, 1)" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtestj1 + " values (1, 2)" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtestj2 + " values(1, 'trenton')" ) );
- QVERIFY_SQL( q, exec( "insert into " + qtestj2 + " values(2, 'marius')" ) );
-
- QVERIFY_SQL( q, exec( "select qtestj1.id1, qtestj1.id2, qtestj2.id, qtestj2.name, qtestj3.id, qtestj3.name "
- "from " + qtestj1 + " qtestj1 left outer join " + qtestj2 +
- " qtestj2 on (qtestj1.id1 = qtestj2.id) "
- "left outer join " + qtestj2 + " as qtestj3 on (qtestj1.id2 = qtestj3.id)" ) );
-
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
- QCOMPARE( q.value( 1 ).toInt(), 1 );
- QCOMPARE( q.value( 2 ).toInt(), 1 );
- QCOMPARE( q.value( 3 ).toString(), QString( "trenton" ) );
- QCOMPARE( q.value( 4 ).toInt(), 1 );
- QCOMPARE( q.value( 5 ).toString(), QString( "trenton" ) );
-
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
- QCOMPARE( q.value( 1 ).toInt(), 2 );
- QCOMPARE( q.value( 2 ).toInt(), 1 );
- QCOMPARE( q.value( 3 ).toString(), QString( "trenton" ) );
- QCOMPARE( q.value( 4 ).toInt(), 2 );
- QCOMPARE( q.value( 5 ).toString(), QString( "marius" ) );
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), 1);
+ QCOMPARE(q.value(1).toInt(), 2);
+ QCOMPARE(q.value(2).toInt(), 1);
+ QCOMPARE(q.value(3).toString(), u"trenton");
+ QCOMPARE(q.value(4).toInt(), 2);
+ QCOMPARE(q.value(5).toString(), u"marius");
}
void tst_QSqlQuery::synonyms()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
QSqlQuery q(db);
- QVERIFY_SQL( q, exec("select a.id, a.t_char, a.t_varchar from " + qtest + " a where a.id = 1") );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
- QCOMPARE( q.value( 1 ).toString().trimmed(), QString( "Char1" ) );
- QCOMPARE( q.value( 2 ).toString().trimmed(), QString( "VarChar1" ) );
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "select a.id, a.t_char, a.t_varchar from %1 a where a.id = 1")
+ .arg(qtest)));
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), 1);
+ QCOMPARE(q.value(1).toString().trimmed(), u"Char1");
+ QCOMPARE(q.value(2).toString().trimmed(), u"VarChar1");
QSqlRecord rec = q.record();
- QCOMPARE(( int )rec.count(), 3 );
- QCOMPARE( rec.field( 0 ).name().toLower(), QString( "id" ) );
- QCOMPARE( rec.field( 1 ).name().toLower(), QString( "t_char" ) );
- QCOMPARE( rec.field( 2 ).name().toLower(), QString( "t_varchar" ) );
+ QCOMPARE(rec.count(), qsizetype(3));
+ QCOMPARE(rec.field(0).name().toLower(), u"id");
+ QCOMPARE(rec.field(1).name().toLower(), u"t_char");
+ QCOMPARE(rec.field(2).name().toLower(), u"t_varchar");
}
// It doesn't make sense to split this into several tests
void tst_QSqlQuery::prepare_bind_exec()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ 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");
- {
- // new scope for SQLITE
- static const QString utf8str = QString::fromUtf8( "काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम् ॥" );
+ { // New scope for SQLITE:
+ static const QString utf8str = QString::fromUtf8("काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम् ॥");
- static const QString values[6] = { "Harry", "Trond", "Mark", "Ma?rk", "?", ":id" };
+ static const QString values[6] = {
+ u"Harry"_s, u"Trond"_s, u"Mark"_s, u"Ma?rk"_s, u"?"_s, u":id"_s
+ };
- bool useUnicode = db.driver()->hasFeature( QSqlDriver::Unicode );
+ bool useUnicode = db.driver()->hasFeature(QSqlDriver::Unicode);
- QSqlQuery q( db );
- QString createQuery;
+ QSqlQuery q(db);
+ QLatin1String createQuery;
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::PostgreSQL)
- QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
-
- if (dbType == QSqlDriver::MSSqlServer || dbType == QSqlDriver::Sybase)
- createQuery = "create table " + qtest_prepare + " (id int primary key, name nvarchar(200) null, name2 nvarchar(200) null)";
- else if (dbType == QSqlDriver::MySqlServer && useUnicode)
- createQuery = "create table " + qtest_prepare + " (id int not null primary key, name varchar(200) character set utf8, name2 varchar(200) character set utf8)";
- else
- createQuery = "create table " + qtest_prepare + " (id int not null primary key, name varchar(200), name2 varchar(200))";
-
- q.exec("drop table " + qtest_prepare);
- QVERIFY_SQL( q, exec( createQuery ) );
-
- QVERIFY( q.prepare( "insert into " + qtest_prepare + " (id, name) values (:id, :name)" ) );
- int i;
+ QVERIFY_SQL(q, exec("set client_min_messages='warning'"));
+
+ 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;
+ case QSqlDriver::MySqlServer:
+ if (useUnicode) {
+ createQuery = QLatin1String("create table %1 (id int not null primary key, "
+ "name varchar(200) character set utf8, "
+ "name2 varchar(200) character set utf8)");
+ break;
+ }
+ Q_FALLTHROUGH();
+ default:
+ createQuery = QLatin1String("create table %1 (id int not null primary key, "
+ "name varchar(200), name2 varchar(200))");
+ break;
+ }
- for ( i = 0; i < 6; ++i ) {
- q.bindValue( ":name", values[i] );
- q.bindValue( ":id", i );
- QVERIFY_SQL( q, exec() );
- QVariantList m = q.boundValues();
- QCOMPARE(( int ) m.count(), 2 );
+ QVERIFY_SQL(q, exec(createQuery.arg(qtest_prepare)));
+ QVERIFY(q.prepare(QLatin1String("insert into %1 (id, name) values (:id, :name)")
+ .arg(qtest_prepare)));
+ 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.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 );
-
- QVERIFY_SQL( q, exec() );
+ q.bindValue(":id", 8);
+ QVERIFY_SQL(q, exec());
- if ( useUnicode ) {
- q.bindValue( ":id", 7 );
- q.bindValue( ":name", utf8str );
- QVERIFY_SQL( q, exec() );
+ if (useUnicode) {
+ q.bindValue(":id", 7);
+ q.bindValue(":name", utf8str);
+ QVERIFY_SQL(q, exec());
}
- QVERIFY_SQL( q, exec( "SELECT * FROM " + qtest_prepare + " order by id" ) );
-
- for ( i = 0; i < 6; ++i ) {
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), i );
- QCOMPARE( q.value( 1 ).toString().trimmed(), values[ i ] );
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT * FROM %1 order by id").arg(qtest_prepare)));
+ for (int i = 0; i < 6; ++i) {
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), i);
+ QCOMPARE(q.value(1).toString().trimmed(), values[i]);
}
- if ( useUnicode ) {
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), 7 );
- QCOMPARE( q.value( 1 ).toString(), utf8str );
+ if (useUnicode) {
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), 7);
+ QCOMPARE(q.value(1).toString(), utf8str);
}
- QVERIFY_SQL( q, next() );
-
- QCOMPARE( q.value( 0 ).toInt(), 8 );
- QCOMPARE( q.value( 1 ).toString(), values[5] );
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), 8);
+ QCOMPARE(q.value(1).toString(), values[5]);
- QVERIFY( q.prepare( "insert into " + qtest_prepare + " (id, name) values (:id, 'Bart')" ) );
- q.bindValue( ":id", 99 );
- QVERIFY_SQL( q, exec() );
- q.bindValue( ":id", 100 );
- QVERIFY_SQL( q, exec() );
- QVERIFY( q.exec( "select * from " + qtest_prepare + " where id > 98 order by id" ) );
+ QVERIFY(q.prepare(QLatin1String("insert into %1 (id, name) values (:id, 'Bart')")
+ .arg(qtest_prepare)));
+ q.bindValue(":id", 99);
+ QVERIFY_SQL(q, exec());
+ q.bindValue(":id", 100);
+ QVERIFY_SQL(q, exec());
+ QVERIFY(q.exec(QLatin1String("select * from %1 where id > 98 order by id")
+ .arg(qtest_prepare)));
- for ( i = 99; i <= 100; ++i ) {
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), i );
- QCOMPARE( q.value( 1 ).toString().trimmed(), QString( "Bart" ) );
+ for (int i = 99; i <= 100; ++i) {
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), i);
+ QCOMPARE(q.value(1).toString().trimmed(), u"Bart");
}
/*** SELECT stuff ***/
- QVERIFY( q.prepare( "select * from " + qtest_prepare + " where id = :id" ) );
-
- for ( i = 0; i < 6; ++i ) {
- q.bindValue( ":id", i );
- QVERIFY_SQL( q, exec() );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), i );
- QCOMPARE( q.value( 1 ).toString().trimmed(), values[ i ] );
+ QVERIFY(q.prepare(QLatin1String("select * from %1 where id = :id").arg(qtest_prepare)));
+
+ for (int i = 0; i < 6; ++i) {
+ q.bindValue(":id", i);
+ QVERIFY_SQL(q, exec());
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), i);
+ QCOMPARE(q.value(1).toString().trimmed(), values[i]);
QSqlRecord rInf = q.record();
- QCOMPARE(( int )rInf.count(), 3 );
- QCOMPARE( rInf.field( 0 ).name().toUpper(), QString( "ID" ) );
- QCOMPARE( rInf.field( 1 ).name().toUpper(), QString( "NAME" ) );
- QVERIFY( !q.next() );
+ QCOMPARE(rInf.count(), qsizetype(3));
+ QCOMPARE(rInf.field(0).name().toUpper(), u"ID");
+ QCOMPARE(rInf.field(1).name().toUpper(), u"NAME");
+ QVERIFY(!q.next());
}
- QVERIFY_SQL( q, exec( "DELETE FROM " + qtest_prepare ) );
-
- /*** Below we test QSqlQuery::boundValues() with position arguments.
- * Due to the fact that the name of a positional argument is not
- * specified by the Qt docs, we test that the QList contains
- * the correct values in the same order as QSqlResult::boundValueName
- * returns since it should be in insertion order (i.e. field order). ***/
- QVERIFY( q.prepare( "insert into " + qtest_prepare + " (id, name) values (?, ?)" ) );
- q.bindValue( 0, 0 );
- q.bindValue( 1, values[ 0 ] );
- QCOMPARE( q.boundValues().size(), 2 );
+ QVERIFY_SQL(q, exec("DELETE FROM " + qtest_prepare));
+
+ /* Below we test QSqlQuery::boundValues() with position arguments.
+ Due to the fact that the name of a positional argument is not
+ specified by the Qt docs, we test that the QList contains the correct
+ values in the same order as QSqlResult::boundValueName returns since
+ it should be in insertion order (i.e. field order). */
+ QVERIFY(q.prepare(QLatin1String("insert into %1 (id, name) values (?, ?)")
+ .arg(qtest_prepare)));
+ q.bindValue(0, 0);
+ q.bindValue(1, values[0]);
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 0);
QCOMPARE(q.boundValues().at(1).toString(), values[0]);
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValues().size(), 2 );
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 0);
QCOMPARE(q.boundValues().at(1).toString(), values[0]);
- q.addBindValue( 1 );
- q.addBindValue( values[ 1 ] );
- QCOMPARE( q.boundValues().size(), 2 );
+ q.addBindValue(1);
+ q.addBindValue(values[1]);
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 1);
QCOMPARE(q.boundValues().at(1).toString(), values[1]);
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValues().size(), 2 );
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 1);
QCOMPARE(q.boundValues().at(1).toString(), values[1]);
- q.addBindValue( 2 );
- q.addBindValue( values[ 2 ] );
- QCOMPARE( q.boundValues().size(), 2 );
+ q.addBindValue(2);
+ q.addBindValue(values[2]);
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 2);
QCOMPARE(q.boundValues().at(1).toString(), values[2]);
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValues().size(), 2 );
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 2);
QCOMPARE(q.boundValues().at(1).toString(), values[2]);
- q.addBindValue( 3 );
- q.addBindValue( values[ 3 ] );
- QCOMPARE( q.boundValues().size(), 2 );
+ q.addBindValue(3);
+ q.addBindValue(values[3]);
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 3);
QCOMPARE(q.boundValues().at(1).toString(), values[3]);
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValues().size(), 2 );
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 3);
QCOMPARE(q.boundValues().at(1).toString(), values[3]);
- q.addBindValue( 4 );
- q.addBindValue( values[ 4 ] );
- QCOMPARE( q.boundValues().size(), 2 );
+ q.addBindValue(4);
+ q.addBindValue(values[4]);
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 4);
QCOMPARE(q.boundValues().at(1).toString(), values[4]);
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValues().size(), 2 );
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 4);
QCOMPARE(q.boundValues().at(1).toString(), values[4]);
- q.bindValue( 1, values[ 5 ] );
- q.bindValue( 0, 5 );
- QCOMPARE( q.boundValues().size(), 2 );
+ q.bindValue(1, values[5]);
+ q.bindValue(0, 5);
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 5);
QCOMPARE(q.boundValues().at(1).toString(), values[5]);
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValues().size(), 2 );
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 5);
QCOMPARE(q.boundValues().at(1).toString(), values[5]);
- q.bindValue( 0, 6 );
- q.bindValue( 1, QString() );
- QCOMPARE( q.boundValues().size(), 2 );
+ q.bindValue(0, 6);
+ q.bindValue(1, QString());
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 6);
QCOMPARE(q.boundValues().at(1).toString(), QString());
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.boundValues().size(), 2 );
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.boundValues().size(), 2);
QCOMPARE(q.boundValues().at(0).toInt(), 6);
QCOMPARE(q.boundValues().at(1).toString(), QString());
- if ( db.driver()->hasFeature( QSqlDriver::Unicode ) ) {
- q.bindValue( 0, 7 );
- q.bindValue( 1, utf8str );
+ if (db.driver()->hasFeature(QSqlDriver::Unicode)) {
+ q.bindValue(0, 7);
+ q.bindValue(1, utf8str);
QCOMPARE(q.boundValues().at(0).toInt(), 7);
QCOMPARE(q.boundValues().at(1).toString(), utf8str);
- QVERIFY_SQL( q, exec() );
+ QVERIFY_SQL(q, exec());
QCOMPARE(q.boundValues().at(0).toInt(), 7);
QCOMPARE(q.boundValues().at(1).toString(), utf8str);
}
@@ -2274,234 +2236,227 @@ void tst_QSqlQuery::prepare_bind_exec()
QCOMPARE(q.boundValues().at(2).toInt(), 10);
QFAIL_SQL(q, exec());
- QVERIFY_SQL( q, exec( "SELECT * FROM " + qtest_prepare + " order by id" ) );
-
- for ( i = 0; i < 6; ++i ) {
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), i );
- QCOMPARE( q.value( 1 ).toString().trimmed(), values[ i ] );
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT * FROM %1 order by id").arg(qtest_prepare)));
+ for (int i = 0; i < 6; ++i) {
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), i);
+ QCOMPARE(q.value(1).toString().trimmed(), values[i]);
}
- QVERIFY( q.next() );
+ QVERIFY(q.next());
- QCOMPARE( q.value( 0 ).toInt(), 6 );
- QVERIFY( q.value( 1 ).toString().isEmpty() );
+ QCOMPARE(q.value(0).toInt(), 6);
+ QVERIFY(q.value(1).toString().isEmpty());
- if ( useUnicode ) {
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), 7 );
- QCOMPARE( q.value( 1 ).toString(), utf8str );
+ if (useUnicode) {
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), 7);
+ QCOMPARE(q.value(1).toString(), utf8str);
}
- QVERIFY( q.prepare( "insert into " + qtest_prepare + " (id, name) values (?, 'Bart')" ) );
-
- q.bindValue( 0, 99 );
- QVERIFY_SQL( q, exec() );
- q.addBindValue( 100 );
- QVERIFY_SQL( q, exec() );
- QVERIFY( q.exec( "select * from " + qtest_prepare + " where id > 98 order by id" ) );
+ QVERIFY(q.prepare(QLatin1String("insert into %1 (id, name) values (?, 'Bart')")
+ .arg(qtest_prepare)));
+ q.bindValue(0, 99);
+ QVERIFY_SQL(q, exec());
+ q.addBindValue(100);
+ QVERIFY_SQL(q, exec());
- for ( i = 99; i <= 100; ++i ) {
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), i );
- QCOMPARE( q.value( 1 ).toString().trimmed(), QString( "Bart" ) );
+ QVERIFY(q.exec(QLatin1String("select * from %1 where id > 98 order by id")
+ .arg(qtest_prepare)));
+ for (int i = 99; i <= 100; ++i) {
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), i);
+ QCOMPARE(q.value(1).toString().trimmed(), u"Bart");
}
- /* insert a duplicate id and make sure the db bails out */
- QVERIFY( q.prepare( "insert into " + qtest_prepare + " (id, name) values (?, ?)" ) );
-
+ // Insert a duplicate id and make sure the db bails out:
+ QVERIFY(q.prepare(QLatin1String("insert into %1 (id, name) values (?, ?)")
+ .arg(qtest_prepare)));
q.addBindValue( 99 );
+ q.addBindValue(u"something silly"_s);
- q.addBindValue( "something silly" );
-
- QVERIFY( !q.exec() );
+ QVERIFY(!q.exec());
+ QVERIFY(q.lastError().isValid());
+ QVERIFY(!q.isActive());
- QVERIFY( q.lastError().isValid() );
-
- QVERIFY( !q.isActive() );
-
- QVERIFY( q.prepare( "insert into " + qtest_prepare + " (id, name, name2) values (:id, :name, :name)" ) );
- for ( i = 101; i < 103; ++i ) {
- q.bindValue( ":id", i );
- q.bindValue( ":name", "name" );
- QVERIFY( q.exec() );
+ QVERIFY(q.prepare(QLatin1String(
+ "insert into %1 (id, name, name2) values (:id, :name, :name)")
+ .arg(qtest_prepare)));
+ for (int i = 101; i < 103; ++i) {
+ q.bindValue(":id", i);
+ q.bindValue(":name", "name");
+ QVERIFY(q.exec());
}
// Test for QTBUG-6420
- QVERIFY( q.exec( "select * from " + qtest_prepare + " where id > 100 order by id" ) );
- QVERIFY( q.next() );
- QCOMPARE( q.value(0).toInt(), 101 );
- QCOMPARE( q.value(1).toString(), QString("name") );
- QCOMPARE( q.value(2).toString(), QString("name") );
-
- // Test that duplicated named placeholders before the next unique one works correctly - QTBUG-65150
- QVERIFY(q.prepare("insert into " + qtest_prepare + " (id, name, name2) values (:id, :id, :name)"));
- for (i = 104; i < 106; ++i) {
+ QVERIFY(q.exec(QLatin1String("select * from %1 where id > 100 order by id")
+ .arg(qtest_prepare)));
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), 101);
+ QCOMPARE(q.value(1).toString(), u"name");
+ QCOMPARE(q.value(2).toString(), u"name");
+
+ // Test that duplicated named placeholders before the next unique one
+ // works correctly - QTBUG-65150
+ QVERIFY(q.prepare(QLatin1String("insert into %1 (id, name, name2) values (:id, :id, :name)")
+ .arg(qtest_prepare)));
+ for (int i = 104; i < 106; ++i) {
q.bindValue(":id", i);
q.bindValue(":name", "name");
QVERIFY(q.exec());
}
- QVERIFY(q.exec("select * from " + qtest_prepare + " where id > 103 order by id"));
+ QVERIFY(q.exec(QLatin1String("select * from %1 where id > 103 order by id")
+ .arg(qtest_prepare)));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 104);
- QCOMPARE(q.value(1).toString(), QString("104"));
- QCOMPARE(q.value(2).toString(), QString("name"));
+ QCOMPARE(q.value(1).toString(), u"104");
+ QCOMPARE(q.value(2).toString(), u"name");
// Test that duplicated named placeholders in any order
- QVERIFY(q.prepare("insert into " + qtest_prepare + " (id, name, name2) values (:id, :name, :id)"));
- for (i = 107; i < 109; ++i) {
+ QVERIFY(q.prepare(QLatin1String("insert into %1 (id, name, name2) values (:id, :name, :id)")
+ .arg(qtest_prepare)));
+ for (int i = 107; i < 109; ++i) {
q.bindValue(":id", i);
q.bindValue(":name", "name");
QVERIFY(q.exec());
}
- QVERIFY(q.exec("select * from " + qtest_prepare + " where id > 106 order by id"));
+ QVERIFY(q.exec(QLatin1String("select * from %1 where id > 106 order by id")
+ .arg(qtest_prepare)));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 107);
- QCOMPARE(q.value(1).toString(), QString("name"));
- QCOMPARE(q.value(2).toString(), QString("107"));
+ QCOMPARE(q.value(1).toString(), u"name");
+ QCOMPARE(q.value(2).toString(), u"107");
// Test just duplicated placeholders
- QVERIFY(q.prepare("insert into " + qtest_prepare + " (id, name, name2) values (110, :name, :name)"));
+ QVERIFY(q.prepare(QLatin1String(
+ "insert into %1 (id, name, name2) values (110, :name, :name)")
+ .arg(qtest_prepare)));
q.bindValue(":name", "name");
QVERIFY_SQL(q, exec());
- QVERIFY(q.exec("select * from " + qtest_prepare + " where id > 109 order by id"));
+ QVERIFY(q.exec(QLatin1String("select * from %1 where id > 109 order by id")
+ .arg(qtest_prepare)));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 110);
- QCOMPARE(q.value(1).toString(), QString("name"));
- QCOMPARE(q.value(2).toString(), QString("name"));
- } // end of SQLite scope
+ QCOMPARE(q.value(1).toString(), u"name");
+ QCOMPARE(q.value(2).toString(), u"name");
+ } // End of SQLite scope.
}
void tst_QSqlQuery::prepared_select()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- QVERIFY_SQL( q, prepare( "select a.id, a.t_char, a.t_varchar from " + qtest + " a where a.id = ?" ) );
-
- q.bindValue( 0, 1 );
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.at(), ( int )QSql::BeforeFirstRow );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
-
- q.bindValue( 0, 2 );
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.at(), ( int )QSql::BeforeFirstRow );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), 2 );
-
- q.bindValue( 0, 3 );
- QVERIFY_SQL( q, exec() );
- QCOMPARE( q.at(), ( int )QSql::BeforeFirstRow );
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), 3 );
-
- QVERIFY_SQL( q, prepare( "select a.id, a.t_char, a.t_varchar from " + qtest + " a where a.id = ?" ) );
- QCOMPARE( q.at(), ( int )QSql::BeforeFirstRow );
- QVERIFY( !q.first() );
-}
-
-void tst_QSqlQuery::sqlServerLongStrings()
-{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType != QSqlDriver::MSSqlServer)
- QSKIP( "SQL Server specific test");
-
- QSqlQuery q( db );
-
- QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("qtest_longstr", __FILE__, db) + " (id int primary key, longstring ntext)"));
-
- QVERIFY_SQL(q, prepare("INSERT INTO " + qTableName("qtest_longstr", __FILE__, db) + " VALUES (?, ?)"));
-
- q.addBindValue( 0 );
-
- q.addBindValue( QString::fromLatin1( "bubu" ) );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ const QString query = QLatin1String(
+ "select a.id, a.t_char, a.t_varchar from %1 a where a.id = ?").arg(qtest);
- QVERIFY_SQL( q, exec() );
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, prepare(query));
- QString testStr;
+ q.bindValue(0, 1);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), 1);
- testStr.fill( QLatin1Char( 'a' ), 85000 );
+ q.bindValue(0, 2);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), 2);
- q.addBindValue( 1 );
+ q.bindValue(0, 3);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), 3);
- q.addBindValue( testStr );
+ QVERIFY_SQL(q, prepare(query));
+ QCOMPARE(q.at(), QSql::BeforeFirstRow);
+ QVERIFY(!q.first());
+}
- QVERIFY_SQL( q, exec() );
+void tst_QSqlQuery::sqlServerLongStrings()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ if (tst_Databases::getDatabaseType(db) != QSqlDriver::MSSqlServer)
+ QSKIP("Test is specific to SQL Server");
- QVERIFY_SQL(q, exec("select * from " + qTableName( "qtest_longstr", __FILE__, db)));
+ TableScope ts(db, "qtest_longstr", __FILE__);
+ QSqlQuery q(db);
- QVERIFY_SQL( q, next() );
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id int primary key, longstring ntext)")
+ .arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 VALUES (?, ?)").arg(ts.tableName())));
- QCOMPARE( q.value( 0 ).toInt(), 0 );
+ q.addBindValue(0);
+ q.addBindValue(u"bubu"_s);
+ QVERIFY_SQL(q, exec());
- QCOMPARE( q.value( 1 ).toString(), QString::fromLatin1( "bubu" ) );
+ const QString testStr(85000, QLatin1Char('a'));
- QVERIFY_SQL( q, next() );
+ q.addBindValue(1);
+ q.addBindValue(testStr);
+ QVERIFY_SQL(q, exec());
+ QVERIFY_SQL(q, exec("select * from " + ts.tableName()));
- QCOMPARE( q.value( 0 ).toInt(), 1 );
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), 0);
+ QCOMPARE(q.value(1).toString(), u"bubu");
- QCOMPARE( q.value( 1 ).toString(), testStr );
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), 1);
+ QCOMPARE(q.value(1).toString(), testStr);
}
void tst_QSqlQuery::invalidQuery()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- QSqlQuery q( db );
+ QSqlQuery q(db);
- QVERIFY( !q.exec() );
+ QVERIFY(!q.exec());
- QVERIFY( !q.exec( "blahfasel" ) );
- QVERIFY( q.lastError().type() != QSqlError::NoError );
- QVERIFY( !q.next() );
- QVERIFY( !q.isActive() );
+ QVERIFY(!q.exec("blahfasel"));
+ QVERIFY(q.lastError().type() != QSqlError::NoError);
+ QVERIFY(!q.next());
+ QVERIFY(!q.isActive());
- if (dbType != QSqlDriver::Oracle && dbType != QSqlDriver::DB2 && !db.driverName().startsWith("QODBC")) {
- // oracle and db2 just prepares everything without complaining
- if ( db.driver()->hasFeature( QSqlDriver::PreparedQueries ) )
- QVERIFY( !q.prepare( "blahfasel" ) );
+ if (dbType != QSqlDriver::Oracle && dbType != QSqlDriver::DB2
+ && !db.driverName().startsWith("QODBC")) {
+ // Oracle and DB2 just prepare everything without complaining:
+ if (db.driver()->hasFeature(QSqlDriver::PreparedQueries))
+ QVERIFY(!q.prepare("blahfasel"));
}
- QVERIFY( !q.exec() );
-
- QVERIFY( !q.isActive() );
- QVERIFY( !q.next() );
+ QVERIFY(!q.exec());
+ QVERIFY(!q.isActive());
+ QVERIFY(!q.next());
}
void tst_QSqlQuery::batchExec()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- const QString tableName = qTableName("qtest_batch", __FILE__, db);
- tst_Databases::safeDropTable(db, tableName);
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ QSqlQuery q(db);
+ TableScope ts(db, "qtest_batch", __FILE__);
+ const auto &tableName = ts.tableName();
const auto dbType = tst_Databases::getDatabaseType(db);
- QString timeStampString;
- if (dbType == QSqlDriver::Interbase)
- timeStampString = QLatin1String("TIMESTAMP");
- else
- timeStampString = QLatin1String("TIMESTAMP (3)");
+ QLatin1String timeStampString(dbType == QSqlDriver::Interbase ? "TIMESTAMP" : "TIMESTAMP (3)");
- QVERIFY_SQL(q, exec(QStringLiteral("create table ") + tableName +
- QStringLiteral(" (id int, name varchar(20), dt date, num numeric(8, 4), "
- "dtstamp ") + timeStampString +
- QStringLiteral(", extraId int, extraName varchar(20))")));
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create table %2 (id int, name varchar(20), dt date, "
+ "num numeric(8, 4), dtstamp %1, extraId int, extraName varchar(20))")
+ .arg(timeStampString, tableName)));
const QVariantList intCol = { 1, 2, QVariant(QMetaType(QMetaType::Int)) };
- const QVariantList charCol = { QStringLiteral("harald"), QStringLiteral("boris"),
+ const QVariantList charCol = { u"harald"_s, u"boris"_s,
QVariant(QMetaType(QMetaType::QString)) };
const QDateTime currentDateTime = QDateTime(QDateTime::currentDateTime());
const QVariantList dateCol = { currentDateTime.date(), currentDateTime.date().addDays(-1),
@@ -2511,30 +2466,31 @@ void tst_QSqlQuery::batchExec()
QVariant(QMetaType(QMetaType::QDateTime)) };
// Test with positional placeholders
- QVERIFY_SQL(q, prepare(QStringLiteral("insert into ") + tableName +
- QStringLiteral(" (id, name, dt, num, dtstamp, extraId, extraName) values "
- "(?, ?, ?, ?, ?, ?, ?)")));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 "
+ "(id, name, dt, num, dtstamp, extraId, extraName) "
+ "values (?, ?, ?, ?, ?, ?, ?)").arg(tableName)));
q.addBindValue(intCol);
- q.addBindValue( charCol );
- q.addBindValue( dateCol );
- q.addBindValue( numCol );
+ q.addBindValue(charCol);
+ q.addBindValue(dateCol);
+ q.addBindValue(numCol);
q.addBindValue(timeStampCol);
q.addBindValue(intCol);
q.addBindValue(charCol);
- QVERIFY_SQL( q, execBatch() );
- QVERIFY_SQL(q, exec(QStringLiteral("select id, name, dt, num, dtstamp, "
- "extraId, extraName from ") + tableName));
+ QVERIFY_SQL(q, execBatch());
+ QVERIFY_SQL(q, exec(QLatin1String("select id, name, dt, num, dtstamp, extraId, extraName from ")
+ + tableName));
for (int i = 0; i < intCol.size(); ++i) {
QVERIFY(q.next());
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));
- 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 the "
- "current datetime for a timestamp field", Continue);
+ 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 "
+ "the current datetime for a timestamp field", Continue);
}
QCOMPARE(q.value(4).toDateTime(), timeStampCol.at(i));
QCOMPARE(q.value(5).toInt(), intCol.at(i));
@@ -2542,10 +2498,11 @@ void tst_QSqlQuery::batchExec()
}
// Empty table ready for retesting with duplicated named placeholders
- QVERIFY_SQL(q, exec(QStringLiteral("delete from ") + tableName));
- QVERIFY_SQL(q, prepare(QStringLiteral("insert into ") + tableName +
- QStringLiteral(" (id, name, dt, num, dtstamp, extraId, extraName) "
- "values (:id, :name, :dt, :num, :dtstamp, :id, :name)")));
+ QVERIFY_SQL(q, exec(QLatin1String("delete from ") + tableName));
+ QVERIFY_SQL(q, prepare(QLatin1String(
+ "insert into %1 (id, name, dt, num, dtstamp, extraId, extraName) "
+ "values (:id, :name, :dt, :num, :dtstamp, :id, :name)")
+ .arg(tableName)));
q.bindValue(":id", intCol);
q.bindValue(":name", charCol);
q.bindValue(":dt", dateCol);
@@ -2553,18 +2510,19 @@ void tst_QSqlQuery::batchExec()
q.bindValue(":dtstamp", timeStampCol);
QVERIFY_SQL(q, execBatch());
- QVERIFY_SQL(q, exec(QStringLiteral("select id, name, dt, num, dtstamp, extraId, extraName from ") +
- tableName));
+ QVERIFY_SQL(q, exec(QLatin1String("select id, name, dt, num, dtstamp, extraId, extraName from ")
+ + tableName));
for (int i = 0; i < intCol.size(); ++i) {
QVERIFY(q.next());
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));
- 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 the "
- "current datetime for a timestamp field", Continue);
+ 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 "
+ "the current datetime for a timestamp field", Continue);
}
QCOMPARE(q.value(4).toDateTime(), timeStampCol.at(i));
QCOMPARE(q.value(5).toInt(), intCol.at(i));
@@ -2572,19 +2530,21 @@ 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("create or replace procedure " + procName +
- " (x in timestamp, y out timestamp) is\n"
- "begin\n"
- " y := x;\n"
- "end;\n"));
- QVERIFY(q.prepare("call " + procName + "(?, ?)"));
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create or replace procedure %1 (x in timestamp, y out timestamp) "
+ "is\n"
+ "begin\n"
+ " y := x;\n"
+ "end;\n").arg(procName)));
+ QVERIFY(q.prepare(QLatin1String("call %1(?, ?)").arg(procName)));
q.addBindValue(timeStampCol, QSql::In);
QVariantList emptyDateTimes;
emptyDateTimes.reserve(timeStampCol.size());
- for (int i = 0; i < timeStampCol.size(); i++)
+ for (int i = 0; i < timeStampCol.size(); ++i)
emptyDateTimes << QVariant(QDateTime());
q.addBindValue(emptyDateTimes, QSql::Out);
QVERIFY_SQL(q, execBatch());
@@ -2597,20 +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("CREATE TABLE " + tableName + " (id INT)"));
- QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " (id) VALUES (?)"));
+ 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) {
- QVariantList ids;
- ids << i;
+ const QVariantList ids = { i };
q.addBindValue(ids);
QVERIFY_SQL(q, execBatch());
}
- QVERIFY_SQL(q, exec("SELECT id FROM " + tableName + " ORDER BY id"));
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT id FROM %1 ORDER BY id").arg(ts.tableName())));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 0);
@@ -2621,210 +2580,230 @@ void tst_QSqlQuery::QTBUG_43874()
void tst_QSqlQuery::oraArrayBind()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- if ( !db.driver()->hasFeature( QSqlDriver::BatchOperations ) )
- QSKIP( "Database can't do BatchOperations");
-
- QSqlQuery q( db );
-
- QVERIFY_SQL( q, exec( "CREATE OR REPLACE PACKAGE ora_array_test "
- "IS "
- "TYPE names_type IS TABLE OF VARCHAR(64) NOT NULL INDEX BY BINARY_INTEGER; "
- "names_tab names_type; "
- "PROCEDURE set_name(name_in IN VARCHAR2, row_in in INTEGER); "
- "PROCEDURE get_name(row_in IN INTEGER, str_out OUT VARCHAR2); "
- "PROCEDURE get_table(tbl OUT names_type); "
- "PROCEDURE set_table(tbl IN names_type); "
- "END ora_array_test; " ) );
-
- QVERIFY_SQL( q, exec( "CREATE OR REPLACE PACKAGE BODY ora_array_test "
- "IS "
- "PROCEDURE set_name(name_in IN VARCHAR2, row_in in INTEGER) "
- "IS "
- "BEGIN "
- "names_tab(row_in) := name_in; "
- "END set_name; "
-
- "PROCEDURE get_name(row_in IN INTEGER, str_out OUT VARCHAR2) "
- "IS "
- "BEGIN "
- "str_out := names_tab(row_in); "
- "END get_name; "
-
- "PROCEDURE get_table(tbl OUT names_type) "
- "IS "
- "BEGIN "
- "tbl:=names_tab; "
- "END get_table; "
-
- "PROCEDURE set_table(tbl IN names_type) "
- "IS "
- "BEGIN "
- "names_tab := tbl; "
- "END set_table; "
- "END ora_array_test; " ) );
-
- QVariantList list;
-
- list << QString( "lorem" ) << QString( "ipsum" ) << QString( "dolor" ) << QString( "sit" ) << QString( "amet" );
-
- QVERIFY_SQL( q, prepare( "BEGIN "
- "ora_array_test.set_table(?); "
- "END;" ) );
-
- q.bindValue( 0, list, QSql::In );
-
- QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsColumns ) );
-
- QVERIFY_SQL( q, prepare( "BEGIN "
- "ora_array_test.get_table(?); "
- "END;" ) );
-
- list.clear();
-
- list << QString( 64,' ' ) << QString( 64,' ' ) << QString( 64,' ' ) << QString( 64,' ' ) << QString( 64,' ' );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- q.bindValue( 0, list, QSql::Out );
+ if (!db.driver()->hasFeature(QSqlDriver::BatchOperations))
+ QSKIP("Database can't do BatchOperations");
- QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsColumns ) );
+ QSqlQuery q(db);
- QVariantList out_list = q.boundValue( 0 ).toList();
+ QVERIFY_SQL(q, exec("CREATE OR REPLACE PACKAGE ora_array_test "
+ "IS TYPE names_type IS "
+ "TABLE OF VARCHAR(64) NOT NULL INDEX BY BINARY_INTEGER; "
+ "names_tab names_type; "
+ "PROCEDURE set_name(name_in IN VARCHAR2, row_in in INTEGER); "
+ "PROCEDURE get_name(row_in IN INTEGER, str_out OUT VARCHAR2); "
+ "PROCEDURE get_table(tbl OUT names_type); "
+ "PROCEDURE set_table(tbl IN names_type); "
+ "END ora_array_test; "));
+
+ QVERIFY_SQL(q, exec("CREATE OR REPLACE PACKAGE BODY ora_array_test "
+ "IS "
+ "PROCEDURE set_name(name_in IN VARCHAR2, row_in in INTEGER) "
+ "IS "
+ "BEGIN "
+ "names_tab(row_in) := name_in; "
+ "END set_name; "
+
+ "PROCEDURE get_name(row_in IN INTEGER, str_out OUT VARCHAR2) "
+ "IS "
+ "BEGIN "
+ "str_out := names_tab(row_in); "
+ "END get_name; "
+
+ "PROCEDURE get_table(tbl OUT names_type) "
+ "IS "
+ "BEGIN "
+ "tbl:=names_tab; "
+ "END get_table; "
+
+ "PROCEDURE set_table(tbl IN names_type) "
+ "IS "
+ "BEGIN "
+ "names_tab := tbl; "
+ "END set_table; "
+ "END ora_array_test; "));
+
+ QVariantList list = { u"lorem"_s, u"ipsum"_s, u"dolor"_s, u"sit"_s, u"amet"_s };
+
+ QVERIFY_SQL(q, prepare("BEGIN "
+ "ora_array_test.set_table(?); "
+ "END;"));
+ q.bindValue(0, list, QSql::In);
+ QVERIFY_SQL(q, execBatch(QSqlQuery::ValuesAsColumns));
+ QVERIFY_SQL(q, prepare("BEGIN "
+ "ora_array_test.get_table(?); "
+ "END;"));
- QCOMPARE( out_list.at( 0 ).toString(), QString( "lorem" ) );
+ list.clear();
+ list.resize(5, QString(64, ' '));
- QCOMPARE( out_list.at( 1 ).toString(), QString( "ipsum" ) );
+ q.bindValue(0, list, QSql::Out);
- QCOMPARE( out_list.at( 2 ).toString(), QString( "dolor" ) );
+ QVERIFY_SQL(q, execBatch(QSqlQuery::ValuesAsColumns));
- QCOMPARE( out_list.at( 3 ).toString(), QString( "sit" ) );
+ const QVariantList out_list = q.boundValue(0).toList();
- QCOMPARE( out_list.at( 4 ).toString(), QString( "amet" ) );
+ QCOMPARE(out_list.at(0).toString(), u"lorem");
+ QCOMPARE(out_list.at(1).toString(), u"ipsum");
+ QCOMPARE(out_list.at(2).toString(), u"dolor");
+ QCOMPARE(out_list.at(3).toString(), u"sit");
+ QCOMPARE(out_list.at(4).toString(), u"amet");
- QVERIFY_SQL( q, exec( "DROP PACKAGE ora_array_test" ) );
+ QVERIFY_SQL(q, exec("DROP PACKAGE ora_array_test"));
}
-/*
- Tests that QSqlDatabase::record and QSqlQuery::record returns the same thing
- otherwise our models get confused.
- */
+/* Tests that QSqlDatabase::record() and QSqlQuery::record() return the same
+ thing - otherwise our models get confused.
+*/
void tst_QSqlQuery::record_sqlite()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QSqlQuery q( db );
+ TableScope ts(db, "record_sqlite");
+ QSqlQuery q(db);
- QVERIFY_SQL(q, exec("create table " + qTableName("record_sqlite", __FILE__, db) + "(id integer primary key, name varchar, title int)"));
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create table %1(id integer primary key, name varchar, title int)")
+ .arg(ts.tableName())));
- QSqlRecord rec = db.record(qTableName("record_sqlite", __FILE__, db));
+ QSqlRecord rec = db.record(ts.tableName());
- QCOMPARE( rec.count(), 3 );
- QCOMPARE( rec.field( 0 ).metaType().id(), QMetaType::Int );
- QCOMPARE( rec.field( 1 ).metaType().id(), QMetaType::QString );
- QCOMPARE( rec.field( 2 ).metaType().id(), QMetaType::Int );
+ QCOMPARE(rec.count(), 3);
+ QCOMPARE(rec.field(0).metaType().id(), QMetaType::Int);
+ QCOMPARE(rec.field(1).metaType().id(), QMetaType::QString);
+ QCOMPARE(rec.field(2).metaType().id(), QMetaType::Int);
- /* important - select from an empty table */
- QVERIFY_SQL(q, exec("select id, name, title from " + qTableName("record_sqlite", __FILE__, db)));
+ // Important - select from an empty table:
+ QVERIFY_SQL(q, exec("select id, name, title from " + ts.tableName()));
rec = q.record();
- QCOMPARE( rec.count(), 3 );
- QCOMPARE( rec.field( 0 ).metaType().id(), QMetaType::Int );
- QCOMPARE( rec.field( 1 ).metaType().id(), QMetaType::QString );
- QCOMPARE( rec.field( 2 ).metaType().id(), QMetaType::Int );
+ QCOMPARE(rec.count(), 3);
+ QCOMPARE(rec.field(0).metaType().id(), QMetaType::Int);
+ QCOMPARE(rec.field(1).metaType().id(), QMetaType::QString);
+ QCOMPARE(rec.field(2).metaType().id(), QMetaType::Int);
}
void tst_QSqlQuery::oraLong()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QString aLotOfText( 127000, QLatin1Char( 'H' ) );
+ QString aLotOfText(127000, QLatin1Char('H'));
+ TableScope ts(db, "qtest_longstr", __FILE__);
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest_longstr", __FILE__, db) + " (id int primary key, astr long)"));
- QVERIFY_SQL(q, prepare("insert into " + qTableName("qtest_longstr", __FILE__, db) + " (id, astr) values (?, ?)"));
- q.addBindValue( 1 );
- q.addBindValue( aLotOfText );
- QVERIFY_SQL( q, exec() );
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QLatin1String("create table %1 (id int primary key, astr long)")
+ .arg(ts.tableName())));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1 (id, astr) values (?, ?)")
+ .arg(ts.tableName())));
+ q.addBindValue(1);
+ q.addBindValue(aLotOfText);
+ QVERIFY_SQL(q, exec());
- QVERIFY_SQL(q, exec("select id,astr from " + qTableName("qtest_longstr", __FILE__, db)));
+ QVERIFY_SQL(q, exec("select id,astr from " + ts.tableName()));
- QVERIFY( q.next() );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
- QCOMPARE( q.value( 1 ).toString(), aLotOfText );
+ QVERIFY(q.next());
+ QCOMPARE(q.value(0).toInt(), 1);
+ QCOMPARE(q.value(1).toString(), aLotOfText);
}
void tst_QSqlQuery::execErrorRecovery()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ 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("create table " + tbl + " (id int not null primary key)"));
- QVERIFY_SQL(q, prepare("insert into " + tbl + " values (?)" ));
+ 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() );
+ q.addBindValue(1);
+ QVERIFY_SQL(q, exec());
- q.addBindValue( 1 ); // binding the same pkey - should fail
- QVERIFY( !q.exec() );
+ q.addBindValue(1); // Binding the same pkey - should fail.
+ QVERIFY(!q.exec());
- q.addBindValue( 2 ); // this should work again
- QVERIFY_SQL( q, exec() );
+ q.addBindValue(2); // This should work again.
+ QVERIFY_SQL(q, exec());
+}
+
+void tst_QSqlQuery::prematureExec()
+{
+ QFETCH(QString, dbName);
+ // We only want the engine name, for addDatabase():
+ int cut = dbName.indexOf(QChar('@'));
+ if (cut < 0)
+ QSKIP("Failed to parse database type out of name");
+ dbName.truncate(cut);
+ cut = dbName.indexOf(QChar('_'));
+ if (cut >= 0)
+ dbName = dbName.sliced(cut + 1);
+
+ const auto tidier = qScopeGuard([dbName]() { QSqlDatabase::removeDatabase(dbName); });
+ // Note: destruction of db needs to happen before we call removeDatabase.
+ auto db = QSqlDatabase::addDatabase(dbName);
+ QSqlQuery q(db);
+
+ QTest::ignoreMessage(QtWarningMsg,
+ "QSqlDatabasePrivate::removeDatabase: connection "
+ "'qt_sql_default_connection' is still in use, all "
+ "queries will cease to work.");
+ QTest::ignoreMessage(QtWarningMsg,
+ "QSqlDatabasePrivate::addDatabase: duplicate connection name "
+ "'qt_sql_default_connection', old connection removed.");
+ auto otherDb = QSqlDatabase::addDatabase(dbName);
+
+ QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::exec: called before driver has been set up");
+ // QTBUG-100037: shouldn't crash !
+ QVERIFY(!q.exec("select stuff from TheVoid"));
}
void tst_QSqlQuery::lastInsertId()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- if ( !db.driver()->hasFeature( QSqlDriver::LastInsertId ) )
- QSKIP( "Database doesn't support lastInsertId");
+ if (!db.driver()->hasFeature(QSqlDriver::LastInsertId))
+ QSKIP("Database doesn't support lastInsertId");
- QSqlQuery q( db );
+ QSqlQuery q(db);
// 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);
- QVERIFY_SQL(q, exec(QStringLiteral("create table ") + tst_lastInsertId +
- QStringLiteral(" (id serial not null, t_varchar "
- "varchar(20), t_char char(20), primary key(id))")));
- QVERIFY_SQL(q, exec(QStringLiteral("insert into ") + tst_lastInsertId +
- QStringLiteral(" (t_varchar, t_char) values "
- "('VarChar41', 'Char41')")));
+ 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(ts.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 (t_varchar, t_char) values "
+ "('VarChar41', 'Char41')").arg(ts.tableName())));
} else {
- QVERIFY_SQL(q, exec(QStringLiteral("insert into ") + qtest +
- QStringLiteral(" values (41, 'VarChar41', 'Char41')")));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 values (41, 'VarChar41', 'Char41')")
+ .arg(qtest)));
}
- QVariant v = q.lastInsertId();
-
- QVERIFY( v.isValid() );
+ QVERIFY(q.lastInsertId().isValid());
}
void tst_QSqlQuery::lastQuery()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QSqlQuery q( db );
+ QSqlQuery q(db);
QString sql = "select * from " + qtest;
- QVERIFY_SQL( q, exec( sql ) );
- QCOMPARE( q.lastQuery(), sql );
- QCOMPARE( q.executedQuery(), sql );
+ QVERIFY_SQL(q, exec(sql));
+ QCOMPARE(q.lastQuery(), sql);
+ QCOMPARE(q.executedQuery(), sql);
}
void tst_QSqlQuery::lastQueryTwoQueries()
@@ -2848,30 +2827,34 @@ void tst_QSqlQuery::lastQueryTwoQueries()
void tst_QSqlQuery::psql_bindWithDoubleColonCastOperator()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- const QString tablename(qTableName("bindtest", __FILE__, db));
-
- QSqlQuery q( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QVERIFY_SQL( q, exec( "create table " + tablename + " (id1 int, id2 int, id3 int, fld1 int, fld2 int)" ) );
- QVERIFY_SQL( q, exec( "insert into " + tablename + " values (1, 2, 3, 10, 5)" ) );
+ TableScope ts(db, "bindtest", __FILE__);
- QVERIFY_SQL( q, prepare( "select sum((fld1 - fld2)::int) from " + tablename + " where id1 = :myid1 and id2 =:myid2 and id3=:myid3" ) );
- q.bindValue( ":myid1", 1 );
- q.bindValue( ":myid2", 2 );
- q.bindValue( ":myid3", 3 );
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create table %1 (id1 int, id2 int, id3 int, fld1 int, fld2 int)")
+ .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", ts.tableName());
+ QVERIFY_SQL(q, prepare(query));
+ q.bindValue(":myid1", 1);
+ q.bindValue(":myid2", 2);
+ q.bindValue(":myid3", 3);
- QVERIFY_SQL( q, exec() );
- QVERIFY_SQL( q, next() );
+ QVERIFY_SQL(q, exec());
+ QVERIFY_SQL(q, next());
- // the positional placeholders are converted to named placeholders in executedQuery()
- if (db.driver()->hasFeature(QSqlDriver::PreparedQueries))
- QCOMPARE(q.executedQuery(), QString("select sum((fld1 - fld2)::int) from " + tablename + " where id1 = :myid1 and id2 =:myid2 and id3=:myid3"));
- else
- QCOMPARE(q.executedQuery(), QString("select sum((fld1 - fld2)::int) from " + tablename + " where id1 = 1 and id2 =2 and id3=3"));
+ // The positional placeholders are converted to named placeholders in executedQuery()
+ const QString expected = db.driver()->hasFeature(QSqlDriver::PreparedQueries)
+ ? query : queryTemplate.arg("1", "2", "3", ts.tableName());
+ QCOMPARE(q.executedQuery(), expected);
}
void tst_QSqlQuery::psql_specialFloatValues()
@@ -2881,29 +2864,28 @@ void tst_QSqlQuery::psql_specialFloatValues()
if (!std::numeric_limits<float>::has_infinity)
QSKIP("Platform does not have infinity");
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
- CHECK_DATABASE( db );
+ CHECK_DATABASE(db);
QSqlQuery query(db);
- const QString tableName = qTableName("floattest", __FILE__, db);
- QVERIFY_SQL( query, exec("create table " + tableName + " (value float)" ) );
- QVERIFY_SQL(query, prepare("insert into " + tableName + " values(:value)") );
-
- QVariantList data;
- data << QVariant(double(42.42))
- << QVariant(std::numeric_limits<double>::quiet_NaN())
- << QVariant(std::numeric_limits<double>::infinity())
- << QVariant(float(42.42))
- << QVariant(std::numeric_limits<float>::quiet_NaN())
- << QVariant(std::numeric_limits<float>::infinity());
-
- foreach (const QVariant &v, data) {
+ 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)),
+ QVariant(std::numeric_limits<double>::quiet_NaN()),
+ QVariant(std::numeric_limits<double>::infinity()),
+ QVariant(float(42.42)),
+ QVariant(std::numeric_limits<float>::quiet_NaN()),
+ QVariant(std::numeric_limits<float>::infinity()),
+ };
+
+ for (const QVariant &v : data) {
query.bindValue(":value", v);
- QVERIFY_SQL( query, exec() );
+ QVERIFY_SQL(query, exec());
}
-
- QVERIFY_SQL( query, exec("drop table " + tableName) );
}
/* For task 157397: Using QSqlQuery with an invalid QSqlDatabase
@@ -2913,25 +2895,28 @@ void tst_QSqlQuery::psql_specialFloatValues()
void tst_QSqlQuery::queryOnInvalidDatabase()
{
{
- QTest::ignoreMessage( QtWarningMsg, "QSqlDatabase: INVALID driver not loaded" );
- QSqlDatabase db = QSqlDatabase::addDatabase( "INVALID", "invalidConnection" );
- QVERIFY2( db.lastError().isValid(),
- qPrintable( QString( "db.lastError().isValid() should be true!" ) ) );
-
- QTest::ignoreMessage( QtWarningMsg, "QSqlQuery::exec: database not open" );
- QSqlQuery query( "SELECT 1 AS ID", db );
- QVERIFY2( query.lastError().isValid(),
- qPrintable( QString( "query.lastError().isValid() should be true!" ) ) );
- }
+ const auto tidier = qScopeGuard([]() {
+ QSqlDatabase::removeDatabase("invalidConnection");
+ });
+ // Note: destruction of db needs to happen before we call removeDatabase.
+ QTest::ignoreMessage(QtWarningMsg, "QSqlDatabase: INVALID driver not loaded");
+#if QT_CONFIG(regularexpression)
+ QTest::ignoreMessage(QtWarningMsg,
+ QRegularExpression("QSqlDatabase: available drivers: "));
+#endif
+ QSqlDatabase db = QSqlDatabase::addDatabase("INVALID", "invalidConnection");
+ QVERIFY(db.lastError().isValid());
- QSqlDatabase::removeDatabase( "invalidConnection" );
+ QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::exec: database not open");
+ QSqlQuery query("SELECT 1 AS ID", db);
+ QVERIFY(query.lastError().isValid());
+ }
{
- QSqlDatabase db = QSqlDatabase::database( "this connection does not exist" );
- QTest::ignoreMessage( QtWarningMsg, "QSqlQuery::exec: database not open" );
- QSqlQuery query( "SELECT 1 AS ID", db );
- QVERIFY2( query.lastError().isValid(),
- qPrintable( QString( "query.lastError().isValid() should be true!" ) ) );
+ QSqlDatabase db = QSqlDatabase::database("this connection does not exist");
+ QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::exec: database not open");
+ QSqlQuery query("SELECT 1 AS ID", db);
+ QVERIFY(query.lastError().isValid());
}
}
@@ -2941,299 +2926,313 @@ void tst_QSqlQuery::queryOnInvalidDatabase()
*/
void tst_QSqlQuery::createQueryOnClosedDatabase()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
// Only supported by these drivers
if (dbType != QSqlDriver::PostgreSQL && dbType != QSqlDriver::Oracle
- && dbType != QSqlDriver::MySqlServer && dbType != QSqlDriver::DB2)
- QSKIP( "Test is specific for PostgreSQL, Oracle, MySql and DB2");
+ && dbType != QSqlDriver::MySqlServer && dbType != QSqlDriver::DB2) {
+ QSKIP("Test is specific for PostgreSQL, Oracle, MySql and DB2");
+ }
db.close();
- QSqlQuery q( db );
+ QSqlQuery q(db);
db.open();
- QVERIFY_SQL( q, exec( QString( "select * from %1 where id = 1" ).arg( qtest ) ) );
+ QVERIFY_SQL(q, exec(QLatin1String("select * from %1 where id = 1").arg(qtest)));
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
- QCOMPARE( q.value( 1 ).toString().trimmed(), QLatin1String( "VarChar1" ) );
- QCOMPARE( q.value( 2 ).toString().trimmed(), QLatin1String( "Char1" ) );
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), 1);
+ QCOMPARE(q.value(1).toString().trimmed(), u"VarChar1");
+ QCOMPARE(q.value(2).toString().trimmed(), u"Char1");
db.close();
- QVERIFY2( !q.exec( QString( "select * from %1 where id = 1" ).arg( qtest ) ),
- qPrintable( QString( "This can't happen! The query should not have been executed!" ) ) );
+ QVERIFY2(!q.exec(QLatin1String("select * from %1 where id = 1").arg(qtest)),
+ "This can't happen! The query should not have been executed!");
}
void tst_QSqlQuery::reExecutePreparedForwardOnlyQuery()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QSqlQuery q( db );
- q.setForwardOnly( true );
+ QSqlQuery q(db);
+ q.setForwardOnly(true);
- QVERIFY_SQL( q, prepare( QString( "SELECT id, t_varchar, t_char FROM %1 WHERE id = :id" ).arg( qtest ) ) );
- q.bindValue( ":id", 1 );
- QVERIFY_SQL( q, exec() );
+ QVERIFY_SQL(q, prepare(QLatin1String("SELECT id, t_varchar, t_char FROM %1 WHERE id = :id")
+ .arg(qtest)));
+ q.bindValue(":id", 1);
+ QVERIFY_SQL(q, exec());
// Do something, like iterate over the result, or skip to the end
- QVERIFY_SQL( q, last() );
+ QVERIFY_SQL(q, last());
- QVERIFY_SQL( q, exec() );
+ QVERIFY_SQL(q, exec());
/* This was broken with SQLite because the cache size was set to 0 in the 2nd execute.
When forwardOnly is set we don't cahce the entire result, but we do cache the current row
but this requires the cache size to be equal to the column count.
*/
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
- QCOMPARE( q.value( 1 ).toString().trimmed(), QString( "VarChar1" ) );
- QCOMPARE( q.value( 2 ).toString().trimmed(), QString( "Char1" ) );
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), 1);
+ QCOMPARE(q.value(1).toString().trimmed(), u"VarChar1");
+ QCOMPARE(q.value(2).toString().trimmed(), u"Char1");
}
void tst_QSqlQuery::finish()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- QSqlQuery q( db );
- QVERIFY_SQL( q, prepare( "SELECT id FROM " + qtest + " WHERE id = ?" ) );
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, prepare(QLatin1String("SELECT id FROM %1 WHERE id = ?").arg(qtest)));
int id = 4;
- q.bindValue( 0, id );
- QVERIFY_SQL( q, exec() );
- QVERIFY( q.isActive() );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), id );
+ q.bindValue(0, id);
+ QVERIFY_SQL(q, exec());
+ QVERIFY(q.isActive());
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), id);
q.finish();
- QVERIFY( !q.isActive() ); // query is now inactive
- QCOMPARE( q.boundValue( 0 ).toInt(), id ); // bound values are retained
+ QVERIFY(!q.isActive()); // Query is now inactive, but ...
+ QCOMPARE(q.boundValue(0).toInt(), id); // bound values are retained.
- QVERIFY_SQL( q, exec() ); // no prepare necessary
- QVERIFY( q.isActive() );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), id );
+ QVERIFY_SQL(q, exec()); // No prepare needed.
+ QVERIFY(q.isActive());
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), id);
q.finish();
- QVERIFY( !q.isActive() );
+ QVERIFY(!q.isActive());
- QVERIFY_SQL( q, exec( "SELECT id FROM " + qtest + " WHERE id = 1" ) );
- QVERIFY( q.isActive() );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), 1 );
- QCOMPARE( q.record().count(), 1 );
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT id FROM %1 WHERE id = 1").arg(qtest)));
+ QVERIFY(q.isActive());
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), 1);
+ QCOMPARE(q.record().count(), 1);
}
void tst_QSqlQuery::sqlite_finish()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- if ( db.databaseName().startsWith( ':' ) )
- QSKIP( "This test requires a database on the filesystem, not in-memory");
+ if (db.databaseName().startsWith(':'))
+ QSKIP("This test requires a database on the filesystem, not in-memory");
{
- QSqlDatabase db2 = QSqlDatabase::addDatabase( "QSQLITE", "sqlite_finish_sqlite" );
- db2.setDatabaseName( db.databaseName() );
- QVERIFY_SQL( db2, open() );
-
- const QString tableName(qTableName("qtest_lockedtable", __FILE__, db));
- QSqlQuery q( db );
+ const auto tidier = qScopeGuard([]() {
+ QSqlDatabase::removeDatabase("sqlite_finish_sqlite");
+ });
+ // Note: destruction of db2 needs to happen before we call removeDatabase.
+ QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE", "sqlite_finish_sqlite");
+ db2.setDatabaseName(db.databaseName());
+ QVERIFY_SQL(db2, open());
+
+ TableScope ts(db, "qtest_lockedtable", __FILE__);
+ const auto &tableName = ts.tableName();
+ QSqlQuery q(db);
- tst_Databases::safeDropTable( db, tableName );
- q.exec( "CREATE TABLE " + tableName + " (pk_id INTEGER PRIMARY KEY, whatever TEXT)" );
- q.exec( "INSERT INTO " + tableName + " values(1, 'whatever')" );
- q.exec( "INSERT INTO " + tableName + " values(2, 'whatever more')" );
+ 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));
+ q.exec(QLatin1String("INSERT INTO %1 values(2, 'whatever more')").arg(tableName));
// This creates a read-lock in the database
- QVERIFY_SQL( q, exec( "SELECT * FROM " + tableName + " WHERE pk_id = 1 or pk_id = 2" ) );
- QVERIFY_SQL( q, next() );
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT * FROM %1 WHERE pk_id = 1 or pk_id = 2")
+ .arg(tableName)));
+ QVERIFY_SQL(q, next());
// The DELETE will fail because of the read-lock
- QSqlQuery q2( db2 );
- QVERIFY( !q2.exec( "DELETE FROM " + tableName + " WHERE pk_id=2" ) );
- QCOMPARE( q2.numRowsAffected(), -1 );
+ QSqlQuery q2(db2);
+ QVERIFY(!q2.exec(QLatin1String("DELETE FROM %1 WHERE pk_id=2").arg(tableName)));
+ QCOMPARE(q2.numRowsAffected(), -1);
// The DELETE will succeed now because finish() removes the lock
q.finish();
- QVERIFY_SQL( q2, exec( "DELETE FROM " + tableName + " WHERE pk_id=2" ) );
- QCOMPARE( q2.numRowsAffected(), 1 );
-
- tst_Databases::safeDropTable( db, tableName );
+ QVERIFY_SQL(q2, exec(QLatin1String("DELETE FROM %1 WHERE pk_id=2").arg(tableName)));
+ QCOMPARE(q2.numRowsAffected(), 1);
}
-
- QSqlDatabase::removeDatabase( "sqlite_finish_sqlite" );
}
void tst_QSqlQuery::nextResult()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (!db.driver()->hasFeature(QSqlDriver::MultipleResultSets))
QSKIP("DBMS does not support multiple result sets");
- QSqlQuery q( db );
- const QString tableName(qTableName("more_results", __FILE__, db));
-
- QVERIFY_SQL( q, exec( "CREATE TABLE " + tableName + " (id integer, text varchar(20), num numeric(6, 3), empty varchar(10));" ) );
-
- QVERIFY_SQL( q, exec( "INSERT INTO " + tableName + " VALUES(1, 'one', 1.1, '');" ) );
-
- QVERIFY_SQL( q, exec( "INSERT INTO " + tableName + " VALUES(2, 'two', 2.2, '');" ) );
-
- QVERIFY_SQL( q, exec( "INSERT INTO " + tableName + " VALUES(3, 'three', 3.3, '');" ) );
+ QSqlQuery q(db);
+ TableScope ts(db, "more_results", __FILE__);
+ const auto &tableName = ts.tableName();
- QVERIFY_SQL( q, exec( "INSERT INTO " + tableName + " VALUES(4, 'four', 4.4, '');" ) );
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "CREATE TABLE %1 (id integer, text varchar(20), "
+ "num numeric(6, 3), empty varchar(10));").arg(tableName)));
- QStringList tstStrings;
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 VALUES(1, 'one', 1.1, '');").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 VALUES(2, 'two', 2.2, '');").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 VALUES(3, 'three', 3.3, '');")
+ .arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 VALUES(4, 'four', 4.4, '');")
+ .arg(tableName)));
- tstStrings << "one" << "two" << "three" << "four";
+ const QString tstStrings[] = { u"one"_s, u"two"_s, u"three"_s, u"four"_s };
// Query that returns only one result set, nothing special about this
- QVERIFY_SQL( q, exec( QString( "SELECT * FROM %1;" ).arg( tableName ) ) );
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT * FROM %1;").arg(tableName)));
- QVERIFY( q.next() ); // Move to first row of the result set
+ QVERIFY(q.next()); // Move to first row of the result set
- QVERIFY( !q.nextResult() ); // No more result sets are available
+ QVERIFY(!q.nextResult()); // No more result sets are available
- QVERIFY( !q.isActive() ); // So the query is no longer active
+ QVERIFY(!q.isActive()); // So the query is no longer active
- QVERIFY( !q.next() ); // ... and no data is available as the call
+ QVERIFY(!q.next()); // ... and no data is available as the call
- // to nextResult() discarded the result set
+ // Attempting nextResult() discarded the result set.
// Query that returns two result sets (batch sql)
// When working with multiple result sets SQL Server insists on non-scrollable cursors
if (db.driverName().startsWith("QODBC"))
- q.setForwardOnly( true );
-
- QVERIFY_SQL( q, exec( "SELECT id FROM " + tableName + "; SELECT text, num FROM " + tableName + ';' ) );
-
- QCOMPARE( q.record().count(), 1 ); // Check that the meta data is as expected
-
- QCOMPARE( q.record().field( 0 ).name().toUpper(), QString( "ID" ) );
+ q.setForwardOnly(true);
- QCOMPARE( q.record().field( 0 ).metaType().id(), QMetaType::Int );
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT id FROM %1; SELECT text, num FROM %1;")
+ .arg(tableName)));
- QVERIFY( q.nextResult() ); // Discards first result set and move to the next
-
- QCOMPARE( q.record().count(), 2 ); // New meta data should be available
+ QCOMPARE(q.record().count(), 1); // Check that the meta data is as expected
+ QCOMPARE(q.record().field(0).name().toUpper(), u"ID");
+ QCOMPARE(q.record().field(0).metaType().id(), QMetaType::Int);
- QCOMPARE( q.record().field( 0 ).name().toUpper(), QString( "TEXT" ) );
+ QVERIFY(q.nextResult()); // Discards first result set and move to the next
+ QCOMPARE(q.record().count(), 2); // New meta data should be available
- QCOMPARE( q.record().field( 0 ).metaType().id(), QMetaType::QString );
+ QCOMPARE(q.record().field(0).name().toUpper(), u"TEXT");
+ QCOMPARE(q.record().field(0).metaType().id(), QMetaType::QString);
- QCOMPARE( q.record().field( 1 ).name().toUpper(), QString( "NUM" ) );
+ QCOMPARE(q.record().field(1).name().toUpper(), u"NUM");
QCOMPARE(q.record().field(1).metaType().id(), QMetaType::Double);
- QVERIFY( q.next() ); // Move to first row of the second result set
-
+ QVERIFY(q.next()); // Move to first row of the second result set
QFAIL_SQL(q, nextResult()); // No more result sets after this
-
- QVERIFY( !q.isActive() ); // So the query is no longer active
-
- QVERIFY( !q.next() ); // ... and no data is available as the call to
+ QVERIFY(!q.isActive()); // So the query is no longer active
+ QVERIFY(!q.next()); // ... and no data is available as the call to
// nextResult() discarded the result set
// Query that returns one result set, a count of affected rows and then another result set
- QString query1 = QString( "SELECT id, text, num, empty FROM %1 WHERE id <= 3" ).arg( tableName );
-
- QString query2 = QString( "UPDATE %1 SET empty = 'Yatta!'" ).arg( tableName );
-
- QString query3 = QString( "SELECT id, empty FROM %1 WHERE id <=2" ).arg( tableName );
-
- QVERIFY_SQL( q, exec( QString( "%1; %2; %3;" ).arg( query1 ).arg( query2 ).arg( query3 ) ) );
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT id, text, num, empty FROM %1 WHERE id <= 3; "
+ "UPDATE %1 SET empty = 'Yatta!'; "
+ "SELECT id, empty FROM %1 WHERE id <=2;").arg(tableName)));
// Check result set returned by first statement
- QVERIFY( q.isSelect() ); // The first statement is a select
-
- for ( int i = 0; i < 3; i++ ) {
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), 1+i );
- QCOMPARE( q.value( 1 ).toString(), tstStrings.at( i ) );
- QCOMPARE( q.value( 2 ).toDouble(), 1.1*( i+1 ) );
- QVERIFY( q.value( 3 ).toString().isEmpty() );
+ QVERIFY(q.isSelect()); // The first statement is a select
+
+ for (int i = 0; i < 3; ++i) {
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), 1 + i);
+ QCOMPARE(q.value(1).toString(), tstStrings[i]);
+ QCOMPARE(q.value(2).toDouble(), 1.1 * (i + 1));
+ QVERIFY(q.value(3).toString().isEmpty());
}
- QVERIFY_SQL( q, nextResult() );
+ QVERIFY_SQL(q, nextResult());
- QVERIFY( !q.isSelect() ); // The second statement isn't a SELECT
- QVERIFY( !q.next() ); // ... so no result set is available
- QCOMPARE( q.numRowsAffected(), 4 ); // 4 rows was affected by the UPDATE
+ QVERIFY(!q.isSelect()); // The second statement isn't a SELECT
+ QVERIFY(!q.next()); // ... so no result set is available
+ QCOMPARE(q.numRowsAffected(), 4); // 4 rows was affected by the UPDATE
// Check result set returned by third statement
- QVERIFY_SQL( q, nextResult() );
- QVERIFY( q.isSelect() ); // The third statement is a SELECT
+ QVERIFY_SQL(q, nextResult());
+ QVERIFY(q.isSelect()); // The third statement is a SELECT
- for ( int i = 0; i < 2; i++ ) {
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), 1+i );
- QCOMPARE( q.value( 1 ).toString(), QString( "Yatta!" ) );
+ for (int i = 0; i < 2; ++i) {
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), 1 + i);
+ QCOMPARE(q.value(1).toString(), u"Yatta!");
}
// Stored procedure with multiple result sets
const QString procName(qTableName("proc_more_res", __FILE__, db));
- if (dbType == QSqlDriver::PostgreSQL)
- q.exec(QString("DROP FUNCTION %1(refcursor, refcursor);").arg(procName));
- else
- q.exec(QString("DROP PROCEDURE %1;").arg(procName));
-
- if (dbType == QSqlDriver::MySqlServer)
- QVERIFY_SQL( q, exec( QString( "CREATE PROCEDURE %1()"
- "\nBEGIN"
- "\nSELECT id, text FROM %2;"
- "\nSELECT empty, num, text, id FROM %3;"
- "\nEND" ).arg( procName ).arg( tableName ).arg( tableName ) ) );
- else if (dbType == QSqlDriver::DB2)
- QVERIFY_SQL( q, exec( QString( "CREATE PROCEDURE %1()"
- "\nRESULT SETS 2"
- "\nLANGUAGE SQL"
- "\np1:BEGIN"
- "\nDECLARE cursor1 CURSOR WITH RETURN FOR SELECT id, text FROM %2;"
- "\nDECLARE cursor2 CURSOR WITH RETURN FOR SELECT empty, num, text, id FROM %3;"
- "\nOPEN cursor1;"
- "\nOPEN cursor2;"
- "\nEND p1" ).arg( procName ).arg( tableName ).arg( tableName ) ) );
- else if (dbType == QSqlDriver::PostgreSQL)
- QVERIFY_SQL(q, exec(QString("CREATE FUNCTION %1(ref1 refcursor, ref2 refcursor)"
- "\nRETURNS SETOF refcursor AS $$"
- "\nBEGIN"
- "\nOPEN ref1 FOR SELECT id, text FROM %2;"
- "\nRETURN NEXT ref1;"
- "\nOPEN ref2 FOR SELECT empty, num, text, id FROM %2;"
- "\nRETURN NEXT ref2;"
- "\nEND;"
- "\n$$ LANGUAGE plpgsql").arg(procName).arg(tableName)));
- else
- QVERIFY_SQL( q, exec( QString( "CREATE PROCEDURE %1"
- "\nAS"
- "\nSELECT id, text FROM %2"
- "\nSELECT empty, num, text, id FROM %3" ).arg( procName ).arg( tableName ).arg( tableName ) ) );
-
- if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::DB2) {
- q.setForwardOnly( true );
- QVERIFY_SQL( q, exec( QString( "CALL %1()" ).arg( procName ) ) );
- } else if (dbType == QSqlDriver::PostgreSQL) {
+ auto dropProc = [&]() {
+ q.exec(QLatin1String(dbType == QSqlDriver::PostgreSQL
+ ? "DROP FUNCTION %1(refcursor, refcursor);"
+ : "DROP PROCEDURE %1;").arg(procName));
+ };
+ dropProc(); // To make sure it's not there before we start.
+
+ QLatin1String creator;
+ switch (dbType) {
+ case QSqlDriver::MySqlServer:
+ creator = QLatin1String("CREATE PROCEDURE %1()\n"
+ "BEGIN\n"
+ " SELECT id, text FROM %2;\n"
+ " SELECT empty, num, text, id FROM %2;\n"
+ "END");
+ break;
+ case QSqlDriver::DB2:
+ creator = QLatin1String("CREATE PROCEDURE %1()\n"
+ "RESULT SETS 2\n"
+ "LANGUAGE SQL\n"
+ "p1:BEGIN\n"
+ " DECLARE cursor1 CURSOR WITH RETURN FOR "
+ "SELECT id, text FROM %2;\n"
+ " DECLARE cursor2 CURSOR WITH RETURN FOR "
+ "SELECT empty, num, text, id FROM %2;\n"
+ " OPEN cursor1;\n"
+ " OPEN cursor2;\n"
+ "END p1");
+ break;
+ case QSqlDriver::PostgreSQL:
+ creator = QLatin1String("CREATE FUNCTION %1(ref1 refcursor, ref2 refcursor)\n"
+ "RETURNS SETOF refcursor AS $$\n"
+ "BEGIN\n"
+ " OPEN ref1 FOR SELECT id, text FROM %2;\n"
+ " RETURN NEXT ref1;\n"
+ " OPEN ref2 FOR SELECT empty, num, text, id FROM %2;\n"
+ " RETURN NEXT ref2;\n"
+ "END;\n"
+ "$$ LANGUAGE plpgsql");
+ break;
+ default:
+ creator = QLatin1String("CREATE PROCEDURE %1\n"
+ "AS\n"
+ "SELECT id, text FROM %2\n"
+ "SELECT empty, num, text, id FROM %2");
+ break;
+ }
+ QVERIFY_SQL(q, exec(creator.arg(procName, tableName)));
+ const auto tidier = qScopeGuard(dropProc);
+
+ QLatin1String caller;
+ switch (dbType) {
+ case QSqlDriver::MySqlServer:
+ case QSqlDriver::DB2:
+ q.setForwardOnly(true);
+ caller = QLatin1String("CALL %1()");
+ break;
+ case QSqlDriver::PostgreSQL:
// Returning multiple result sets from PostgreSQL stored procedure:
// http://sqlines.com/postgresql/how-to/return_result_set_from_stored_procedure
- QVERIFY_SQL(q, exec(QString("BEGIN;"
- "SELECT %1('cur1', 'cur2');"
- "FETCH ALL IN cur1;"
- "FETCH ALL IN cur2;"
- "COMMIT;").arg(procName)));
- } else {
- QVERIFY_SQL( q, exec( QString( "EXEC %1" ).arg( procName ) ) );
+ caller = QLatin1String("BEGIN;"
+ " SELECT %1('cur1', 'cur2');"
+ " FETCH ALL IN cur1;"
+ " FETCH ALL IN cur2;"
+ "COMMIT;");
+ break;
+ default:
+ caller = QLatin1String("EXEC %1");
+ break;
}
+ QVERIFY_SQL(q, exec(caller.arg(procName)));
if (dbType == QSqlDriver::PostgreSQL) {
// First result set - start of transaction
@@ -3249,29 +3248,29 @@ void tst_QSqlQuery::nextResult()
QVERIFY(q.nextResult());
}
- for ( int i = 0; i < 4; i++ ) {
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toInt(), i+1 );
- QCOMPARE( q.value( 1 ).toString(), tstStrings.at( i ) );
+ for (int i = 0; i < 4; ++i) {
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), i + 1);
+ QCOMPARE(q.value(1).toString(), tstStrings[i]);
}
- QVERIFY_SQL( q, nextResult() );
+ QVERIFY_SQL(q, nextResult());
+ QVERIFY_SQL(q, isActive());
- QVERIFY_SQL( q, isActive() );
-
- for ( int i = 0; i < 4; i++ ) {
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toString(), QString( "Yatta!" ) );
- QCOMPARE( q.value( 1 ).toDouble(), 1.1*( 1+i ) );
- QCOMPARE( q.value( 2 ).toString(), tstStrings.at( i ) );
- QCOMPARE( q.value( 3 ).toInt(), 1+i );
+ for (int i = 0; i < 4; ++i) {
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toString(), u"Yatta!");
+ QCOMPARE(q.value(1).toDouble(), 1.1 * (1 + i));
+ QCOMPARE(q.value(2).toString(), tstStrings[i]);
+ QCOMPARE(q.value(3).toInt(), 1 + i);
}
// MySQL also counts the CALL itself as a result
if (dbType == QSqlDriver::MySqlServer) {
- QVERIFY( q.nextResult() );
- QVERIFY( !q.isSelect() ); // ... but it's not a select
- QCOMPARE( q.numRowsAffected(), 0 ); // ... and no rows are affected (at least not with this procedure)
+ QVERIFY(q.nextResult());
+ QVERIFY(!q.isSelect()); // ... but it's not a select
+ // ... and no rows are affected (at least not with this procedure):
+ QCOMPARE(q.numRowsAffected(), 0);
}
if (dbType == QSqlDriver::PostgreSQL) {
// Last result set - commit transaction
@@ -3280,14 +3279,8 @@ void tst_QSqlQuery::nextResult()
QCOMPARE(q.numRowsAffected(), 0);
}
- QVERIFY( !q.nextResult() );
-
- QVERIFY( !q.isActive() );
-
- if (dbType == QSqlDriver::PostgreSQL)
- q.exec(QString("DROP FUNCTION %1(refcursor, refcursor);").arg(procName));
- else
- q.exec(QString("DROP PROCEDURE %1;").arg(procName));
+ QVERIFY(!q.nextResult());
+ QVERIFY(!q.isActive());
}
@@ -3296,76 +3289,76 @@ void tst_QSqlQuery::nextResult()
// enough to be run with all backends.
void tst_QSqlQuery::blobsPreparedQuery()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
- if ( !db.driver()->hasFeature( QSqlDriver::BLOB ) || !db.driver()->hasFeature( QSqlDriver::PreparedQueries ) )
- QSKIP( "DBMS does not support BLOBs or prepared queries");
+ if (!db.driver()->hasFeature(QSqlDriver::BLOB)
+ || !db.driver()->hasFeature(QSqlDriver::PreparedQueries)) {
+ 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.
- QString shortBLOB( "abc" );
- QString longerBLOB( "abcdefghijklmnopqrstuvxyz¿äëïöü¡ " );
+ QSqlQuery q(db);
+ q.setForwardOnly(true); // This is needed to make the test work with DB2.
+ QString shortBLOB("abc");
+ QString longerBLOB("abcdefghijklmnopqrstuvxyz¿äëïöü¡ ");
// In PostgreSQL a BLOB is not called a BLOB, but a BYTEA! :-)
// ... and in SQL Server it can be called a lot, but IMAGE will do.
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- QString typeName( "BLOB" );
- if (dbType == QSqlDriver::PostgreSQL)
- typeName = "BYTEA";
- else if (dbType == QSqlDriver::MSSqlServer)
- typeName = "IMAGE";
-
- QVERIFY_SQL( q, exec( QString( "CREATE TABLE %1(id INTEGER, data %2)" ).arg( tableName ).arg( typeName ) ) );
- q.prepare( QString( "INSERT INTO %1(id, data) VALUES(:id, :data)" ).arg( tableName ) );
- q.bindValue( ":id", 1 );
- q.bindValue( ":data", shortBLOB );
- QVERIFY_SQL( q, exec() );
+ const QLatin1String typeName(dbType == QSqlDriver::PostgreSQL ? "BYTEA"
+ : dbType == QSqlDriver::MSSqlServer ? "IMAGE" : "BLOB");
+
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1(id INTEGER, data %2)")
+ .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());
- q.bindValue( ":id", 2 );
- q.bindValue( ":data", longerBLOB );
- QVERIFY_SQL( q, exec() );
+ q.bindValue(":id", 2);
+ q.bindValue(":data", longerBLOB);
+ QVERIFY_SQL(q, exec());
// Two executions and result sets
- q.prepare( QString( "SELECT data FROM %1 WHERE id = ?" ).arg( tableName ) );
- q.bindValue( 0, QVariant( 1 ) );
- QVERIFY_SQL( q, exec() );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toString(), shortBLOB );
+ 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());
+ QCOMPARE(q.value(0).toString(), shortBLOB);
- q.bindValue( 0, QVariant( 2 ) );
- QVERIFY_SQL( q, exec() );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toString().toUtf8(), longerBLOB.toUtf8() );
+ q.bindValue(0, QVariant(2));
+ QVERIFY_SQL(q, exec());
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toString().toUtf8(), longerBLOB.toUtf8());
// Only one execution and result set
- q.prepare( QString( "SELECT id, data FROM %1 ORDER BY id" ).arg( tableName ) );
- QVERIFY_SQL( q, exec() );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 1 ).toString(), shortBLOB );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 1 ).toString(), longerBLOB );
+ 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);
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(1).toString(), longerBLOB);
}
// There were problems with navigating past the end of a table returning an error on mysql
void tst_QSqlQuery::emptyTableNavigate()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
{
- QSqlQuery q( db );
- const QString tbl = qTableName("qtest_empty", __FILE__, db);
- q.exec("drop table " + tbl);
- QVERIFY_SQL(q, exec("create table " + tbl + " (id char(10))"));
- QVERIFY_SQL(q, prepare("select * from " + tbl));
- QVERIFY_SQL( q, exec() );
- QVERIFY( !q.next() );
- QCOMPARE( q.lastError().isValid(), false );
+ TableScope ts(db, "qtest_empty", __FILE__);
+ QSqlQuery q(db);
+ 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());
}
}
@@ -3374,133 +3367,147 @@ 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);
- QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType == QSqlDriver::PostgreSQL) {
- QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE ") + tableName + QStringLiteral("("
- "id serial NOT NULL, "
- "datefield timestamp, primary key(id));")));
- } else if (dbType == QSqlDriver::MySqlServer) {
- QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE ") + tableName + QStringLiteral("("
- "id integer NOT NULL AUTO_INCREMENT,"
- "datefield timestamp, primary key(id));")));
- } else if (dbType == QSqlDriver::Interbase) {
+ QLatin1String creator;
+ switch (tst_Databases::getDatabaseType(db)) {
+ case QSqlDriver::PostgreSQL:
+ creator = QLatin1String("CREATE TABLE %1(id serial NOT NULL, "
+ "datefield timestamp, primary key(id));");
+ break;
+ case QSqlDriver::MySqlServer:
+ creator = QLatin1String("CREATE TABLE %1(id integer NOT NULL AUTO_INCREMENT, "
+ "datefield timestamp, primary key(id));");
+ break;
+ case QSqlDriver::Interbase:
// Since there is no auto-increment feature in Interbase we allow it to be null
- QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE ") + tableName + QStringLiteral("("
- "id integer,"
- "datefield timestamp);")));
- } else {
- QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE ") + tableName + QStringLiteral("("
- "\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT,"
- "\"datefield\" timestamp);")));
+ 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(
- QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (datefield) VALUES (current_timestamp);"
- )));
- QVERIFY_SQL(q, exec(QStringLiteral("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());
}
void tst_QSqlQuery::task_217003()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- QSqlQuery q( db );
- const QString Planet(qTableName( "Planet", __FILE__, db));
-
- q.exec("drop table " + Planet);
- QVERIFY_SQL( q, exec( "create table " + Planet + " (Name varchar(20))" ) );
- QVERIFY_SQL( q, exec( "insert into " + Planet + " VALUES ('Mercury')" ) );
- QVERIFY_SQL( q, exec( "insert into " + Planet + " VALUES ('Venus')" ) );
- QVERIFY_SQL( q, exec( "insert into " + Planet + " VALUES ('Earth')" ) );
- QVERIFY_SQL( q, exec( "insert into " + Planet + " VALUES ('Mars')" ) );
-
- QVERIFY_SQL( q, exec( "SELECT Name FROM " + Planet ) );
- QVERIFY_SQL( q, seek( 3 ) );
- QCOMPARE( q.value( 0 ).toString(), QString( "Mars" ) );
- QVERIFY_SQL( q, seek( 1 ) );
- QCOMPARE( q.value( 0 ).toString(), QString( "Venus" ) );
- QVERIFY_SQL( q, exec( "SELECT Name FROM " + Planet ) );
- QVERIFY_SQL( q, seek( 3 ) );
- QCOMPARE( q.value( 0 ).toString(), QString( "Mars" ) );
- QVERIFY_SQL( q, seek( 0 ) );
- QCOMPARE( q.value( 0 ).toString(), QString( "Mercury" ) );
- QVERIFY_SQL( q, seek( 1 ) );
- QCOMPARE( q.value( 0 ).toString(), QString( "Venus" ) );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "Planet", __FILE__);
+ const auto &planets = ts.tableName();
+
+ 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)));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 VALUES ('Earth')").arg(planets)));
+ QVERIFY_SQL(q, exec(QLatin1String("insert into %1 VALUES ('Mars')").arg(planets)));
+
+ QVERIFY_SQL(q, exec("SELECT Name FROM " + planets));
+ QVERIFY_SQL(q, seek(3));
+ QCOMPARE(q.value(0).toString(), u"Mars");
+ QVERIFY_SQL(q, seek(1));
+ QCOMPARE(q.value(0).toString(), u"Venus");
+ QVERIFY_SQL(q, exec("SELECT Name FROM " + planets));
+ QVERIFY_SQL(q, seek(3));
+ QCOMPARE(q.value(0).toString(), u"Mars");
+ QVERIFY_SQL(q, seek(0));
+ QCOMPARE(q.value(0).toString(), u"Mercury");
+ QVERIFY_SQL(q, seek(1));
+ QCOMPARE(q.value(0).toString(), u"Venus");
}
void tst_QSqlQuery::task_250026()
{
- QString data258, data1026;
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- QSqlQuery q( db );
-
- const QString tableName(qTableName("task_250026", __FILE__, db));
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "task_250026", __FILE__);
- if ( !q.exec( "create table " + tableName + " (longfield varchar(1100))" ) ) {
+ 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");
+ QSKIP("Db doesn't support \"1100\" as a size for fields");
}
- data258.fill( 'A', 258 );
- data1026.fill( 'A', 1026 );
- QVERIFY_SQL( q, prepare( "insert into " + tableName + "(longfield) VALUES (:longfield)" ) );
- 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, next() );
- QCOMPARE( q.value( 0 ).toString().length(), data258.length() );
- QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toString().length(), data1026.length() );
+ const QString data258(258, QLatin1Char('A'));
+ const QString data1026(1026, QLatin1Char('A'));
+ QVERIFY_SQL(q, prepare(QLatin1String("insert into %1(longfield) VALUES (:longfield)")
+ .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 " + ts.tableName()));
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toString().size(), data258.size());
+ QVERIFY_SQL(q, next());
+ 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(
QSqlDatabase::database(dbName), "crashTest");
qDebug() << "Testing crash in sqlquery dtor for driver" << clonedDb.driverName();
QVERIFY(clonedDb.open());
QSqlQuery q(clonedDb);
clonedDb.close();
- QSqlDatabase::removeDatabase("crashTest");
}
}
-void tst_QSqlQuery::task_233829()
+void tst_QSqlQuery::testNaN()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlQuery q( db );
- const QString tableName(qTableName("task_233829", __FILE__, db));
- QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + "(dbl1 double precision,dbl2 double precision) without oids;"));
-
- QString queryString("INSERT INTO " + tableName +"(dbl1, dbl2) VALUES(?,?)");
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "testNaN", __FILE__);
- double k = 0.0;
- QVERIFY_SQL(q,prepare(queryString));
- q.bindValue(0,0.0 / k); // nan
- q.bindValue(1,0.0 / k); // nan
- QVERIFY_SQL(q,exec());
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "CREATE TABLE %1(dbl1 double precision,dbl2 double precision) "
+ "without oids;").arg(ts.tableName())));
+ const QString queryString =
+ QLatin1String("INSERT INTO %1(dbl1, dbl2) VALUES(?,?)").arg(ts.tableName());
+
+ const double nan = qQNaN();
+ QVERIFY_SQL(q, prepare(queryString));
+ q.bindValue(0, nan);
+ q.bindValue(1, nan);
+ 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, "
@@ -3537,75 +3544,71 @@ void tst_QSqlQuery::QTBUG_12477()
void tst_QSqlQuery::sqlServerReturn0()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType != QSqlDriver::MSSqlServer)
- QSKIP("SQL Server specific test");
-
- const QString tableName(qTableName("test141895", __FILE__, db)), procName(qTableName("test141895_proc", __FILE__, db));
- QSqlQuery q( db );
- q.exec("DROP TABLE " + tableName);
- q.exec("DROP PROCEDURE " + procName);
- QVERIFY_SQL(q, exec("CREATE TABLE "+tableName+" (id integer)"));
- QVERIFY_SQL(q, exec("INSERT INTO "+tableName+" (id) VALUES (1)"));
- QVERIFY_SQL(q, exec("INSERT INTO "+tableName+" (id) VALUES (2)"));
- QVERIFY_SQL(q, exec("INSERT INTO "+tableName+" (id) VALUES (2)"));
- QVERIFY_SQL(q, exec("INSERT INTO "+tableName+" (id) VALUES (3)"));
- QVERIFY_SQL(q, exec("INSERT INTO "+tableName+" (id) VALUES (1)"));
- QVERIFY_SQL(q, exec("CREATE PROCEDURE "+procName+
- " AS "
- "SELECT * FROM "+tableName+" WHERE ID = 2 "
- "RETURN 0"));
-
- QVERIFY_SQL(q, exec("{CALL " + procName + QLatin1Char('}')));
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ if (tst_Databases::getDatabaseType(db) != QSqlDriver::MSSqlServer)
+ QSKIP("Test is specific to SQL Server");
+ ProcScope ps(db, "test141895_proc", __FILE__);
+ TableScope ts(db, "test141895", __FILE__);
+ const auto &tableName = ts.tableName();
+ QSqlQuery q(db);
+ 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)));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id) VALUES (2)").arg(tableName)));
+ 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 %2 WHERE ID = 2 "
+ "RETURN 0").arg(ps.name(), ts.tableName())));
+
+ QVERIFY_SQL(q, exec(QLatin1String("{CALL %1}").arg(ps.name())));
QVERIFY_SQL(q, next());
}
void tst_QSqlQuery::QTBUG_551()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
QSqlQuery q(db);
const QString pkgname(qTableName("pkg", __FILE__, db));
- QVERIFY_SQL(q, exec("CREATE OR REPLACE PACKAGE "+pkgname+" IS \n\
- \n\
- TYPE IntType IS TABLE OF INTEGER INDEX BY BINARY_INTEGER;\n\
- TYPE VCType IS TABLE OF VARCHAR2(60) INDEX BY BINARY_INTEGER;\n\
- PROCEDURE P (Inp IN IntType, Outp OUT VCType);\n\
- END "+ pkgname + QLatin1Char(';')));
-
- QVERIFY_SQL(q, exec("CREATE OR REPLACE PACKAGE BODY "+pkgname+" IS\n\
- PROCEDURE P (Inp IN IntType, Outp OUT VCType)\n\
- IS\n\
- BEGIN\n\
- Outp(1) := '1. Value is ' ||TO_CHAR(Inp(1));\n\
- Outp(2) := '2. Value is ' ||TO_CHAR(Inp(2));\n\
- Outp(3) := '3. Value is ' ||TO_CHAR(Inp(3));\n\
- END p;\n\
- END " + pkgname + QLatin1Char(';')));
-
- QVariantList inLst, outLst, res_outLst;
-
- q.prepare("begin "+pkgname+".p(:inp, :outp); end;");
-
- QString StVal;
- StVal.reserve(60);
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "CREATE OR REPLACE PACKAGE %1 IS \n\n"
+ "TYPE IntType IS TABLE OF INTEGER INDEX BY BINARY_INTEGER;\n"
+ "TYPE VCType IS TABLE OF VARCHAR2(60) INDEX BY BINARY_INTEGER;\n"
+ "PROCEDURE P (Inp IN IntType, Outp OUT VCType);\n"
+ "END %1;").arg(pkgname)));
+
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE OR REPLACE PACKAGE BODY %1 IS\n"
+ "PROCEDURE P (Inp IN IntType, Outp OUT VCType)\n"
+ " IS\n"
+ " BEGIN\n"
+ " Outp(1) := '1. Value is ' ||TO_CHAR(Inp(1));\n"
+ " Outp(2) := '2. Value is ' ||TO_CHAR(Inp(2));\n"
+ " Outp(3) := '3. Value is ' ||TO_CHAR(Inp(3));\n"
+ " END p;\n"
+ "END %1;").arg(pkgname)));
+
+ q.prepare(QLatin1String("begin %1.p(:inp, :outp); end;").arg(pkgname));
+
+ QString text;
+ text.reserve(60);
// loading arrays
- for (int Cnt=0; Cnt < 3; Cnt++) {
- inLst << Cnt;
- outLst << StVal;
+ QVariantList inLst, outLst;
+ for (int count = 0; count < 3; ++count) {
+ inLst << count;
+ outLst << text;
}
q.bindValue(":inp", inLst);
q.bindValue(":outp", outLst, QSql::Out);
- QVERIFY_SQL(q, execBatch(QSqlQuery::ValuesAsColumns) );
- res_outLst = qvariant_cast<QVariantList>(q.boundValues().at(1));
+ QVERIFY_SQL(q, execBatch(QSqlQuery::ValuesAsColumns));
+ const auto res_outLst = qvariant_cast<QVariantList>(q.boundValues().at(1));
QCOMPARE(res_outLst[0].toString(), QLatin1String("1. Value is 0"));
QCOMPARE(res_outLst[1].toString(), QLatin1String("2. Value is 1"));
@@ -3614,21 +3617,18 @@ void tst_QSqlQuery::QTBUG_551()
void tst_QSqlQuery::QTBUG_12186()
{
- QFETCH( QString, dbName );
+ QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
- // make sure that query.boundValues() returns the values in the right order
- // even for more than 16 placeholders
+ // Make sure that query.boundValues() returns the values in the right order
+ // even for more than 16 placeholders:
QSqlQuery query(db);
- query.prepare("INSERT INTO person (col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11, col12, col13, col14, col15, col16, col17, col18) "
+ query.prepare("INSERT INTO person (col1, col2, col3, col4, col5, col6, col7, col8, col9, "
+ "col10, col11, col12, col13, col14, col15, col16, col17, col18) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
- QList<QVariant> values;
-
- for (int i = 0; i < 18; ++i)
- values << i;
-
- foreach (QVariant v, values)
+ const QList<QVariant> values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
+ for (const QVariant &v : values)
query.bindValue(v.toInt(), v);
QCOMPARE(query.boundValues(), values);
@@ -3636,18 +3636,18 @@ void tst_QSqlQuery::QTBUG_12186()
void tst_QSqlQuery::QTBUG_14132()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
QSqlQuery q(db);
const QString procedureName(qTableName("procedure", __FILE__, db));
- QVERIFY_SQL(q, exec("CREATE OR REPLACE PROCEDURE "+ procedureName + " (outStr OUT varchar2) \n\
- is \n\
- begin \n\
- outStr := 'OUTSTRING'; \n\
- end;"));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE OR REPLACE PROCEDURE %1 (outStr OUT varchar2)\n"
+ "is\n"
+ "begin\n"
+ " outStr := 'OUTSTRING'; \n"
+ "end;").arg(procedureName)));
QString placeholder = "XXXXXXXXX";
- QVERIFY(q.prepare("CALL "+procedureName+"(?)"));
+ QVERIFY(q.prepare(QLatin1String("CALL %1(?)").arg(procedureName)));
q.addBindValue(placeholder, QSql::Out);
QVERIFY_SQL(q, exec());
QCOMPARE(q.boundValue(0).toString(), QLatin1String("OUTSTRING"));
@@ -3660,76 +3660,77 @@ void tst_QSqlQuery::QTBUG_18435()
CHECK_DATABASE(db);
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType != QSqlDriver::MSSqlServer || !db.driverName().startsWith("QODBC"))
- QSKIP("SQL Server specific test");
+ 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 =
- "CREATE PROCEDURE " + procName + " @key nvarchar(50) OUTPUT AS\n"
- "BEGIN\n"
- " SET NOCOUNT ON\n"
- " SET @key = 'TEST'\n"
- "END\n";
+ 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(ps.name());
QVERIFY_SQL(q, exec(stmt));
- QVERIFY_SQL(q, prepare("{CALL "+ 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()
{
- // Since QSqlTableModel will escape the identifiers, we need to escape
- // them for databases that are case sensitive
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- const QString timetest(qTableName("timetest", __FILE__, db));
- tst_Databases::safeDropTable(db, timetest);
+ // Since QSqlTableModel will escape the identifiers, we need to escape them
+ // for databases that are case sensitive.
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "timetest", __FILE__);
QSqlQuery q(db);
- QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE ") + timetest + QStringLiteral(" (t TIME)")));
- QVERIFY_SQL(q, exec(QStringLiteral("INSERT INTO ") + timetest +
- QStringLiteral(" VALUES ('1:2:3.666')")));
+ 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);
+ 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"), QString("01:02:03.666"));
- QVERIFY_SQL(timetestModel,setData(timetestModel.index(0, 0), QTime(0,12,34,500)));
- QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"), QString("00:12:34.500"));
+ QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"),
+ u"01:02:03.666");
+ QVERIFY_SQL(timetestModel, setData(timetestModel.index(0, 0), QTime(0, 12, 34, 500)));
+ QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"),
+ u"00:12:34.500");
QVERIFY_SQL(timetestModel, submitAll());
- QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"), QString("00:12:34.500"));
+ QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"),
+ u"00:12:34.500");
- QVERIFY_SQL(q, exec(QStringLiteral("UPDATE ") + timetest +
- QStringLiteral(" SET t = '0:11:22.33'")));
+ 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"), QString("00:11:22.330"));
-
+ QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"),
+ u"00:11:22.330");
}
void tst_QSqlQuery::QTBUG_6421()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ 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("create table "+tableName+"(COL1 char(10), COL2 char(10), COL3 char(10))"));
- QVERIFY_SQL(q, exec("create index INDEX1 on "+tableName+" (COL1 desc)"));
- QVERIFY_SQL(q, exec("create index INDEX2 on "+tableName+" (COL2 desc)"));
- QVERIFY_SQL(q, exec("create index INDEX3 on "+tableName+" (COL3 desc)"));
+ QVERIFY_SQL(q, exec(QLatin1String(
+ "create table %1(COL1 char(10), COL2 char(10), COL3 char(10))")
+ .arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("create index INDEX1 on %1 (COL1 desc)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("create index INDEX2 on %1 (COL2 desc)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("create index INDEX3 on %1 (COL3 desc)").arg(tableName)));
q.setForwardOnly(true);
- QVERIFY_SQL(q, exec("select COLUMN_EXPRESSION from ALL_IND_EXPRESSIONS where TABLE_NAME='" + tableName + QLatin1Char('\'')));
+ QVERIFY_SQL(q, exec(QLatin1String("select COLUMN_EXPRESSION from ALL_IND_EXPRESSIONS "
+ "where TABLE_NAME='%1'")
+ .arg(tableName)));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toString(), QLatin1String("\"COL1\""));
QVERIFY_SQL(q, next());
@@ -3740,53 +3741,53 @@ void tst_QSqlQuery::QTBUG_6421()
void tst_QSqlQuery::QTBUG_6618()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType != QSqlDriver::MSSqlServer)
- QSKIP("SQL Server specific test");
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ if (tst_Databases::getDatabaseType(db) != QSqlDriver::MSSqlServer)
+ QSKIP("Test is specific to SQL Server");
+ ProcScope ps(db, "tst_raiseError", __FILE__);
QSqlQuery q(db);
- q.exec("drop procedure " + qTableName("tst_raiseError", __FILE__, db)); //non-fatal
QString errorString;
- for (int i=0;i<110;i++)
- errorString+="reallylong";
- errorString+=" error";
- QVERIFY_SQL(q, exec("create procedure " + qTableName("tst_raiseError", __FILE__, db) + " as\n"
- "begin\n"
- " raiserror('" + errorString + "', 16, 1)\n"
- "end\n" ));
- q.exec("{call " + qTableName("tst_raiseError", __FILE__, db) + QLatin1Char('}'));
+ for (int i = 0; i < 110; ++i)
+ errorString += "reallylong";
+ errorString += " error";
+ QVERIFY_SQL(q, exec(QLatin1String("create procedure %1 as\n"
+ "begin\n"
+ " raiserror('%2', 16, 1)\n"
+ "end\n").arg(ps.name(), errorString)));
+ q.exec(QLatin1String("{call %1}").arg(ps.name()));
QVERIFY(q.lastError().text().contains(errorString));
}
void tst_QSqlQuery::QTBUG_6852()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "bug6852", __FILE__);
+ const auto &tableName = ts.tableName();
+ ProcScope ps(db, "bug6852_proc", __FILE__);
+
QSqlQuery q(db);
- const QString tableName(qTableName("bug6852", __FILE__, db)), procName(qTableName("bug6852_proc", __FILE__, db));
-
- QVERIFY_SQL(q, exec("DROP PROCEDURE IF EXISTS "+procName));
- QVERIFY_SQL(q, exec("CREATE TABLE "+tableName+"(\n"
- "MainKey INT NOT NULL,\n"
- "OtherTextCol VARCHAR(45) NOT NULL,\n"
- "PRIMARY KEY(`MainKey`))"));
- QVERIFY_SQL(q, exec("INSERT INTO "+tableName+" VALUES(0, \"Disabled\")"));
- QVERIFY_SQL(q, exec("INSERT INTO "+tableName+" VALUES(5, \"Error Only\")"));
- QVERIFY_SQL(q, exec("INSERT INTO "+tableName+" VALUES(10, \"Enabled\")"));
- QVERIFY_SQL(q, exec("INSERT INTO "+tableName+" VALUES(15, \"Always\")"));
- QVERIFY_SQL(q, exec("CREATE PROCEDURE "+procName+"()\n"
- "READS SQL DATA\n"
- "BEGIN\n"
- " SET @st = 'SELECT MainKey, OtherTextCol from "+tableName+"';\n"
- " PREPARE stmt from @st;\n"
- " EXECUTE stmt;\n"
- "END;"));
-
- QVERIFY_SQL(q, exec("CALL "+procName+"()"));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1(\n"
+ "MainKey INT NOT NULL,\n"
+ "OtherTextCol VARCHAR(45) NOT NULL,\n"
+ "PRIMARY KEY(`MainKey`))").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 VALUES(0, \"Disabled\")").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 VALUES(5, \"Error Only\")").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 VALUES(10, \"Enabled\")").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 VALUES(15, \"Always\")").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE PROCEDURE %1()\n"
+ "READS SQL DATA\n"
+ "BEGIN\n"
+ " SET @st = 'SELECT MainKey, OtherTextCol from %2';\n"
+ " PREPARE stmt from @st;\n"
+ " EXECUTE stmt;\n"
+ "END;").arg(ps.name(), tableName)));
+
+ 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"));
@@ -3794,21 +3795,22 @@ void tst_QSqlQuery::QTBUG_6852()
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));
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ TableScope ts(db, "bug5765", __FILE__);
- QVERIFY_SQL(q, exec("CREATE TABLE "+tableName+"(testval TINYINT(1) DEFAULT 0)"));
- q.prepare("INSERT INTO "+tableName+" SET testval = :VALUE");
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1(testval TINYINT(1) DEFAULT 0)")
+ .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);
@@ -3826,53 +3828,56 @@ void tst_QSqlQuery::QTBUG_5765()
QCOMPARE(q.value(0).toInt(), 123);
}
-/**
-* This test case tests multiple statements in one execution.
-* Sqlite driver doesn't support multiple statement at one time.
-* If more than one statement is given, the exec or prepare function
-* return failure to the client.
+/* Test multiple statements in one execution.
+ SQLite driver doesn't support that. If more than one statement is given, the
+ exec or prepare function return failure to the client.
*/
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);
- QStringList stList;
- QString tableName(qTableName("bug21884", __FILE__, db));
- stList << "create table " + tableName + "(id integer primary key, note string)";
- stList << "select * from " + tableName + QLatin1Char(';');
- stList << "select * from " + tableName + "; \t\n\r";
- stList << "drop table " + tableName;
-
-
- foreach (const QString& st, stList) {
- QVERIFY_SQL(q, exec(st));
- }
-
- foreach (const QString& st, stList) {
- QVERIFY_SQL(q, prepare(st));
- QVERIFY_SQL(q, exec());
+ {
+ const QString good[] = {
+ QLatin1String("create table %1(id integer primary key, note string)").arg(tableName),
+ QLatin1String("select * from %1;").arg(tableName),
+ QLatin1String("select * from %1; \t\n\r").arg(tableName),
+ QLatin1String("drop table %1").arg(tableName)
+ };
+
+ for (const QString &st : good)
+ QVERIFY_SQL(q, exec(st));
+
+ for (const QString &st : good) {
+ QVERIFY_SQL(q, prepare(st));
+ QVERIFY_SQL(q, exec());
+ }
}
- stList.clear();
- stList << "create table " + tableName + "(id integer primary key); select * from " + tableName;
- stList << "create table " + tableName + "(id integer primary key); syntax error!;";
- stList << "create table " + tableName + "(id integer primary key);;";
- stList << "create table " + tableName + "(id integer primary key);\'\"\a\b\b\v";
-
- foreach (const QString&st , stList) {
- QVERIFY2(!q.prepare(st), qPrintable(QString("the statement is expected to fail! ") + st));
- QVERIFY2(!q.exec(st), qPrintable(QString("the statement is expected to fail! ") + st));
+ {
+ const QString bad[] = {
+ QLatin1String("create table %1(id integer primary key); select * from ").arg(tableName),
+ QLatin1String("create table %1(id integer primary key); syntax error!;").arg(tableName),
+ QLatin1String("create table %1(id integer primary key);;").arg(tableName),
+ QLatin1String("create table %1(id integer primary key);\'\"\a\b\b\v").arg(tableName)
+ };
+
+ QLatin1String shouldFail("the statement is expected to fail! %1");
+ for (const QString &st : bad) {
+ QVERIFY2(!q.prepare(st), qPrintable(shouldFail.arg(st)));
+ QVERIFY2(!q.exec(st), qPrintable(shouldFail.arg(st)));
+ }
}
}
-/**
- * This test case test sqlite driver close function. Sqlite driver should close cleanly
- * even if there is still outstanding prepared statement.
- */
+/* Test SQLite driver close function. SQLite driver should close cleanly even if
+ there is still outstanding prepared statement.
+*/
void tst_QSqlQuery::QTBUG_16967()
{
QSqlQuery q2;
@@ -3887,7 +3892,7 @@ void tst_QSqlQuery::QTBUG_16967()
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);
@@ -3896,7 +3901,7 @@ void tst_QSqlQuery::QTBUG_16967()
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();
@@ -3906,7 +3911,7 @@ void tst_QSqlQuery::QTBUG_16967()
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);
@@ -3915,37 +3920,38 @@ void tst_QSqlQuery::QTBUG_16967()
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);
}
}
-/**
- * In SQLite when a boolean value is bound to a placeholder, it should be converted
- * into integer 0/1 rather than text "false"/"true". According to documentation,
- * SQLite does not have separate Boolean storage class. Instead, Boolean values are
- * stored as integers.
- */
+/* In SQLite, when a boolean value is bound to a placeholder, it should be
+ converted into integer 0/1 rather than text "false"/"true". According to
+ documentation, SQLite does not have a separate Boolean storage class.
+ Instead, Boolean values are stored as integers.
+*/
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("create table " + tableName + "(id integer primary key, val1 bool, val2 boolean)");
+ q.prepare(QLatin1String("create table %1(id integer primary key, val1 bool, val2 boolean)")
+ .arg(tableName));
QVERIFY_SQL(q, exec());
- q.prepare("insert into " + tableName + "(id, val1, val2) values(?, ?, ?);");
+ q.prepare(QLatin1String("insert into %1(id, val1, val2) values(?, ?, ?);").arg(tableName));
q.addBindValue(1);
q.addBindValue(true);
q.addBindValue(false);
QVERIFY_SQL(q, exec());
- QString sql="select * from " + tableName;
+ QString sql = "select * from " + tableName;
QVERIFY_SQL(q, exec(sql));
QVERIFY_SQL(q, next());
@@ -3954,24 +3960,24 @@ void tst_QSqlQuery::QTBUG_23895()
QCOMPARE(q.value(0).toInt(), 1);
QCOMPARE(q.record().field(1).metaType().id(), QMetaType::Bool);
QCOMPARE(q.value(1).metaType().id(), QMetaType::LongLong);
- QCOMPARE(q.value(1).toBool(), true);
+ QVERIFY(q.value(1).toBool());
QCOMPARE(q.record().field(2).metaType().id(), QMetaType::Bool);
QCOMPARE(q.value(2).metaType().id(), QMetaType::LongLong);
- QCOMPARE(q.value(2).toBool(), false);
+ QVERIFY(!q.value(2).toBool());
- q.prepare("insert into " + tableName + "(id, val1, val2) values(?, ?, ?);");
+ q.prepare(QLatin1String("insert into %1(id, val1, val2) values(?, ?, ?);").arg(tableName));
q.addBindValue(2);
q.addBindValue(false);
q.addBindValue(false);
QVERIFY_SQL(q, exec());
- sql="select * from " + tableName + " where val1";
+ sql = QLatin1String("select * from %1 where val1").arg(tableName);
QVERIFY_SQL(q, exec(sql));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 1);
QVERIFY(!q.next());
- sql="select * from " + tableName + " where not val2";
+ sql = QLatin1String("select * from %1 where not val2").arg(tableName);
QVERIFY_SQL(q, exec(sql));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 1);
@@ -3980,60 +3986,54 @@ void tst_QSqlQuery::QTBUG_23895()
QVERIFY(!q.next());
}
-/**
- * Test for aliases with dots
- */
+// Test for aliases with dots:
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("create table " + tableName + "(val1 bool)");
+ q.prepare(QLatin1String("create table %1(val1 bool)").arg(ts.tableName()));
QVERIFY_SQL(q, exec());
- q.prepare("insert into " + tableName + "(val1) values(?);");
+ 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());
QCOMPARE(q.record().indexOf("value1"), 0);
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::Bool);
- QCOMPARE(q.value(0).toBool(), true);
+ 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
+ QCOMPARE(q.record().indexOf("value.one"), 0); // Was -1 before bug fix.
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::Bool);
- QCOMPARE(q.value(0).toBool(), true);
+ QVERIFY(q.value(0).toBool());
}
void tst_QSqlQuery::QTBUG_2192()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ 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(QString("CREATE TABLE " + tableName + " (dt %1)").arg(tst_Databases::dateTimeTypeName(db))));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (dt %2)")
+ .arg(ts.tableName(), tst_Databases::dateTimeTypeName(db))));
QDateTime dt = QDateTime(QDate(2012, 7, 4), QTime(23, 59, 59, 999));
- QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " (dt) VALUES (?)"));
+ 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
@@ -4046,15 +4046,14 @@ void tst_QSqlQuery::QTBUG_2192()
void tst_QSqlQuery::QTBUG_36211()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ 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(QString("CREATE TABLE %1 (dtwtz timestamptz, dtwotz timestamp)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (dtwtz timestamptz, dtwotz timestamp)")
+ .arg(ts.tableName())));
#if QT_CONFIG(timezone)
QTimeZone l_tzBrazil("America/Sao_Paulo");
@@ -4062,7 +4061,8 @@ void tst_QSqlQuery::QTBUG_36211()
QVERIFY(l_tzBrazil.isValid());
QVERIFY(l_tzChina.isValid());
QDateTime dt = QDateTime(QDate(2014, 10, 30), QTime(14, 12, 02, 357));
- QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " (dtwtz, dtwotz) VALUES (:dt, :dt)"));
+ QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 (dtwtz, dtwotz) VALUES (:dt, :dt)")
+ .arg(ts.tableName())));
q.bindValue(":dt", dt);
QVERIFY_SQL(q, exec());
q.bindValue(":dt", dt.toTimeZone(l_tzBrazil));
@@ -4070,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());
@@ -4089,29 +4089,28 @@ void tst_QSqlQuery::QTBUG_36211()
void tst_QSqlQuery::QTBUG_53969()
{
- QFETCH( QString, dbName );
- QList<int> values = QList<int>() << 10 << 20 << 127 << 128 << 1, tableValues;
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
+ QFETCH(QString, dbName);
+ const QList<int> values = { 10, 20, 127, 128, 1 };
+ QList<int> tableValues;
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ 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(QString("CREATE TABLE %1 (id INT AUTO_INCREMENT PRIMARY KEY, "
- "test_number TINYINT(3) UNSIGNED)")
- .arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INT AUTO_INCREMENT PRIMARY KEY, "
+ "test_number TINYINT(3) UNSIGNED)")
+ .arg(ts.tableName())));
- QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " (test_number) VALUES (:value)"));
+ QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 (test_number) VALUES (:value)")
+ .arg(ts.tableName())));
- QList<int>::iterator begin = values.begin(), end = values.end(), it;
- for (it = begin; it != end; ++it) {
- q.bindValue(":value", *it);
+ 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()) {
@@ -4119,7 +4118,7 @@ void tst_QSqlQuery::QTBUG_53969()
tableValues.push_back(q.value(0).toUInt(&ok));
QVERIFY(ok);
}
- QCOMPARE(values, tableValues);
+ QCOMPARE(tableValues, values);
}
}
@@ -4128,145 +4127,131 @@ 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);
- QString sqlCommand = QStringLiteral("CREATE TABLE %1 (`lonlat_point` POINT NULL) ENGINE = InnoDB;").arg(tableName);
- QVERIFY(sqlQuery.exec(sqlCommand));
- sqlCommand = QStringLiteral("INSERT INTO %1(lonlat_point) VALUES(ST_GeomFromText('POINT(1 1)'));").arg(tableName);
- QVERIFY(sqlQuery.exec(sqlCommand));
- sqlCommand = QStringLiteral("SELECT * FROM %1;").arg(tableName);
- QVERIFY(sqlQuery.exec(sqlCommand));
+ QVERIFY(sqlQuery.exec(QLatin1String(
+ "CREATE TABLE %1 (`lonlat_point` POINT NULL) ENGINE = InnoDB;")
+ .arg(ts.tableName())));
+ QVERIFY(sqlQuery.exec(QLatin1String(
+ "INSERT INTO %1(lonlat_point) VALUES(ST_GeomFromText('POINT(1 1)'));")
+ .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());
}
void tst_QSqlQuery::oraOCINumber()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
- const QString qtest_oraOCINumber(qTableName("qtest_oraOCINumber", __FILE__, db));
-
- QSqlQuery q( db );
- q.setForwardOnly( true );
- QVERIFY_SQL( q, exec( "create table " + qtest_oraOCINumber +
- " (col1 number(20), col2 number(20))" ) );
- QVERIFY(q.prepare("insert into " + qtest_oraOCINumber + " values (?, ?)"));
- QVariantList col1Values;
- QVariantList col2Values;
- col1Values << (qulonglong)(1)
- << (qulonglong)(0)
- << (qulonglong)(INT_MAX)
- << (qulonglong)(UINT_MAX)
- << (qulonglong)(LONG_MAX)
- << (qulonglong)(ULONG_MAX)
- << (qulonglong)(LLONG_MAX)
- << (qulonglong)(ULLONG_MAX);
-
- col2Values << (qlonglong)(1)
- << (qlonglong)(0)
- << (qlonglong)(-1)
- << (qlonglong)(LONG_MAX)
- << (qlonglong)(LONG_MIN)
- << (qlonglong)(ULONG_MAX)
- << (qlonglong)(LLONG_MAX)
- << (qlonglong)(LLONG_MIN);
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(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(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),
+ qulonglong(LONG_MAX), qulonglong(ULONG_MAX), qulonglong(LLONG_MAX),
+ qulonglong(ULLONG_MAX)
+ };
+ const QVariantList col2Values = {
+ qlonglong(1), qlonglong(0), qlonglong(-1), qlonglong(LONG_MAX), qlonglong(LONG_MIN),
+ qlonglong(ULONG_MAX), qlonglong(LLONG_MAX), qlonglong(LLONG_MIN)
+ };
q.addBindValue(col1Values);
q.addBindValue(col2Values);
QVERIFY(q.execBatch());
- QString sqlStr = "select * from " + qtest_oraOCINumber + " where col1 = :bindValue0 AND col2 = :bindValue1";
- QVERIFY(q.prepare(sqlStr));
+ QVERIFY(q.prepare(QLatin1String(
+ "select * from %1 where col1 = :bindValue0 AND col2 = :bindValue1")
+ .arg(ts.tableName())));
- q.bindValue(":bindValue0", (qulonglong)(1), QSql::InOut);
- q.bindValue(":bindValue1", (qlonglong)(1), QSql::InOut);
+ q.bindValue(":bindValue0", qulonglong(1), QSql::InOut);
+ q.bindValue(":bindValue1", qlonglong(1), QSql::InOut);
- QVERIFY_SQL( q, exec() );
- QVERIFY( q.next() );
- QCOMPARE(q.boundValue( 0 ).toULongLong(), qulonglong(1));
- QCOMPARE(q.boundValue( 1 ).toLongLong(), (qlonglong)(1));
-
- q.bindValue(":bindValue0", (qulonglong)(0), QSql::InOut);
- q.bindValue(":bindValue1", (qlonglong)(0), QSql::InOut);
- QVERIFY_SQL( q, exec() );
+ QVERIFY_SQL(q, exec());
+ QVERIFY(q.next());
+ QCOMPARE(q.boundValue(0).toULongLong(), qulonglong(1));
+ QCOMPARE(q.boundValue(1).toLongLong(), qlonglong(1));
- QVERIFY( q.next() );
- QCOMPARE(q.boundValue( 0 ).toULongLong(), (qulonglong)(0));
- QCOMPARE(q.boundValue( 1 ).toLongLong(), (qlonglong)(0));
+ q.bindValue(":bindValue0", qulonglong(0), QSql::InOut);
+ q.bindValue(":bindValue1", qlonglong(0), QSql::InOut);
+ QVERIFY_SQL(q, exec());
- q.bindValue(":bindValue0", (qulonglong)(INT_MAX), QSql::InOut);
- q.bindValue(":bindValue1", (qlonglong)(-1), QSql::InOut);
- QVERIFY_SQL( q, exec() );
+ QVERIFY(q.next());
+ QCOMPARE(q.boundValue(0).toULongLong(), qulonglong(0));
+ QCOMPARE(q.boundValue(1).toLongLong(), qlonglong(0));
- QVERIFY( q.next() );
- QCOMPARE(q.boundValue( 0 ).toULongLong(), (qulonglong)(INT_MAX));
- QCOMPARE(q.boundValue( 1 ).toLongLong(), (qlonglong)(-1));
+ q.bindValue(":bindValue0", qulonglong(INT_MAX), QSql::InOut);
+ q.bindValue(":bindValue1", qlonglong(-1), QSql::InOut);
+ QVERIFY_SQL(q, exec());
- q.bindValue(":bindValue0", (qulonglong)(UINT_MAX), QSql::InOut);
- q.bindValue(":bindValue1", (qlonglong)(LONG_MAX), QSql::InOut);
- QVERIFY_SQL( q, exec() );
+ QVERIFY(q.next());
+ QCOMPARE(q.boundValue(0).toULongLong(), qulonglong(INT_MAX));
+ QCOMPARE(q.boundValue(1).toLongLong(), qlonglong(-1));
- QVERIFY( q.next() );
- QCOMPARE(q.boundValue( 0 ).toULongLong(), (qulonglong)(UINT_MAX));
- QCOMPARE(q.boundValue( 1 ).toLongLong(), (qlonglong)(LONG_MAX));
+ q.bindValue(":bindValue0", qulonglong(UINT_MAX), QSql::InOut);
+ q.bindValue(":bindValue1", qlonglong(LONG_MAX), QSql::InOut);
+ QVERIFY_SQL(q, exec());
- q.bindValue(":bindValue0", (qulonglong)(LONG_MAX), QSql::InOut);
- q.bindValue(":bindValue1", (qlonglong)(LONG_MIN), QSql::InOut);
- QVERIFY_SQL( q, exec() );
+ QVERIFY(q.next());
+ QCOMPARE(q.boundValue(0).toULongLong(), qulonglong(UINT_MAX));
+ QCOMPARE(q.boundValue(1).toLongLong(), qlonglong(LONG_MAX));
- QVERIFY( q.next() );
- QCOMPARE(q.boundValue( 0 ).toULongLong(), (qulonglong)(LONG_MAX));
- QCOMPARE(q.boundValue( 1 ).toLongLong(), (qlonglong)(LONG_MIN));
+ q.bindValue(":bindValue0", qulonglong(LONG_MAX), QSql::InOut);
+ q.bindValue(":bindValue1", qlonglong(LONG_MIN), QSql::InOut);
+ QVERIFY_SQL(q, exec());
- q.bindValue(":bindValue0", (qulonglong)(ULONG_MAX), QSql::InOut);
- q.bindValue(":bindValue1", (qlonglong)(ULONG_MAX), QSql::InOut);
- QVERIFY_SQL( q, exec() );
+ QVERIFY(q.next());
+ QCOMPARE(q.boundValue(0).toULongLong(), qulonglong(LONG_MAX));
+ QCOMPARE(q.boundValue(1).toLongLong(), qlonglong(LONG_MIN));
- QVERIFY( q.next() );
- QCOMPARE(q.boundValue( 0 ).toULongLong(), (qulonglong)(ULONG_MAX));
- QCOMPARE(q.boundValue( 1 ).toLongLong(), (qlonglong)(ULONG_MAX));
+ q.bindValue(":bindValue0", qulonglong(ULONG_MAX), QSql::InOut);
+ q.bindValue(":bindValue1", qlonglong(ULONG_MAX), QSql::InOut);
+ QVERIFY_SQL(q, exec());
- q.bindValue(":bindValue0", (qulonglong)(LLONG_MAX), QSql::InOut);
- q.bindValue(":bindValue1", (qlonglong)(LLONG_MAX), QSql::InOut);
- QVERIFY_SQL( q, exec() );
+ QVERIFY(q.next());
+ QCOMPARE(q.boundValue(0).toULongLong(), qulonglong(ULONG_MAX));
+ QCOMPARE(q.boundValue(1).toLongLong(), qlonglong(ULONG_MAX));
- QVERIFY( q.next() );
- QCOMPARE(q.boundValue( 0 ).toULongLong(), (qulonglong)(LLONG_MAX));
- QCOMPARE(q.boundValue( 1 ).toLongLong(), (qlonglong)(LLONG_MAX));
+ q.bindValue(":bindValue0", qulonglong(LLONG_MAX), QSql::InOut);
+ q.bindValue(":bindValue1", qlonglong(LLONG_MAX), QSql::InOut);
+ QVERIFY_SQL(q, exec());
- q.bindValue(":bindValue0", (qulonglong)(ULLONG_MAX), QSql::InOut);
- q.bindValue(":bindValue1", (qlonglong)(LLONG_MIN), QSql::InOut);
- QVERIFY_SQL( q, exec() );
+ QVERIFY(q.next());
+ QCOMPARE(q.boundValue(0).toULongLong(), qulonglong(LLONG_MAX));
+ QCOMPARE(q.boundValue(1).toLongLong(), qlonglong(LLONG_MAX));
- QVERIFY( q.next() );
- QCOMPARE(q.boundValue( 0 ).toULongLong(), (qulonglong)(ULLONG_MAX));
- QCOMPARE(q.boundValue( 1 ).toLongLong(), (qlonglong)(LLONG_MIN));
+ q.bindValue(":bindValue0", qulonglong(ULLONG_MAX), QSql::InOut);
+ q.bindValue(":bindValue1", qlonglong(LLONG_MIN), QSql::InOut);
+ QVERIFY_SQL(q, exec());
+ QVERIFY(q.next());
+ QCOMPARE(q.boundValue(0).toULongLong(), qulonglong(ULLONG_MAX));
+ QCOMPARE(q.boundValue(1).toLongLong(), qlonglong(LLONG_MIN));
}
void tst_QSqlQuery::sqlite_constraint()
{
- QFETCH( QString, dbName );
- QSqlDatabase db = QSqlDatabase::database( dbName );
- CHECK_DATABASE( db );
-
- QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType != QSqlDriver::SQLite)
- QSKIP("Sqlite3 specific test");
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
QSqlQuery q(db);
const QString trigger(qTableName("test_constraint", __FILE__, db));
- QVERIFY_SQL(q, exec("CREATE TEMP TRIGGER "+trigger+" BEFORE DELETE ON "+qtest+
- "\nFOR EACH ROW "
- "\nBEGIN"
- "\n SELECT RAISE(ABORT, 'Raised Abort successfully');"
- "\nEND;"
- ));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TEMP TRIGGER %1 BEFORE DELETE ON %2\n"
+ "FOR EACH ROW\n"
+ "BEGIN\n"
+ " SELECT RAISE(ABORT, 'Raised Abort successfully');\n"
+ "END;").arg(trigger, qtest)));
- QVERIFY(!q.exec("DELETE FROM "+qtest));
+ QVERIFY(!q.exec("DELETE FROM " + qtest));
QCOMPARE(q.lastError().databaseText(), QLatin1String("Raised Abort successfully"));
}
@@ -4275,28 +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("CREATE TABLE " + tableName + " (id INTEGER, realVal REAL)"));
- QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id, realVal) VALUES (1, 2.3)"));
- QVERIFY_SQL(q, exec("SELECT realVal FROM " + tableName));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INTEGER, realVal REAL)")
+ .arg(ts.tableName())));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id, realVal) VALUES (1, 2.3)")
+ .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("INSERT INTO " + tableName + " (id, realVal) VALUES (?, ?)");
+ 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("SELECT realVal FROM " + tableName + " WHERE ID=4"));
+ 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);
@@ -4307,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;
@@ -4316,11 +4338,11 @@ 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("CREATE TABLE " + tableName + " (id INTEGER)"));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INTEGER)").arg(tableName)));
// First test without any entries
QVERIFY_SQL(q, exec("SELECT SUM(id) FROM " + tableName));
@@ -4330,8 +4352,8 @@ void tst_QSqlQuery::aggregateFunctionTypes()
else
QCOMPARE(q.record().field(0).metaType().id(), sumType);
- QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id) VALUES (1)"));
- QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id) VALUES (2)"));
+ 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)));
QVERIFY_SQL(q, exec("SELECT SUM(id) FROM " + tableName));
QVERIFY(q.next());
@@ -4340,13 +4362,14 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY_SQL(q, exec("SELECT AVG(id) FROM " + tableName));
QVERIFY(q.next());
- if (dbType == QSqlDriver::SQLite || dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::MySqlServer
- || dbType == QSqlDriver::Oracle) {
+ if (dbType == QSqlDriver::SQLite || dbType == QSqlDriver::PostgreSQL
+ || dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::Oracle) {
QCOMPARE(q.value(0).toDouble(), 1.5);
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::Double);
} else {
QCOMPARE(q.value(0).toInt(), 1);
- QCOMPARE(q.record().field(0).metaType().id(), (dbType == QSqlDriver::Interbase ? QMetaType::LongLong : QMetaType::Int));
+ QCOMPARE(q.record().field(0).metaType().id(),
+ dbType == QSqlDriver::Interbase ? QMetaType::LongLong : QMetaType::Int);
}
QVERIFY_SQL(q, exec("SELECT COUNT(id) FROM " + tableName));
@@ -4365,11 +4388,11 @@ 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("CREATE TABLE " + tableName + " (id REAL)"));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id REAL)").arg(tableName)));
// First test without any entries
QVERIFY_SQL(q, exec("SELECT SUM(id) FROM " + tableName));
@@ -4379,8 +4402,8 @@ void tst_QSqlQuery::aggregateFunctionTypes()
else
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::Double);
- QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id) VALUES (1.5)"));
- QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id) VALUES (2.5)"));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id) VALUES (1.5)").arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id) VALUES (2.5)").arg(tableName)));
QVERIFY_SQL(q, exec("SELECT SUM(id) FROM " + tableName));
QVERIFY(q.next());
@@ -4410,16 +4433,17 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QString field = "id";
// PSQL does not have the round() function with real type
- if (dbType == QSqlDriver::PostgreSQL) {
+ if (dbType == QSqlDriver::PostgreSQL)
field += "::NUMERIC";
- }
- QVERIFY_SQL(q, exec("SELECT ROUND(" + field + ", 1) FROM " + tableName + " WHERE id=1.5"));
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT ROUND(%1, 1) FROM %2 WHERE id=1.5")
+ .arg(field, tableName)));
QVERIFY(q.next());
QCOMPARE(q.value(0).toDouble(), 1.5);
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::Double);
- QVERIFY_SQL(q, exec("SELECT ROUND(" + field + ", 0) FROM " + tableName + " WHERE id=2.5"));
+ QVERIFY_SQL(q, exec(QLatin1String("SELECT ROUND(%1, 0) FROM %2 WHERE id=2.5")
+ .arg(field, tableName)));
QVERIFY(q.next());
if (dbType == QSqlDriver::MySqlServer)
QCOMPARE(q.value(0).toDouble(), 2.0);
@@ -4428,26 +4452,42 @@ 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("CREATE TABLE " + tableName + " (id INTEGER, txt VARCHAR(50))"));
+ 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
QCOMPARE(q.record().field(0).metaType().id(), QMetaType::QString);
- QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id, txt) VALUES (1, 'lower')"));
- QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id, txt) VALUES (2, 'upper')"));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id, txt) VALUES (1, 'lower')")
+ .arg(tableName)));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id, txt) VALUES (2, 'upper')")
+ .arg(tableName)));
QVERIFY_SQL(q, exec("SELECT MAX(txt) FROM " + tableName));
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);
}
}
@@ -4457,13 +4497,13 @@ 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("CREATE TABLE " + tableName + " (id " + type + ')'));
+ QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %2 (id %1)").arg(type, tableName)));
if (withPreparedStatement) {
- QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " (id) VALUES (?)"));
+ QVERIFY_SQL(q, prepare(QLatin1String("INSERT INTO %1 (id) VALUES (?)").arg(tableName)));
}
for (int i = 0; i < values.size(); ++i) {
const T v = values.at(i);
@@ -4471,12 +4511,13 @@ void runIntegralTypesMysqlTest(QSqlDatabase &db, const QString &tableName, const
q.bindValue(0, v);
QVERIFY_SQL(q, exec());
} else {
- QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id) VALUES (" + QString::number(v) + QLatin1Char(')')));
+ QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id) VALUES (%2)")
+ .arg(tableName, QString::number(v))));
}
variantValues.append(QVariant::fromValue(v));
}
- // ensure we can read them back properly
+ // Ensure we can read them back properly:
if (withPreparedStatement) {
QVERIFY_SQL(q, prepare("SELECT id FROM " + tableName));
QVERIFY_SQL(q, exec());
@@ -4504,8 +4545,8 @@ void runIntegralTypesMysqlTest(QSqlDatabase &db, const QString &tableName,
const T min = std::numeric_limits<T>::min(),
const T max = std::numeric_limits<T>::max())
{
- // insert some values
- const int steps = 20;
+ // Insert some values:
+ constexpr int steps = 20;
const T increment = (max / steps - min / steps);
QList<T> values;
values.reserve(steps);
@@ -4524,47 +4565,65 @@ void tst_QSqlQuery::integralTypesMysql()
const QList<bool> boolValues = QList<bool>() << false << true;
for (int i = 0; i < 2; ++i) {
const bool withPreparedStatement = (i == 1);
- runIntegralTypesMysqlTest<bool>(db, "tinyInt1Test", "TINYINT(1)", withPreparedStatement, boolValues);
- runIntegralTypesMysqlTest<bool>(db, "unsignedTinyInt1Test", "TINYINT(1) UNSIGNED", withPreparedStatement, boolValues);
+ runIntegralTypesMysqlTest<bool>(db, "tinyInt1Test", "TINYINT(1)",
+ withPreparedStatement, boolValues);
+ runIntegralTypesMysqlTest<bool>(db, "unsignedTinyInt1Test", "TINYINT(1) UNSIGNED",
+ withPreparedStatement, boolValues);
runIntegralTypesMysqlTest<qint8>(db, "tinyIntTest", "TINYINT", withPreparedStatement);
- runIntegralTypesMysqlTest<quint8>(db, "unsignedTinyIntTest", "TINYINT UNSIGNED", withPreparedStatement);
+ runIntegralTypesMysqlTest<quint8>(db, "unsignedTinyIntTest", "TINYINT UNSIGNED",
+ withPreparedStatement);
runIntegralTypesMysqlTest<qint16>(db, "smallIntTest", "SMALLINT", withPreparedStatement);
- runIntegralTypesMysqlTest<quint16>(db, "unsignedSmallIntTest", "SMALLINT UNSIGNED", withPreparedStatement);
- runIntegralTypesMysqlTest<qint32>(db, "mediumIntTest", "MEDIUMINT", withPreparedStatement, -(1 << 23), (1 << 23) - 1);
- runIntegralTypesMysqlTest<quint32>(db, "unsignedMediumIntTest", "MEDIUMINT UNSIGNED", withPreparedStatement, 0, (1 << 24) - 1);
+ runIntegralTypesMysqlTest<quint16>(db, "unsignedSmallIntTest", "SMALLINT UNSIGNED",
+ withPreparedStatement);
+ runIntegralTypesMysqlTest<qint32>(db, "mediumIntTest", "MEDIUMINT", withPreparedStatement,
+ -(1 << 23), (1 << 23) - 1);
+ runIntegralTypesMysqlTest<quint32>(db, "unsignedMediumIntTest", "MEDIUMINT UNSIGNED",
+ withPreparedStatement, 0, (1 << 24) - 1);
runIntegralTypesMysqlTest<qint32>(db, "intTest", "INT", withPreparedStatement);
- runIntegralTypesMysqlTest<quint32>(db, "unsignedIntTest", "INT UNSIGNED", withPreparedStatement);
+ runIntegralTypesMysqlTest<quint32>(db, "unsignedIntTest", "INT UNSIGNED",
+ withPreparedStatement);
runIntegralTypesMysqlTest<qint64>(db, "bigIntTest", "BIGINT", withPreparedStatement);
- runIntegralTypesMysqlTest<quint64>(db, "unsignedBigIntTest", "BIGINT UNSIGNED", 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()
{
- QDateTime utc = QDateTime(QDate(2150, 1, 5), QTime(14, 0, 0, 123), Qt::UTC);
- QDateTime localtime = QDateTime(QDate(2150, 1, 5), QTime(14, 0, 0, 123), Qt::LocalTime);
- 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("create table " + tableName + " (id int, dt_utc datetime, dt_lt datetime, dt_tzoffset datetime)"));
- QVERIFY_SQL(create, prepare("insert into " + tableName + " (id, dt_utc, dt_lt, dt_tzoffset) values (?, ?, ?, ?)"));
+ QVERIFY_SQL(create, exec(QLatin1String(
+ "create table %1 (id int, dt_utc datetime, dt_lt datetime, "
+ "dt_tzoffset datetime)").arg(ts.tableName())));
+ QVERIFY_SQL(create, prepare(QLatin1String("insert into %1 (id, dt_utc, dt_lt, dt_tzoffset) "
+ "values (?, ?, ?, ?)").arg(ts.tableName())));
create.addBindValue(0);
create.addBindValue(utc);
create.addBindValue(localtime);
create.addBindValue(tzoffset);
-
QVERIFY_SQL(create, exec());
QSqlQuery q(db);
- q.prepare("SELECT dt_utc, dt_lt, dt_tzoffset FROM " + tableName + " WHERE id = ?");
+ q.prepare(QLatin1String("SELECT dt_utc, dt_lt, dt_tzoffset FROM %1 WHERE id = ?")
+ .arg(ts.tableName()));
q.addBindValue(0);
QVERIFY_SQL(q, exec());
@@ -4580,13 +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("create table " + tableName + " (dec2 decimal(4,2), dec0 decimal(20,0), dec3 decimal(20,3))"));
- QVERIFY_SQL(create, prepare("insert into " + tableName + " (dec2, dec0, dec3) values (?, ?, ?)"));
+ QVERIFY_SQL(create, exec(QLatin1String(
+ "create table %1 (dec2 decimal(4,2), dec0 decimal(20,0), "
+ "dec3 decimal(20,3))").arg(ts.tableName())));
+ QVERIFY_SQL(create, prepare(QLatin1String(
+ "insert into %1 (dec2, dec0, dec3) values (?, ?, ?)")
+ .arg(ts.tableName())));
create.addBindValue("99.99");
create.addBindValue("12345678901234567890");
@@ -4595,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());
@@ -4606,10 +4667,26 @@ 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())
- QSKIP( "No database drivers are available in this Qt configuration");
+ QSKIP("No database drivers are available in this Qt configuration");
QTest::addColumn<QString>("dbName");
QTest::addColumn<QString>("tableName");
@@ -4618,8 +4695,8 @@ void tst_QSqlQuery::dateTime_data()
QTest::addColumn<QList<QDateTime> >("expectedDateTimes");
#if QT_CONFIG(timezone)
- // Using time zones which are highly unlikely to be the same as the testing machine's one
- // as it could pass as a result despite it.
+ // Using time zones which are highly unlikely to be the same as the testing
+ // machine's one as it could pass as a result despite it.
// +8.5 hours from UTC to North Korea
const QTimeZone afterUTCTimeZone(30600);
// -8 hours from UTC to Belize
@@ -4657,27 +4734,26 @@ 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())
<< dbName << tableNameTSWithTimeZone
- << QStringLiteral(" (dt TIMESTAMP WITH TIME ZONE)")
+ << u" (dt TIMESTAMP WITH TIME ZONE)"_s
<< dateTimes << dateTimes;
QTest::newRow(QString(dbName + " timestamp with local time zone").toLatin1())
<< dbName << tableNameTSWithTimeZone
- << QStringLiteral(" (dt TIMESTAMP WITH LOCAL TIME ZONE)")
+ << u" (dt TIMESTAMP WITH LOCAL TIME ZONE)"_s
<< dateTimes << expectedDateTimesLocalTZ;
QTest::newRow(QString(dbName + "timestamp").toLatin1())
- << dbName << tableNameTS << QStringLiteral(" (dt TIMESTAMP(3))")
+ << dbName << tableNameTS << u" (dt TIMESTAMP(3))"_s
<< dateTimes << expectedTimeStampDateTimes;
QTest::newRow(QString(dbName + "date").toLatin1())
- << dbName << tableNameDate << QStringLiteral(" (dt DATE)")
+ << dbName << tableNameDate << u" (dt DATE)"_s
<< dateTimes << expectedDateTimes;
}
}
@@ -4687,9 +4763,7 @@ void tst_QSqlQuery::dateTime()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
-
- QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
- if (dbType != QSqlDriver::Oracle)
+ if (tst_Databases::getDatabaseType(db) != QSqlDriver::Oracle)
QSKIP("Implemented only for Oracle");
QFETCH(QString, tableName);
@@ -4697,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)) {
- QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " values(:dt)"));
+ 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);
+ }
+}
+
+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 : qAsConst(expectedDateTimes)) {
+ for (const QDateTime &dt : std::as_const(expectedDateTimes)) {
QVERIFY(q.next());
QCOMPARE(q.value(0).toDateTime(), dt);
}
@@ -4722,14 +4872,17 @@ void tst_QSqlQuery::sqliteVirtualTable()
CHECK_DATABASE(db);
const auto tableName = qTableName("sqliteVirtual", __FILE__, db);
QSqlQuery qry(db);
- QVERIFY_SQL(qry, exec("create virtual table " + tableName + " using fts3(id, name)"));
+ QVERIFY_SQL(qry, exec(QLatin1String("create virtual table %1 using fts3(id, name)")
+ .arg(tableName)));
// Delibrately malform the query to try and provoke a potential crash situation
- QVERIFY_SQL(qry, prepare("select * from " + tableName + " where name match '?'"));
+ QVERIFY_SQL(qry, prepare(QLatin1String("select * from %1 where name match '?'")
+ .arg(tableName)));
qry.addBindValue("Andy");
QVERIFY(!qry.exec());
- QVERIFY_SQL(qry, prepare("insert into " + tableName + "(id, name) VALUES (?, ?)"));
+ QVERIFY_SQL(qry, prepare(QLatin1String("insert into %1(id, name) VALUES (?, ?)")
+ .arg(tableName)));
qry.addBindValue(1);
qry.addBindValue("Andy");
QVERIFY_SQL(qry, exec());
@@ -4739,12 +4892,13 @@ void tst_QSqlQuery::sqliteVirtualTable()
QCOMPARE(qry.value(0).toInt(), 1);
QCOMPARE(qry.value(1).toString(), "Andy");
- QVERIFY_SQL(qry, prepare("insert into " + tableName + "(id, name) values (:id, :name)"));
+ QVERIFY_SQL(qry, prepare(QLatin1String("insert into %1(id, name) values (:id, :name)")
+ .arg(tableName)));
qry.bindValue(":id", 2);
qry.bindValue(":name", "Peter");
QVERIFY_SQL(qry, exec());
- QVERIFY_SQL(qry, prepare("select * from " + tableName + " where name match ?"));
+ QVERIFY_SQL(qry, prepare(QLatin1String("select * from %1 where name match ?").arg(tableName)));
qry.addBindValue("Peter");
QVERIFY_SQL(qry, exec());
QVERIFY(qry.next());
@@ -4759,29 +4913,36 @@ 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("create table " + tableName + " (t time(6))"));
+ QVERIFY_SQL(qry, exec(QLatin1String("create table %1 (t time(6))").arg(tableName)));
// MySQL will convert days into hours and add them together so 17 days 11 hours becomes 419 hours
- const QStringList timeData = { "-838:59:59.000000", "-123:45:56.789", "000:00:00.0", "123:45:56.789",
- "838:59:59.000000", "15:50", "12", "1213", "0 1:2:3", "17 11:22:33" };
- const QStringList resultTimeData = { "-838:59:59.000000", "-123:45:56.789000", "00:00:00.000000",
- "123:45:56.789000", "838:59:59.000000", "15:50:00.000000", "00:00:12.000000", "00:12:13.000000",
- "01:02:03.000000", "419:22:33.000000" };
- for (const QString &time : timeData)
- QVERIFY_SQL(qry, exec("insert into " + tableName + " (t) VALUES ('" + time + "')"));
+ const QString timeData[] = {
+ u"-838:59:59.000000"_s, u"-123:45:56.789"_s, u"000:00:00.0"_s, u"123:45:56.789"_s,
+ u"838:59:59.000000"_s, u"15:50"_s, u"12"_s, u"1213"_s, u"0 1:2:3"_s, u"17 11:22:33"_s
+ };
+ const QString resultTimeData[] = {
+ u"-838:59:59.000000"_s, u"-123:45:56.789000"_s, u"00:00:00.000000"_s,
+ u"123:45:56.789000"_s, u"838:59:59.000000"_s, u"15:50:00.000000"_s,
+ u"00:00:12.000000"_s, u"00:12:13.000000"_s, u"01:02:03.000000"_s, u"419:22:33.000000"_s
+ };
+ for (const QString &time : timeData) {
+ QVERIFY_SQL(qry, exec(QLatin1String("insert into %2 (t) VALUES ('%1')")
+ .arg(time, tableName)));
+ }
QVERIFY_SQL(qry, exec("select * from " + tableName));
- for (const QString &time : qAsConst(resultTimeData)) {
+ for (const QString &time : resultTimeData) {
QVERIFY(qry.next());
QCOMPARE(qry.value(0).toString(), time);
}
QVERIFY_SQL(qry, exec("delete from " + tableName));
for (const QString &time : timeData) {
- QVERIFY_SQL(qry, prepare("insert into " + tableName + " (t) VALUES (:time)"));
+ QVERIFY_SQL(qry, prepare(QLatin1String("insert into %1 (t) VALUES (:time)")
+ .arg(tableName)));
qry.bindValue(0, time);
QVERIFY_SQL(qry, exec());
}
@@ -4792,9 +4953,12 @@ void tst_QSqlQuery::mysql_timeType()
}
QVERIFY_SQL(qry, exec("delete from " + tableName));
- const QList<QTime> qTimeBasedData = { QTime(), QTime(1, 2, 3, 4), QTime(0, 0, 0, 0), QTime(23,59,59,999) };
+ const QTime qTimeBasedData[] = {
+ QTime(), QTime(1, 2, 3, 4), QTime(0, 0, 0, 0), QTime(23, 59, 59, 999)
+ };
for (const QTime &time : qTimeBasedData) {
- QVERIFY_SQL(qry, prepare("insert into " + tableName + " (t) VALUES (:time)"));
+ QVERIFY_SQL(qry, prepare(QLatin1String("insert into %1 (t) VALUES (:time)")
+ .arg(tableName)));
qry.bindValue(0, time);
QVERIFY_SQL(qry, exec());
}
@@ -4811,13 +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("create table " + arrayTable + " (intData int[0:4], longData bigint[5], "
- "charData varchar(255)[5], boolData boolean[2])"));
- QVERIFY_SQL(qry, prepare("insert into " + arrayTable + " (intData, longData, charData, boolData) "
- "values(?, ?, ?, ?)"));
+ QVERIFY_SQL(qry, exec(QLatin1String(
+ "create table %1 (intData int[0:4], longData bigint[5], "
+ "charData varchar(255)[5], boolData boolean[2])").arg(ts.tableName())));
+ QVERIFY_SQL(qry, prepare(QLatin1String("insert into %1 (intData, longData, charData, boolData)"
+ " 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}};
@@ -4826,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());
@@ -4834,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);
@@ -4854,5 +5054,83 @@ void tst_QSqlQuery::ibase_executeBlock()
QCOMPARE(qry.value(0).toInt(), 4);
}
-QTEST_MAIN( tst_QSqlQuery )
+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 ac71e0edc2..6aeae86d7d 100644
--- a/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
+++ b/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -39,12 +14,7 @@
class tst_QSqlRecord : public QObject
{
-Q_OBJECT
-
-public:
- tst_QSqlRecord();
- virtual ~tst_QSqlRecord();
-
+ Q_OBJECT
public slots:
void init();
@@ -70,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();
@@ -99,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"));
@@ -182,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() );
@@ -225,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__" ) );
}
@@ -258,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() );
}
@@ -437,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() );
@@ -503,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 d9c5a411ba..072e683d68 100644
--- a/tests/auto/sql/kernel/qsqlresult/testsqldriver.h
+++ b/tests/auto/sql/kernel/qsqlresult/testsqldriver.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// 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 cae8491b81..da438dcfd6 100644
--- a/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp
+++ b/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QtSql/QtSql>
@@ -54,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()
@@ -62,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 163e433bd1..0bebb7edd5 100644
--- a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
+++ b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -283,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
@@ -310,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 ac94961a84..a669c72a1e 100644
--- a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
+++ b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -87,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;
};
@@ -98,8 +73,8 @@ private:
class DBTestModel: public QSqlQueryModel
{
public:
- DBTestModel(QObject *parent = nullptr): QSqlQueryModel(parent) {}
- QModelIndex indexInQuery(const QModelIndex &item) const { return QSqlQueryModel::indexInQuery(item); }
+ using QSqlQueryModel::QSqlQueryModel;
+ using QSqlQueryModel::indexInQuery;
};
tst_QSqlQueryModel::tst_QSqlQueryModel()
@@ -113,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);
@@ -124,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)
@@ -142,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);
@@ -227,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);
@@ -257,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);
@@ -270,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);
@@ -284,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);
@@ -326,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);
@@ -355,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);
@@ -370,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);
@@ -449,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);
@@ -477,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
@@ -524,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);
}
@@ -548,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,
@@ -573,9 +548,9 @@ void tst_QSqlQueryModel::setQueryWithNoRowsInResultSet()
// The query's result set will be empty so no signals should be emitted!
QSqlQuery query(db);
QVERIFY_SQL(query, exec("SELECT * FROM " + qTableName("test", __FILE__, db) + " where 0 = 1"));
- model.setQuery(query);
- QCOMPARE(modelRowsAboutToBeInsertedSpy.count(), 0);
- QCOMPARE(modelRowsInsertedSpy.count(), 0);
+ model.setQuery(std::move(query));
+ 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 f0a8006b79..5977689ab6 100644
--- a/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp
+++ b/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -102,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);
}
@@ -119,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));
@@ -171,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 89d975422a..5e3643ec8e 100644
--- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
+++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -32,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();
@@ -81,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()
@@ -109,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);
@@ -139,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);
}
@@ -172,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()
@@ -211,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);
@@ -252,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
@@ -459,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);
@@ -569,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);
@@ -677,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()
@@ -761,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);
@@ -806,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" << "" << "";
@@ -819,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";
@@ -898,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);
@@ -935,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);
@@ -989,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);
@@ -1000,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);
@@ -1022,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"));
@@ -1038,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);
@@ -1068,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);
@@ -1111,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());
@@ -1178,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);
@@ -1186,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);
@@ -1210,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);
@@ -1234,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);
@@ -1260,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);
@@ -1289,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());
@@ -1342,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);
@@ -1393,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);
@@ -1478,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)
@@ -1505,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);
@@ -1530,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);
@@ -1544,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 6980bc19e2..9c93fc2b18 100644
--- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -141,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(); }
@@ -154,6 +131,9 @@ private slots:
void invalidFilterAndHeaderData_data() { generic_data(); }
void invalidFilterAndHeaderData(); //QTBUG-23879
+
+ void sqlite_selectFromIdentifierWithDot_data() { generic_data("QSQLITE"); }
+ void sqlite_selectFromIdentifierWithDot();
private:
void generic_data(const QString& engine=QString());
void generic_data_with_strategies(const QString& engine=QString());
@@ -161,6 +141,7 @@ private:
tst_QSqlTableModel::tst_QSqlTableModel()
{
+ QVERIFY(dbs.open());
}
tst_QSqlTableModel::~tst_QSqlTableModel()
@@ -169,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")) {
@@ -198,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);
@@ -217,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))"));
}
@@ -228,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);
@@ -306,35 +282,37 @@ void tst_QSqlTableModel::select()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const auto test = qTableName("test1", __FILE__, db);
-
- QSqlTableModel model(0, db);
- model.setTable(test);
- model.setSort(0, Qt::AscendingOrder);
- QVERIFY_SQL(model, select());
+ const QStringList tables = {qTableName("test1", __FILE__, db),
+ qTableName("test1", __FILE__, db).remove(QLatin1Char('"'))};
+ for (const QString &tbl : tables) {
+ QSqlTableModel model(0, db);
+ model.setTable(tbl);
+ model.setSort(0, Qt::AscendingOrder);
+ QVERIFY_SQL(model, select());
- QCOMPARE(model.rowCount(), 3);
- QCOMPARE(model.columnCount(), 3);
+ QCOMPARE(model.rowCount(), 3);
+ 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)).toInt(), 1);
- QCOMPARE(model.data(model.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)).toInt(), 1);
+ QCOMPARE(model.data(model.index(0, 3)), QVariant());
- QCOMPARE(model.data(model.index(1, 0)).toInt(), 2);
- QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond"));
- QCOMPARE(model.data(model.index(1, 2)).toInt(), 2);
- QCOMPARE(model.data(model.index(1, 3)), QVariant());
+ QCOMPARE(model.data(model.index(1, 0)).toInt(), 2);
+ QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond"));
+ QCOMPARE(model.data(model.index(1, 2)).toInt(), 2);
+ QCOMPARE(model.data(model.index(1, 3)), QVariant());
- QCOMPARE(model.data(model.index(2, 0)).toInt(), 3);
- QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi"));
- QCOMPARE(model.data(model.index(2, 2)).toInt(), 3);
- QCOMPARE(model.data(model.index(2, 3)), QVariant());
+ QCOMPARE(model.data(model.index(2, 0)).toInt(), 3);
+ QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi"));
+ QCOMPARE(model.data(model.index(2, 2)).toInt(), 3);
+ QCOMPARE(model.data(model.index(2, 3)), QVariant());
- QCOMPARE(model.data(model.index(3, 0)), QVariant());
- QCOMPARE(model.data(model.index(3, 1)), QVariant());
- QCOMPARE(model.data(model.index(3, 2)), QVariant());
- QCOMPARE(model.data(model.index(3, 3)), QVariant());
+ QCOMPARE(model.data(model.index(3, 0)), QVariant());
+ QCOMPARE(model.data(model.index(3, 1)), QVariant());
+ QCOMPARE(model.data(model.index(3, 2)), QVariant());
+ QCOMPARE(model.data(model.index(3, 3)), QVariant());
+ }
}
class SelectRowModel: public QSqlTableModel
@@ -449,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);
@@ -600,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());
@@ -620,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));
@@ -733,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);
@@ -843,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);
@@ -993,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);
@@ -1111,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);
@@ -1131,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());
@@ -1167,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
@@ -1198,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);
@@ -1216,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);
@@ -1401,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);
@@ -1478,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);
@@ -1684,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();
}
@@ -1719,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);
@@ -1803,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);
@@ -1947,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);
@@ -1966,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);
@@ -2160,5 +2199,48 @@ void tst_QSqlTableModel::modelInAnotherThread()
QVERIFY(t.isFinished());
}
+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);
+ {
+ QSqlQuery qry(db);
+ QVERIFY_SQL(qry, exec("create table " + fieldDot.tableName() + " (id int primary key, "
+ "\"person.firstname\" varchar(20))"));
+ QVERIFY_SQL(qry, exec("insert into " + fieldDot.tableName() + " values(1, 'Andy')"));
+ QSqlTableModel model(0, db);
+ 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"));
+ }
+ {
+ QSqlQuery qry(db);
+ QVERIFY_SQL(qry, exec("create table " + tableDot.tableName() + " (id int primary key, "
+ "\"person.firstname\" varchar(20))"));
+ QVERIFY_SQL(qry, exec("insert into " + tableDot.tableName() + " values(1, 'Andy')"));
+ QSqlTableModel model(0, db);
+ 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"));
+ }
+ {
+ QSqlDatabase attachedDb = QSqlDatabase::addDatabase("QSQLITE", "attachedDb");
+ attachedDb.setDatabaseName(db.databaseName().replace("foo.db", "attached.db"));
+ QVERIFY(attachedDb.open());
+ 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.tableName()));
+ QVERIFY_SQL(model, select());
+ QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
+ QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Andy"));
+ }
+}
+
QTEST_MAIN(tst_QSqlTableModel)
#include "tst_qsqltablemodel.moc"