Add overload of QSqlDatabase::cloneDatabase to allow cloning cross threads

Since QSqlDatabase::database() cannot be used to access another database
from another thread, then the overload is provided to make it possible
to clone with just the connection name. This will handle the cloning
internally safely then.

Fixes: QTBUG-72545
Change-Id: I861cc5aa2c38c1e3797f6f086594a1228f05bada
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Andy Shaw 2018-12-21 14:34:28 +01:00 committed by Christian Ehrlicher
parent 37b3098302
commit f03941e411
3 changed files with 45 additions and 0 deletions

View File

@ -1379,6 +1379,40 @@ QSqlDatabase QSqlDatabase::cloneDatabase(const QSqlDatabase &other, const QStrin
return db;
}
/*!
\since 5.13
\overload
Clones the database connection \a other and stores it as \a
connectionName. All the settings from the original database, e.g.
databaseName(), hostName(), etc., are copied across. Does nothing
if \a other is an invalid database. Returns the newly created
database connection.
\note The new connection has not been opened. Before using the new
connection, you must call open().
This overload is useful when cloning the database in another thread to the
one that is used by the database represented by \a other.
*/
QSqlDatabase QSqlDatabase::cloneDatabase(const QString &other, const QString &connectionName)
{
const QConnectionDict *dict = dbDict();
Q_ASSERT(dict);
dict->lock.lockForRead();
QSqlDatabase otherDb = dict->value(other);
dict->lock.unlock();
if (!otherDb.isValid())
return QSqlDatabase();
QSqlDatabase db(otherDb.driverName());
db.d->copy(otherDb.d);
QSqlDatabasePrivate::addDatabase(db, connectionName);
return db;
}
/*!
\since 4.4

View File

@ -118,6 +118,7 @@ public:
static QSqlDatabase addDatabase(QSqlDriver* driver,
const QString& connectionName = QLatin1String(defaultConnection));
static QSqlDatabase cloneDatabase(const QSqlDatabase &other, const QString& connectionName);
static QSqlDatabase cloneDatabase(const QString &other, const QString& connectionName);
static QSqlDatabase database(const QString& connectionName = QLatin1String(defaultConnection),
bool open = true);
static void removeDatabase(const QString& connectionName);

View File

@ -2422,6 +2422,16 @@ public slots:
QSqlDatabase invalidDb = QSqlDatabase::database("invalid");
QVERIFY(!invalidDb.isValid());
{
QSqlDatabase clonedDatabase = QSqlDatabase::cloneDatabase(dbName, "CloneDB");
QVERIFY(!clonedDatabase.isOpen());
QVERIFY(clonedDatabase.isValid());
QVERIFY(clonedDatabase.open());
QVERIFY(clonedDatabase.isOpen());
clonedDatabase.close();
}
QThread::currentThread()->exit();
}
private: