/** * 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(); }
/** * Fetches a list of files and adds migrations to the database migrations table. * * @uses MpmListHelper::getListOfFiles() * @uses MpmListHelper::getTotalMigrations() * @uses MpmListHelper::getFullList() * @uses MpmListHelper::getTimestampArray() * @uses MpmDbHelper::getMethod() * @uses MpmDbHelper::getPdoObj() * @uses MpmDbHelper::getMysqliObj() * @uses MPM_METHOD_PDO * * @return void */ static function mergeFilesWithDb() { $db_config = $GLOBALS['db_config']; $migrations_table = $db_config->migrations_table; $files = MpmListHelper::getListOfFiles(); $total_migrations = MpmListHelper::getTotalMigrations(); $db_list = MpmListHelper::getFullList(0, $total_migrations); $file_timestamps = MpmListHelper::getTimestampArray($files); if (MpmDbHelper::getMethod() == MPM_METHOD_PDO) { if (count($files) > 0) { $pdo = MpmDbHelper::getPdoObj(); $pdo->beginTransaction(); try { foreach ($files as $file) { $sql = "INSERT IGNORE INTO `{$migrations_table}` ( `timestamp`, `active`, `is_current` ) VALUES ( '{$file->timestamp}', 0, 0 )"; $pdo->exec($sql); } } catch (Exception $e) { $pdo->rollback(); echo "\n\nError: " . $e->getMessage(); echo "\n\n"; exit; } $pdo->commit(); } if (count($db_list)) { $pdo->beginTransaction(); try { foreach ($db_list as $obj) { if (!in_array($obj->timestamp, $file_timestamps) && $obj->active == 0) { $sql = "DELETE FROM `{$migrations_table}` WHERE `id` = '{$obj->id}'"; $pdo->exec($sql); } } } catch (Exception $e) { $pdo->rollback(); echo "\n\nError: " . $e->getMessage(); echo "\n\n"; exit; } $pdo->commit(); } } else { $mysqli = MpmDbHelper::getMysqliObj(); $mysqli->autocommit(false); if (count($files) > 0) { try { $stmt = $mysqli->prepare('INSERT IGNORE INTO `' . $migrations_table . '` ( `timestamp`, `active`, `is_current` ) VALUES ( ?, 0, 0 )'); foreach ($files as $file) { $stmt->bind_param('s', $file->timestamp); $result = $stmt->execute(); if ($result === false) { throw new Exception('Unable to execute query to update file list.'); } } } catch (Exception $e) { $mysqli->rollback(); $mysqli->close(); echo "\n\nError:", $e->getMessage(), "\n\n"; exit; } $mysqli->commit(); } if (count($db_list)) { try { $stmt = $mysqli->prepare('DELETE FROM `' . $migrations_table . '` WHERE `id` = ?'); foreach ($db_list as $obj) { if (!in_array($obj->timestamp, $file_timestamps) && $obj->active == 0) { $stmt->bind_param('i', $obj->id); $result = $stmt->execute(); if ($result === false) { throw new Exception('Unable to execute query to remove stale files from the list.'); } } } } catch (Exception $e) { $mysqli->rollback(); $mysqli->close(); echo "\n\nError: " . $e->getMessage(); echo "\n\n"; exit; } $mysqli->commit(); } $mysqli->close(); } }
/** * 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; }
/** * 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 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(); }
/** * 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(); }
/** * @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; } }