summaryrefslogtreecommitdiffhomepage
path: root/migration/migration.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2016-09-09 08:51:25 +0200
committerStanislaw Halik <sthalik@misaki.pl>2016-09-09 15:00:58 +0200
commit6bc3fe31a3f354afc7be870a4a2d375ab6c746b6 (patch)
tree39b439b16cb872b3d982a6083a546456001d0f8e /migration/migration.cpp
parentcc6fc6577940df89c57db08743b181291c2a4b43 (diff)
add support for migrations
They're run from the UI thread so can even be interactive.
Diffstat (limited to 'migration/migration.cpp')
-rw-r--r--migration/migration.cpp129
1 files changed, 129 insertions, 0 deletions
diff --git a/migration/migration.cpp b/migration/migration.cpp
new file mode 100644
index 00000000..6e54de19
--- /dev/null
+++ b/migration/migration.cpp
@@ -0,0 +1,129 @@
+#include "migration.hpp"
+
+#include "options/options.hpp"
+#include "compat/util.hpp"
+
+#include <QString>
+#include <QSettings>
+#include <QDebug>
+
+#include <memory>
+
+namespace migrations {
+
+namespace detail {
+
+void migrator::register_migration(migration* m)
+{
+ migrations().push_back(m);
+}
+
+migrator::vec& migrator::migrations()
+{
+ static vec ret;
+ return ret;
+}
+
+QString migrator::last_migration_time()
+{
+ QString ret;
+
+ std::shared_ptr<QSettings> s(options::group::ini_file());
+
+ s->beginGroup("migrations");
+ ret = s->value("last-migration-at", "19700101_00").toString();
+ s->endGroup();
+
+ return ret;
+}
+
+QString migrator::time_after_migrations()
+{
+ const vec list = sorted_migrations();
+
+ if (list.size() == 0u)
+ return QStringLiteral("19700101_00");
+
+ QString ret = list[list.size() - 1]->unique_date();
+ ret += QStringLiteral("~");
+
+ return ret;
+}
+
+void migrator::set_last_migration_time(const QString& val)
+{
+ std::shared_ptr<QSettings> s(options::group::ini_file());
+
+ s->beginGroup("migrations");
+ s->setValue("last-migration-at", val);
+ s->endGroup();
+}
+
+migrator::vec migrator::sorted_migrations()
+{
+ vec list(migrations());
+ std::sort(list.begin(), list.end(), [](const mm x, const mm y) { return x->unique_date() < y->unique_date(); });
+ return list;
+}
+
+std::vector<QString> migrator::run()
+{
+ vec migrations = sorted_migrations();
+ vstr done;
+
+ const QString last_migration = last_migration_time();
+
+ qDebug() << "migration: config" << options::group::ini_filename() << "time" << last_migration;
+
+ for (migration* m_ : migrations)
+ {
+ migration& m(*m_);
+
+ const QString date = m.unique_date();
+
+ if (date <= last_migration)
+ continue;
+
+ if (m.should_run())
+ {
+ m.run();
+ done.push_back(m.name());
+ }
+ }
+
+ mark_config_as_not_needing_migration();
+
+ if (done.size())
+ {
+ qDebug() << "migration: done" << done.size() << "units";
+ for (const QString& name : done)
+ qDebug() << "--" << name;
+ qDebug() << "";
+ }
+
+ return done;
+}
+
+}
+
+migration::migration() {}
+migration::~migration() {}
+
+} // ns
+
+std::vector<QString> run_migrations()
+{
+ return migrations::detail::migrator::run();
+}
+
+void mark_config_as_not_needing_migration()
+{
+ using m = migrations::detail::migrator;
+
+ m::mark_config_as_not_needing_migration();
+}
+
+void migrations::detail::migrator::mark_config_as_not_needing_migration()
+{
+ set_last_migration_time(time_after_migrations());
+}