diff options
Diffstat (limited to 'tests/auto/sql/models')
9 files changed, 370 insertions, 419 deletions
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 ce65dcf674..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 override { 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, @@ -574,8 +549,8 @@ void tst_QSqlQueryModel::setQueryWithNoRowsInResultSet() QSqlQuery query(db); QVERIFY_SQL(query, exec("SELECT * FROM " + qTableName("test", __FILE__, db) + " where 0 = 1")); model.setQuery(std::move(query)); - QCOMPARE(modelRowsAboutToBeInsertedSpy.count(), 0); - QCOMPARE(modelRowsInsertedSpy.count(), 0); + QCOMPARE(modelRowsAboutToBeInsertedSpy.size(), 0); + QCOMPARE(modelRowsInsertedSpy.size(), 0); } class NestedResetsTest: public QSqlQueryModel diff --git a/tests/auto/sql/models/qsqlrelationaldelegate/CMakeLists.txt b/tests/auto/sql/models/qsqlrelationaldelegate/CMakeLists.txt index b76a3f7b9c..ea2dc6131d 100644 --- a/tests/auto/sql/models/qsqlrelationaldelegate/CMakeLists.txt +++ b/tests/auto/sql/models/qsqlrelationaldelegate/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qsqlrelationaldelegate.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qsqlrelationaldelegate Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qsqlrelationaldelegate LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qsqlrelationaldelegate SOURCES tst_qsqlrelationaldelegate.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Sql Qt::SqlPrivate diff --git a/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp b/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp index 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 a83cb37605..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(); } @@ -173,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")) { @@ -202,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); @@ -221,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))")); } @@ -232,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); @@ -455,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); @@ -606,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()); @@ -626,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)); @@ -739,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); @@ -849,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); @@ -999,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); @@ -1117,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); @@ -1137,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()); @@ -1173,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 @@ -1204,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); @@ -1222,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); @@ -1407,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); @@ -1484,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); @@ -1690,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(); } @@ -1725,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); @@ -1809,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); @@ -1953,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); @@ -1972,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); @@ -2170,29 +2203,27 @@ void tst_QSqlTableModel::sqlite_selectFromIdentifierWithDot() { QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); + TableScope fieldDot(db, "fieldDot", __FILE__); + TableScope tableDot(db, u'[' + qTableName("table.dot", __FILE__, db) + u']'); CHECK_DATABASE(db); { - const auto fieldDot = qTableName("fieldDot", __FILE__, db); - tst_Databases::safeDropTable(db, fieldDot); QSqlQuery qry(db); - QVERIFY_SQL(qry, exec("create table " + fieldDot + " (id int primary key, " + QVERIFY_SQL(qry, exec("create table " + fieldDot.tableName() + " (id int primary key, " "\"person.firstname\" varchar(20))")); - QVERIFY_SQL(qry, exec("insert into " + fieldDot + " values(1, 'Andy')")); + QVERIFY_SQL(qry, exec("insert into " + fieldDot.tableName() + " values(1, 'Andy')")); QSqlTableModel model(0, db); - model.setTable(fieldDot); + model.setTable(fieldDot.tableName()); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Andy")); } - const auto tableDot = QLatin1Char('[') + qTableName("table.dot", __FILE__, db) + QLatin1Char(']'); { - tst_Databases::safeDropTable(db, tableDot); QSqlQuery qry(db); - QVERIFY_SQL(qry, exec("create table " + tableDot + " (id int primary key, " + QVERIFY_SQL(qry, exec("create table " + tableDot.tableName() + " (id int primary key, " "\"person.firstname\" varchar(20))")); - QVERIFY_SQL(qry, exec("insert into " + tableDot + " values(1, 'Andy')")); + QVERIFY_SQL(qry, exec("insert into " + tableDot.tableName() + " values(1, 'Andy')")); QSqlTableModel model(0, db); - model.setTable(tableDot); + model.setTable(tableDot.tableName()); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Andy")); @@ -2204,7 +2235,7 @@ void tst_QSqlTableModel::sqlite_selectFromIdentifierWithDot() QSqlQuery qry(attachedDb); QVERIFY_SQL(qry, exec(QString("attach '%1' AS 'attached'").arg(db.databaseName()))); QSqlTableModel model(0, attachedDb); - model.setTable(QString("attached.%1").arg(tableDot)); + model.setTable(QString("attached.%1").arg(tableDot.tableName())); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Andy")); |