diff --git a/src/Cache.cpp b/src/Cache.cpp
index eb5c93aa..1a097cff 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -665,8 +665,15 @@ Cache::deleteData()
}
}
+//! migrates db to the current format
bool
-Cache::isFormatValid()
+Cache::runMigrations()
+{
+ return true;
+}
+
+cache::CacheVersion
+Cache::formatVersion()
{
auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
@@ -676,18 +683,16 @@ Cache::isFormatValid()
txn.commit();
if (!res)
- return false;
+ return cache::CacheVersion::Older;
std::string stored_version(current_version.data(), current_version.size());
- if (stored_version != CURRENT_CACHE_FORMAT_VERSION) {
- nhlog::db()->warn("breaking changes in the cache format. stored: {}, current: {}",
- stored_version,
- CURRENT_CACHE_FORMAT_VERSION);
- return false;
- }
-
- return true;
+ if (stored_version < CURRENT_CACHE_FORMAT_VERSION)
+ return cache::CacheVersion::Older;
+ else if (stored_version > CURRENT_CACHE_FORMAT_VERSION)
+ return cache::CacheVersion::Older;
+ else
+ return cache::CacheVersion::Current;
}
void
@@ -2468,10 +2473,17 @@ setup()
}
bool
-isFormatValid()
+runMigrations()
+{
+ return instance_->runMigrations();
+}
+
+cache::CacheVersion
+formatVersion()
{
- return instance_->isFormatValid();
+ return instance_->formatVersion();
}
+
void
setCurrentFormat()
{
diff --git a/src/Cache.h b/src/Cache.h
index 99c63550..12465c9d 100644
--- a/src/Cache.h
+++ b/src/Cache.h
@@ -111,10 +111,15 @@ removeRoom(const QString &roomid);
void
setup();
-bool
-isFormatValid();
+//! returns if the format is current, older or newer
+cache::CacheVersion
+formatVersion();
+//! set the format version to the current version
void
setCurrentFormat();
+//! migrates db to the current format
+bool
+runMigrations();
std::map<QString, mtx::responses::Timeline>
roomMessages();
diff --git a/src/CacheStructs.h b/src/CacheStructs.h
index ab7bbc71..ef08cfcb 100644
--- a/src/CacheStructs.h
+++ b/src/CacheStructs.h
@@ -8,6 +8,15 @@
#include <mtx/events/join_rules.hpp>
+namespace cache {
+enum class CacheVersion : int
+{
+ Older = -1,
+ Current = 0,
+ Newer = 1,
+};
+}
+
struct RoomMember
{
QString user_id;
diff --git a/src/Cache_p.h b/src/Cache_p.h
index 982099ea..0d66a608 100644
--- a/src/Cache_p.h
+++ b/src/Cache_p.h
@@ -102,8 +102,9 @@ public:
void removeRoom(const std::string &roomid);
void setup();
- bool isFormatValid();
+ cache::CacheVersion formatVersion();
void setCurrentFormat();
+ bool runMigrations();
std::map<QString, mtx::responses::Timeline> roomMessages();
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 981e6b80..689e9ca4 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -17,6 +17,7 @@
#include <QApplication>
#include <QImageReader>
+#include <QMessageBox>
#include <QSettings>
#include <QShortcut>
#include <QtConcurrent>
@@ -642,20 +643,37 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token)
&NotificationsManager::removeNotification);
const bool isInitialized = cache::isInitialized();
- const bool isValid = cache::isFormatValid();
+ const auto cacheVersion = cache::formatVersion();
if (!isInitialized) {
cache::setCurrentFormat();
- } else if (isInitialized && !isValid) {
- // TODO: Deleting session data but keep using the
- // same device doesn't work.
- cache::deleteData();
-
- cache::init(userid);
- cache::setCurrentFormat();
- } else if (isInitialized) {
- loadStateFromCache();
- return;
+ } else {
+ if (cacheVersion == cache::CacheVersion::Current) {
+ loadStateFromCache();
+ return;
+ } else if (cacheVersion == cache::CacheVersion::Older) {
+ if (!cache::runMigrations()) {
+ QMessageBox::critical(
+ this,
+ tr("Cache migration failed!"),
+ tr("Migrating the cache to the current version failed. "
+ "This can have different reasons. Please open an "
+ "issue and try to use an older version in the mean "
+ "time. Alternatively you can try deleting the cache "
+ "manually"));
+ QCoreApplication::quit();
+ }
+ loadStateFromCache();
+ return;
+ } else if (cacheVersion == cache::CacheVersion::Newer) {
+ QMessageBox::critical(
+ this,
+ tr("Incompatible cache version"),
+ tr("The cache on your disk is newer than this version of Nheko "
+ "supports. Please update or clear your cache."));
+ QCoreApplication::quit();
+ return;
+ }
}
} catch (const lmdb::error &e) {
|