[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdb] autotests: KDbTestUtils: improve memory management of the connection object (silent)
From:       Jaroslaw Staniek <null () kde ! org>
Date:       2018-09-10 11:01:35
Message-ID: E1fzJwl-0006zN-D8 () code ! kde ! org
[Download RAW message or body]

Git commit 0e284f3e282ec09ed9deaee528110217c3939cec by Jaroslaw Staniek.
Committed on 10/09/2018 at 10:59.
Pushed by staniek into branch 'master'.

KDbTestUtils: improve memory management of the connection object

This fixes possible use-after-free by KDbNativeStatementBuilder

GIT_SILENT

FIXED-IN:3.2.0

M  +7    -7    autotests/ConnectionTest.cpp
M  +42   -42   autotests/KDbTest.cpp
M  +73   -46   autotests/KDbTestUtils.cpp
M  +6    -2    autotests/KDbTestUtils.h
M  +2    -2    autotests/MissingTableTest.cpp
M  +5    -5    autotests/OrderByColumnTest.cpp
M  +5    -5    autotests/QuerySchemaTest.cpp
M  +1    -1    autotests/parser/SqlParserTest.cpp

https://commits.kde.org/kdb/0e284f3e282ec09ed9deaee528110217c3939cec

diff --git a/autotests/ConnectionTest.cpp b/autotests/ConnectionTest.cpp
index 865d324a..9d34f9fa 100644
--- a/autotests/ConnectionTest.cpp
+++ b/autotests/ConnectionTest.cpp
@@ -116,16 +116,16 @@ void ConnectionTest::testConnectToNonexistingDb()
     KDbConnectionData cdata;
     cdata.setDatabaseName(QLatin1String("/really-non-existing/path/fiuwehf2349f8h23c2jcoeqw"));
  QVERIFY(utils.testConnect(cdata));
-    QVERIFY(utils.connection);
-    KDB_VERIFY(utils.connection, \
!utils.connection->databaseExists(utils.connection->data().databaseName()), +    \
QVERIFY(utils.connection()); +    KDB_VERIFY(utils.connection(), \
!utils.connection()->databaseExists(utils.connection()->data().databaseName()),  \
                "Database should not exist");
-    KDB_EXPECT_FAIL(utils.connection, utils.connection->useDatabase(),
+    KDB_EXPECT_FAIL(utils.connection(), utils.connection()->useDatabase(),
                     ERR_OBJECT_NOT_FOUND, "Should fail to use database");
-    KDB_EXPECT_FAIL(utils.connection, utils.connection->isDatabaseUsed(),
+    KDB_EXPECT_FAIL(utils.connection(), utils.connection()->isDatabaseUsed(),
                     ERR_OBJECT_NOT_FOUND, "Database can't be used after call to \
                useDatabase()");
-    QVERIFY2(utils.connection->closeDatabase(), "Closing after failed USE should \
                work");
-    KDB_VERIFY(utils.connection, utils.connection->disconnect(), "Failed to \
                disconnect database");
-    QVERIFY2(!utils.connection->isConnected(), "Should not be connected");
+    QVERIFY2(utils.connection()->closeDatabase(), "Closing after failed USE should \
work"); +    KDB_VERIFY(utils.connection(), utils.connection()->disconnect(), "Failed \
to disconnect database"); +    QVERIFY2(!utils.connection()->isConnected(), "Should \
not be connected");  }
 
 void ConnectionTest::cleanupTestCase()
diff --git a/autotests/KDbTest.cpp b/autotests/KDbTest.cpp
index 57c5b6b5..fe95c134 100644
--- a/autotests/KDbTest.cpp
+++ b/autotests/KDbTest.cpp
@@ -1034,27 +1034,27 @@ void KDbTest::testTemporaryTableName()
     QVERIFY(utils.testCreateDbWithTables("KDbTest"));
 
     QString baseName = QLatin1String("foobar");
-    QString tempName1 = KDb::temporaryTableName(utils.connection.data(), baseName);
+    QString tempName1 = KDb::temporaryTableName(utils.connection(), baseName);
     QVERIFY(!tempName1.isEmpty());
     QVERIFY(tempName1.contains(baseName));
-    QString tempName2 = KDb::temporaryTableName(utils.connection.data(), baseName);
+    QString tempName2 = KDb::temporaryTableName(utils.connection(), baseName);
     QVERIFY(!tempName2.isEmpty());
     QVERIFY(tempName2.contains(baseName));
     QVERIFY(tempName1 != tempName2);
 
-    utils.connection->closeDatabase();
+    utils.connection()->closeDatabase();
     QTest::ignoreMessage(QtWarningMsg, "Missing database handle");
     QTest::ignoreMessage(QtWarningMsg, QRegularExpression("!executeQuery().*"));
-    QString tempName = KDb::temporaryTableName(utils.connection.data(), baseName);
+    QString tempName = KDb::temporaryTableName(utils.connection(), baseName);
     QVERIFY2(tempName.isEmpty(), "Temporary name should not be created when database \
is closed ");  
-    utils.connection->disconnect();
+    utils.connection()->disconnect();
     QTest::ignoreMessage(QtWarningMsg, "Missing database handle");
     QTest::ignoreMessage(QtWarningMsg, QRegularExpression("!executeQuery().*"));
-    tempName = KDb::temporaryTableName(utils.connection.data(), baseName);
+    tempName = KDb::temporaryTableName(utils.connection(), baseName);
     QVERIFY2(tempName.isEmpty(), "Temporary name should not be created connection is \
missing");  
-    utils.connection->dropDatabase(utils.connection->data().databaseName());
+    utils.connection()->dropDatabase(utils.connection()->data().databaseName());
 }
 
 //! @todo add tests
@@ -1088,26 +1088,26 @@ KDB_EXPORT QString identifierExpectedMessage(const QString \
&valueName,  void KDbTest::deleteRecordWithOneConstraintsTest()
 {
     QVERIFY(utils.testCreateDbWithTables("KDbTest"));
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "id", 2));
-    QVERIFY2(KDb::deleteRecords(utils.connection.data(), "persons", "id", "3"),
+    QVERIFY(KDb::deleteRecords(utils.connection(), "persons", "id", 2));
+    QVERIFY2(KDb::deleteRecords(utils.connection(), "persons", "id", "3"),
             "Passing a valid Integer in String Format");
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "id", "Foo"));
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "name", \
                "Jaroslaw"));
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "surname", \
                "FooBar"));
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "age", 45));
+    QVERIFY(KDb::deleteRecords(utils.connection(), "persons", "id", "Foo"));
+    QVERIFY(KDb::deleteRecords(utils.connection(), "persons", "name", "Jaroslaw"));
+    QVERIFY(KDb::deleteRecords(utils.connection(), "persons", "surname", "FooBar"));
+    QVERIFY(KDb::deleteRecords(utils.connection(), "persons", "age", 45));
     // and empty data.
-    KDbTableSchema *kdb_t = utils.connection.data()->tableSchema("persons");
+    KDbTableSchema *kdb_t = utils.connection()->tableSchema("persons");
     QVERIFY(kdb_t);
-    QVERIFY2(utils.connection.data()->insertRecord(kdb_t, 10, 20, QVariant(), \
"Bar"), +    QVERIFY2(utils.connection()->insertRecord(kdb_t, 10, 20, QVariant(), \
"Bar"),  "Inserting NULL data");
-    QVERIFY2(utils.connection.data()->insertRecord(kdb_t,15, 20, "", "Bar"),
+    QVERIFY2(utils.connection()->insertRecord(kdb_t,15, 20, "", "Bar"),
              "Inserting empty data");
-    QVERIFY2(KDb::deleteRecords(utils.connection.data(), "persons", "name", \
QString()), +    QVERIFY2(KDb::deleteRecords(utils.connection(), "persons", "name", \
QString()),  "Passing a null value instead of string");
     //
-    QVERIFY2(KDb::deleteRecords(utils.connection.data(), "persons", "name", ""),
+    QVERIFY2(KDb::deleteRecords(utils.connection(), "persons", "name", ""),
              "Passing an empty string");
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "age", \
"Nitish")); +    QVERIFY(KDb::deleteRecords(utils.connection(), "persons", "age", \
"Nitish"));  QVERIFY(utils.testDisconnectAndDropDb());
 }
 
@@ -1125,11 +1125,11 @@ static QRegularExpression resultRegExp(const QString &code, \
const QString &messa  void KDbTest::deleteNonExistingRecordTest()
 {
     QVERIFY(utils.testCreateDbWithTables("KDbTest"));
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "id", 400));
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "name", \
"FooBar")); +    QVERIFY(KDb::deleteRecords(utils.connection(), "persons", "id", \
400)); +    QVERIFY(KDb::deleteRecords(utils.connection(), "persons", "name", \
                "FooBar"));
     QTest::ignoreMessage(QtWarningMsg, resultRegExp("260", "Error while executing \
                SQL statement.",
         "DELETE FROM \\[persons\\] WHERE \\[Foo\\]='FooBar'", "0", "no such column: \
                Foo"));
-    QVERIFY2(!KDb::deleteRecords(utils.connection.data(), "persons", "Foo", \
"FooBar"), +    QVERIFY2(!KDb::deleteRecords(utils.connection(), "persons", "Foo", \
                "FooBar"),
              "Passing a NonExisting Column - should fail because 'Foo' column does \
not exist, "  "See also https://bugs.kde.org/376052");
     QVERIFY(utils.testDisconnectAndDropDb());
@@ -1138,28 +1138,28 @@ void KDbTest::deleteNonExistingRecordTest()
 void KDbTest::deleteRecordWithTwoConstraintsTest()
 {
     QVERIFY(utils.testCreateDbWithTables("KDbTest"));
-    QVERIFY2(KDb::deleteRecords(utils.connection.data(), "persons", "id", \
KDbField::Integer, +    QVERIFY2(KDb::deleteRecords(utils.connection(), "persons", \
"id", KDbField::Integer,  2, "age", KDbField::Integer, 60),
              "Both fields are INTEGER");
-    KDbTableSchema *kdb_t = utils.connection.data()->tableSchema("persons");
+    KDbTableSchema *kdb_t = utils.connection()->tableSchema("persons");
     QVERIFY(kdb_t);
-    utils.connection.data()->insertRecord(kdb_t, 10, QVariant(), "Foo", "Bar") ;
-    QVERIFY2(KDb::deleteRecords(utils.connection.data(), "persons", "id", \
KDbField::Integer, +    utils.connection()->insertRecord(kdb_t, 10, QVariant(), \
"Foo", "Bar") ; +    QVERIFY2(KDb::deleteRecords(utils.connection(), "persons", "id", \
                KDbField::Integer,
                                 10, "age", KDbField::Integer, QVariant()),
              "Passing NULL value for integer field");
-    QVERIFY(utils.connection.data()->insertRecord(kdb_t, 20, QVariant(), QVariant(), \
                "Bar"));
-    QVERIFY2(KDb::deleteRecords(utils.connection.data(), "persons", "age", \
KDbField::Integer, +    QVERIFY(utils.connection()->insertRecord(kdb_t, 20, \
QVariant(), QVariant(), "Bar")); +    QVERIFY2(KDb::deleteRecords(utils.connection(), \
                "persons", "age", KDbField::Integer,
                                 QVariant(), "name", KDbField::Text, QVariant()),
              "Passing 2 NULL values");
-    QVERIFY2(KDb::deleteRecords(utils.connection.data(), "persons", "age", \
KDbField::Integer, +    QVERIFY2(KDb::deleteRecords(utils.connection(), "persons", \
"age", KDbField::Integer,  20, "name", KDbField::Text, "Jaroslaw"),
              "One argument is Integer and another is Text");
-    QVERIFY2(KDb::deleteRecords(utils.connection.data(), "persons", "age", \
KDbField::Integer, +    QVERIFY2(KDb::deleteRecords(utils.connection(), "persons", \
"age", KDbField::Integer,  20, "name", KDbField::Text, 56),
              "Two arguments, passing second integer instead of text but it is \
                converted to text");
     QTest::ignoreMessage(QtWarningMsg, resultRegExp("260", "Error while executing \
                SQL statement.",
         "DELETE FROM \\[persons\\] WHERE \\[age\\]=TRAP AND \\[name\\]='56'", "0", \
                "no such column: TRAP"));
-    QVERIFY2(!KDb::deleteRecords(utils.connection.data(), "persons", "age", \
KDbField::Integer, +    QVERIFY2(!KDb::deleteRecords(utils.connection(), "persons", \
"age", KDbField::Integer,  "TRAP", "name", KDbField::Text, 56),
              "Passing text instead of integer, conversion error expected");
     QVERIFY(utils.testDisconnectAndDropDb());
@@ -1168,18 +1168,18 @@ void KDbTest::deleteRecordWithTwoConstraintsTest()
 void  KDbTest::deleteRecordWithThreeConstraintsTest()
 {
     QVERIFY(utils.testCreateDbWithTables("KDbTest"));
-    KDbTableSchema *kdb_t = utils.connection.data()->tableSchema("persons");
+    KDbTableSchema *kdb_t = utils.connection()->tableSchema("persons");
     QVERIFY(kdb_t);
     //One null value.
-    QVERIFY(utils.connection.data()->insertRecord(kdb_t, 10, QVariant(), "Foo", \
                "Bar"));
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "age", \
KDbField::Integer, QVariant(), +    QVERIFY(utils.connection()->insertRecord(kdb_t, \
10, QVariant(), "Foo", "Bar")); +    QVERIFY(KDb::deleteRecords(utils.connection(), \
                "persons", "age", KDbField::Integer, QVariant(),
                                 "name", KDbField::Text, "Foo", "surname", \
KDbField::Text, "Bar"));  //Mix of null and empty values
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "age", \
KDbField::Integer, QVariant(), +    QVERIFY(KDb::deleteRecords(utils.connection(), \
                "persons", "age", KDbField::Integer, QVariant(),
                                 "name", KDbField::Text, "", "surname", \
                KDbField::Text, ""));
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "age", \
KDbField::Integer,27, +    QVERIFY(KDb::deleteRecords(utils.connection(), "persons", \
                "age", KDbField::Integer,27,
                                 "name", KDbField::Text, "Jaraslaw", "id", \
                KDbField::Integer, 1));
-    QVERIFY(KDb::deleteRecords(utils.connection.data(), "persons", "age", \
KDbField::Integer, 60, +    QVERIFY(KDb::deleteRecords(utils.connection(), "persons", \
                "age", KDbField::Integer, 60,
                                 "name", KDbField::Text, "Lech", "id", \
KDbField::Integer, 2));  QVERIFY(utils.testDisconnectAndDropDb());
 }
@@ -1187,19 +1187,19 @@ void  KDbTest::deleteRecordWithThreeConstraintsTest()
 void KDbTest::deleteAllRecordsTest()
 {
     QVERIFY(utils.testCreateDbWithTables("KDbTest"));
-    QVERIFY(KDb::deleteAllRecords(utils.connection.data(), "persons"));
+    QVERIFY(KDb::deleteAllRecords(utils.connection(), "persons"));
 
     QRegularExpression deleteAllErrorRegExp = resultRegExp(
         "", "Error while executing SQL statement.", "DELETE FROM \\[.*\\]", 0, "no \
such table: .*");  QTest::ignoreMessage(QtWarningMsg, deleteAllErrorRegExp);
-    QVERIFY2(!KDb::deleteAllRecords(utils.connection.data(), QString()),
+    QVERIFY2(!KDb::deleteAllRecords(utils.connection(), QString()),
              "Passing a null table name");
     QTest::ignoreMessage(QtWarningMsg, deleteAllErrorRegExp);
-    QVERIFY2(!KDb::deleteAllRecords(utils.connection.data(), ""),
+    QVERIFY2(!KDb::deleteAllRecords(utils.connection(), ""),
              "Passing an empty table name");
-    QVERIFY(KDb::deleteAllRecords(utils.connection.data(), "cars"));
+    QVERIFY(KDb::deleteAllRecords(utils.connection(), "cars"));
     QTest::ignoreMessage(QtWarningMsg, deleteAllErrorRegExp);
-    QVERIFY2(!KDb::deleteAllRecords(utils.connection.data(), "NonExistingTable"),
+    QVERIFY2(!KDb::deleteAllRecords(utils.connection(), "NonExistingTable"),
              "Passing a nonexisting table name");
     QVERIFY(utils.testDisconnectAndDropDb());
 }
diff --git a/autotests/KDbTestUtils.cpp b/autotests/KDbTestUtils.cpp
index abb9ffc7..51fcc5a8 100644
--- a/autotests/KDbTestUtils.cpp
+++ b/autotests/KDbTestUtils.cpp
@@ -1,5 +1,5 @@
 /* This file is part of the KDE project
-   Copyright (C) 2015 Jarosław Staniek <staniek@kde.org>
+   Copyright (C) 2015-2018 Jarosław Staniek <staniek@kde.org>
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -102,11 +102,33 @@ public:
     Private() {}
     QScopedPointer<KDbNativeStatementBuilder> kdbBuilder;
     QScopedPointer<KDbNativeStatementBuilder> driverBuilder;
+
+    KDbConnection *connection()
+    {
+        return m_connection.data();
+    }
+
+    void setConnection(KDbConnection *conn)
+    {
+        kdbBuilder.reset(); // dependency will be removed
+        m_connection.reset(conn);
+    }
+
+    KDbConnection* takeConnection()
+    {
+        if (!m_connection) {
+            return nullptr;
+        }
+        kdbBuilder.reset(); // dependency may be removed
+        return m_connection.take();
+    }
+
+private:
+    QScopedPointer<KDbConnection> m_connection;
 };
 
 KDbTestUtils::KDbTestUtils()
-    : connection(nullptr)
-    , d(new Private)
+    : d(new Private)
 {
     QCoreApplication::addLibraryPath(KDB_LOCAL_PLUGINS_DIR); // make plugins work \
without installing them  }
@@ -116,20 +138,25 @@ KDbTestUtils::~KDbTestUtils()
     delete d;
 }
 
+KDbConnection* KDbTestUtils::connection()
+{
+    return d->connection();
+}
+
 KDbNativeStatementBuilder* KDbTestUtils::kdbBuilder()
 {
-    Q_ASSERT(connection);
-    if (connection && !d->kdbBuilder) {
-        d->kdbBuilder.reset(new KDbNativeStatementBuilder(connection.data(), \
KDb::KDbEscaping)); +    Q_ASSERT(connection());
+    if (connection() && !d->kdbBuilder) {
+        d->kdbBuilder.reset(new KDbNativeStatementBuilder(connection(), \
KDb::KDbEscaping));  }
     return d->kdbBuilder.data();
 }
 
 KDbNativeStatementBuilder* KDbTestUtils::driverBuilder()
 {
-    Q_ASSERT(connection);
-    if (connection && !d->driverBuilder) {
-        d->driverBuilder.reset(new KDbNativeStatementBuilder(connection.data(), \
KDb::DriverEscaping)); +    Q_ASSERT(connection());
+    if (connection() && !d->driverBuilder) {
+        d->driverBuilder.reset(new KDbNativeStatementBuilder(connection(), \
KDb::DriverEscaping));  }
     return d->driverBuilder.data();
 }
@@ -219,46 +246,46 @@ void KDbTestUtils::testConnectInternal(const KDbConnectionData \
&cdata,  extraSqliteExtensionPaths << SQLITE_LOCAL_ICU_EXTENSION_PATH;
     connOptionsOverride.insert("extraSqliteExtensionPaths", \
extraSqliteExtensionPaths);  
-    connection.reset(); // remove previous connection if present
+    d->setConnection(nullptr); // remove previous connection if present
     const int connCount = driver->connections().count();
-    connection.reset(driver->createConnection(cdata, connOptionsOverride));
-    KDB_VERIFY(driver, !connection.isNull(), "Failed to create connection");
+    d->setConnection(driver->createConnection(cdata, connOptionsOverride));
+    KDB_VERIFY(driver, connection(), "Failed to create connection");
     QVERIFY2(cdata.driverId().isEmpty(), "Connection data has filled driver ID");
-    QCOMPARE(connection->data().driverId(), driver->metaData()->id());
-    QVERIFY2(driver->connections().contains(connection.data()), "Driver does not \
list created connection"); +    QCOMPARE(connection()->data().driverId(), \
driver->metaData()->id()); +    \
QVERIFY2(driver->connections().contains(connection()), "Driver does not list created \
connection");  QCOMPARE(driver->connections().count(), connCount + 1); // one more
 
-    const KDbUtils::Property extraSqliteExtensionPathsProperty = \
connection->options()->property("extraSqliteExtensionPaths"); +    const \
KDbUtils::Property extraSqliteExtensionPathsProperty = \
                connection()->options()->property("extraSqliteExtensionPaths");
     QVERIFY2(!extraSqliteExtensionPathsProperty.isNull(), "extraSqliteExtensionPaths \
                property not found");
     QCOMPARE(extraSqliteExtensionPathsProperty.value().type(), \
                QVariant::StringList);
     QCOMPARE(extraSqliteExtensionPathsProperty.value().toStringList(), \
extraSqliteExtensionPaths);  
-    const KDbUtils::Property readOnlyProperty = \
connection->options()->property("readOnly"); +    const KDbUtils::Property \
readOnlyProperty = connection()->options()->property("readOnly");  \
                QVERIFY2(!readOnlyProperty.isNull(), "readOnly property not found");
-    QCOMPARE(readOnlyProperty.value().toBool(), \
connection->options()->isReadOnly()); +    \
QCOMPARE(readOnlyProperty.value().toBool(), connection()->options()->isReadOnly());  
     //! @todo Add extensive test for a read-only connection
 
-    KDB_VERIFY(connection, connection->connect(), "Failed to connect");
-    KDB_VERIFY(connection, connection->isConnected(), "Database not connected after \
call to connect()"); +    KDB_VERIFY(connection(), connection()->connect(), "Failed \
to connect"); +    KDB_VERIFY(connection(), connection()->isConnected(), "Database \
not connected after call to connect()");  }
 
 void KDbTestUtils::testUseInternal()
 {
-    KDB_VERIFY(connection, \
connection->databaseExists(connection->data().databaseName()), "Database does not \
                exists");
-    KDB_VERIFY(connection, connection->useDatabase(), "Failed to use database");
-    KDB_VERIFY(connection, connection->isDatabaseUsed(), "Database not used after \
call to useDatabase()"); +    KDB_VERIFY(connection(), \
connection()->databaseExists(connection()->data().databaseName()), "Database does not \
exist"); +    KDB_VERIFY(connection(), connection()->useDatabase(), "Failed to use \
database"); +    KDB_VERIFY(connection(), connection()->isDatabaseUsed(), "Database \
not used after call to useDatabase()");  }
 
 void KDbTestUtils::testConnectAndUseInternal(const KDbConnectionData &cdata,
                                              const KDbConnectionOptions &options)
 {
-    if (!testConnect(cdata, options) || !connection) {
+    if (!testConnect(cdata, options) || !connection()) {
         qWarning() << driver->result();
         QFAIL("testConnect");
     }
-    if (!testUse() || !connection->isDatabaseUsed()) {
-        qWarning() << connection->result();
+    if (!testUse() || !connection()->isDatabaseUsed()) {
+        qWarning() << connection()->result();
         bool result = testDisconnect();
         Q_UNUSED(result);
         QFAIL("testUse");
@@ -283,58 +310,58 @@ void KDbTestUtils::testCreateDbInternal(const QString &dbName)
     cdata.setDatabaseName(fullDbName);
 
     QVERIFY(testConnect(cdata));
-    QVERIFY(connection);
+    QVERIFY(connection());
 
     //! @todo KDbDriver::metaData
     {
-        QScopedPointer<KDbConnection> connGuard(connection.take());
+        QScopedPointer<KDbConnection> connGuard(d->takeConnection());
 
         if (connGuard->databaseExists(dbName)) {
             KDB_VERIFY(connGuard, connGuard->dropDatabase(fullDbName), "Failed to \
drop database");  }
         KDB_VERIFY(connGuard, !connGuard->databaseExists(fullDbName), "Database \
                exists");
         KDB_VERIFY(connGuard, connGuard->createDatabase(fullDbName), "Failed to \
                create db");
-        KDB_VERIFY(connGuard, connGuard->databaseExists(fullDbName), "Database does \
                not exists after creation");
-        connection.reset(connGuard.take());
+        KDB_VERIFY(connGuard, connGuard->databaseExists(fullDbName), "Database does \
not exist after creation"); +        d->setConnection(connGuard.take());
     }
 }
 
 void KDbTestUtils::testCreateDbWithTablesInternal(const QString &dbName)
 {
     QVERIFY(testCreateDb(dbName));
-    KDB_VERIFY(connection, connection->useDatabase(), "Failed to use database");
+    KDB_VERIFY(connection(), connection()->useDatabase(), "Failed to use database");
     testCreateTablesInternal();
 }
 
 void KDbTestUtils::testPropertiesInternal()
 {
     QStringList properties;
-    properties << connection->databaseProperties().names();
+    properties << connection()->databaseProperties().names();
     QVERIFY(properties.contains("kexidb_major_ver"));
     bool ok;
-    QVERIFY(connection->databaseProperties().value("kexidb_major_ver").toInt(&ok) >= \
0); +    QVERIFY(connection()->databaseProperties().value("kexidb_major_ver").toInt(&ok) \
>= 0);  QVERIFY(ok);
     QVERIFY(properties.contains("kexidb_minor_ver"));
-    QVERIFY(connection->databaseProperties().value("kexidb_minor_ver").toInt(&ok) >= \
0); +    QVERIFY(connection()->databaseProperties().value("kexidb_minor_ver").toInt(&ok) \
>= 0);  QVERIFY(ok);
 }
 
 void KDbTestUtils::testCreateTablesInternal()
 {
-    QVERIFY2(tablesTest_createTables(connection.data()) == 0, "Failed to create test \
data"); +    QVERIFY2(tablesTest_createTables(connection()) == 0, "Failed to create \
test data");  }
 
 void KDbTestUtils::testDisconnectPrivate()
 {
-    if (!connection) {
+    if (!connection()) {
         return;
     }
-    KDB_VERIFY(connection, connection->closeDatabase(), "Failed to close database");
-    KDB_VERIFY(connection, !connection->isDatabaseUsed(), "Database still used after \
                closing");
-    KDB_VERIFY(connection, connection->closeDatabase(), "Second closeDatabase() call \
                should not fail");
-    KDB_VERIFY(connection, connection->disconnect(), "Failed to disconnect \
                database");
-    KDB_VERIFY(connection, !connection->isConnected(), "Database still connected \
                after disconnecting");
-    KDB_VERIFY(connection, connection->disconnect(), "Second disconnect() call \
should not fail"); +    KDB_VERIFY(connection(), connection()->closeDatabase(), \
"Failed to close database"); +    KDB_VERIFY(connection(), \
!connection()->isDatabaseUsed(), "Database still used after closing"); +    \
KDB_VERIFY(connection(), connection()->closeDatabase(), "Second closeDatabase() call  \
should not fail"); +    KDB_VERIFY(connection(), connection()->disconnect(), "Failed \
to disconnect database"); +    KDB_VERIFY(connection(), !connection()->isConnected(), \
"Database still connected after disconnecting"); +    KDB_VERIFY(connection(), \
connection()->disconnect(), "Second disconnect() call should not fail");  }
 
 void KDbTestUtils::testDisconnectInternal()
@@ -342,20 +369,20 @@ void KDbTestUtils::testDisconnectInternal()
     const int connCount = driver ? driver->connections().count() : 0;
     testDisconnectPrivate();
     QVERIFY(!QTest::currentTestFailed());
-    connection.reset();
+    d->setConnection(nullptr);
     QCOMPARE(driver ? driver->connections().count() : -1, connCount - 1); // one \
less  }
 
 void KDbTestUtils::testDropDbInternal()
 {
-    QVERIFY(connection->dropDatabase(connection->data().databaseName()));
+    QVERIFY(connection()->dropDatabase(connection()->data().databaseName()));
 }
 
 void KDbTestUtils::testDisconnectAndDropDbInternal()
 {
-    QString dbName(connection.data()->data().databaseName());
+    QString dbName(connection()->data().databaseName());
     testDisconnectPrivate();
     QVERIFY(!QTest::currentTestFailed());
-    KDB_VERIFY(connection, connection->dropDatabase(dbName), "Failed to drop \
                database");
-    connection.reset();
+    KDB_VERIFY(connection(), connection()->dropDatabase(dbName), "Failed to drop \
database"); +    d->setConnection(nullptr);
 }
diff --git a/autotests/KDbTestUtils.h b/autotests/KDbTestUtils.h
index e8fdc64c..0ac0b7cb 100644
--- a/autotests/KDbTestUtils.h
+++ b/autotests/KDbTestUtils.h
@@ -1,5 +1,5 @@
 /* This file is part of the KDE project
-   Copyright (C) 2015 Jarosław Staniek <staniek@kde.org>
+   Copyright (C) 2015-2018 Jarosław Staniek <staniek@kde.org>
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -131,7 +131,11 @@ public:
 
     KDbDriverManager manager;
     QPointer<KDbDriver> driver;
-    QScopedPointer<KDbConnection> connection;
+
+    /**
+     * Returns associated connection
+     */
+    KDbConnection* connection();
 
     /**
      * Returns builder for generating KDb SQL statements
diff --git a/autotests/MissingTableTest.cpp b/autotests/MissingTableTest.cpp
index 1332d771..9f333300 100644
--- a/autotests/MissingTableTest.cpp
+++ b/autotests/MissingTableTest.cpp
@@ -62,11 +62,11 @@ void MissingTableTest::testListTables()
 {
     const bool alsoSystemTables = true;
     bool ok;
-    QStringList foundTableNames = m_utils.connection->tableNames(alsoSystemTables, \
&ok); +    QStringList foundTableNames = \
m_utils.connection()->tableNames(alsoSystemTables, &ok);  QVERIFY(ok);
 
     // call again with ok == nullptr
-    QCOMPARE(foundTableNames, m_utils.connection->tableNames(alsoSystemTables));
+    QCOMPARE(foundTableNames, m_utils.connection()->tableNames(alsoSystemTables));
 
     // make sure missing table is not present
     std::sort(foundTableNames.begin(), foundTableNames.end());
diff --git a/autotests/OrderByColumnTest.cpp b/autotests/OrderByColumnTest.cpp
index 4376b5e5..47f6b636 100644
--- a/autotests/OrderByColumnTest.cpp
+++ b/autotests/OrderByColumnTest.cpp
@@ -45,7 +45,7 @@ void OrderByColumnTest::testSelect1Query()
     QVERIFY(orderBy->isEmpty());
     QCOMPARE(orderBy->count(), 0);
     orderBy->appendField(oneField);
-    KDbConnection *conn = utils.connection.data();
+    KDbConnection *conn = utils.connection();
 
     // automatic alias "expr1"
     KDbEscapedString sql;
@@ -81,12 +81,12 @@ void OrderByColumnTest::testOrderByIndex()
 {
     QVERIFY(utils.testCreateDbWithTables("OrderByColumnTest"));
     KDbQuerySchema query;
-    KDbTableSchema *carsTable = utils.connection->tableSchema("cars");
+    KDbTableSchema *carsTable = utils.connection()->tableSchema("cars");
     QVERIFY(carsTable);
     query.addTable(carsTable);
     query.addAsterisk(new KDbQueryAsterisk(&query));
     KDbOrderByColumnList* orderBy = query.orderByColumnList();
-    KDbConnection *conn = utils.connection.data();
+    KDbConnection *conn = utils.connection();
 
     // "SELECT * FROM cars ORDER BY model ASC, owner DESC"
     QVERIFY(query.orderByColumnList()->isEmpty());
@@ -107,7 +107,7 @@ void OrderByColumnTest::testOrderByColumnName()
 {
     QVERIFY(utils.testCreateDbWithTables("OrderByColumnTest"));
     KDbQuerySchema query;
-    KDbTableSchema *carsTable = utils.connection->tableSchema("cars");
+    KDbTableSchema *carsTable = utils.connection()->tableSchema("cars");
     QVERIFY(carsTable);
     query.addTable(carsTable);
     query.addAsterisk(new KDbQueryAsterisk(&query));
@@ -126,7 +126,7 @@ void OrderByColumnTest::testOrderByColumnName()
     QVERIFY(ownerField);
     orderBy->appendField(modelField);
     orderBy->appendField(ownerField);
-    KDbConnection *conn = utils.connection.data();
+    KDbConnection *conn = utils.connection();
     KDbEscapedString orderBySql = orderBy->toSqlString(true, conn, &query, \
KDb::KDbEscaping);  QCOMPARE(orderBySql, "cars.model, cars.owner");
 
diff --git a/autotests/QuerySchemaTest.cpp b/autotests/QuerySchemaTest.cpp
index 67fe66c1..acfd0ecc 100644
--- a/autotests/QuerySchemaTest.cpp
+++ b/autotests/QuerySchemaTest.cpp
@@ -38,7 +38,7 @@ void QuerySchemaTest::testCaching()
 {
     QVERIFY(utils.testCreateDbWithTables("QuerySchemaTest"));
     KDbQuerySchema query;
-    KDbTableSchema *carsTable = utils.connection->tableSchema("cars");
+    KDbTableSchema *carsTable = utils.connection()->tableSchema("cars");
     QVERIFY(carsTable);
     query.addTable(carsTable);
     KDbField *idField = carsTable->field("id");
@@ -47,18 +47,18 @@ void QuerySchemaTest::testCaching()
     query.addField(idField);
     query.addAsterisk(new KDbQueryAsterisk(&query, *carsTable));
     QCOMPARE(query.fieldCount(), 2);
-    const KDbQueryColumnInfo::Vector expandedAll1 = \
query.fieldsExpanded(utils.connection.data()); +    const KDbQueryColumnInfo::Vector \
expandedAll1 = query.fieldsExpanded(utils.connection());  \
QCOMPARE(expandedAll1.count(), 4);  const KDbQueryColumnInfo::Vector expandedUnique1
-        = query.fieldsExpanded(utils.connection.data(), \
KDbQuerySchema::FieldsExpandedMode::Unique); +        = \
query.fieldsExpanded(utils.connection(), KDbQuerySchema::FieldsExpandedMode::Unique); \
QCOMPARE(expandedUnique1.count(), 3);  // remove the asterisk -> "SELECT id from \
cars"  query.removeField(query.field(1));
     QCOMPARE(query.fieldCount(), 1);
-    const KDbQueryColumnInfo::Vector expandedAll2 = \
query.fieldsExpanded(utils.connection.data()); +    const KDbQueryColumnInfo::Vector \
expandedAll2 = query.fieldsExpanded(utils.connection());  \
QCOMPARE(expandedAll2.count(), 1);  const KDbQueryColumnInfo::Vector expandedUnique2
-        = query.fieldsExpanded(utils.connection.data(), \
KDbQuerySchema::FieldsExpandedMode::Unique); +        = \
query.fieldsExpanded(utils.connection(), KDbQuerySchema::FieldsExpandedMode::Unique); \
QCOMPARE(expandedUnique2.count(), 1);  }
 
diff --git a/autotests/parser/SqlParserTest.cpp b/autotests/parser/SqlParserTest.cpp
index 19ca85b6..c60a59a1 100644
--- a/autotests/parser/SqlParserTest.cpp
+++ b/autotests/parser/SqlParserTest.cpp
@@ -47,7 +47,7 @@ bool SqlParserTest::openDatabase(const QString &path)
     if (!m_utils.testConnectAndUse(path, options)) {
         return false;
     }
-    m_parser.reset(new KDbParser(m_utils.connection.data()));
+    m_parser.reset(new KDbParser(m_utils.connection()));
 #if 0
     if (m_conn->databaseExists(dbName)) {
         if (!m_conn->dropDatabase(dbName)) {


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic