/**
  * 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();
     // are we forcing this?
     $forced = '';
     if (isset($this->arguments[0]) && strcasecmp($this->arguments[0], '--force') == 0) {
         $forced = '--force';
     }
     try {
         $total_migrations = MpmMigrationHelper::getMigrationCount();
         if ($total_migrations == 0) {
             $clw = MpmCommandLineWriter::getInstance();
             $clw->addText('No migrations exist.');
             $clw->write();
         } else {
             $to_id = MpmMigrationHelper::getLatestMigration();
             $obj = new MpmUpController('up', array($to_id, $forced));
             $obj->doAction($quiet);
         }
     } catch (Exception $e) {
         echo "\n\nERROR: " . $e->getMessage() . "\n\n";
         exit;
     }
 }
 /** 
  * 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();
     }
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MpmDbHelper::test()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::addText()
  * @uses MpmCommandLineWriter::write()
  * @uses MpmCommandLineWriter::writeHeader()
  * @uses MpmCommandLineWriter::writeFooter()
  * @uses MpmBuildController::build()
  * @uses MPM_DB_PATH
  *
  * @return void
  */
 public function doAction()
 {
     // make sure system is init'ed
     MpmDbHelper::test();
     $this->clw = MpmCommandLineWriter::getInstance();
     $with_data = $forced = $dryrun = false;
     // are we adding a schema file?
     if (isset($this->arguments[0])) {
         if ($this->arguments[0] == 'add') {
             $this->add();
             // stop here
             exit;
         } else {
             if ($this->arguments[0] == 'with_data') {
                 $with_data = true;
                 // remove the first 'with_data'
                 array_shift($this->arguments);
             }
         }
     }
     // parse other optional arguments
     list($forced, $dryrun) = $this->parse_options($this->arguments);
     // make sure the schema file exists
     if (!file_exists(MPM_DB_PATH . 'schema.php')) {
         $this->clw->addText('The schema file does not exist.  Run this command with the "add" argument to create one (only a stub).');
         $this->clw->write();
         exit;
     }
     // make sure the test data file exists
     if ($with_data == true && !file_exists(MPM_DB_PATH . 'test_data.php')) {
         $this->clw->addText('The test data file does not exist.  Run this command with the "add" argument to create one (only a stub).');
         $this->clw->write();
         exit;
     }
     $this->clw->writeHeader();
     if (!$forced && !$dryrun) {
         echo "\nWARNING:  IF YOU CONTINUE, ALL TABLES IN YOUR DATABASE WILL BE ERASED!";
         echo "\nDO YOU WANT TO CONTINUE? [y/N] ";
         $answer = fgets(STDIN);
         $answer = trim($answer);
         $answer = strtolower($answer);
         if (empty($answer) || substr($answer, 0, 1) == 'n') {
             echo "\nABORTED!\n\n";
             $this->clw->writeFooter();
             exit;
         }
     }
     echo "\n";
     $this->build($with_data);
     $this->clw->writeFooter();
     exit;
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MpmRunController::displayHelp()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::addText()
  * @uses MpmCommandLineWriter::write()
  * @uses MpmCommandLineWriter::writeHeader()
  * @uses MpmCommandLineWriter::writeFooter()
  * @uses MpmMigrationHelper::doesMigrationExist() 
  * @uses MpmMigrationHelper::getMigrationObject()
  * @uses MpmMigrationHelper::runMigration()
  *
  * @return void
  */
 public function doAction()
 {
     // make sure system is init'ed
     MpmDbHelper::test();
     if (count($this->arguments) != 2) {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('ERROR: You must provide two arguments with this command.');
         $obj->addText(' ');
         $this->displayHelp();
         return;
     }
     // are we running the up or the down?
     $type = strtolower($this->arguments[0]);
     // what number do we want to run?
     $num = $this->arguments[1];
     if (!is_numeric($num)) {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('ERROR: Migration number must be numeric.');
         $obj->addText(' ');
         $this->displayHelp();
         return;
     }
     if ($type != 'up' && $type != 'down') {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('ERROR: Method must be either up or down.');
         $obj->addText(' ');
         $this->displayHelp();
         return;
     }
     // does this migration number exist?
     if (!MpmMigrationHelper::doesMigrationExist($num)) {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('ERROR: Migration ' . $num . ' does not exist.');
         $obj->write();
         return;
     }
     $row = MpmMigrationHelper::getMigrationObject($num);
     $obj = MpmCommandLineWriter::getInstance();
     $obj->writeHeader();
     MpmMigrationHelper::runMigration($row, $type);
     echo "\n";
     $obj->writeFooter();
 }
 /**
  * Returns the requested template file as a string
  *
  * @uses MPM_PATH
  *
  * @param string $file the filename of the template being requested
  * @param array	 $vars an array of key value pairs that correspond to variables that should be replaced in the template file
  *
  * @return string
  */
 public static function getTemplate($file, $vars = array())
 {
     // don't raise exception
     $db_config = MpmDbHelper::get_db_config(false);
     if (!$db_config) {
         $db_config = new stdClass();
         $db_config->db_path = MPM_PATH . '/lib/templates/';
     }
     // has the file been customized?
     if (file_exists($db_config->db_path . 'templates/' . $file)) {
         $contents = file_get_contents($db_config->db_path . 'templates/' . $file);
     } else {
         $contents = file_get_contents(MPM_PATH . '/lib/templates/' . $file);
     }
     foreach ($vars as $key => $val) {
         $contents = str_replace('@@' . $key . '@@', $val, $contents);
     }
     return $contents;
 }
 /**
  * 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 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();
     try {
         $total_migrations = MpmMigrationHelper::getMigrationCount();
         if ($total_migrations == 0) {
             $clw = MpmCommandLineWriter::getInstance();
             $clw->addText('No migrations exist.');
             $clw->write();
         } else {
             $to_id = MpmMigrationHelper::getLatestMigration();
             $obj = new MpmUpController('up', array_merge(array($to_id), $this->arguments));
             $obj->doAction($quiet);
         }
     } catch (Exception $e) {
         echo "\n\nERROR: " . $e->getMessage() . "\n\n";
         exit;
     }
 }
 /**
  * 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 MpmDbHelper::test()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::addText()
  * @uses MpmCommandLineWriter::write()
  * @uses MpmCommandLineWriter::writeHeader()
  * @uses MpmCommandLineWriter::writeFooter()
  * @uses MpmBuildController::build()
  * @uses MPM_DB_PATH
  *
  * @return void
  */
 public function doAction()
 {
     // make sure system is init'ed
     MpmDbHelper::test();
     $clw = MpmCommandLineWriter::getInstance();
     $forced = false;
     $with_data = false;
     // are we adding a schema file?
     if (isset($this->arguments[0]) && $this->arguments[0] == 'add') {
         // make sure the schema file doesn't exist
         if (file_exists(MPM_DB_PATH . 'schema.php') || file_exists(MPM_DB_PATH . 'test_data.php')) {
             $clw->addText('The schema and/or test data files already exist.  Delete them first if you want to use this option.');
             $clw->write();
             exit;
         }
         $file = MpmTemplateHelper::getTemplate('schema.txt');
         $test_data_file = MpmTemplateHelper::getTemplate('test_data.txt');
         $fp = fopen(MPM_DB_PATH . 'schema.php', "w");
         if ($fp == false) {
             echo "\nUnable to write to file.  Initialization failed!\n\n";
             exit;
         }
         $success = fwrite($fp, $file);
         if ($success == false) {
             echo "\nUnable to write to file.  Initialization failed!\n\n";
             exit;
         }
         fclose($fp);
         $fp = fopen(MPM_DB_PATH . 'test_data.php', "w");
         if ($fp == false) {
             echo "\nUnable to write to file.  Initialization failed!\n\n";
             exit;
         }
         $success = fwrite($fp, $test_data_file);
         if ($success == false) {
             echo "\nUnable to write to file.  Initialization failed!\n\n";
             exit;
         }
         fclose($fp);
         $clw->addText('File ' . MPM_DB_PATH . 'schema.php has been created.');
         $clw->addText('File ' . MPM_DB_PATH . 'test_data.php has been created.');
         $clw->write();
         exit;
     } else {
         if (isset($this->arguments[0]) && $this->arguments[0] == 'with_data') {
             $with_data = true;
         } else {
             if (isset($this->arguments[0]) && $this->arguments[0] == '--force') {
                 $forced = true;
             }
         }
     }
     // make sure the schema file exists
     if (!file_exists(MPM_DB_PATH . 'schema.php')) {
         $clw->addText('The schema file does not exist.  Run this command with the "add" argument to create one (only a stub).');
         $clw->write();
         exit;
     }
     // make sure the test data file exists
     if ($with_data == true && !file_exists(MPM_DB_PATH . 'test_data.php')) {
         $clw->addText('The test data file does not exist.  Run this command with the "add" argument to create one (only a stub).');
         $clw->write();
         exit;
     }
     $clw->writeHeader();
     if (!$forced) {
         echo "\nWARNING:  IF YOU CONTINUE, ALL TABLES IN YOUR DATABASE WILL BE ERASED!";
         echo "\nDO YOU WANT TO CONTINUE? [y/N] ";
         $answer = fgets(STDIN);
         $answer = trim($answer);
         $answer = strtolower($answer);
         if (empty($answer) || substr($answer, 0, 1) == 'n') {
             echo "\nABORTED!\n\n";
             $clw->writeFooter();
             exit;
         }
     }
     echo "\n";
     $this->build($with_data);
     $clw->writeFooter();
     exit;
 }
 /**
  * Fetches a list of migrations which have already been run.
  *
  * @uses MpmDbHelper::doSingleRowSelect()
  * @uses MpmDbHelper::doMultiRowSelect()
  *
  * @param string $latestTimestamp the current timestamp of the migration run last
  * @param string $direction the way we are migrating; should either be up or down
  *
  * @return array
  */
 public static function getListFromDb($latestTimestamp, $direction = 'up')
 {
     $db_config = $GLOBALS['db_config'];
     $migrations_table = $db_config->migrations_table;
     if ($direction == 'down') {
         $sql = "SELECT * FROM `{$migrations_table}` WHERE `timestamp` <= '{$latestTimestamp}' AND `active` = 1";
         $countSql = "SELECT COUNT(*) as total FROM `{$migrations_table}` WHERE `timestamp` <= '{$latestTimestamp}' AND `active` = 1";
     } else {
         $sql = "SELECT * FROM `{$migrations_table}` WHERE `timestamp` >= '{$latestTimestamp}' AND `active` = 1";
         $countSql = "SELECT COUNT(*) as total FROM `{$migrations_table}` WHERE `timestamp` >= '{$latestTimestamp}' AND `active` = 1";
     }
     $list = array();
     $countObj = MpmDbHelper::doSingleRowSelect($countSql);
     if ($countObj->total > 0) {
         $results = MpmDbHelper::doMultiRowSelect($sql);
         foreach ($results as $obj) {
             $list[] = $obj->timestamp;
         }
     }
     return $list;
 }
 /**
  * Returns a migration object; this object contains all data stored in the DB for the particular migration ID.
  *
  * @uses MpmDbHelper::getMethod()
  * @uses MpmDbHelper::getDbObj()
  * @uses MPM_METHOD_MYSQLI
  * @uses MPM_METHOD_PDO
  *
  * @param int $id the ID of the migration
  *
  * @return object
  */
 public static function getMigrationObject($id)
 {
     $sql = "SELECT * FROM `mpm_migrations` WHERE `id` = '{$id}'";
     $obj = null;
     try {
         switch (MpmDbHelper::getMethod()) {
             case MPM_METHOD_PDO:
                 $pdo = MpmDbHelper::getDbObj();
                 $stmt = $pdo->query($sql);
                 $obj = $stmt->fetch(PDO::FETCH_OBJ);
                 break;
             case MPM_METHOD_MYSQLI:
                 $mysqli = MpmDbHelper::getDbObj();
                 $stmt = $mysqli->query($sql);
                 $obj = $stmt->fetch_object();
                 break;
         }
     } catch (Exception $e) {
         echo "\n\nERROR: " . $e->getMessage() . "\n\n";
         exit;
     }
     return $obj;
 }
Beispiel #12
0
 /**
  * Clears the migrations table and then rebuilds it.
  *
  * @uses MpmListHelper::mergeFilesWithDb()
  * @uses MpmDbHelper::doSingleRowSelect()
  *
  * @return void
  */
 public function reloadMigrations()
 {
     $db_config = $GLOBALS['db_config'];
     $migrations_table = $db_config->migrations_table;
     echo 'Clearing out existing migration data... ';
     $this->dbObj->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->exec('UPDATE `' . $migrations_table . '` SET `is_current` = 0');
             $this->dbObj->exec('UPDATE `' . $migrations_table . '` SET `is_current` = 1 WHERE `timestamp` = "' . $this->initialMigrationTimestamp . '"');
             $this->dbObj->exec('UPDATE `' . $migrations_table . '` SET `active` = 1 WHERE `timestamp` <= "' . $this->initialMigrationTimestamp . '"');
         }
         echo 'done.', "\n";
     }
 }
 /**
  * @param $migrations_table
  */
 public function init_migration_db_table($migrations_table)
 {
     echo "\nlooking for existing migrations table... ";
     try {
         if (false === MpmDbHelper::checkForDbTable()) {
             echo "not found.\n";
             echo "Creating migrations table... ";
             $sql1 = "CREATE TABLE IF NOT EXISTS `{$migrations_table}` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `timestamp` DATETIME NOT NULL, `active` TINYINT(1) NOT NULL DEFAULT 0, `is_current` TINYINT(1) NOT NULL DEFAULT 0, PRIMARY KEY ( `id` ) ) ENGINE=InnoDB";
             $sql2 = "CREATE UNIQUE INDEX `TIMESTAMP_INDEX` ON `{$migrations_table}` ( `timestamp` )";
             if (MpmDbHelper::getMethod() == MPM_METHOD_PDO) {
                 $pdo = MpmDbHelper::getDbObj();
                 $pdo->beginTransaction();
                 try {
                     $pdo->internal_exec($sql1);
                     $pdo->internal_exec($sql2);
                 } catch (Exception $e) {
                     $pdo->rollback();
                     echo "failure!\n\n" . 'Unable to create required ' . $migrations_table . ' table:' . $e->getMessage();
                     echo "\n\n";
                     exit;
                 }
                 $pdo->commit();
             } else {
                 $mysqli = MpmDbHelper::getDbObj();
                 $mysqli->internal_exec($sql1);
                 if ($mysqli->errno) {
                     echo "failure!\n\n" . 'Unable to create required ' . $migrations_table . ' table:' . $mysqli->error;
                     echo "\n\n";
                     exit;
                 }
                 $mysqli->internal_exec($sql2);
                 if ($mysqli->errno) {
                     echo "failure!\n\n" . 'Unable to create required ' . $migrations_table . ' table:' . $mysqli->error;
                     echo "\n\n";
                     exit;
                 }
             }
             echo "done.\n\n";
         } else {
             echo "found.\n\n";
         }
     } catch (Exception $e) {
         echo "failure!\n\nUnable to complete initialization: " . $e->getMessage() . "\n\n";
         echo "Check your database settings and re-run init.\n\n";
         exit;
     }
 }
 /**
  * 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();
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MPM_PATH
  * @uses MPM_METHOD_PDO
  * @uses MPM_METHOD_MYSQLI
  * @uses MpmDbHelper::checkForDbTable()
  * @uses MpmDbHelper::getDbObj()
  * @uses MpmDbHelper::getMethod()
  * @uses MpmInitController::displayHelp()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::writeHeader()
  * @uses MpmCommandLineWriter::writeFooter()
  * @uses MpmBuildController::build()
  * 
  * @return void
  */
 public function doAction()
 {
     $user = '';
     $dbname = '';
     $port = '';
     $db_path = '';
     $method = 0;
     $clw = MpmCommandLineWriter::getInstance();
     $clw->writeHeader();
     echo "Defaults are in brackets ([]).  To accept the default, simply press ENTER.\n\n";
     if (file_exists(MPM_PATH . '/config/db_config.php')) {
         echo "\nWARNING:  IF YOU CONTINUE, YOUR EXISTING MIGRATION SETUP WILL BE ERASED!";
         echo "\nThis will not affect your existing migrations or database, but \ncould cause your future migrations to fail.";
         echo "\nDO YOU WANT TO CONTINUE? [y/N] ";
         $answer = fgets(STDIN);
         $answer = trim($answer);
         $answer = strtolower($answer);
         if (empty($answer) || substr($answer, 0, 1) == 'n') {
             echo "\nABORTED!\n\n";
             $clw->writeFooter();
             exit;
         } else {
             require MPM_PATH . '/config/db_config.php';
         }
     }
     do {
         echo "\nWhich method would you like to use to connect to\nthe database?  " . MPM_METHOD_PDO . "=PDO or " . MPM_METHOD_MYSQLI . "=MySQLi";
         if (isset($db_config)) {
             echo " [" . $db_config->method . "]";
         }
         echo ": ";
         $method = fgets(STDIN);
         $method = trim($method);
         if (!is_numeric($method)) {
             $method = 0;
         }
         if (empty($method) && isset($db_config)) {
             $method = $db_config->method;
         }
     } while ($method < MPM_METHOD_PDO || $method > MPM_METHOD_MYSQLI || $method == 0);
     echo "\nEnter your MySQL database hostname or IP address [";
     if (isset($db_config)) {
         echo $db_config->host;
     } else {
         echo 'localhost';
     }
     echo ']: ';
     $host = fgets(STDIN);
     $host = trim($host);
     if (empty($host)) {
         if (isset($db_config)) {
             $host = $db_config->host;
         } else {
             $host = 'localhost';
         }
     }
     while (empty($port)) {
         echo "\nEnter your MySQL database port [";
         if (isset($db_config)) {
             echo $db_config->port;
         } else {
             echo '3306';
         }
         echo ']: ';
         $port = fgets(STDIN);
         $port = trim($port);
         if (empty($port)) {
             $port = 3306;
         }
         if (!is_numeric($port)) {
             $port = '';
         }
     }
     while (empty($user)) {
         echo "\nEnter your MySQL database username";
         if (isset($db_config)) {
             echo ' [', $db_config->user, ']';
         }
         echo ': ';
         $user = fgets(STDIN);
         $user = trim($user);
         if (empty($user) && isset($db_config)) {
             $user = $db_config->user;
         }
     }
     echo "\nEnter your MySQL database password (enter - for no password) [";
     if (isset($db_config)) {
         echo $db_config->pass;
     }
     echo ']: ';
     $pass = fgets(STDIN);
     $pass = trim($pass);
     if (empty($pass) && isset($db_config)) {
         $pass = $db_config->pass;
     } else {
         if ($pass == '-') {
             $pass = '';
         }
     }
     while (empty($dbname)) {
         echo "\nEnter your MySQL database name";
         if (isset($db_config)) {
             echo ' [', $db_config->name, ']';
         }
         echo ': ';
         $dbname = fgets(STDIN);
         $dbname = trim($dbname);
         if (empty($dbname) && isset($db_config)) {
             $dbname = $db_config->name;
         }
     }
     echo "\nEnter the directory where you'd like to store your\nmigration files [";
     if (isset($db_config)) {
         echo $db_config->db_path;
     } else {
         echo MPM_PATH . '/db/';
     }
     echo ']: ';
     $db_path = fgets(STDIN);
     $db_path = trim($db_path);
     if (empty($db_path) && isset($db_config)) {
         $db_path = $db_config->db_path;
     } else {
         if (empty($db_path) && !isset($db_config)) {
             $db_path = MPM_PATH . '/db/';
         }
     }
     if (substr($db_path, strlen($db_path) - 1, 1) != '/') {
         $db_path .= '/';
     }
     $method = (int) $method;
     if (file_exists($db_path . 'schema.php')) {
         echo "\nPerform build of database after initialization (builds schema\nand runs all existing migrations) [y/N]: ";
         $do_build = fgets(STDIN);
         $do_build = trim($do_build);
         $doBuild = false;
         if (strcasecmp(substr($do_build, 0, 1), 'y') == 0) {
             $doBuild = true;
         }
     }
     $file = '<?php' . "\n\n";
     $file .= '$db_config = (object) array();' . "\n";
     $file .= '$db_config->host = ' . "'" . $host . "';" . "\n";
     $file .= '$db_config->port = ' . "'" . $port . "';" . "\n";
     $file .= '$db_config->user = '******'" . $user . "';" . "\n";
     $file .= '$db_config->pass = '******'" . $pass . "';" . "\n";
     $file .= '$db_config->name = ' . "'" . $dbname . "';" . "\n";
     $file .= '$db_config->db_path = ' . "'" . $db_path . "';" . "\n";
     $file .= '$db_config->method = ' . $method . ";" . "\n";
     $file .= "\n?>";
     if (file_exists(MPM_PATH . '/config/db_config.php')) {
         unlink(MPM_PATH . '/config/db_config.php');
     }
     $fp = fopen(MPM_PATH . '/config/db_config.php', "w");
     if ($fp == false) {
         echo "\nUnable to write to file.  Initialization failed!\n\n";
         exit;
     }
     $success = fwrite($fp, $file);
     if ($success == false) {
         echo "\nUnable to write to file.  Initialization failed!\n\n";
         exit;
     }
     fclose($fp);
     require MPM_PATH . '/config/db_config.php';
     $GLOBALS['db_config'] = $db_config;
     echo "\nConfiguration saved... looking for existing migrations table... ";
     try {
         if (false === MpmDbHelper::checkForDbTable()) {
             echo "not found.\n";
             echo "Creating migrations table... ";
             $sql1 = "CREATE TABLE IF NOT EXISTS `mpm_migrations` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `timestamp` DATETIME NOT NULL, `active` TINYINT(1) NOT NULL DEFAULT 0, `is_current` TINYINT(1) NOT NULL DEFAULT 0, PRIMARY KEY ( `id` ) ) ENGINE=InnoDB";
             $sql2 = "CREATE UNIQUE INDEX `TIMESTAMP_INDEX` ON `mpm_migrations` ( `timestamp` )";
             if (MpmDbHelper::getMethod() == MPM_METHOD_PDO) {
                 $pdo = MpmDbHelper::getDbObj();
                 $pdo->beginTransaction();
                 try {
                     $pdo->exec($sql1);
                     $pdo->exec($sql2);
                 } catch (Exception $e) {
                     $pdo->rollback();
                     echo "failure!\n\n" . 'Unable to create required mpm_migrations table:' . $e->getMessage();
                     echo "\n\n";
                     exit;
                 }
                 $pdo->commit();
             } else {
                 $mysqli = MpmDbHelper::getDbObj();
                 $mysqli->query($sql1);
                 if ($mysqli->errno) {
                     echo "failure!\n\n" . 'Unable to create required mpm_migrations table:' . $mysqli->error;
                     echo "\n\n";
                     exit;
                 }
                 $mysqli->query($sql2);
                 if ($mysqli->errno) {
                     echo "failure!\n\n" . 'Unable to create required mpm_migrations table:' . $mysqli->error;
                     echo "\n\n";
                     exit;
                 }
             }
             echo "done.\n\n";
         } else {
             echo "found.\n\n";
         }
     } catch (Exception $e) {
         echo "failure!\n\nUnable to complete initialization: " . $e->getMessage() . "\n\n";
         echo "Check your database settings and re-run init.\n\n";
         exit;
     }
     if (isset($doBuild) && $doBuild === true) {
         $obj = new MpmBuildController();
         $obj->build();
         echo "\n\n";
     }
     echo "Initalization complete!  Type 'php migrate.php help' for a list of commands.\n\n";
     $clw->writeFooter();
     exit;
 }
 /**
  * Returns an array of all the tables in the database.
  *
  * @uses MpmDbHelper::getDbObj()
  * @uses MpmDbHelper::getMethod()
  *
  * @return array
  */
 public static function getTables(&$dbObj = null)
 {
     if ($dbObj == null) {
         $dbObj = MpmDbHelper::getDbObj();
     }
     $sql = "SHOW TABLES";
     $tables = array();
     switch (MpmDbHelper::getMethod()) {
         case MPM_METHOD_PDO:
             try {
                 foreach ($dbObj->query($sql) as $row) {
                     $tables[] = $row[0];
                 }
             } catch (Exception $e) {
             }
             break;
         case MPM_METHOD_MYSQLI:
             try {
                 $result = $dbObj->query($sql);
                 while ($row = $result->fetch_array()) {
                     $tables[] = $row[0];
                 }
             } catch (Exception $e) {
             }
             break;
     }
     return $tables;
 }
 /**
  * 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 MpmDbHelper::test()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::addText()
  * @uses MpmCommandLineWriter::write()
  * @uses MpmCommandLineWriter::writeHeader()
  * @uses MpmCommandLineWriter::writeFooter()
  * @uses MpmBuildController::build()
  * @uses MPM_DB_PATH
  * 
  * @return void
  */
 public function doAction()
 {
     // make sure system is init'ed
     MpmDbHelper::test();
     $clw = MpmCommandLineWriter::getInstance();
     $forced = false;
     // are we adding a schema file?
     if (isset($this->arguments[0]) && $this->arguments[0] == 'add') {
         // make sure the schema file doesn't exist
         if (file_exists(MPM_DB_PATH . 'schema.php')) {
             $clw->addText('The schema file already exists.  Delete it first if you want to use this option.');
             $clw->write();
             exit;
         }
         $db = MpmDbHelper::getDbObj();
         $result = $db->exec("show tables");
         $schema_queries = array();
         while ($row = $result->fetch_array(MYSQLI_NUM)) {
             if ($row[0] === 'mpm_migrations') {
                 continue;
             }
             $tabres = $db->exec("show create table {$row[0]}");
             $tabrow = $tabres->fetch_array(MYSQLI_NUM);
             $schema_queries[] = $tabrow[1];
         }
         $file = "<?php\n";
         $file .= "/**\n";
         $file .= " * This file houses the MpmInitialSchema class.\n";
         $file .= " *\n";
         $file .= " * This file may be deleted if you do not wish to use the build command or build on init features.\n";
         $file .= " *\n";
         $file .= " * @package    mysql_php_migrations\n";
         $file .= " * @subpackage Classes\n";
         $file .= " * @license    http://www.opensource.org/licenses/bsd-license.php  The New BSD License\n";
         $file .= " * @link       http://code.google.com/p/mysql-php-migrations/\n";
         $file .= " */\n";
         $file .= "\n";
         $file .= "/**\n";
         $file .= " * The MpmInitialSchema class is used to build an initial database structure.\n";
         $file .= " *\n";
         $file .= " * @package    mysql_php_migrations\n";
         $file .= " * @subpackage Classes\n";
         $file .= " */\n";
         $file .= "class MpmInitialSchema extends MpmSchema\n";
         $file .= "{\n";
         $file .= "\n";
         $file .= "\t" . 'protected $tables = array(' . "\n";
         $file .= "\t\"" . implode("\",\n\t\"", $schema_queries);
         $file .= "\"\n\t);\n\n";
         $file .= "\tpublic function __construct()\n";
         $file .= "\t{\n";
         $file .= "\t\tparent::__construct();\n";
         $file .= "\n";
         $file .= "\t\t/* If you build your initial schema having already executed a number of migrations,\n";
         $file .= "\t\t* you should set the initial migration timestamp.\n";
         $file .= "\t\t*\n";
         $file .= "\t\t* The initial migration timestamp will be set to active and this migration and all\n";
         $file .= "\t\t* previous will be ignored when the build command is used.\n";
         $file .= "\t\t*\n";
         $file .= "\t\t* EX:\n";
         $file .= "\t\t*\n";
         $file .= "\t\t* " . '$' . "this->initialMigrationTimestamp = '2009-08-01 15:23:44';\n";
         $file .= "\t\t*/\n";
         $file .= "\t\t" . '$' . "this->initialMigrationTimestamp = date('Y-m-d H:i:s');\n";
         $file .= "\t}\n";
         $file .= "\n";
         $file .= "\tpublic function build()\n";
         $file .= " \t{\n";
         $file .= "\t\t/* Add the queries needed to build the initial structure of your database.\n";
         $file .= "\t\t*\n";
         $file .= "\t\t* EX:\n";
         $file .= "\t\t*\n";
         $file .= "\t\t* " . '$' . "this->dbObj->exec('CREATE TABLE `testing` ( `id` INT(11) AUTO_INCREMENT NOT NULL, `vals` INT(11) NOT NULL, PRIMARY KEY ( `id` ))');\n";
         $file .= "\t\t*/\n";
         $file .= "\t\tforeach(\$this->tables as \$table)\n";
         $file .= "\t\t{\n";
         $file .= "\t\t\t\$this->dbObj->exec(\$table);\n";
         $file .= "\t\t}\n";
         $file .= "\t}\n";
         $file .= "\n";
         $file .= "}\n";
         $file .= "\n";
         $file .= "?>";
         $fp = fopen(MPM_DB_PATH . 'schema.php', "w");
         if ($fp == false) {
             echo "\nUnable to write to file.  Initialization failed!\n\n";
             exit;
         }
         $success = fwrite($fp, $file);
         if ($success == false) {
             echo "\nUnable to write to file.  Initialization failed!\n\n";
             exit;
         }
         fclose($fp);
         $clw->addText('File ' . MPM_DB_PATH . 'schema.php has been created.');
         $clw->write();
         exit;
     } else {
         if (isset($this->arguments[0]) && $this->arguments[0] == '--force') {
             $forced = true;
         }
     }
     // make sure the schema file exists
     if (!file_exists(MPM_DB_PATH . 'schema.php')) {
         $clw->addText('The schema file does not exist.  Run this command with the "add" argument to create one (only a stub).');
         $clw->write();
         exit;
     }
     $clw->writeHeader();
     if (!$forced) {
         echo "\nWARNING:  IF YOU CONTINUE, ALL TABLES IN YOUR DATABASE WILL BE ERASED!";
         echo "\nDO YOU WANT TO CONTINUE? [y/N] ";
         $answer = fgets(STDIN);
         $answer = trim($answer);
         $answer = strtolower($answer);
         if (empty($answer) || substr($answer, 0, 1) == 'n') {
             echo "\nABORTED!\n\n";
             $clw->writeFooter();
             exit;
         }
     }
     echo "\n";
     $this->build();
     $clw->writeFooter();
     exit;
 }
 /**
  * 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();
     $filename_note = '';
     if (!empty($this->arguments)) {
         $argument = preg_replace('|[^a-zA-Z0-9_-]|', '', $this->arguments[0]);
         if (!empty($argument)) {
             $filename_note = '_' . $argument;
         }
     }
     // get date stamp for use in generating filename
     $date_stamp = date('Y_m_d_H_i_s');
     $filename = $date_stamp . $filename_note . '.php';
     $classname = 'Migration_' . $date_stamp;
     // get list of files
     $files = glob(MPM_DB_PATH . $date_stamp . '*.php');
     // if filename is taken, throw error
     if (!empty($files)) {
         $obj = MpmCommandLineWriter::getInstance();
         $obj->addText('Unable to obtain a unique filename for your migration.  Please try again in a few seconds.');
         $obj->write();
         exit;
     }
     // 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";
         $file .= "\t\t" . '$pdo->exec("DO 0");' . "\n";
         $file .= "\t}\n\n";
         $file .= "\t" . 'public function down(PDO &$pdo)' . "\n";
         $file .= "\t{\n";
         $file .= "\t\t" . '$pdo->exec("DO 0");' . "\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";
         $file .= "\t\t" . '$mysqli->exec("DO 0");' . "\n";
         $file .= "\t}\n\n";
         $file .= "\t" . 'public function down(ExceptionalMysqli &$mysqli)' . "\n";
         $file .= "\t{\n";
         $file .= "\t\t" . '$mysqli->exec("DO 0");' . "\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 ' . MPM_DB_PATH . $filename);
     $obj->write();
 }