/** * Object constructor. * * @uses MpmDbHelper::getDbObj() * * @param bool $dryrun * @return MpmSchema */ public function __construct($dryrun = false) { $this->dryrun = $dryrun; $this->dbObj = MpmDbHelper::getDbObj(); $this->dbObj->dryrun = $dryrun; $this->initialMigrationTimestamp = null; }
/** * 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; }
/** * Object constructor. * * @uses MpmDbHelper::getDbObj() * * @return MpmSchema */ public function __construct() { $this->dbObj = MpmDbHelper::getDbObj(); $this->initialMigrationTimestamp = null; }
/** * 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; }
/** * @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 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; }