From fb805b9cdb5f108b15da33aa0bd6c250aac7a8b1 Mon Sep 17 00:00:00 2001 From: Mick Sayson Date: Mon, 24 Sep 2018 01:05:43 -0700 Subject: [PATCH] feat(db): Support schema version upgrades --- src/persistence/history.cpp | 46 +++++++++++++++++++++++++++++++++++++ src/persistence/history.h | 1 + 2 files changed, 47 insertions(+) diff --git a/src/persistence/history.cpp b/src/persistence/history.cpp index b259e8bdd..4485ddaba 100644 --- a/src/persistence/history.cpp +++ b/src/persistence/history.cpp @@ -35,6 +35,7 @@ */ static constexpr int NUM_MESSAGES_DEFAULT = 100; // arbitrary number of messages loaded when not loading by date +static constexpr int SCHEMA_VERSION = 0; /** * @brief Prepares the database to work with the history. @@ -48,6 +49,13 @@ History::History(std::shared_ptr db) return; } + dbSchemaUpgrade(); + + // dbSchemaUpgrade may have put us in an invalid state + if (!isValid()) { + return; + } + db->execLater( "CREATE TABLE IF NOT EXISTS peers (id INTEGER PRIMARY KEY, public_key TEXT NOT NULL " "UNIQUE);" @@ -493,3 +501,41 @@ QList History::getChatHistory(const QString& friendPk, con return messages; } + +/** + * @brief Upgrade the db schema + * @note On future alterations of the database all you have to do is bump the SCHEMA_VERSION + * variable and add another case to the switch statement below. Make sure to fall through on each case. + */ +void History::dbSchemaUpgrade() +{ + int64_t databaseSchemaVersion; + db->execNow(RawDatabase::Query("PRAGMA user_version", [&] (const QVector& row){ + databaseSchemaVersion = row[0].toLongLong(); + })); + + if (databaseSchemaVersion > SCHEMA_VERSION) { + qWarning() << "Database version is newer than we currently support. Please upgrade qTox"; + // We don't know what future versions have done, we have to disable db access until we re-upgrade + db.reset(); + } + else if (databaseSchemaVersion == SCHEMA_VERSION) { + // No work to do + return; + } + + switch (databaseSchemaVersion) + { + //case 0: + // do 0 -> 1 upgrade + // //fallthrough + //case 1: + // do 1 -> 2 upgrade + // //fallthrough + // etc. + default: + db->execLater(RawDatabase::Query(QStringLiteral("PRAGMA user_version = %1;").arg(SCHEMA_VERSION))); + qDebug() << "Database upgrade finished (databaseSchemaVersion " + << databaseSchemaVersion << " -> " << SCHEMA_VERSION << ")"; + } +} diff --git a/src/persistence/history.h b/src/persistence/history.h index 5da854378..693053a90 100644 --- a/src/persistence/history.h +++ b/src/persistence/history.h @@ -99,6 +99,7 @@ protected: private: QList getChatHistory(const QString& friendPk, const QDateTime& from, const QDateTime& to, int numMessages); + void dbSchemaUpgrade(); std::shared_ptr db; QHash peers; };