1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#include "database/mixxxdb.h"
#include "database/schemamanager.h"
#include "util/assert.h"
#include "util/logger.h"
// The schema XML is baked into the binary via Qt resources.
//static
const QString MixxxDb::kDefaultSchemaFile(":/schema.xml");
//static
const int MixxxDb::kRequiredSchemaVersion = 32;
namespace {
const mixxx::Logger kLogger("MixxxDb");
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");
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 = kType;
params.connectOptions = kConnectOptions;
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 += 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.
//
// See also:
// https://www.sqlite.org/inmemorydb.html
if (inMemoryConnection) {
params.filePath += QStringLiteral("?mode=memory&cache=shared");
}
params.userName = kUserName;
params.password = kPassword;
return params;
}
} // anonymous namespace
MixxxDb::MixxxDb(
const UserSettingsPointer& pConfig,
bool inMemoryConnection)
: m_pDbConnectionPool(std::make_shared<mixxx::DbConnectionPool>(dbConnectionParams(pConfig, inMemoryConnection), "MIXXX")) {
}
bool MixxxDb::initDatabaseSchema(
const QSqlDatabase& database,
const QString& schemaFile,
int schemaVersion) {
QString okToExit = tr("Click OK to exit.");
QString upgradeFailed = tr("Cannot upgrade database schema");
QString upgradeToVersionFailed =
tr("Unable to upgrade your database schema to version %1")
.arg(QString::number(schemaVersion));
QString helpEmail = tr("For help with database issues contact:") + "\n" +
"mixxx-devel@lists.sourceforge.net";
switch (SchemaManager(database).upgradeToSchemaVersion(schemaFile, schemaVersion)) {
case SchemaManager::Result::CurrentVersion:
case SchemaManager::Result::UpgradeSucceeded:
case SchemaManager::Result::NewerVersionBackwardsCompatible:
return true; // done
case SchemaManager::Result::UpgradeFailed:
QMessageBox::warning(
0, upgradeFailed,
upgradeToVersionFailed + "\n" +
tr("Your mixxxdb.sqlite file may be corrupt.") + "\n" +
tr("Try renaming it and restarting Mixxx.") + "\n" +
helpEmail + "\n\n" + okToExit,
QMessageBox::Ok);
return false; // abort
case SchemaManager::Result::NewerVersionIncompatible:
QMessageBox::warning(
0, upgradeFailed,
upgradeToVersionFailed + "\n" +
tr("Your mixxxdb.sqlite file was created by a newer "
"version of Mixxx and is incompatible.") +
"\n\n" + okToExit,
QMessageBox::Ok);
return false; // abort
case SchemaManager::Result::SchemaError:
QMessageBox::warning(
0, upgradeFailed,
upgradeToVersionFailed + "\n" +
tr("The database schema file is invalid.") + "\n" +
helpEmail + "\n\n" + okToExit,
QMessageBox::Ok);
return false; // abort
}
// Suppress compiler warning
DEBUG_ASSERT(!"unhandled switch/case");
return false;
}
|