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/FileLogger.h"
#include "utility/logging/LogManager.h"
#include "utility/Version.h"
#include "Application.h"
#include "includes.h" // defines 'void setup(int argc, char *argv[])'
@@ -31,6 +32,8 @@ void init()
int main(int argc, char *argv[])
{
Version version = Version::fromString(GIT_VERSION_NUMBER);
setup(argc, argv);
QApplication qtApp(argc, argv);
@@ -41,7 +44,7 @@ int main(int argc, char *argv[])
QtSplashScreen* splash = new QtSplashScreen(whitePixmap, Qt::WindowStaysOnTopHint);
splash->setMessage("Loading UI");
splash->setVersion(GIT_VERSION_NUMBER);
splash->setVersion(version.toDisplayString().c_str());
splash->exec(qtApp);
init();
@@ -49,7 +52,7 @@ int main(int argc, char *argv[])
QtViewFactory viewFactory;
QtNetworkFactory networkFactory;
std::shared_ptr<Application> app = Application::create(&viewFactory, &networkFactory);
std::shared_ptr<Application> app = Application::create(version, &viewFactory, &networkFactory);
if (splash)
{
+2 -2
View File
@@ -4,7 +4,7 @@
#include <QLineEdit>
#include <QLabel>
#include "version.h"
#include "utility/Version.h"
QtAbout::QtAbout(QWidget *parent)
: QtSettingsWindow(parent)
@@ -46,7 +46,7 @@ void QtAbout::populateForm(QFormLayout* layout)
acknowledgementsLabel->setAlignment(Qt::AlignTop);
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()
+6 -2
View File
@@ -5,6 +5,7 @@
#include "utility/messaging/type/MessageActivateNodes.h"
#include "utility/messaging/type/MessageStatus.h"
#include "utility/scheduling/TaskScheduler.h"
#include "utility/Version.h"
#include "component/view/GraphViewStyle.h"
#include "component/controller/NetworkFactory.h"
@@ -14,8 +15,11 @@
#include "settings/ApplicationSettings.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();
std::shared_ptr<Application> ptr(new Application());
+2 -3
View File
@@ -16,6 +16,7 @@ class NetworkFactory;
class ViewFactory;
class MainView;
class StorageCache;
class Version;
class Application
: public MessageListener<MessageFinishedParsing>
@@ -24,7 +25,7 @@ class Application
, public MessageListener<MessageSaveProject>
{
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();
~Application();
@@ -50,8 +51,6 @@ private:
std::shared_ptr<ComponentManager> m_componentManager;
std::shared_ptr<IDECommunicationController> m_ideCommunicationController;
bool m_isInitialParse;
};
#endif // APPLICATION_H
+3 -1
View File
@@ -58,7 +58,7 @@ add_files(
component/controller/FeatureController.h
component/controller/GraphController.cpp
component/controller/GraphController.h
component/controller/IDECommunicationController.cpp
component/controller/IDECommunicationController.h
component/controller/NetworkFactory.cpp
@@ -307,6 +307,8 @@ add_files(
utility/utility.h
utility/utilityString.cpp
utility/utilityString.h
utility/Version.cpp
utility/Version.h
Application.cpp
Application.h
+9 -2
View File
@@ -1,8 +1,11 @@
#include "Project.h"
#include "utility/file/FileSystem.h"
#include "utility/logging/logging.h"
#include "utility/messaging/type/MessageFinishedParsing.h"
#include "utility/scheduling/TaskGroupSequential.h"
#include "utility/utility.h"
#include "utility/Version.h"
#include "data/access/StorageAccessProxy.h"
#include "data/graph/Token.h"
@@ -11,8 +14,6 @@
#include "data/TaskCleanStorage.h"
#include "settings/ApplicationSettings.h"
#include "settings/ProjectSettings.h"
#include "utility/file/FileSystem.h"
#include "utility/scheduling/TaskGroupSequential.h"
std::shared_ptr<Project> Project::create(StorageAccessProxy* storageAccessProxy)
{
@@ -144,6 +145,12 @@ void Project::setProjectSettingsFilePath(const FilePath& path)
FilePath dbPath = FilePath(path).replaceExtension("sqlite");
m_storageWasLoaded = dbPath.exists();
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());
+64
View File
@@ -6,6 +6,7 @@
#include "utility/text/TextAccess.h"
#include "utility/utility.h"
#include "utility/utilityString.h"
#include "utility/Version.h"
SqliteStorage::SqliteStorage(const std::string& dbFilePath)
{
@@ -47,6 +48,23 @@ void SqliteStorage::rollbackTransaction()
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)
{
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.edge;");
m_database.execDML("DROP TABLE IF EXISTS main.element;");
m_database.execDML("DROP TABLE IF EXISTS main.meta;");
}
void SqliteStorage::setupTables()
{
m_database.execDML(
"CREATE TABLE IF NOT EXISTS meta("
"id INTEGER, "
"key TEXT, "
"value TEXT, "
"PRIMARY KEY(id));"
);
m_database.execDML(
"CREATE TABLE IF NOT EXISTS element("
"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
{
CppSQLite3Query q = m_database.execQuery(query.c_str());
+9
View File
@@ -15,6 +15,7 @@
#include "data/StorageTypes.h"
class TextAccess;
class Version;
class SqliteStorage
{
@@ -29,6 +30,9 @@ public:
void commitTransaction();
void rollbackTransaction();
Version getVersion() const;
void setVersion(const Version& version);
Id addEdge(int type, Id sourceNodeId, Id targetNodeId);
Id addNode(int type, Id nameId, bool defined);
Id addFile(Id nameId, const std::string& filePath, const std::string& modificationTime);
@@ -107,6 +111,11 @@ private:
void clearTables();
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;
std::vector<StorageFile> getAllFiles(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/type/DataType.h"
#include "settings/ApplicationSettings.h"
#include "utility/Version.h"
Storage::Storage(const FilePath& dbPath)
: m_sqliteStorage(dbPath.str())
@@ -29,6 +30,11 @@ Storage::~Storage()
{
}
Version Storage::getVersion() const
{
return m_sqliteStorage.getVersion();
}
void Storage::clear()
{
m_sqliteStorage.clear();
@@ -148,6 +154,7 @@ void Storage::logStats() const
void Storage::startParsing()
{
m_sqliteStorage.setVersion(Version::getApplicationVersion());
}
void Storage::finishParsing()
+2
View File
@@ -23,6 +23,8 @@ public:
Storage(const FilePath& dbPath);
virtual ~Storage();
Version getVersion() const;
void clear();
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