diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2018-04-28 17:19:27 +0200 | 
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2018-04-28 21:27:35 +0200 | 
| commit | 526304a41970c1ad890cf81d92bb4b123e8608e7 (patch) | |
| tree | c057d10fb1a45abf6d863796784a3e6c2c84b900 | |
| parent | c3722c724101c2772a2ce6e91ee3ecac62204b6a (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.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(); | 
