/**
  * @static
  * @param object $obj		a simple object with migration information (from a migration list)
  * @param string $method
  * @param array $options
  * @return mixed
  */
 public static function runMigration(&$obj, $method = 'up', array $options = array())
 {
     // if true, exceptions will not cause the script to exit
     $forced = isset($options['forced']) ? $options['forced'] : false;
     // if true, only echo back the SQL to be run
     $dryrun = isset($options['dryrun']) ? $options['dryrun'] : false;
     $db_config = MpmDbHelper::get_db_config();
     $migrations_table = $db_config->migrations_table;
     $filename = MpmStringHelper::getFilenameFromTimestamp($obj->timestamp);
     $classname = 'Migration_' . str_replace('.php', '', $filename);
     // make sure the file exists; if it doesn't, skip it but display a message
     $migration_file = MpmListHelper::get_migration_file(MPM_DB_PATH . $filename);
     if (!$migration_file) {
         echo "\n\tMigration " . $obj->timestamp . ' (ID ' . $obj->id . ') skipped - file missing.';
         return;
     }
     // file exists -- run the migration
     require_once $migration_file;
     $migration = new $classname();
     $msg = "# Performing " . strtoupper($method) . " migration " . $obj->timestamp . ' (ID ' . $obj->id . ')';
     if (!empty($migration->info)) {
         $msg .= "\n# {$migration->info}";
     }
     echo "\n" . $msg . " ... ";
     MpmSqlLogger::log_to_file("\n" . $msg . "\n");
     if ($migration instanceof MpmMigration) {
         $dbObj = MpmDbHelper::getPdoObj();
     } else {
         $dbObj = MpmDbHelper::getMysqliObj();
     }
     if ($dryrun) {
         $dbObj->dryrun = true;
     }
     $dbObj->beginTransaction();
     if ($method == 'down') {
         $active = 0;
     } else {
         $active = 1;
     }
     try {
         $migration->{$method}($dbObj);
         $sql = "UPDATE `{$migrations_table}` SET `active` = '{$active}' WHERE `id` = {$obj->id}";
         $dbObj->internal_exec($sql);
     } catch (Exception $e) {
         $dbObj->rollback();
         echo "failed!";
         echo "\n";
         $clw = MpmCommandLineWriter::getInstance();
         $clw->writeLine($e->getMessage(), 12);
         if (!$forced) {
             echo "\n\n";
             // Return with non-0 error code to notify external caller to stop the deployment
             exit(1);
         } else {
             return;
         }
     }
     $dbObj->commit();
     echo "done.";
 }
Example #2
0
 /** 
  * Object constructor.
  * 
  * @uses MpmDbHelper::test()
  * @uses MpmListHelper::mergeFilesWithDb()
  *
  * @param array $arguments an array of command line arguments (minus the first two elements which should already be shifted off from the MpmControllerFactory)
  *
  * @return MpmController
  */
 public function __construct($command = 'help', $arguments = array())
 {
     $this->arguments = $arguments;
     $this->command = $command;
     if ($command != 'help' && $command != 'init') {
         MpmDbHelper::test();
         MpmListHelper::mergeFilesWithDb();
     }
 }
 /**
  * Clears the migrations table and then rebuilds it.
  *
  * @uses MpmListHelper::mergeFilesWithDb()
  * @uses MpmDbHelper::doSingleRowSelect()
  *
  * @return void
  */
 public function reloadMigrations()
 {
     echo 'Clearing out existing migration data... ';
     $this->dbObj->exec('TRUNCATE TABLE `mpm_migrations`');
     echo 'done.', "\n\n", 'Rebuilding migration data... ';
     MpmListHelper::mergeFilesWithDb();
     echo 'done.', "\n";
     if ($this->initialMigrationTimestamp != null) {
         echo "\n", 'Updating initial migration timestamp to ', $this->initialMigrationTimestamp, '... ';
         $result = MpmDbHelper::doSingleRowSelect('SELECT COUNT(*) AS total FROM `mpm_migrations` WHERE `timestamp` = "' . $this->initialMigrationTimestamp . '"', $this->dbObj);
         if ($result->total == 1) {
             $this->dbObj->exec('UPDATE `mpm_migrations` SET `is_current` = 0');
             $this->dbObj->exec('UPDATE `mpm_migrations` SET `is_current` = 1 WHERE `timestamp` = "' . $this->initialMigrationTimestamp . '"');
             $this->dbObj->exec('UPDATE `mpm_migrations` SET `active` = 1 WHERE `timestamp` <= "' . $this->initialMigrationTimestamp . '"');
         }
         echo 'done.', "\n";
     }
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MPM_DB_PATH
  * @uses MpmDbHelper::test()
  * @uses MpmListHelper::getFiles()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::addText()
  * @uses MpmCommandLineWriter::write()
  * @uses MpmDbHelper::getMethod()
  * @uses MpmUpController::displayHelp()
  *
  * @return void
  */
 public function doAction()
 {
     // make sure system is init'ed
     MpmDbHelper::test();
     // get date stamp for use in generating filename
     $date_stamp = date('Y_m_d_H_i_s');
     $filename = $date_stamp . '.php';
     $vars = array('timestamp' => $date_stamp);
     //$classname = 'Migration_' . $date_stamp;
     // get list of files
     $files = MpmListHelper::getFiles();
     // if filename is taken, throw error
     if (in_array($filename, $files)) {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('Unable to obtain a unique filename for your migration.  Please try again in a few seconds.');
         $obj->write();
     }
     // create file
     if (MpmDbHelper::getMethod() == MPM_METHOD_PDO) {
         $file = MpmTemplateHelper::getTemplate('pdo_migration.txt', $vars);
     } else {
         $file = MpmTemplateHelper::getTemplate('mysqli_migration.txt', $vars);
     }
     // write the file
     $fp = fopen(MPM_DB_PATH . $filename, "w");
     if ($fp == false) {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('Unable to write new migration file.');
         $obj->write();
     }
     $success = fwrite($fp, $file);
     if ($success == false) {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('Unable to write new migration file.');
         $obj->write();
     }
     fclose($fp);
     // display success message
     $obj = MpmCommandLineWriter::getInstance();
     $obj->addText('New migration created: file /db/' . $filename);
     $obj->write();
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MpmDbHelper::test()
  * @uses MpmMigrationHelper::getCurrentMigrationTimestamp()
  * @uses MpmMigrationHelper::getCurrentMigrationNumber()
  * @uses MpmListHelper::getFullList()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::writeHeader()
  * @uses MpmCommandLineWriter::writeFooter()
  *
  * @return void
  */
 public function doAction()
 {
     // make sure we're init'd
     MpmDbHelper::test();
     // get latest timestamp
     $latest = MpmMigrationHelper::getCurrentMigrationTimestamp();
     // get latest number
     $num = MpmMigrationHelper::getCurrentMigrationNumber();
     // get list of migrations
     $list = MpmListHelper::getFullList();
     // get command line writer
     $clw = MpmCommandLineWriter::getInstance();
     $clw->writeHeader();
     if (empty($latest)) {
         echo "You have not performed any migrations yet.";
     } else {
         echo "You are currently on migration {$num} -- " . $latest . '.';
     }
     echo "\n";
     $clw->writeFooter();
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MpmListController::displayHelp()
  * @uses MpmListHelper::getFullList()
  * @uses MpmListHelper::getTotalMigrations()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::addText()
  * @uses MpmCommandLineWriter::write()
  * 
  * @return void
  */
 public function doAction()
 {
     $page = 1;
     $per_page = 30;
     if (isset($this->arguments[0])) {
         $page = $this->arguments[0];
     }
     if (isset($this->arguments[1])) {
         $per_page = $this->arguments[1];
     }
     if (!is_numeric($per_page)) {
         $per_page = 30;
     }
     if (!is_numeric($page)) {
         $page = 1;
     }
     $start_idx = ($page - 1) * $per_page;
     $list = MpmListHelper::getFullList($start_idx, $per_page);
     $total = MpmListHelper::getTotalMigrations();
     $total_pages = ceil($total / $per_page);
     $clw = MpmCommandLineWriter::getInstance();
     if ($total == 0) {
         $clw->addText('No migrations exist.');
     } else {
         $clw->addText("WARNING: Migration numbers may not be in order due to interleaving.", 4);
         $clw->addText(" ");
         $clw->addText("#\t\tTimestamp", 6);
         $clw->addText("=========================================", 4);
         foreach ($list as $obj) {
             if (strlen($obj->id) > 1) {
                 $clw->addText($obj->id . "\t" . $obj->timestamp, 6);
             } else {
                 $clw->addText($obj->id . "\t\t" . $obj->timestamp, 6);
             }
         }
         $clw->addText(" ");
         $clw->addText("Page {$page} of {$total_pages}, {$total} migrations in all.", 4);
     }
     $clw->write();
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MpmListController::displayHelp()
  * @uses MpmListHelper::getFullList()
  * @uses MpmListHelper::getTotalMigrations()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::addText()
  * @uses MpmCommandLineWriter::write()
  * 
  * @return void
  */
 public function doAction()
 {
     $page = 1;
     $per_page = 30;
     if (isset($this->arguments[0])) {
         $page = $this->arguments[0];
     }
     if (isset($this->arguments[1])) {
         $per_page = $this->arguments[1];
     }
     if (!is_numeric($per_page)) {
         $per_page = 30;
     }
     if (!is_numeric($page)) {
         $page = 1;
     }
     $start_idx = ($page - 1) * $per_page;
     $list = MpmListHelper::getFullList($start_idx, $per_page, true);
     $total = MpmListHelper::getTotalMigrations();
     $total_pages = ceil($total / $per_page);
     $clw = MpmCommandLineWriter::getInstance();
     if ($total == 0) {
         $clw->addText('No migrations exist.');
     } else {
         $clw->addText("WARNING: Migration numbers may not be in order due to interleaving.", 4);
         $clw->addText(" ");
         $clw->addText("#\t\tTimestamp\t\tDescription", 6);
         $clw->addText(str_repeat('=', 80), 4);
         foreach ($list as $obj) {
             // "highlight" the current migration
             $id = $obj->is_current ? "*" . $obj->id . "*" : $obj->id;
             $id_indent = strlen($id) > 1 ? "\t" : "\t\t";
             $clw->addText($id . $id_indent . $obj->timestamp . "\t" . $obj->info, 6);
         }
         $clw->addText(" ");
         $clw->addText("Page {$page} of {$total_pages}, {$total} migrations in all.", 4);
     }
     $clw->write();
 }
 /**
  * Returns an array of migration filenames.
  *
  * @uses MpmListHelper::getListOfFiles()
  *
  * @return array
  */
 public static function getFiles()
 {
     $files = array();
     $list = MpmListHelper::getListOfFiles();
     foreach ($list as $obj) {
         $files[] = $obj->filename;
     }
     return $files;
 }
Example #9
0
 /**
  * Clears the migrations table and then rebuilds it.
  *
  * @uses MpmListHelper::mergeFilesWithDb()
  * @uses MpmDbHelper::doSingleRowSelect()
  *
  * @return void
  */
 public function reloadMigrations()
 {
     if ($this->dryrun) {
         echo "No clear out existing migration data for dry-run.\n";
     } else {
         $db_config = MpmDbHelper::get_db_config();
         $migrations_table = $db_config->migrations_table;
         echo 'Clearing out existing migration data... ';
         $this->dbObj->internal_exec('TRUNCATE TABLE `' . $migrations_table . '`');
         echo 'done.', "\n\n", 'Rebuilding migration data... ';
         MpmListHelper::mergeFilesWithDb();
         echo 'done.', "\n";
         if ($this->initialMigrationTimestamp != null) {
             echo "\n", 'Updating initial migration timestamp to ', $this->initialMigrationTimestamp, '... ';
             $result = MpmDbHelper::doSingleRowSelect('SELECT COUNT(*) AS total FROM `' . $migrations_table . '` WHERE `timestamp` = "' . $this->initialMigrationTimestamp . '"', $this->dbObj);
             if ($result->total == 1) {
                 $this->dbObj->internal_exec('UPDATE `' . $migrations_table . '` SET `is_current` = 0');
                 $this->dbObj->internal_exec('UPDATE `' . $migrations_table . '` SET `is_current` = 1 WHERE `timestamp` = "' . $this->initialMigrationTimestamp . '"');
                 $this->dbObj->internal_exec('UPDATE `' . $migrations_table . '` SET `active` = 1 WHERE `timestamp` <= "' . $this->initialMigrationTimestamp . '"');
             }
             echo 'done.', "\n";
         }
     }
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MpmLatestController::displayHelp()
  * @uses MpmDbHelper::test()
  * @uses MpmMigrationHelper::getMigrationCount()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmMigrationHelper::getLatestMigration()
  * @uses MpmUpController::doAction()
  * 
  * @param bool $quiet supresses certain text when true
  *
  * @return void
  */
 public function doAction($quiet = false)
 {
     // make sure we're init'd
     MpmDbHelper::test();
     //get completed migrations from database
     //get migrations from file
     $oldest_migration_id = MpmMigrationHelper::getOldestMigration();
     $current_timestamp = MpmMigrationHelper::getCurrentMigrationTimestamp();
     $current_num = MpmMigrationHelper::getCurrentMigrationNumber();
     /*$latest_num =  MpmMigrationHelper::getLatestMigration();
       $latest_timestamp = MpmMigrationHelper::getTimestampFromId($latest_num);*/
     $db_migrations = MpmListHelper::getListFromDb($current_timestamp, 'down');
     $files = MpmListHelper::getListOfFiles();
     $all_file_timestamps = MpmListHelper::getTimestampArray($files);
     $file_timestamps = array();
     foreach ($all_file_timestamps as $timestamp) {
         if ($timestamp <= $current_timestamp) {
             $file_timestamps[] = $timestamp;
         }
     }
     end($all_file_timestamps);
     $latest_timestamp = current($all_file_timestamps);
     //compare timestamps that are in either array to timestamps that are in both arrays to find missing timestamps in either
     //$missing_merges = array_diff(array_unique( array_merge($file_timestamps,$db_migrations) ), array_intersect($file_timestamps,$db_migrations) );
     $missing_database = array_diff($file_timestamps, $db_migrations);
     $missing_files = array_diff($db_migrations, $file_timestamps);
     $missing_merges = array_merge($missing_files, $missing_database);
     sort($missing_merges);
     reset($missing_merges);
     $oldest_missing = current($missing_merges);
     $clw = MpmCommandLineWriter::getInstance();
     $clw->writeHeader();
     if (!$current_num) {
         echo 'You have not run any migrations';
     } else {
         echo "You are currently on migration {$current_num} -- " . $current_timestamp . '.';
     }
     if (!empty($missing_files)) {
         echo "\n\nCompleted migrations that are no longer in migrations directory\n----------\n";
         foreach ($missing_files as $file) {
             echo " {$file}\n";
         }
     }
     if (!empty($missing_database)) {
         echo "\n\nOld migrations that have not been run\n----------";
         foreach ($missing_database as $db) {
             echo "\n {$db}";
         }
     }
     if ($current_timestamp < $latest_timestamp) {
         echo "\nLatest migration is: {$latest_timestamp}.";
     }
     if ($oldest_missing && $oldest_missing <= $current_timestamp || $current_timestamp < $latest_timestamp) {
         echo "\n\n--- Migration Path --------------------------\n";
         $post_down_timestamp = $current_timestamp;
         if ($oldest_missing && $oldest_missing <= $current_timestamp) {
             //find target down timestamp
             $previous_migration = MpmMigrationHelper::getNextTimestamp($oldest_missing, 'down');
             if ($previous_migration) {
                 $post_down_timestamp = $previous_migration->timestamp;
                 echo "\n  Migrate down to: {$previous_migration->id} -- {$previous_migration->timestamp}";
             } else {
                 $post_down_timestamp = 0;
                 echo "\n  Remove all migrations";
             }
         }
         if ($post_down_timestamp < $latest_timestamp) {
             echo "\n  Migrate up to latest: {$latest_timestamp}";
         }
     } else {
         echo "\n\n  You are up to date";
     }
     /*$total_migrations = MpmMigrationHelper::getMigrationCount();
     		if ($total_migrations == 0)
     		{
     			$clw = MpmCommandLineWriter::getInstance();
     			$clw->addText('No migrations exist.');
     			$clw->write();
     			exit;
     		}
     		$to_id = MpmMigrationHelper::getLatestMigration();
     		$obj = new MpmUpController('up', array ( $to_id, $forced ));
        		$obj->doAction($quiet);
            */
     $clw->writeFooter();
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MpmLatestController::displayHelp()
  * @uses MpmDbHelper::test()
  * @uses MpmMigrationHelper::getMigrationCount()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmMigrationHelper::getLatestMigration()
  * @uses MpmUpController::doAction()
  * 
  * @param bool $quiet supresses certain text when true
  *
  * @return void
  */
 public function doAction($quiet = false)
 {
     // make sure we're init'd
     MpmDbHelper::test();
     $clw = MpmCommandLineWriter::getInstance();
     $clw->writeHeader();
     // are we forcing this?
     $forced = '';
     if (isset($this->arguments[0]) && strcasecmp($this->arguments[0], '--force') == 0) {
         $forced = '--force';
     }
     //get completed migrations from database
     //get migrations from file
     $oldest_migration_id = MpmMigrationHelper::getOldestMigration();
     $current_timestamp = MpmMigrationHelper::getCurrentMigrationTimestamp();
     $current_num = MpmMigrationHelper::getCurrentMigrationNumber();
     //$latest_num =  MpmMigrationHelper::getLatestMigration();
     //$latest_timestamp = MpmMigrationHelper::getTimestampFromId($latest_num);
     $db_migrations = MpmListHelper::getListFromDb($current_timestamp, 'down');
     $files = MpmListHelper::getListOfFiles();
     $all_file_timestamps = MpmListHelper::getTimestampArray($files);
     $file_timestamps = array();
     foreach ($all_file_timestamps as $timestamp) {
         if ($timestamp <= $current_timestamp) {
             $file_timestamps[] = $timestamp;
         }
     }
     end($file_timestamps);
     $latest_timestamp = current($file_timestamps);
     //compare timestamps that are in either array to timestamps that are in both arrays to find missing timestamps in either
     //$missing_merges = array_diff(array_unique( array_merge($file_timestamps,$db_migrations) ), array_intersect($file_timestamps,$db_migrations) );
     $missing_database = array_diff($file_timestamps, $db_migrations);
     $missing_files = array_diff($db_migrations, $file_timestamps);
     $missing_merges = array_merge($missing_files, $missing_database);
     sort($missing_merges);
     reset($missing_merges);
     $oldest_missing = current($missing_merges);
     try {
         if ($oldest_missing && $oldest_missing <= $current_timestamp) {
             $previous_migration = MpmMigrationHelper::getNextTimestamp($oldest_missing, 'down');
             if ($previous_migration) {
                 $target_down = $previous_migration->id;
             } else {
                 $target_down = -1;
             }
             $down = new MpmDownController('down', array($target_down, $forced, true));
             $down->doAction($quiet);
         }
         //merge files with database
         MpmListHelper::mergeFilesWithDb();
         $newest_id = MpmMigrationHelper::getLatestMigration();
         if ($newest_id) {
             $newest_timestamp = MpmMigrationHelper::getTimestampFromId($newest_id);
             $current_timestamp = MpmMigrationHelper::getCurrentMigrationTimestamp();
             if ($newest_timestamp > $current_timestamp) {
                 $obj = new MpmUpController('up', array($newest_id, $forced, true));
                 $obj->doAction($quiet);
             } else {
                 echo "\nUp to Date";
             }
         } else {
             echo "\nUp to Date";
         }
     } catch (Exception $e) {
         echo "\n\nERROR: " . $e->getMessage() . "\n\n";
         exit;
     }
     $clw->writeFooter();
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MPM_DB_PATH
  * @uses MpmDbHelper::test()
  * @uses MpmListHelper::getFiles()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::addText()
  * @uses MpmCommandLineWriter::write()
  * @uses MpmDbHelper::getMethod()
  * @uses MpmUpController::displayHelp()
  * 
  * @return void
  */
 public function doAction()
 {
     // make sure system is init'ed
     MpmDbHelper::test();
     // get date stamp for use in generating filename
     $date_stamp = date('Y_m_d_H_i_s');
     $filename = $date_stamp . '.php';
     $classname = 'Migration_' . $date_stamp;
     // get list of files
     $files = MpmListHelper::getFiles();
     // if filename is taken, throw error
     if (in_array($filename, $files)) {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('Unable to obtain a unique filename for your migration.  Please try again in a few seconds.');
         $obj->write();
     }
     // create file
     if (MpmDbHelper::getMethod() == MPM_METHOD_PDO) {
         $file = "<?php\n\n";
         $file .= 'class ' . $classname . ' extends MpmMigration' . "\n";
         $file .= "{\n\n";
         $file .= "\t" . 'public function up(PDO &$pdo)' . "\n";
         $file .= "\t{\n\t\t\n";
         $file .= "\t}\n\n";
         $file .= "\t" . 'public function down(PDO &$pdo)' . "\n";
         $file .= "\t{\n\t\t\n";
         $file .= "\t}\n\n";
         $file .= "}\n\n";
         $file .= "?>";
     } else {
         $file = "<?php\n\n";
         $file .= 'class ' . $classname . ' extends MpmMysqliMigration' . "\n";
         $file .= "{\n\n";
         $file .= "\t" . 'public function up(ExceptionalMysqli &$mysqli)' . "\n";
         $file .= "\t{\n\t\t\n";
         $file .= "\t}\n\n";
         $file .= "\t" . 'public function down(ExceptionalMysqli &$mysqli)' . "\n";
         $file .= "\t{\n\t\t\n";
         $file .= "\t}\n\n";
         $file .= "}\n\n";
         $file .= "?>";
     }
     // write the file
     $fp = fopen(MPM_DB_PATH . $filename, "w");
     if ($fp == false) {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('Unable to write new migration file.');
         $obj->write();
     }
     $success = fwrite($fp, $file);
     if ($success == false) {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('Unable to write new migration file.');
         $obj->write();
     }
     fclose($fp);
     // display success message
     $obj = MpmCommandLineWriter::getInstance();
     $obj->addText('New migration created: file /db/' . $filename);
     $obj->write();
 }