From dd2f9310c406c6b48c884ab938e4f457404a360d Mon Sep 17 00:00:00 2001 From: Danny van Kooten Date: Mon, 18 Nov 2024 10:23:59 +0100 Subject: [PATCH] change migration runner to update database version after each migration instead of only at the far end --- koko-analytics.php | 1 + .../1.0.2-add-cap-to-administrator-role.php | 9 -- ...column-types-add-cap-to-administrator.php} | 6 + src/class-migrations.php | 105 ++++++++---------- src/class-plugin.php | 30 ----- 5 files changed, 52 insertions(+), 99 deletions(-) delete mode 100644 migrations/1.0.2-add-cap-to-administrator-role.php rename migrations/{1.0.2-change-column-types.php => 1.0.2-change-column-types-add-cap-to-administrator.php} (87%) diff --git a/koko-analytics.php b/koko-analytics.php index 35df6fd1..3dbe7efc 100755 --- a/koko-analytics.php +++ b/koko-analytics.php @@ -51,6 +51,7 @@ add_action('admin_bar_menu', 'KokoAnalytics\admin_bar_menu', 40, 1); } +new Migrations('koko_analytics_version', KOKO_ANALYTICS_VERSION, KOKO_ANALYTICS_PLUGIN_DIR . '/migrations/'); new Dashboard(); $aggregator = new Aggregator(); new Plugin($aggregator); diff --git a/migrations/1.0.2-add-cap-to-administrator-role.php b/migrations/1.0.2-add-cap-to-administrator-role.php deleted file mode 100644 index 54bf60b3..00000000 --- a/migrations/1.0.2-add-cap-to-administrator-role.php +++ /dev/null @@ -1,9 +0,0 @@ -add_cap('view_koko_analytics'); - $role->add_cap('manage_koko_analytics'); -} diff --git a/migrations/1.0.2-change-column-types.php b/migrations/1.0.2-change-column-types-add-cap-to-administrator.php similarity index 87% rename from migrations/1.0.2-change-column-types.php rename to migrations/1.0.2-change-column-types-add-cap-to-administrator.php index caaf0c46..4d3c9872 100644 --- a/migrations/1.0.2-change-column-types.php +++ b/migrations/1.0.2-change-column-types-add-cap-to-administrator.php @@ -15,3 +15,9 @@ $wpdb->query("ALTER TABLE {$wpdb->prefix}koko_analytics_referrer_stats MODIFY pageviews MEDIUMINT UNSIGNED NOT NULL"); $wpdb->query("ALTER TABLE {$wpdb->prefix}koko_analytics_referrer_urls MODIFY id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT"); + +$role = get_role('administrator'); +if ($role) { + $role->add_cap('view_koko_analytics'); + $role->add_cap('manage_koko_analytics'); +} diff --git a/src/class-migrations.php b/src/class-migrations.php index fa909c53..b51515d9 100755 --- a/src/class-migrations.php +++ b/src/class-migrations.php @@ -12,96 +12,81 @@ class Migrations { - /** - * @var string - */ + protected $option_name; protected $version_from; - - /** - * @var string - */ protected $version_to; - - /** - * @var string - */ + protected $current_version; protected $migrations_dir; - /** - * @param string $from - * @param string $to - * @param string $migrations_dir - */ - public function __construct(string $from, string $to, string $migrations_dir) + public function __construct(string $option_name, string $version_to, string $migrations_dir) { - $this->version_from = $from; - $this->version_to = $to; + $this->option_name = $option_name; + $this->version_from = get_option($this->option_name, '0.0.0'); + $this->version_to = $version_to; $this->migrations_dir = $migrations_dir; + $this->hook(); } - /** - * Run the various upgrade routines, all the way up to the latest version - * @throws Exception - * @return bool - */ - public function run(): bool + public function hook(): void + { + add_action('init', [$this, 'maybe_run'], 5, 0); + } + + public function maybe_run(): void { - $migrations = $this->find_migrations(); + if (\version_compare($this->version_from, $this->version_to, '>=')) { + return; + } - foreach ($migrations as $migration_file) { - $this->run_migration($migration_file); + // check if migrations not already running + if (get_transient('koko_analytics_migrations_running')) { + return; } - return count($migrations) > 0; + set_transient('koko_analytics_migrations_running', true, 120); + $this->run(); + delete_transient('koko_analytics_migrations_running'); } /** - * @return array + * Run the various migration files, all the way up to the latest version */ - public function find_migrations(): array + protected function run(): void { $files = glob(rtrim($this->migrations_dir, '/') . '/*.php'); - - // return empty array when glob returns non-array value. if (! is_array($files)) { - return array(); + return; } - $migrations = array(); foreach ($files as $file) { - $migration = basename($file); - $parts = explode('-', $migration); - $version = $parts[0]; - - // check if migration file is not for an even higher version - if (version_compare($version, $this->version_to, '>')) { - continue; - } - - // check if we ran migration file before. - if (version_compare($this->version_from, $version, '>=')) { - continue; - } - - // schedule migration file for running - $migrations[] = $file; + $this->handle_file($file); } - - return $migrations; } /** - * Include a migration file and runs it. - * - * @param string $file - * @throws Exception + * @var string Absolute path to migration file */ - protected function run_migration(string $file) + protected function handle_file(string $file): void { - if (! \file_exists($file)) { - throw new Exception("Migration file $file does not exist."); + $migration = basename($file); + $parts = explode('-', $migration); + $migraton_version = $parts[0]; + + // check if migration file is not for an even higher version + if (version_compare($migraton_version, $this->version_to, '>')) { + return; } + // check if we ran migration file before. + if (version_compare($this->version_from, $migraton_version, '>=')) { + return; + } + + // run migration file include $file; + + // update option so later runs start after this migration + $this->version_from = $migraton_version; + update_option($this->option_name, $migraton_version, true); } } diff --git a/src/class-plugin.php b/src/class-plugin.php index a978a0e7..f4749121 100644 --- a/src/class-plugin.php +++ b/src/class-plugin.php @@ -23,7 +23,6 @@ public function __construct(Aggregator $aggregator) $this->aggregator = $aggregator; register_activation_hook(KOKO_ANALYTICS_PLUGIN_FILE, [$this, 'on_activation']); - add_action('init', [$this, 'maybe_run_db_migrations'], 5, 0); add_action('init', [$this, 'maybe_run_actions'], 20, 0); } @@ -62,33 +61,4 @@ public function maybe_run_actions(): void wp_safe_redirect(remove_query_arg('koko_analytics_action')); exit; } - - public function maybe_run_db_migrations(): void - { - $from_version = get_option('koko_analytics_version', '0.0.0'); - $to_version = KOKO_ANALYTICS_VERSION; - if (\version_compare($from_version, $to_version, '>=')) { - return; - } - - // check if migrations not already running - if (get_transient('koko_analytics_migrations_running')) { - return; - } - - // set transient to prevent migrations from running simultaneously - set_transient('koko_analytics_migrations_running', true, 120); - - // run upgrade migrations (if any) - $migrations_dir = KOKO_ANALYTICS_PLUGIN_DIR . '/migrations/'; - $migrations = new Migrations($from_version, $to_version, $migrations_dir); - $migrations->run(); - update_option('koko_analytics_version', $to_version, true); - - // delete transient once done - delete_transient('koko_analytics_migrations_running'); - - // make sure scheduled event is set up correctly - $this->aggregator->setup_scheduled_event(); - } }