X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fcore%2Fabstractsqlstorage.cpp;h=9fe95b9d05dbda19a847ac21da4a7cef81eaed9e;hb=6a63070246d89aa2a2474e3a9a1035fa889ad77e;hp=ad08947d9120b6b1a3a2038566fa560a28cbe7b1;hpb=4a5065255e652dd0c301bac0db41b7afb777ef49;p=quassel.git diff --git a/src/core/abstractsqlstorage.cpp b/src/core/abstractsqlstorage.cpp index ad08947d..9fe95b9d 100644 --- a/src/core/abstractsqlstorage.cpp +++ b/src/core/abstractsqlstorage.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2013 by the Quassel Project * + * Copyright (C) 2005-2018 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -41,7 +41,7 @@ AbstractSqlStorage::~AbstractSqlStorage() { // disconnect the connections, so their deletion is no longer interessting for us QHash::iterator conIter; - for (conIter = _connectionPool.begin(); conIter != _connectionPool.end(); conIter++) { + for (conIter = _connectionPool.begin(); conIter != _connectionPool.end(); ++conIter) { QSqlDatabase::removeDatabase(conIter.value()->name()); disconnect(conIter.value(), 0, this, 0); } @@ -53,7 +53,14 @@ QSqlDatabase AbstractSqlStorage::logDb() if (!_connectionPool.contains(QThread::currentThread())) addConnectionToPool(); - return QSqlDatabase::database(_connectionPool[QThread::currentThread()]->name()); + QSqlDatabase db = QSqlDatabase::database(_connectionPool[QThread::currentThread()]->name(),false); + + if (!db.isOpen()) { + qWarning() << "Database connection" << displayName() << "for thread" << QThread::currentThread() << "was lost, attempting to reconnect..."; + dbConnect(db); + } + + return db; } @@ -90,19 +97,30 @@ void AbstractSqlStorage::addConnectionToPool() db.setPassword(password()); } + dbConnect(db); +} + + +void AbstractSqlStorage::dbConnect(QSqlDatabase &db) +{ if (!db.open()) { - qWarning() << "Unable to open database" << displayName() << "for thread" << QThread::currentThread(); - qWarning() << "-" << db.lastError().text(); + quWarning() << "Unable to open database" << displayName() << "for thread" << QThread::currentThread(); + quWarning() << "-" << db.lastError().text(); } else { - initDbSession(db); + if (!initDbSession(db)) { + quWarning() << "Unable to initialize database" << displayName() << "for thread" << QThread::currentThread(); + db.close(); + } } } -Storage::State AbstractSqlStorage::init(const QVariantMap &settings) +Storage::State AbstractSqlStorage::init(const QVariantMap &settings, + const QProcessEnvironment &environment, + bool loadFromEnvironment) { - setConnectionProperties(settings); + setConnectionProperties(settings, environment, loadFromEnvironment); _debug = Quassel::isOptionSet("debug"); @@ -128,17 +146,27 @@ Storage::State AbstractSqlStorage::init(const QVariantMap &settings) } } - quInfo() << qPrintable(displayName()) << "Storage Backend is ready. Quassel Schema Version:" << installedSchemaVersion(); + quInfo() << qPrintable(displayName()) << "storage backend is ready. Schema version:" << installedSchemaVersion(); return IsReady; } QString AbstractSqlStorage::queryString(const QString &queryName, int version) { - if (version == 0) - version = schemaVersion(); + QFileInfo queryInfo; + + // The current schema is stored in the root folder, while upgrade queries are stored in the + // 'versions/##' subfolders. + if (version == 0) { + // Use the current SQL schema, not a versioned request + queryInfo = QFileInfo(QString(":/SQL/%1/%2.sql").arg(displayName()).arg(queryName)); + // If version is needed later, get it via version = schemaVersion(); + } else { + // Use the specified schema version, not the general folder + queryInfo = QFileInfo(QString(":/SQL/%1/version/%2/%3.sql") + .arg(displayName()).arg(version).arg(queryName)); + } - QFileInfo queryInfo(QString(":/SQL/%1/%2/%3.sql").arg(displayName()).arg(version).arg(queryName)); if (!queryInfo.exists() || !queryInfo.isFile() || !queryInfo.isReadable()) { qCritical() << "Unable to read SQL-Query" << queryName << "for engine" << displayName(); return QString(); @@ -157,7 +185,8 @@ QString AbstractSqlStorage::queryString(const QString &queryName, int version) QStringList AbstractSqlStorage::setupQueries() { QStringList queries; - QDir dir = QDir(QString(":/SQL/%1/%2/").arg(displayName()).arg(schemaVersion())); + // The current schema is stored in the root folder, including setup scripts. + QDir dir = QDir(QString(":/SQL/%1/").arg(displayName())); foreach(QFileInfo fileInfo, dir.entryInfoList(QStringList() << "setup*", QDir::NoFilter, QDir::Name)) { queries << queryString(fileInfo.baseName()); } @@ -165,9 +194,10 @@ QStringList AbstractSqlStorage::setupQueries() } -bool AbstractSqlStorage::setup(const QVariantMap &settings) +bool AbstractSqlStorage::setup(const QVariantMap &settings, const QProcessEnvironment &environment, + bool loadFromEnvironment) { - setConnectionProperties(settings); + setConnectionProperties(settings, environment, loadFromEnvironment); QSqlDatabase db = logDb(); if (!db.isOpen()) { qCritical() << "Unable to setup Logging Backend!"; @@ -195,7 +225,8 @@ bool AbstractSqlStorage::setup(const QVariantMap &settings) QStringList AbstractSqlStorage::upgradeQueries(int version) { QStringList queries; - QDir dir = QDir(QString(":/SQL/%1/%2/").arg(displayName()).arg(version)); + // Upgrade queries are stored in the 'version/##' subfolders. + QDir dir = QDir(QString(":/SQL/%1/version/%2/").arg(displayName()).arg(version)); foreach(QFileInfo fileInfo, dir.entryInfoList(QStringList() << "upgrade*", QDir::NoFilter, QDir::Name)) { queries << queryString(fileInfo.baseName(), version); } @@ -232,7 +263,8 @@ int AbstractSqlStorage::schemaVersion() int version; bool ok; - QDir dir = QDir(":/SQL/" + displayName()); + // Schema versions are stored in the 'version/##' subfolders. + QDir dir = QDir(QString(":/SQL/%1/version/").arg(displayName())); foreach(QFileInfo fileInfo, dir.entryInfoList()) { if (!fileInfo.isDir()) continue; @@ -259,7 +291,7 @@ bool AbstractSqlStorage::watchQuery(QSqlQuery &query) QVariantMap boundValues = query.boundValues(); QStringList valueStrings; QVariantMap::const_iterator iter; - for (iter = boundValues.constBegin(); iter != boundValues.constEnd(); iter++) { + for (iter = boundValues.constBegin(); iter != boundValues.constEnd(); ++iter) { QString value; QSqlField field; if (query.driver()) { @@ -380,6 +412,8 @@ QString AbstractSqlMigrator::migrationObject(MigrationObject moType) return "IrcServer"; case UserSetting: return "UserSetting"; + case CoreState: + return "CoreState"; }; return QString(); } @@ -406,7 +440,7 @@ void AbstractSqlMigrator::dumpStatus() qWarning() << " bound Values:"; QList list = boundValues(); for (int i = 0; i < list.size(); ++i) - qWarning() << i << ": " << list.at(i).toString().toAscii().data(); + qWarning() << i << ": " << list.at(i).toString().toLatin1().data(); qWarning() << " Error Number:" << lastError().number(); qWarning() << " Error Message:" << lastError().text(); } @@ -473,6 +507,10 @@ bool AbstractSqlMigrationReader::migrateTo(AbstractSqlMigrationWriter *writer) if (!transferMo(UserSetting, userSettingMo)) return false; + CoreStateMO coreStateMO; + if (!transferMo(CoreState, coreStateMO)) + return false; + if (!_writer->postProcess()) abortMigration(); return finalizeMigration(); @@ -555,3 +593,13 @@ bool AbstractSqlMigrationReader::transferMo(MigrationObject moType, T &mo) qDebug() << "Done."; return true; } + +uint qHash(const SenderData &key) { + return qHash(QString(key.sender + "\n" + key.realname + "\n" + key.avatarurl)); +} + +bool operator==(const SenderData &a, const SenderData &b) { + return a.sender == b.sender && + a.realname == b.realname && + a.avatarurl == b.avatarurl; +}