summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2018-04-28 17:19:27 +0200
committerStanislaw Halik <sthalik@misaki.pl>2018-04-28 21:27:35 +0200
commit526304a41970c1ad890cf81d92bb4b123e8608e7 (patch)
treec057d10fb1a45abf6d863796784a3e6c2c84b900
parentc3722c724101c2772a2ce6e91ee3ecac62204b6a (diff)
migration: use thunks
Otherwise we get QCoreApplication used before QApplication instance is created. Requesting the sorted migration data will force the thunks.
-rw-r--r--migration/migration.cpp103
-rw-r--r--migration/migration.hpp60
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();