Skip to content

Instantly share code, notes, and snippets.

@mindplay-dk
Last active December 25, 2015 02:29

Revisions

  1. mindplay-dk revised this gist Jan 15, 2014. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions upgrade.php
    Original file line number Diff line number Diff line change
    @@ -48,7 +48,7 @@ public function __construct()
    }

    /**
    * @param $path SQL file path
    * @param string $path SQL file path
    *
    * @return bool true on success, false on failure
    */
    @@ -161,10 +161,6 @@ public function run()

    $options = getopt('', array('init', 'dry', 'host:', 'user:', 'password:', 'database:', 'status:', 'mask:'));

    if (array_key_exists('init', $options)) {
    exit($task->init());
    }

    if (array_key_exists('dry', $options)) {
    unset($options['dry']);
    $task->dry = true;
    @@ -174,4 +170,8 @@ public function run()
    $task->$name = $value;
    }

    if (array_key_exists('init', $options)) {
    exit($task->init());
    }

    exit($task->run());
  2. mindplay-dk revised this gist Oct 30, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions upgrade.php
    Original file line number Diff line number Diff line change
    @@ -127,14 +127,14 @@ public function run()
    }

    foreach ($sql_files as $sql_file) {
    $num += 1;

    $filename = basename($sql_file);

    if (isset($applied[$filename])) {
    continue; // file already applied
    }

    $num += 1;

    echo "Applying upgrade: {$filename} ({$num} of {$total})\n";

    // load and attempt to execute:
  3. mindplay-dk created this gist Oct 9, 2013.
    177 changes: 177 additions & 0 deletions upgrade.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,177 @@
    <?php

    /**
    * Simple (forward migration) command-line SQL script runner for MySQL.
    *
    * To initialize the ".upgrade" file:
    *
    * php upgrade.php --init
    *
    * To flag all SQL files as applied (in the status file) without actually doing any work:
    *
    * php upgrade.php --dry
    *
    * To run migrations from "./updates/*.sql":
    *
    * php upgrade.php --user=foo --password=bar --database=mydb
    *
    * To run migrations from another folder:
    *
    * php upgrade.php --user=foo --password=bar --database=mydb --mask=../foo/bar/*.sql
    *
    * List of switches:
    *
    * --database={name} database name - required
    * --host={hostname} database hostname - default is "localhost"
    * --user={username} database username - default is "root"
    * --password={password} database password - default is empty
    * --status={path} path to ".upgrade" status file - defaults to "./.upgrade"
    * --mask={wildcard} path and wildcard of SQL files to apply - defaults to "./updates/*.sql"
    * --dry flag SQL files as applied (in the status file) but do not actually apply them
    * --init initialize (or rewrite) the status file
    */
    class UpgradeTask
    {
    public $init;
    public $user;
    public $password;
    public $database;
    public $status;
    public $mask;
    public $dry = false;

    public function __construct()
    {
    $this->host = 'localhost';
    $this->status = __DIR__ . DIRECTORY_SEPARATOR . '.upgrade';
    $this->mask = __DIR__ . DIRECTORY_SEPARATOR . 'updates' . DIRECTORY_SEPARATOR . '*.sql';
    }

    /**
    * @param $path SQL file path
    *
    * @return bool true on success, false on failure
    */
    private function runSQL($path)
    {
    $command = 'mysql'
    . ' --host=' . $this->host
    . ' --user=' . $this->user
    . ($this->password ? ' --password=' . $this->password : '')
    . ' --database=' . $this->database
    . ' --execute="SOURCE ' . $path . '"';

    passthru($command, $status);

    return $status === 0;
    }

    /**
    * Initialize (create or rewrite) the ".upgrade" status file
    *
    * @return int error level
    */
    public function init()
    {
    file_put_contents($this->status, '');

    echo "Initialized status file: {$this->status}";

    return 0;
    }

    /**
    * @return int error level
    */
    public function run()
    {
    /**
    * @var string $dot_path path to the "runtime/.upgrade" file used to track the last deployed updates
    */

    if (! file_exists($this->status)) {
    echo "Please run 'upgrade init' to initialize the 'runtime/.upgrade' status file.\n";
    return 1;
    }

    if (! isset($this->user, $this->database)) {
    echo "Must specify the username, password and database using command-line switches.\n";
    return 1;
    }

    $sql_path = dirname($this->mask);

    $sql_files = glob($this->mask);

    echo count($sql_files) . " files found in: {$sql_path}\n";

    $applied = array_flip(array_filter(explode("\n", file_get_contents($this->status))));

    if (count($sql_files) === 0) {
    echo "No files found...\n";
    return 0;
    }

    $num = 0;
    $total = count($sql_files) - count($applied);

    if ($total === 0) {
    echo "No pending upgrades...\n";
    return 0;
    }

    echo "{$total} upgrade(s) pending\n";

    if ($this->dry) {
    echo "*** DRY RUN: SQL files will not be applied.\n";
    }

    foreach ($sql_files as $sql_file) {
    $num += 1;

    $filename = basename($sql_file);

    if (isset($applied[$filename])) {
    continue; // file already applied
    }

    echo "Applying upgrade: {$filename} ({$num} of {$total})\n";

    // load and attempt to execute:

    if (! $this->dry) {
    if (! $this->runSQL($sql_file)) {
    echo "*** Aborting upgrades due to error!\n\n";
    return 10;
    }
    }

    // flag file as applied:

    $applied[$filename] = true;

    file_put_contents($this->status, implode("\n", array_keys($applied)));
    }

    return 0;
    }
    }

    $task = new UpgradeTask();

    $options = getopt('', array('init', 'dry', 'host:', 'user:', 'password:', 'database:', 'status:', 'mask:'));

    if (array_key_exists('init', $options)) {
    exit($task->init());
    }

    if (array_key_exists('dry', $options)) {
    unset($options['dry']);
    $task->dry = true;
    }

    foreach ($options as $name => $value) {
    $task->$name = $value;
    }

    exit($task->run());