data: Saving application version to storage and refresh when version changes

The version string of the application is stored on every parse. The utility class Version is used to parse the version
string and compare application and stored string. The third number in the version string is now the storage refresh
number, the project will be refreshed when it changes. (0.2.1 -> 0.2.2)
This commit is contained in:
Eberhard Graether
2015-11-02 10:14:03 +01:00
parent 1ad2dbe86e
commit 62baa51520
12 changed files with 256 additions and 12 deletions
+5 -2
View File
@@ -5,6 +5,7 @@
#include "utility/logging/ConsoleLogger.h" #include "utility/logging/ConsoleLogger.h"
#include "utility/logging/FileLogger.h" #include "utility/logging/FileLogger.h"
#include "utility/logging/LogManager.h" #include "utility/logging/LogManager.h"
#include "utility/Version.h"
#include "Application.h" #include "Application.h"
#include "includes.h" // defines 'void setup(int argc, char *argv[])' #include "includes.h" // defines 'void setup(int argc, char *argv[])'
@@ -31,6 +32,8 @@ void init()
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
Version version = Version::fromString(GIT_VERSION_NUMBER);
setup(argc, argv); setup(argc, argv);
QApplication qtApp(argc, argv); QApplication qtApp(argc, argv);
@@ -41,7 +44,7 @@ int main(int argc, char *argv[])
QtSplashScreen* splash = new QtSplashScreen(whitePixmap, Qt::WindowStaysOnTopHint); QtSplashScreen* splash = new QtSplashScreen(whitePixmap, Qt::WindowStaysOnTopHint);
splash->setMessage("Loading UI"); splash->setMessage("Loading UI");
splash->setVersion(GIT_VERSION_NUMBER); splash->setVersion(version.toDisplayString().c_str());
splash->exec(qtApp); splash->exec(qtApp);
init(); init();
@@ -49,7 +52,7 @@ int main(int argc, char *argv[])
QtViewFactory viewFactory; QtViewFactory viewFactory;
QtNetworkFactory networkFactory; QtNetworkFactory networkFactory;
std::shared_ptr<Application> app = Application::create(&viewFactory, &networkFactory); std::shared_ptr<Application> app = Application::create(version, &viewFactory, &networkFactory);
if (splash) if (splash)
{ {
+2 -2
View File
@@ -4,7 +4,7 @@
#include <QLineEdit> #include <QLineEdit>
#include <QLabel> #include <QLabel>
#include "version.h" #include "utility/Version.h"
QtAbout::QtAbout(QWidget *parent) QtAbout::QtAbout(QWidget *parent)
: QtSettingsWindow(parent) : QtSettingsWindow(parent)
@@ -46,7 +46,7 @@ void QtAbout::populateForm(QFormLayout* layout)
acknowledgementsLabel->setAlignment(Qt::AlignTop); acknowledgementsLabel->setAlignment(Qt::AlignTop);
layout->addRow(acknowledgementsName, acknowledgementsLabel); layout->addRow(acknowledgementsName, acknowledgementsLabel);
layout->addRow(QString("Version:"), new QLabel(GIT_VERSION_NUMBER)); layout->addRow(QString("Version:"), new QLabel(Version::getApplicationVersion().toDisplayString().c_str()));
} }
void QtAbout::handleCancelButtonPress() void QtAbout::handleCancelButtonPress()
+6 -2
View File
@@ -5,6 +5,7 @@
#include "utility/messaging/type/MessageActivateNodes.h" #include "utility/messaging/type/MessageActivateNodes.h"
#include "utility/messaging/type/MessageStatus.h" #include "utility/messaging/type/MessageStatus.h"
#include "utility/scheduling/TaskScheduler.h" #include "utility/scheduling/TaskScheduler.h"
#include "utility/Version.h"
#include "component/view/GraphViewStyle.h" #include "component/view/GraphViewStyle.h"
#include "component/controller/NetworkFactory.h" #include "component/controller/NetworkFactory.h"
@@ -14,8 +15,11 @@
#include "settings/ApplicationSettings.h" #include "settings/ApplicationSettings.h"
#include "settings/ColorScheme.h" #include "settings/ColorScheme.h"
std::shared_ptr<Application> Application::create(ViewFactory* viewFactory, NetworkFactory* networkFactory) std::shared_ptr<Application> Application::create(
{ const Version& version, ViewFactory* viewFactory, NetworkFactory* networkFactory
){
Version::setApplicationVersion(version);
loadSettings(); loadSettings();
std::shared_ptr<Application> ptr(new Application()); std::shared_ptr<Application> ptr(new Application());
+2 -3
View File
@@ -16,6 +16,7 @@ class NetworkFactory;
class ViewFactory; class ViewFactory;
class MainView; class MainView;
class StorageCache; class StorageCache;
class Version;
class Application class Application
: public MessageListener<MessageFinishedParsing> : public MessageListener<MessageFinishedParsing>
@@ -24,7 +25,7 @@ class Application
, public MessageListener<MessageSaveProject> , public MessageListener<MessageSaveProject>
{ {
public: public:
static std::shared_ptr<Application> create(ViewFactory* viewFactory, NetworkFactory* networkFactory); static std::shared_ptr<Application> create(const Version& version, ViewFactory* viewFactory, NetworkFactory* networkFactory);
static void loadSettings(); static void loadSettings();
~Application(); ~Application();
@@ -50,8 +51,6 @@ private:
std::shared_ptr<ComponentManager> m_componentManager; std::shared_ptr<ComponentManager> m_componentManager;
std::shared_ptr<IDECommunicationController> m_ideCommunicationController; std::shared_ptr<IDECommunicationController> m_ideCommunicationController;
bool m_isInitialParse;
}; };
#endif // APPLICATION_H #endif // APPLICATION_H
+2
View File
@@ -307,6 +307,8 @@ add_files(
utility/utility.h utility/utility.h
utility/utilityString.cpp utility/utilityString.cpp
utility/utilityString.h utility/utilityString.h
utility/Version.cpp
utility/Version.h
Application.cpp Application.cpp
Application.h Application.h
+9 -2
View File
@@ -1,8 +1,11 @@
#include "Project.h" #include "Project.h"
#include "utility/file/FileSystem.h"
#include "utility/logging/logging.h" #include "utility/logging/logging.h"
#include "utility/messaging/type/MessageFinishedParsing.h" #include "utility/messaging/type/MessageFinishedParsing.h"
#include "utility/scheduling/TaskGroupSequential.h"
#include "utility/utility.h" #include "utility/utility.h"
#include "utility/Version.h"
#include "data/access/StorageAccessProxy.h" #include "data/access/StorageAccessProxy.h"
#include "data/graph/Token.h" #include "data/graph/Token.h"
@@ -11,8 +14,6 @@
#include "data/TaskCleanStorage.h" #include "data/TaskCleanStorage.h"
#include "settings/ApplicationSettings.h" #include "settings/ApplicationSettings.h"
#include "settings/ProjectSettings.h" #include "settings/ProjectSettings.h"
#include "utility/file/FileSystem.h"
#include "utility/scheduling/TaskGroupSequential.h"
std::shared_ptr<Project> Project::create(StorageAccessProxy* storageAccessProxy) std::shared_ptr<Project> Project::create(StorageAccessProxy* storageAccessProxy)
{ {
@@ -144,6 +145,12 @@ void Project::setProjectSettingsFilePath(const FilePath& path)
FilePath dbPath = FilePath(path).replaceExtension("sqlite"); FilePath dbPath = FilePath(path).replaceExtension("sqlite");
m_storageWasLoaded = dbPath.exists(); m_storageWasLoaded = dbPath.exists();
m_storage = std::make_shared<Storage>(dbPath); m_storage = std::make_shared<Storage>(dbPath);
if (m_storageWasLoaded && m_storage->getVersion().isOlderStorageVersionThan(Version::getApplicationVersion()))
{
m_storage->clear();
m_storageWasLoaded = false;
}
} }
m_storageAccessProxy->setSubject(m_storage.get()); m_storageAccessProxy->setSubject(m_storage.get());
+64
View File
@@ -6,6 +6,7 @@
#include "utility/text/TextAccess.h" #include "utility/text/TextAccess.h"
#include "utility/utility.h" #include "utility/utility.h"
#include "utility/utilityString.h" #include "utility/utilityString.h"
#include "utility/Version.h"
SqliteStorage::SqliteStorage(const std::string& dbFilePath) SqliteStorage::SqliteStorage(const std::string& dbFilePath)
{ {
@@ -47,6 +48,23 @@ void SqliteStorage::rollbackTransaction()
m_database.execDML("ROLLBACK TRANSACTION;"); m_database.execDML("ROLLBACK TRANSACTION;");
} }
Version SqliteStorage::getVersion() const
{
std::string versionStr = getMetaValue("version");
if (versionStr.size())
{
return Version::fromString(versionStr);
}
return Version();
}
void SqliteStorage::setVersion(const Version& version)
{
insertOrUpdateMetaValue("version", version.toString());
}
Id SqliteStorage::addEdge(int type, Id sourceNodeId, Id targetNodeId) Id SqliteStorage::addEdge(int type, Id sourceNodeId, Id targetNodeId)
{ {
m_database.execDML( m_database.execDML(
@@ -708,10 +726,19 @@ void SqliteStorage::clearTables()
m_database.execDML("DROP TABLE IF EXISTS main.node;"); m_database.execDML("DROP TABLE IF EXISTS main.node;");
m_database.execDML("DROP TABLE IF EXISTS main.edge;"); m_database.execDML("DROP TABLE IF EXISTS main.edge;");
m_database.execDML("DROP TABLE IF EXISTS main.element;"); m_database.execDML("DROP TABLE IF EXISTS main.element;");
m_database.execDML("DROP TABLE IF EXISTS main.meta;");
} }
void SqliteStorage::setupTables() void SqliteStorage::setupTables()
{ {
m_database.execDML(
"CREATE TABLE IF NOT EXISTS meta("
"id INTEGER, "
"key TEXT, "
"value TEXT, "
"PRIMARY KEY(id));"
);
m_database.execDML( m_database.execDML(
"CREATE TABLE IF NOT EXISTS element(" "CREATE TABLE IF NOT EXISTS element("
"id INTEGER, " "id INTEGER, "
@@ -793,6 +820,43 @@ void SqliteStorage::setupTables()
); );
} }
bool SqliteStorage::hasTable(const std::string& tableName) const
{
CppSQLite3Query q = m_database.execQuery((
"SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "';"
).c_str());
if (!q.eof())
{
return q.getStringField(0, "") == tableName;
}
return false;
}
std::string SqliteStorage::getMetaValue(const std::string& key) const
{
if (hasTable("meta"))
{
CppSQLite3Query q = m_database.execQuery(("SELECT value FROM meta WHERE key = '" + key + "';").c_str());
if (!q.eof())
{
return q.getStringField(0, "");
}
}
return "";
}
void SqliteStorage::insertOrUpdateMetaValue(const std::string& key, const std::string& value)
{
m_database.execDML((
"INSERT OR REPLACE INTO meta(id, key, value) "
"VALUES( (SELECT id FROM meta WHERE key = '" + key + "'), '" + key + "', '" + value + "');"
).c_str());
}
StorageFile SqliteStorage::getFirstFile(const std::string& query) const StorageFile SqliteStorage::getFirstFile(const std::string& query) const
{ {
CppSQLite3Query q = m_database.execQuery(query.c_str()); CppSQLite3Query q = m_database.execQuery(query.c_str());
+9
View File
@@ -15,6 +15,7 @@
#include "data/StorageTypes.h" #include "data/StorageTypes.h"
class TextAccess; class TextAccess;
class Version;
class SqliteStorage class SqliteStorage
{ {
@@ -29,6 +30,9 @@ public:
void commitTransaction(); void commitTransaction();
void rollbackTransaction(); void rollbackTransaction();
Version getVersion() const;
void setVersion(const Version& version);
Id addEdge(int type, Id sourceNodeId, Id targetNodeId); Id addEdge(int type, Id sourceNodeId, Id targetNodeId);
Id addNode(int type, Id nameId, bool defined); Id addNode(int type, Id nameId, bool defined);
Id addFile(Id nameId, const std::string& filePath, const std::string& modificationTime); Id addFile(Id nameId, const std::string& filePath, const std::string& modificationTime);
@@ -107,6 +111,11 @@ private:
void clearTables(); void clearTables();
void setupTables(); void setupTables();
bool hasTable(const std::string& tableName) const;
std::string getMetaValue(const std::string& key) const;
void insertOrUpdateMetaValue(const std::string& key, const std::string& value);
StorageFile getFirstFile(const std::string& query) const; StorageFile getFirstFile(const std::string& query) const;
std::vector<StorageFile> getAllFiles(const std::string& query) const; std::vector<StorageFile> getAllFiles(const std::string& query) const;
StorageSourceLocation getFirstSourceLocation(const std::string& query) const; StorageSourceLocation getFirstSourceLocation(const std::string& query) const;
+7
View File
@@ -19,6 +19,7 @@
#include "data/parser/ParseVariable.h" #include "data/parser/ParseVariable.h"
#include "data/type/DataType.h" #include "data/type/DataType.h"
#include "settings/ApplicationSettings.h" #include "settings/ApplicationSettings.h"
#include "utility/Version.h"
Storage::Storage(const FilePath& dbPath) Storage::Storage(const FilePath& dbPath)
: m_sqliteStorage(dbPath.str()) : m_sqliteStorage(dbPath.str())
@@ -29,6 +30,11 @@ Storage::~Storage()
{ {
} }
Version Storage::getVersion() const
{
return m_sqliteStorage.getVersion();
}
void Storage::clear() void Storage::clear()
{ {
m_sqliteStorage.clear(); m_sqliteStorage.clear();
@@ -148,6 +154,7 @@ void Storage::logStats() const
void Storage::startParsing() void Storage::startParsing()
{ {
m_sqliteStorage.setVersion(Version::getApplicationVersion());
} }
void Storage::finishParsing() void Storage::finishParsing()
+2
View File
@@ -23,6 +23,8 @@ public:
Storage(const FilePath& dbPath); Storage(const FilePath& dbPath);
virtual ~Storage(); virtual ~Storage();
Version getVersion() const;
void clear(); void clear();
void clearCaches(); void clearCaches();
+114
View File
@@ -0,0 +1,114 @@
#include "utility/Version.h"
#include "utility/utilityString.h"
#include "utility/logging/logging.h"
Version Version::s_version;
Version Version::fromString(const std::string& versionString)
{
Version version;
std::vector<std::string> components = utility::splitToVector(versionString, '-');
if (components.size() != 3)
{
LOG_ERROR("Version string is invalid: " + versionString);
return version;
}
std::vector<std::string> numbers = utility::splitToVector(components[0], '.');
if (numbers.size() > 0)
{
version.m_majorNumber = std::stoi(numbers[0]);
}
if (numbers.size() > 1)
{
version.m_minorNumber = std::stoi(numbers[1]);
}
if (numbers.size() > 2)
{
version.m_refreshNumber = std::stoi(numbers[2]);
}
version.m_commitNumber = std::stoi(components[1]);
version.m_commitHash = components[2];
return version;
}
void Version::setApplicationVersion(const Version& version)
{
s_version = version;
}
const Version& Version::getApplicationVersion()
{
return s_version;
}
Version::Version()
: m_majorNumber(0)
, m_minorNumber(0)
, m_refreshNumber(0)
, m_commitNumber(0)
{
}
bool Version::operator<(const Version& other)
{
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::isOlderStorageVersionThan(const Version& other)
{
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
{
return false;
}
}
std::string Version::toString() const
{
std::stringstream ss;
ss << m_majorNumber << '.' << m_minorNumber << '.' << m_refreshNumber;
ss << '-' << m_commitNumber << '-' << m_commitHash;
return ss.str();
}
std::string Version::toDisplayString() const
{
std::stringstream ss;
ss << m_majorNumber << '.' << m_minorNumber << '.' << m_refreshNumber << '.' << m_commitNumber;
return ss.str();
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef VERSION_H
#define VERSION_H
#include <string>
class Version
{
public:
static Version fromString(const std::string& versionString);
static void setApplicationVersion(const Version& version);
static const Version& getApplicationVersion();
Version();
bool operator<(const Version& other);
bool isOlderStorageVersionThan(const Version& other);
std::string toString() const;
std::string toDisplayString() const;
private:
static Version s_version;
int m_majorNumber;
int m_minorNumber;
int m_refreshNumber;
int m_commitNumber;
std::string m_commitHash;
};
#endif // VERSION_H