/* Copyright (c) 2016, Stanislaw Halik * Permission to use, copy, modify, and/or distribute this * software for any purpose with or without fee is hereby granted, * provided that the above copyright notice and this permission * notice appear in all copies. */ #pragma once #include #include "export.hpp" #include #include #include namespace migrations { struct migration; class registrator; namespace detail { using mptr = std::shared_ptr; using mfun = std::function; struct migrator { static std::vector run(); static void add_migration_thunk(std::function& thunk); static void mark_profile_as_not_needing_migration(); private: static void sort_migrations(); static void register_migration(const mptr& m); static std::vector& migrations(); static void eval_thunks(); static QString last_migration_time(); static QString time_after_migrations(); static void set_last_migration_time(const QString& val); static int to_int(const QString& str, bool& ok); static std::vector& migration_list(); static std::vector& migration_thunks(); }; template struct registrator final { registrator() { mfun f { [] { return std::shared_ptr(new t); } }; migrator::add_migration_thunk(f); } }; } #define OPENTRACK_MIGRATION3(type, ctr) \ static const char init_##ctr = (::migrations::detail::registrator{}, 0); #define OPENTRACK_MIGRATION2(type, ctr) \ OPENTRACK_MIGRATION3(type, ctr) #define OPENTRACK_MIGRATION(type) \ OPENTRACK_MIGRATION2(type, __COUNTER__) struct migration { migration(); migration(const migration&) = delete; migration& operator=(const migration&) = delete; virtual ~migration(); virtual QString unique_date() const = 0; virtual QString name() const = 0; virtual bool should_run() const = 0; virtual void run() = 0; }; } // ns migrations OTR_MIGRATION_EXPORT std::vector run_migrations(); OTR_MIGRATION_EXPORT void mark_profile_as_not_needing_migration();