From 0257a6cbc97be8110fbe6fb0474be92e30b4c9dd Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sat, 22 Feb 2020 00:45:11 +0100 Subject: [PATCH 1/5] Use shared in-memory DB to fix warnings in library tests --- src/database/mixxxdb.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/database/mixxxdb.cpp b/src/database/mixxxdb.cpp index 6dcd79a0a52c..c5b7039d7d8c 100644 --- a/src/database/mixxxdb.cpp +++ b/src/database/mixxxdb.cpp @@ -17,6 +17,8 @@ namespace { const mixxx::Logger kLogger("MixxxDb"); +const QString kDefaultFileName = QStringLiteral("mixxxdb.sqlite"); + // The connection parameters for the main Mixxx DB mixxx::DbConnection::Params dbConnectionParams( const UserSettingsPointer& pConfig, @@ -24,7 +26,16 @@ mixxx::DbConnection::Params dbConnectionParams( mixxx::DbConnection::Params params; params.type = "QSQLITE"; params.hostName = "localhost"; - params.filePath = inMemoryConnection ? QString(":memory:") : QDir(pConfig->getSettingsPath()).filePath("mixxxdb.sqlite"); + params.filePath = QDir(pConfig->getSettingsPath()).filePath(kDefaultFileName); + // Allow multiple connections to the same in-memory database by + // using a named connection. This is needed to make the database + // connection pool work correctly even during tests. + // + // See also: + // https://www.sqlite.org/inmemorydb.html + if (inMemoryConnection) { + params.filePath += "?mode=memory"; + } params.userName = "mixxx"; params.password = "mixxx"; return params; From a10d521507edf52b6a04b3887fb08647584abfaa Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sat, 22 Feb 2020 20:19:39 +0100 Subject: [PATCH 2/5] Open database with URI file path ...that allows to add extra options when opening an SQLite database connection. --- src/database/mixxxdb.cpp | 24 ++++++++++++++++++------ src/util/db/dbconnection.cpp | 1 + src/util/db/dbconnection.h | 1 + 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/database/mixxxdb.cpp b/src/database/mixxxdb.cpp index c5b7039d7d8c..c17f5338a08e 100644 --- a/src/database/mixxxdb.cpp +++ b/src/database/mixxxdb.cpp @@ -17,16 +17,28 @@ namespace { const mixxx::Logger kLogger("MixxxDb"); +const QString kType = QStringLiteral("QSQLITE"); + +const QString kConnectOptions = QStringLiteral("QSQLITE_OPEN_URI"); + const QString kDefaultFileName = QStringLiteral("mixxxdb.sqlite"); +const QString kUserName = QStringLiteral("mixxx"); + +const QString kPassword = QStringLiteral("mixxx"); + // The connection parameters for the main Mixxx DB mixxx::DbConnection::Params dbConnectionParams( const UserSettingsPointer& pConfig, bool inMemoryConnection) { mixxx::DbConnection::Params params; - params.type = "QSQLITE"; - params.hostName = "localhost"; - params.filePath = QDir(pConfig->getSettingsPath()).filePath(kDefaultFileName); + params.type = kType; + params.connectOptions = kConnectOptions; + QString filePath = QDir(pConfig->getSettingsPath()).filePath(kDefaultFileName); + if (!filePath.startsWith(QStringLiteral("/"))) { + filePath = QStringLiteral("/") + filePath; + } + params.filePath = QString(QStringLiteral("file://%1")).arg(filePath); // Allow multiple connections to the same in-memory database by // using a named connection. This is needed to make the database // connection pool work correctly even during tests. @@ -34,10 +46,10 @@ mixxx::DbConnection::Params dbConnectionParams( // See also: // https://www.sqlite.org/inmemorydb.html if (inMemoryConnection) { - params.filePath += "?mode=memory"; + params.filePath += QStringLiteral("?mode=memory"); } - params.userName = "mixxx"; - params.password = "mixxx"; + params.userName = kUserName; + params.password = kPassword; return params; } diff --git a/src/util/db/dbconnection.cpp b/src/util/db/dbconnection.cpp index e60534ce598d..aa53067a471f 100644 --- a/src/util/db/dbconnection.cpp +++ b/src/util/db/dbconnection.cpp @@ -31,6 +31,7 @@ QSqlDatabase createDatabase( QSqlDatabase database = QSqlDatabase::addDatabase(params.type, connectionName); + database.setConnectOptions(params.connectOptions); database.setHostName(params.hostName); database.setDatabaseName(params.filePath); database.setUserName(params.userName); diff --git a/src/util/db/dbconnection.h b/src/util/db/dbconnection.h index aef106bed540..76b6af892875 100644 --- a/src/util/db/dbconnection.h +++ b/src/util/db/dbconnection.h @@ -26,6 +26,7 @@ class DbConnection final { struct Params { QString type; + QString connectOptions; QString hostName; QString filePath; QString userName; From a538364477e37472512bbf3c4608e31c77bff872 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sat, 22 Feb 2020 21:03:10 +0100 Subject: [PATCH 3/5] Use a shared cache for in-memory databases --- src/database/mixxxdb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database/mixxxdb.cpp b/src/database/mixxxdb.cpp index c17f5338a08e..22fc07e0ed41 100644 --- a/src/database/mixxxdb.cpp +++ b/src/database/mixxxdb.cpp @@ -46,7 +46,7 @@ mixxx::DbConnection::Params dbConnectionParams( // See also: // https://www.sqlite.org/inmemorydb.html if (inMemoryConnection) { - params.filePath += QStringLiteral("?mode=memory"); + params.filePath += QStringLiteral("?mode=memory&cache=shared"); } params.userName = kUserName; params.password = kPassword; From a893c102ba7022764ae73d10aa1a393f87e72d52 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sat, 22 Feb 2020 23:10:07 +0100 Subject: [PATCH 4/5] Use absolute file path for URI and optimize string operations --- src/database/mixxxdb.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/database/mixxxdb.cpp b/src/database/mixxxdb.cpp index 22fc07e0ed41..17e53b0aee8e 100644 --- a/src/database/mixxxdb.cpp +++ b/src/database/mixxxdb.cpp @@ -21,6 +21,8 @@ const QString kType = QStringLiteral("QSQLITE"); const QString kConnectOptions = QStringLiteral("QSQLITE_OPEN_URI"); +const QString kUriPrefix = QStringLiteral("file://"); + const QString kDefaultFileName = QStringLiteral("mixxxdb.sqlite"); const QString kUserName = QStringLiteral("mixxx"); @@ -34,11 +36,16 @@ mixxx::DbConnection::Params dbConnectionParams( mixxx::DbConnection::Params params; params.type = kType; params.connectOptions = kConnectOptions; - QString filePath = QDir(pConfig->getSettingsPath()).filePath(kDefaultFileName); - if (!filePath.startsWith(QStringLiteral("/"))) { - filePath = QStringLiteral("/") + filePath; + params.filePath = kUriPrefix; + const QString absFilePath = + QDir(pConfig->getSettingsPath()).absoluteFilePath(kDefaultFileName); + // On Windows absFilePath starts with a drive letter instead of + // the leading '/' as required. + // https://www.sqlite.org/c3ref/open.html#urifilenameexamples + if (!absFilePath.startsWith(QChar('/'))) { + params.filePath += QChar('/'); } - params.filePath = QString(QStringLiteral("file://%1")).arg(filePath); + params.filePath = kUriPrefix + absFilePath; // Allow multiple connections to the same in-memory database by // using a named connection. This is needed to make the database // connection pool work correctly even during tests. From 2ff6e572e304704ed7d3b065a5f8707fe1fdf05c Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sat, 22 Feb 2020 23:31:48 +0100 Subject: [PATCH 5/5] Fix string composition --- src/database/mixxxdb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database/mixxxdb.cpp b/src/database/mixxxdb.cpp index 17e53b0aee8e..e3a2e70cc7e4 100644 --- a/src/database/mixxxdb.cpp +++ b/src/database/mixxxdb.cpp @@ -45,7 +45,7 @@ mixxx::DbConnection::Params dbConnectionParams( if (!absFilePath.startsWith(QChar('/'))) { params.filePath += QChar('/'); } - params.filePath = kUriPrefix + absFilePath; + params.filePath += absFilePath; // Allow multiple connections to the same in-memory database by // using a named connection. This is needed to make the database // connection pool work correctly even during tests.