diff options
Diffstat (limited to 'migration')
-rw-r--r-- | migration/migration.cpp | 103 | ||||
-rw-r--r-- | migration/migration.hpp | 60 |
2 files changed, 94 insertions, 69 deletions
diff --git a/migration/migration.cpp b/migration/migration.cpp index b92d6384..569dff99 100644 --- a/migration/migration.cpp +++ b/migration/migration.cpp @@ -26,11 +26,14 @@ namespace migrations { namespace detail { -void migrator::register_migration(migration* m) +static std::vector<mptr> migration_list; +static std::vector<mfun> migration_thunks; + +void migrator::register_migration(mptr m) { const QString date = m->unique_date(); - for (migration* m2 : migrations()) + for (mptr m2 : migration_list) if (m2->unique_date() == date) std::abort(); @@ -64,13 +67,38 @@ void migrator::register_migration(migration* m) if (day_ < 1 || day_ > 31) abort(); - migrations().push_back(m); + migration_list.push_back(m); } -std::vector<migration*>& migrator::migrations() +void migrator::eval_thunks() { - static std::vector<migration*> ret; - return ret; + for (auto& fun : migration_thunks) + { + mptr m = fun(); + register_migration(m); + } + if (migration_thunks.size()) + sort_migrations(); + migration_thunks.clear(); +} + +void migrator::add_migration_thunk(mfun& thunk) +{ + migration_thunks.push_back(thunk); +} + +std::vector<mptr>& migrator::migrations() +{ + eval_thunks(); + return migration_list; +} + +void migrator::sort_migrations() +{ + std::sort(migration_list.begin(), migration_list.end(), + [](const mptr x, const mptr y) { + return x->unique_date() < y->unique_date(); + }); } QString migrator::last_migration_time() @@ -88,7 +116,7 @@ QString migrator::last_migration_time() QString migrator::time_after_migrations() { - const std::vector<migration*> list = sorted_migrations(); + const std::vector<mptr>& list = migrations(); if (list.size() == 0u) return QStringLiteral("19700101_00"); @@ -113,16 +141,6 @@ void migrator::set_last_migration_time(const QString& val) }); } -std::vector<migration*> migrator::sorted_migrations() -{ - std::vector<migration*> list(migrations()); - - using mm = migration*; - - std::sort(list.begin(), list.end(), [](const mm x, const mm y) { return x->unique_date() < y->unique_date(); }); - return list; -} - int migrator::to_int(const QString& str, bool& ok) { bool tmp = false; @@ -133,46 +151,37 @@ int migrator::to_int(const QString& str, bool& ok) std::vector<QString> migrator::run() { - std::vector<migration*> migrations = sorted_migrations(); std::vector<QString> done; const QString last_migration = last_migration_time(); - 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()) - { - for (const QString& name : done) - { - const QByteArray data = name.toUtf8(); - qDebug() << "migrate:" << data.constData(); - } - } + options::group::with_global_settings_object([&](QSettings&) { + options::group::with_settings_object([&](QSettings&) { + for (mptr m : migrations()) + { + const QString date = m->unique_date(); + + if (date <= last_migration) + continue; + + if (m->should_run()) + { + const QByteArray name = m->name().toUtf8(); + const QByteArray date = m->unique_date().toUtf8(); + qDebug() << "migrate:" << date.constData() << name.constData(); + m->run(); + done.push_back(m->name()); + } + } + mark_config_as_not_needing_migration(); + }); + }); return done; } } -migration::migration() {} -migration::~migration() {} - } // ns std::vector<QString> run_migrations() diff --git a/migration/migration.hpp b/migration/migration.hpp index 5f99de7a..e81e0ae5 100644 --- a/migration/migration.hpp +++ b/migration/migration.hpp @@ -13,25 +13,36 @@ #include "export.hpp" +#include <functional> + namespace migrations { -class migration; +struct migration; class registrator; namespace detail { - class migrator final + using mptr = std::shared_ptr<migration>; + using mfun = std::function<mptr ()>; + + struct migrator { - static std::vector<migration*>& migrations(); + static std::vector<QString> run(); + static void add_migration_thunk(std::function<mptr()>& thunk); + static void mark_config_as_not_needing_migration(); + + private: + static void sort_migrations(); + + static void register_migration(mptr m); + static std::vector<mptr>& migrations(); + + static void eval_thunks(); + static QString last_migration_time(); static QString time_after_migrations(); + static void set_last_migration_time(const QString& val); - migrator() = delete; - static std::vector<migration*> sorted_migrations(); static int to_int(const QString& str, bool& ok); - public: - static std::vector<QString> run(); - static void register_migration(migration* m); - static void mark_config_as_not_needing_migration(); }; template<typename t> @@ -39,8 +50,9 @@ namespace detail { { registrator() { - static t m; - migrator::register_migration(static_cast<migration*>(&m)); + mfun f { []() { return std::shared_ptr<migration>(new t); } }; + + migrator::add_migration_thunk(f); } }; } @@ -49,29 +61,33 @@ namespace detail { # error "oops, need __COUNTER__ extension for preprocessor" #endif -#define OPENTRACK_MIGRATION(type) static ::migrations::detail::registrator<type> opentrack_migration_registrator__ ## __COUNTER__ ## _gensym +#define MIGRATE_EXPAND2(x) x +#define MIGRATE_EXPAND1(x) MIGRATE_EXPAND2(x) +#define MIGRATE_EXPANDED2(type, ctr) \ + static ::migrations::detail::registrator<type> opentrack_migration_registrator_ ## ctr +#define MIGRATE_EXPANDED1(type, ctr) \ + MIGRATE_EXPANDED2(type, ctr) + +#define OPENTRACK_MIGRATION(type) \ + MIGRATE_EXPANDED1(type, MIGRATE_EXPAND1(__COUNTER__)) #ifdef Q_CREATOR_RUN # pragma clang diagnostic ignored "-Wweak-vtables" #endif -class migration +struct migration { - migration& operator=(const migration&) = delete; - migration(const migration&) = delete; - migration& operator=(migration&&) = delete; - migration(migration&&) = delete; - -public: - migration(); - virtual ~migration(); + migration() = default; + inline virtual ~migration(); virtual QString unique_date() const = 0; virtual QString name() const = 0; virtual bool should_run() const = 0; virtual void run() = 0; }; -} +inline migration::~migration() {} + +} // ns migrations OTR_MIGRATION_EXPORT std::vector<QString> run_migrations(); OTR_MIGRATION_EXPORT void mark_config_as_not_needing_migration(); |