From cb869c246550345638ad2ba53f559c3feccc7c1f Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Wed, 20 Jul 2016 14:14:21 +0200 Subject: [PATCH] data: Store separate storage version number in SqliteStorage for managing migrations * deprecated the third version number as storage update number * version can now have either 3 or 4 numbers * whether a .coatidb file is outdated is now solely determined by the SqliteStorage::STORAGE_VERSION --- src/lib/Project.cpp | 7 ++- src/lib/data/PersistentStorage.cpp | 15 ++++-- src/lib/data/PersistentStorage.h | 6 ++- src/lib/data/SqliteStorage.cpp | 78 +++++++++++++++++++++--------- src/lib/data/SqliteStorage.h | 15 ++++-- src/lib/utility/Version.cpp | 48 +++++------------- src/lib/utility/Version.h | 4 +- src/test/SqliteStorageTestSuite.h | 8 +-- 8 files changed, 103 insertions(+), 78 deletions(-) diff --git a/src/lib/Project.cpp b/src/lib/Project.cpp index 9054b6eb..d47454ed 100644 --- a/src/lib/Project.cpp +++ b/src/lib/Project.cpp @@ -183,13 +183,12 @@ void Project::setProjectSettingsFilePath(const FilePath& path) { loadStorage(path); - Version version = m_storage->getVersion(); - if (version.isEmpty()) + if (m_storage->isEmpty()) { m_state = PROJECT_EMPTY; - m_storage->init(); + m_storage->setup(); } - else if (version.isDifferentStorageVersionThan(Version::getApplicationVersion())) + else if (m_storage->isIncompatible()) { m_state = PROJECT_OUTVERSIONED; m_storage.reset(); diff --git a/src/lib/data/PersistentStorage.cpp b/src/lib/data/PersistentStorage.cpp index efaed92e..69085de6 100644 --- a/src/lib/data/PersistentStorage.cpp +++ b/src/lib/data/PersistentStorage.cpp @@ -238,14 +238,19 @@ FilePath PersistentStorage::getDbFilePath() const return m_sqliteStorage.getDbFilePath(); } -Version PersistentStorage::getVersion() const +bool PersistentStorage::isEmpty() const { - return m_sqliteStorage.getVersion(); + return m_sqliteStorage.isEmpty(); } -void PersistentStorage::init() +bool PersistentStorage::isIncompatible() const { - m_sqliteStorage.init(); + return m_sqliteStorage.isIncompatible(); +} + +void PersistentStorage::setup() +{ + m_sqliteStorage.setup(); } void PersistentStorage::clear() @@ -365,7 +370,7 @@ void PersistentStorage::startParsing() { MessageClearErrorCount().dispatch(); - m_sqliteStorage.setVersion(Version::getApplicationVersion()); + m_sqliteStorage.setVersion(); } void PersistentStorage::finishParsing() diff --git a/src/lib/data/PersistentStorage.h b/src/lib/data/PersistentStorage.h index b6caf1d2..277293fb 100644 --- a/src/lib/data/PersistentStorage.h +++ b/src/lib/data/PersistentStorage.h @@ -49,9 +49,11 @@ public: virtual void finishInjection(); FilePath getDbFilePath() const; - Version getVersion() const; - void init(); + bool isEmpty() const; + bool isIncompatible() const; + + void setup(); void clear(); void clearCaches(); diff --git a/src/lib/data/SqliteStorage.cpp b/src/lib/data/SqliteStorage.cpp index ec95e45b..9fd45563 100644 --- a/src/lib/data/SqliteStorage.cpp +++ b/src/lib/data/SqliteStorage.cpp @@ -11,6 +11,8 @@ #include "utility/utilityString.h" #include "utility/Version.h" +const size_t SqliteStorage::STORAGE_VERSION = 1; + SqliteStorage::SqliteStorage(const FilePath& dbFilePath) : m_dbFilePath(dbFilePath) { @@ -31,20 +33,6 @@ SqliteStorage::~SqliteStorage() } } -void SqliteStorage::init() -{ - Version version = getVersion(); - - if (version.isEmpty()) - { - setup(); - } - else if (version.isDifferentStorageVersionThan(Version::getApplicationVersion())) - { - clear(); - } -} - void SqliteStorage::setup() { m_database.execDML("PRAGMA foreign_keys=ON;"); @@ -79,21 +67,33 @@ FilePath SqliteStorage::getDbFilePath() const return m_dbFilePath; } -Version SqliteStorage::getVersion() const +bool SqliteStorage::isEmpty() const { - std::string versionStr = getMetaValue("version"); - - if (versionStr.size()) + size_t storageVersion = getStorageVersion(); + if (storageVersion > 0) { - return Version::fromString(versionStr); + return false; } - return Version(); + Version applicationVersion = getApplicationVersion(); + return applicationVersion.isEmpty(); } -void SqliteStorage::setVersion(const Version& version) +bool SqliteStorage::isIncompatible() const { - insertOrUpdateMetaValue("version", version.toString()); + size_t storageVersion = getStorageVersion(); + if (storageVersion == 0 || storageVersion != STORAGE_VERSION) + { + return true; + } + + return false; +} + +void SqliteStorage::setVersion() +{ + setStorageVersion(); + setApplicationVersion(); } Id SqliteStorage::addEdge(int type, Id sourceNodeId, Id targetNodeId) @@ -797,6 +797,40 @@ void SqliteStorage::insertOrUpdateMetaValue(const std::string& key, const std::s ).c_str()); } +size_t SqliteStorage::getStorageVersion() const +{ + std::string storageVersionStr = getMetaValue("storage_version"); + + if (storageVersionStr.size()) + { + return std::stoi(storageVersionStr); + } + + return 0; +} + +void SqliteStorage::setStorageVersion() +{ + insertOrUpdateMetaValue("storage_version", std::to_string(STORAGE_VERSION)); +} + +Version SqliteStorage::getApplicationVersion() const +{ + std::string versionStr = getMetaValue("version"); + + if (versionStr.size()) + { + return Version::fromString(versionStr); + } + + return Version(); +} + +void SqliteStorage::setApplicationVersion() +{ + insertOrUpdateMetaValue("version", Version::getApplicationVersion().toString()); +} + template <> std::vector SqliteStorage::getAll(const std::string& query) const { diff --git a/src/lib/data/SqliteStorage.h b/src/lib/data/SqliteStorage.h index fa9a5412..e4ee15d6 100644 --- a/src/lib/data/SqliteStorage.h +++ b/src/lib/data/SqliteStorage.h @@ -24,7 +24,6 @@ public: SqliteStorage(const FilePath& dbFilePath); ~SqliteStorage(); - void init(); void setup(); void clear(); @@ -34,8 +33,10 @@ public: FilePath getDbFilePath() const; - Version getVersion() const; - void setVersion(const Version& version); + bool isEmpty() const; + bool isIncompatible() const; + + void setVersion(); Id addEdge(int type, Id sourceNodeId, Id targetNodeId); Id addNode(int type, const std::string& serializedName, int definitionType); @@ -118,6 +119,8 @@ public: int getSourceLocationCount() const; private: + static const size_t STORAGE_VERSION; + void clearTables(); void setupTables(); @@ -126,6 +129,12 @@ private: std::string getMetaValue(const std::string& key) const; void insertOrUpdateMetaValue(const std::string& key, const std::string& value); + size_t getStorageVersion() const; + void setStorageVersion(); + + Version getApplicationVersion() const; + void setApplicationVersion(); + template std::vector getAll(const std::string& query) const; diff --git a/src/lib/utility/Version.cpp b/src/lib/utility/Version.cpp index 5565e613..d6a2faa3 100644 --- a/src/lib/utility/Version.cpp +++ b/src/lib/utility/Version.cpp @@ -49,51 +49,24 @@ const Version& Version::getApplicationVersion() Version::Version() : m_majorNumber(0) , m_minorNumber(0) - , m_refreshNumber(0) + , m_refreshNumber(-1) , m_commitNumber(0) { } bool Version::isEmpty() const { - return m_majorNumber == 0 && m_minorNumber == 0 && m_refreshNumber == 0 && m_commitNumber == 0; -} - -bool Version::operator<(const Version& other) const -{ - if (m_majorNumber != other.m_majorNumber) - { - return m_majorNumber < other.m_majorNumber; - } - else if (m_minorNumber != other.m_minorNumber) - { - return m_minorNumber < other.m_minorNumber; - } - else if (m_refreshNumber != other.m_refreshNumber) - { - return m_refreshNumber < other.m_refreshNumber; - } - else if (m_commitNumber != other.m_commitNumber) - { - return m_commitNumber < other.m_commitNumber; - } - else - { - return false; - } -} - -bool Version::isDifferentStorageVersionThan(const Version& other) const -{ - return m_majorNumber != other.m_majorNumber || - m_minorNumber != other.m_minorNumber || - m_refreshNumber != other.m_refreshNumber; + return m_majorNumber == 0 && m_minorNumber == 0 && m_refreshNumber == -1 && m_commitNumber == 0; } std::string Version::toString() const { std::stringstream ss; - ss << m_majorNumber << '.' << m_minorNumber << '.' << m_refreshNumber; + ss << m_majorNumber << '.' << m_minorNumber; + if (m_refreshNumber != -1) + { + ss << '.' << m_refreshNumber; + } ss << '-' << m_commitNumber << '-' << m_commitHash; return ss.str(); } @@ -101,6 +74,11 @@ std::string Version::toString() const std::string Version::toDisplayString() const { std::stringstream ss; - ss << m_majorNumber << '.' << m_minorNumber << '.' << m_refreshNumber << '.' << m_commitNumber; + ss << m_majorNumber << '.' << m_minorNumber; + if (m_refreshNumber != -1) + { + ss << '.' << m_refreshNumber; + } + ss << '.' << m_commitNumber; return ss.str(); } diff --git a/src/lib/utility/Version.h b/src/lib/utility/Version.h index 7c4ceca3..95c05f6b 100644 --- a/src/lib/utility/Version.h +++ b/src/lib/utility/Version.h @@ -14,8 +14,6 @@ public: Version(); bool isEmpty() const; - bool operator<(const Version& other) const; - bool isDifferentStorageVersionThan(const Version& other) const; std::string toString() const; std::string toDisplayString() const; @@ -25,7 +23,7 @@ private: int m_majorNumber; int m_minorNumber; - int m_refreshNumber; + int m_refreshNumber; // deprecated since switch to storage_version, left for downward compatibility int m_commitNumber; std::string m_commitHash; diff --git a/src/test/SqliteStorageTestSuite.h b/src/test/SqliteStorageTestSuite.h index 272e648e..1c8654eb 100644 --- a/src/test/SqliteStorageTestSuite.h +++ b/src/test/SqliteStorageTestSuite.h @@ -14,7 +14,7 @@ public: int nodeCount = -1; { SqliteStorage storage(databasePath); - storage.init(); + storage.setup(); storage.beginTransaction(); storage.addNode(0, "a", false); storage.commitTransaction(); @@ -31,7 +31,7 @@ public: int nodeCount = -1; { SqliteStorage storage(databasePath); - storage.init(); + storage.setup(); storage.beginTransaction(); int nodeId = storage.addNode(0, "a", false); storage.removeElement(nodeId); @@ -49,7 +49,7 @@ public: int edgeCount = -1; { SqliteStorage storage(databasePath); - storage.init(); + storage.setup(); storage.beginTransaction(); int sourceNodeId = storage.addNode(0, "a", false); int targetNodeId = storage.addNode(0, "b", false); @@ -68,7 +68,7 @@ public: int edgeCount = -1; { SqliteStorage storage(databasePath); - storage.init(); + storage.setup(); storage.beginTransaction(); int sourceNodeId = storage.addNode(0, "a", false); int targetNodeId = storage.addNode(0, "b", false);