Skip to content

Commit

Permalink
change migration runner to update database version after each migrati…
Browse files Browse the repository at this point in the history
…on instead of only at the far end
  • Loading branch information
dannyvankooten committed Nov 18, 2024
1 parent cc1d82c commit dd2f931
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 99 deletions.
1 change: 1 addition & 0 deletions koko-analytics.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 0 additions & 9 deletions migrations/1.0.2-add-cap-to-administrator-role.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
105 changes: 45 additions & 60 deletions src/class-migrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
30 changes: 0 additions & 30 deletions src/class-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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();
}
}

0 comments on commit dd2f931

Please sign in to comment.