diff --git a/init.php b/init.php index 5c881ba..2c9fb1d 100644 --- a/init.php +++ b/init.php @@ -1,3 +1,3 @@ db = $db; - $this->args = $args; - } + function __construct($db = null, $args = array()) + { + $this->db = $db; + $this->args = $args; + } - abstract public function runStrategy(); + public abstract function runStrategy(); } \ No newline at end of file diff --git a/lib/AbstractMigration.class.php b/lib/AbstractMigration.class.php index 5b2640a..8fd5e56 100644 --- a/lib/AbstractMigration.class.php +++ b/lib/AbstractMigration.class.php @@ -8,70 +8,7 @@ abstract class AbstractMigration */ protected $db; - /** - * Build list of sql queries for the up event - */ - protected function buildUp() - { - return isset($this->up) ? $this->up : []; - } - - /** - * Build list of sql queries for the preup event - */ - protected function buildPreup() - { - return isset($this->preup) ? $this->preup : []; - } - - /** - * Build list of sql queries for the postup event - */ - protected function buildPostup() - { - return isset($this->postup) ? $this->postup : []; - } - - /** - * Build list of sql queries for the down event - */ - protected function buildDown() - { - return isset($this->down) ? $this->down : []; - } - - /** - * Build list of sql queries for the predown event - */ - protected function buildPredown() - { - return isset($this->predown) ? $this->predown : []; - } - - /** - * Build list of sql queries for the postdown event - */ - protected function buildPostdown() - { - return isset($this->postdown) ? $this->postdown : []; - } - - /** - * Get current revision number - */ - protected function getRev() - { - return isset($this->rev) ? $this->rev : 0; - } - /** - * Get current alias - */ - protected function getAlias() - { - return (Helper::get('aliasprefix') ?: '') . (string) (isset($this->alias) ? $this->alias : 0); - } - - public function __construct(mysqli $db) + public function __construct(mysqli $db) { $this->db = $db; } @@ -84,37 +21,64 @@ public function runUp() foreach ($this->buildPreup() as $query) { Output::verbose('PREUP: '.$query); if ($this->db->query($query)) { - Output::verbose("Ok"); + Output::verbose('Ok'); } else { Output::verbose($this->db->error); } } - foreach ($this->buildUp() as $query) { Output::verbose('UP: '.$query); if ($this->db->query($query)) { - Output::verbose("Ok"); + Output::verbose('Ok'); } else { Output::verbose($this->db->error); } } - foreach ($this->buildPostup() as $query) { Output::verbose('POSTUP: '.$query); if ($this->db->query($query)) { - Output::verbose("Ok"); + Output::verbose('Ok'); } else { Output::verbose($this->db->error); } } - $verT = Helper::get('versiontable'); $rev = $this->getRev(); $query = "INSERT INTO `{$verT}` SET `rev`={$rev}"; Output::verbose($query); $this->db->query($query); + } + /** + * Build list of sql queries for the preup event + */ + protected function buildPreup() + { + return isset($this->preup) ? $this->preup : array(); + } + /** + * Build list of sql queries for the up event + */ + protected function buildUp() + { + return isset($this->up) ? $this->up : array(); + } + + /** + * Build list of sql queries for the postup event + */ + protected function buildPostup() + { + return isset($this->postup) ? $this->postup : array(); + } + + /** + * Get current revision number + */ + protected function getRev() + { + return isset($this->rev) ? $this->rev : 0; } /** @@ -125,31 +89,59 @@ public function runDown() foreach ($this->buildPredown() as $query) { Output::verbose('PREDOWN: '.$query); if ($this->db->query($query)) { - Output::verbose("Ok"); + Output::verbose('Ok'); } else { Output::verbose($this->db->error); } } - foreach ($this->buildDown() as $query) { Output::verbose('DOWN:'.$query); $this->db->query($query); } - foreach ($this->buildPostdown() as $query) { Output::verbose('POSTDOWN: '.$query); if ($this->db->query($query)) { - Output::verbose("Ok"); + Output::verbose('Ok'); } else { Output::verbose($this->db->error); } } - $verT = Helper::get('versiontable'); $rev = $this->getRev(); $query = "DELETE FROM `{$verT}` WHERE `rev`={$rev}"; Output::verbose($query); $this->db->query($query); + } + /** + * Build list of sql queries for the predown event + */ + protected function buildPredown() + { + return isset($this->predown) ? $this->predown : array(); + } + + /** + * Build list of sql queries for the down event + */ + protected function buildDown() + { + return isset($this->down) ? $this->down : array(); + } + + /** + * Build list of sql queries for the postdown event + */ + protected function buildPostdown() + { + return isset($this->postdown) ? $this->postdown : array(); + } + + /** + * Get current alias + */ + protected function getAlias() + { + return (Helper::get('aliasprefix') ?: '').(string)(isset($this->alias) ? $this->alias : 0); } } \ No newline at end of file diff --git a/lib/AbstractSchema.class.php b/lib/AbstractSchema.class.php index b0e9b50..b2dbd1d 100644 --- a/lib/AbstractSchema.class.php +++ b/lib/AbstractSchema.class.php @@ -2,12 +2,6 @@ abstract class AbstractSchema { - - protected function buildQueries() - { - return isset($this->queries) ? $this->queries : []; - } - public function load(Mysqli $db) { foreach ($this->buildQueries() as $query) { @@ -18,4 +12,8 @@ public function load(Mysqli $db) } } + protected function buildQueries() + { + return isset($this->queries) ? $this->queries : array(); + } } \ No newline at end of file diff --git a/lib/GetOpt.class.php b/lib/GetOpt.class.php index a12491e..084912b 100644 --- a/lib/GetOpt.class.php +++ b/lib/GetOpt.class.php @@ -1,159 +1,154 @@ -getMessage(); - - return false; - } - } else { - self::$errors[] = 'Invalid option \''.$matches[1].'\''; - - return false; - } - } elseif (preg_match('/^-([a-z])/', $arg, $matches)) //short options start with '-', are case-sensitive - { - foreach (str_split($matches[1]) as $o) { - if (isset($short_opts[$o])) { - try { - $result[$short_opts[$o]] = self::parseValue($args, $arg, $opts[$short_opts[$o]]); - } catch (Exception $e) { - self::$errors[] = $e->getMessage(); - - return false; - } - } else { - self::$errors[] = 'Invalid option \''.$matches[1].'\''; - - return false; - } - } - } else { - array_unshift($args, $arg); - break; - } - } - - return $result; - } - - /** - * Return list errors encountered while parsing the arguments - * - * @return array List of errors - */ - static function errors() - { - return self::$errors; - } - - /** - * Expand array values without custom keys into "'value' => true" pairs - * - * @param array $opts Array to process - * - * @return array Processed array - */ - private static function normalizeTpl($opts) - { - foreach ($opts as &$tpl) { - $ntpl = []; - foreach ($tpl as $k => $t) { - if (is_string($k)) { - $ntpl[$k] = $t; - } elseif (is_int($k) && is_string($t)) { - $ntpl[$t] = true; - } - } - $tpl = $ntpl; - } - - return $opts; - } - - /** - * Get the associations between short and long options, if any exist - * - * @param array $opts Options to parse - * - * @return array List of mappings between short_options => long_options - */ - private static function mapShortOpts($opts) - { - $result = []; - - foreach ($opts as $k => $o) { - if (!empty($o['short'])) { - $result[$o['short']] = $k; - } - } - - return $result; - } - - /** - * Get "value" part of the long, if any, from the arguments list. - * - * Note: $args might be modified depending on the given option template - * - * @param array $args List of command-line arguments - * @param string $arg Argument being parsed - * @param array $tpl Template for the argument being parsed - * - * @return mixed Parsed option value, null if no value required - * @throws Exception - */ - private static function parseValue(&$args, $arg, $tpl) - { - foreach ($tpl as $t => $v) { - switch ($t) { - case 'req_val': - if (strpos($arg, '=') === false) { - if (!empty($args)) { - return array_shift($args); - } else { - throw new Exception('Missing option value'); - } - } else { - return substr(strstr($arg, '='), 1); - } - break; - case 'opt_val': - if (strpos($arg, '=') !== false) { - return substr(strstr($arg, '='), 1); - } - break; - } - } - - return null; - } -} - +getMessage(); + + return false; + } + } else { + self::$errors[] = 'Invalid option \''.$matches[1].'\''; + + return false; + } + } elseif (preg_match('/^-([a-z])/', $arg, $matches)) { + foreach (str_split($matches[1]) as $o) { + if (isset($short_opts[$o])) { + try { + $result[$short_opts[$o]] = self::parseValue($args, $arg, $opts[$short_opts[$o]]); + } catch (Exception $e) { + self::$errors[] = $e->getMessage(); + + return false; + } + } else { + self::$errors[] = 'Invalid option \''.$matches[1].'\''; + + return false; + } + } + } else { + array_unshift($args, $arg); + break; + } + } + + return $result; + } + + /** + * Expand array values without custom keys into "'value' => true" pairs + * + * @param array $opts Array to process + * + * @return array Processed array + */ + private static function normalizeTpl($opts) + { + foreach ($opts as &$tpl) { + $ntpl = array(); + foreach ($tpl as $k => $t) { + if (is_string($k)) { + $ntpl[$k] = $t; + } elseif (is_int($k) && is_string($t)) { + $ntpl[$t] = true; + } + } + $tpl = $ntpl; + } + + return $opts; + } + + /** + * Get the associations between short and long options, if any exist + * + * @param array $opts Options to parse + * + * @return array List of mappings between short_options => long_options + */ + private static function mapShortOpts($opts) + { + $result = array(); + foreach ($opts as $k => $o) { + if (!empty($o['short'])) { + $result[$o['short']] = $k; + } + } + + return $result; + } + + /** + * Get "value" part of the long, if any, from the arguments list. + * + * Note: $args might be modified depending on the given option template + * + * @param array $args List of command-line arguments + * @param string $arg Argument being parsed + * @param array $tpl Template for the argument being parsed + * + * @return mixed Parsed option value, null if no value required + * @throws Exception + */ + private static function parseValue(&$args, $arg, $tpl) + { + foreach ($tpl as $t => $v) { + switch ($t) { + case 'req_val': + if (strpos($arg, '=') === false) { + if (!empty($args)) { + return array_shift($args); + } else { + throw new Exception('Missing option value'); + } + } else { + return substr(strstr($arg, '='), 1); + } + break; + case 'opt_val': + if (strpos($arg, '=') !== false) { + return substr(strstr($arg, '='), 1); + } + break; + } + } + + return null; + } + + /** + * Return list errors encountered while parsing the arguments + * + * @return array List of errors + */ + static function errors() + { + return self::$errors; + } +} \ No newline at end of file diff --git a/lib/Helper.class.php b/lib/Helper.class.php index 82b528d..a30c4f0 100644 --- a/lib/Helper.class.php +++ b/lib/Helper.class.php @@ -2,31 +2,29 @@ class Helper { - const TAB = ' '; - const UP = 'Up'; + const TAB = ' '; + const UP = 'Up'; const DOWN = 'Down'; - - static protected $config_tpl - = [ - 'config' => ['short' => 'c', 'req_val'], - 'host' => ['req_val'], - 'user' => ['req_val'], - 'password' => ['req_val'], - 'db' => ['req_val'], - 'savedir' => ['req_val'], - 'verbose' => ['req_val'], - 'versiontable' => ['req_val'], - 'versiontable-engine' => ['opt_val'], - 'aliastable' => ['opt_val'], - 'aliasprefix' => ['opt_val'], - 'forceyes' => ['opt_val'], - 'noninteractive' => ['opt_val'], - 'noprepost' => ['opt_val'], - ]; - - static protected $config - = [ - 'config' => null, //path to alternate config file + protected static $config_tpl + = array( + 'config' => array('short' => 'c', 'req_val'), + 'host' => array('req_val'), + 'user' => array('req_val'), + 'password' => array('req_val'), + 'db' => array('req_val'), + 'savedir' => array('req_val'), + 'verbose' => array('req_val'), + 'versiontable' => array('req_val'), + 'versiontable-engine' => array('opt_val'), + 'aliastable' => array('opt_val'), + 'aliasprefix' => array('opt_val'), + 'forceyes' => array('opt_val'), + 'noninteractive' => array('opt_val'), + 'noprepost' => array('opt_val') + ); + protected static $config + = array( + 'config' => null, 'host' => null, 'user' => null, 'password' => null, @@ -36,21 +34,11 @@ class Helper 'versiontable' => null, 'aliastable' => null, 'aliasprefix' => null, - 'versiontable-engine' => "MyISAM", + 'versiontable-engine' => 'MyISAM', 'forceyes' => false, 'noninteractive' => false, - 'noprepost' => false, - ]; - - static function setConfig($cnf) - { - self::$config = array_replace(self::$config, $cnf); - } - - static function getConfig() - { - return self::$config; - } + 'noprepost' => false + ); /** * Parse command line into config options and commands with its parameters @@ -63,22 +51,19 @@ static function getConfig() */ static function parseCommandLineArgs($args) { - $parsed_args = ['options' => [], 'command' => ['name' => null, 'args' => []]]; - + $parsed_args = array('options' => array(), 'command' => array('name' => null, 'args' => array())); array_shift($args); $opts = GetOpt::extractLeft($args, self::$config_tpl); if ($opts === false) { Output::error('mmp: '.reset(GetOpt::errors())); - exit(1); + die(1); } else { $parsed_args['options'] = $opts; } - //if we didn't traverse the full array just now, move on to command parsing if (!empty($args)) { $parsed_args['command']['name'] = array_shift($args); } - //consider any remaining arguments as command arguments $parsed_args['command']['args'] = $args; @@ -111,17 +96,15 @@ static function checkConfigEnough() * * @return object Initialized controller, False if not found */ - static function getController($name = null, $args = []) + static function getController($name = null, $args = array()) { if (empty($name)) { - return new helpController; + return new helpController(); } - $ctrl = $name.'Controller'; if (!class_exists($ctrl)) { return false; } - try { return new $ctrl(null, $args); } catch (Exception $e) { @@ -129,6 +112,46 @@ static function getController($name = null, $args = []) } } + static function initDirForSavedMigrations() + { + if (is_dir(self::$config['savedir'])) { + return; + } + mkdir(self::$config['savedir'], 493, true); + } + + static function getTmpDbObject() + { + $config = self::getConfig(); + $tmpname = $config['db'].'_'.self::getCurrentVersion(); + $config['db'] = $tmpname; + $db = self::getDbObject(); + $db->query("create database `{$config['db']}`"); + $tmpdb = self::getDbObject($config); + $tmpdb->query('SET FOREIGN_KEY_CHECKS = 0'); + register_shutdown_function(function () use ($config, $tmpdb) { + Output::verbose("database {$config['db']} has been dropped"); + $tmpdb->query("DROP DATABASE `{$config['db']}`"); + }); + + return $tmpdb; + } + + static function getConfig() + { + return self::$config; + } + + static function setConfig($cnf) + { + self::$config = array_replace(self::$config, $cnf); + } + + static function getCurrentVersion() + { + return time(); + } + /** * * @staticvar $db @@ -137,7 +160,7 @@ static function getController($name = null, $args = []) * * @return Mysqli */ - static function getDbObject($config = []) + static function getDbObject($config = array()) { static $db = null; $conf = self::$config; @@ -157,45 +180,13 @@ static function getDbObject($config = []) return new Mysqli($conf['host'], $conf['user'], $conf['password'], $conf['db']); } - static function initDirForSavedMigrations() - { - if (is_dir(self::$config['savedir'])) { - return; - } - mkdir(self::$config['savedir'], 0755, true); - } - - static public function get($key) - { - return isset(self::$config[$key]) ? self::$config[$key] : false; - } - - static function getTmpDbObject() - { - $config = self::getConfig(); - $tmpname = $config['db'].'_'.self::getCurrentVersion(); - $config['db'] = $tmpname; - $db = self::getDbObject(); - $db->query("create database `{$config['db']}`"); - $tmpdb = self::getDbObject($config); - $tmpdb->query("SET FOREIGN_KEY_CHECKS = 0"); - register_shutdown_function(function () use ($config, $tmpdb) { - Output::verbose("database {$config['db']} has been dropped"); - $tmpdb->query("DROP DATABASE `{$config['db']}`"); - }); - - return $tmpdb; - } - static function initVersionTable() { - $engine = self::get("versiontable-engine"); - - if (!in_array($engine, ["MyISAM", "InnoDB"])) { + $engine = self::get('versiontable-engine'); + if (!in_array($engine, array('MyISAM', 'InnoDB'))) { Output::error('mmp: wrong engine for versiontable "'.$engine.'"'); - exit(1); + die(1); } - $db = self::getDbObject(); $tbl = self::get('versiontable'); $rev = self::getCurrentVersion(); @@ -206,15 +197,18 @@ static function initVersionTable() self::initAliasTable($rev); } - static function initAliasTable($rev, $alias_suffix = 1) + public static function get($key) { - $engine = self::get("versiontable-engine"); + return isset(self::$config[$key]) ? self::$config[$key] : false; + } - if (!in_array($engine, ["MyISAM", "InnoDB"])) { + static function initAliasTable($rev, $alias_suffix = 1) + { + $engine = self::get('versiontable-engine'); + if (!in_array($engine, array('MyISAM', 'InnoDB'))) { Output::error('mmp: wrong engine for versiontable "'.$engine.'"'); - exit(1); + die(1); } - $db = self::getDbObject(); $tbl = self::get('aliastable'); if (false === $tbl) { @@ -228,11 +222,6 @@ static function initAliasTable($rev, $alias_suffix = 1) $db->query("INSERT INTO `{$tbl}` VALUES({$rev},'{$alias}')"); } - static function getCurrentVersion() - { - return time(); - } - static function getCurrentAlias() { if (false === self::get('aliastable')) { @@ -250,10 +239,9 @@ static function getMaxAliasVersion() return false; } $alias_prefix = self::get('aliasprefix') ?: ''; - - $res = $db->query("SELECT MAX(REPLACE(`alias`,'{$alias_prefix}','')) FROM `{$tbl}`"); - $row = $res->fetch_array(MYSQLI_NUM); - $max_alias = +$row[0] ?: 0; + $res = $db->query("SELECT MAX(REPLACE(`alias`,'{$alias_prefix}','')) FROM `{$tbl}`"); + $row = $res->fetch_array(MYSQLI_NUM); + $max_alias = +$row[0] ?: 0; return $max_alias; } @@ -266,9 +254,8 @@ static function geAliasVersionByRev($rev) return false; } $alias_prefix = self::get('aliasprefix') ?: ''; - - $res = $db->query("SELECT REPLACE(`alias`,'{$alias_prefix}','') FROM `{$tbl}` WHERE `rev` = {$rev}"); - $row = $res->fetch_array(MYSQLI_NUM); + $res = $db->query("SELECT REPLACE(`alias`,'{$alias_prefix}','') FROM `{$tbl}` WHERE `rev` = {$rev}"); + $row = $res->fetch_array(MYSQLI_NUM); if (isset($row[0])) { return +$row[0]; } else { @@ -286,7 +273,6 @@ static function getRevByAlias($alias) if (is_numeric($alias)) { $alias = (self::get('aliasprefix') ?: '').$alias; } - $res = $db->query("SELECT `rev` FROM `{$tbl}` WHERE `alias` = '{$alias}'"); $row = $res->fetch_array(MYSQLI_NUM); if (isset($row[0])) { @@ -296,13 +282,12 @@ static function getRevByAlias($alias) } } - static function getTables(Mysqli $db) { - $tables = []; + $tables = array(); $result = $db->query('show tables'); if (!$result) { - return []; + return array(); } while ($row = $result->fetch_array(MYSQLI_NUM)) { $tables[] = $row[0]; @@ -322,7 +307,7 @@ static function getSqlForTableCreation($tname, $db) { $tres = $db->query("SHOW CREATE TABLE `{$tname}`"); $trow = $tres->fetch_array(MYSQLI_NUM); - $query = preg_replace('#AUTO_INCREMENT=\S+#is', '', $trow[1]); + $query = preg_replace('#AUTO_INCREMENT=\\S+#is', '', $trow[1]); //$query = preg_replace("#\n\s*#",' ',$query); return $query; @@ -330,12 +315,13 @@ static function getSqlForTableCreation($tname, $db) static function getRoutines($type) { - $routines = []; - $db = self::getDbObject(); - $result = $db->query("show $type status where Db=DATABASE()"); + $routines = array(); + $db = self::getDbObject(); + $result = $db->query("show {$type} status where Db=DATABASE()"); if ($result === false) { return $routines; - } // Don't fail if the DB doesn't support STPs + } + // Don't fail if the DB doesn't support STPs while ($row = $result->fetch_array(MYSQLI_NUM)) { $routines[] = $row[1]; } @@ -345,9 +331,9 @@ static function getRoutines($type) static function getSqlForRoutineCreation($rname, Mysqli $db, $type) { - $tres = $db->query("SHOW CREATE $type `{$rname}`"); + $tres = $db->query("SHOW CREATE {$type} `{$rname}`"); $trow = $tres->fetch_array(MYSQLI_NUM); - $query = preg_replace('#DEFINER=\S+#is', '', $trow[2]); + $query = preg_replace('#DEFINER=\\S+#is', '', $trow[2]); return $query; } @@ -373,13 +359,12 @@ static function getDatabaseVersion(Mysqli $db) */ static function getDatabaseVersions(Mysqli $db) { - $result = []; + $result = array(); $tbl = self::get('versiontable'); $res = $db->query("SELECT rev FROM `{$tbl}` ORDER BY rev ASC"); if ($res === false) { return false; } - while ($row = $res->fetch_array(MYSQLI_NUM)) { $result[] = $row[0]; } @@ -389,17 +374,16 @@ static function getDatabaseVersions(Mysqli $db) static function getDatabaseAliases() { - $result = []; - $db = self::getDbObject(); + $result = array(); + $db = self::getDbObject(); $tbl = self::get('aliastable'); - if (false === $tbl){ - return []; + if (false === $tbl) { + return array(); } - $res = $db->query("SELECT rev, alias FROM `{$tbl}` ORDER BY rev ASC"); + $res = $db->query("SELECT rev, alias FROM `{$tbl}` ORDER BY rev ASC"); if ($res === false) { - return []; + return array(); } - while ($row = $res->fetch_array(MYSQLI_NUM)) { $result[trim($row[0])] = trim($row[1]); } @@ -407,22 +391,27 @@ static function getDatabaseAliases() return $result; } - - static function applyMigration($revision, $db, $direction = self::UP) + static function loadTmpDb($db) { - /** @noinspection PhpIncludeInspection */ - require_once self::get('savedir').'/migration'.$revision.'.php'; - $classname = 'Migration'.$revision; - $migration = new $classname($db); - $method = 'run'.$direction; - $migration->$method(); + $fname = self::get('savedir').'/schema.php'; + if (!file_exists($fname)) { + echo "File: {$fname} does not exist!\n"; + die; + } + require_once $fname; + $sc = new Schema(); + $sc->load($db); + $migrations = self::getAllMigrations(); + foreach ($migrations as $revision) { + self::applyMigration($revision, $db); + } } static function getAllMigrations() { $dir = self::get('savedir'); $files = glob($dir.'/migration*.php'); - $result = []; + $result = array(); foreach ($files as $file) { $key = preg_replace('#[^0-9]#is', '', basename($file)); $result[] = $key; @@ -432,119 +421,92 @@ static function getAllMigrations() return $result; } - static function loadTmpDb($db) + static function applyMigration($revision, $db, $direction = self::UP) { - $fname = self::get('savedir').'/schema.php'; - if (!file_exists($fname)) { - echo "File: {$fname} does not exist!\n"; - exit; - } - - require_once $fname; - $sc = new Schema(); - $sc->load($db); - - $migrations = self::getAllMigrations(); - foreach ($migrations as $revision) { - self::applyMigration($revision, $db); - } - + /** @noinspection PhpIncludeInspection */ + require_once self::get('savedir').'/migration'.$revision.'.php'; + $classname = 'Migration'.$revision; + $migration = new $classname($db); + $method = 'run'.$direction; + $migration->{$method}(); } static function createMigrationContent($version, $alias, $diff) { $indent = self::TAB; - - $content - = "= count($lines) - 1); - - $line = self::escapeString($lines[$i].($isLast ? "" : "\n")); - + $isFirst = $i == 0; + $isLast = $i >= count($lines) - 1; + $line = self::escapeString($lines[$i].($isLast + ? '' + : ' +')); // Line prefix contains concatenation operator $lineprefix = $isFirst ? '' : '. '; - // Line suffix contains submitted string suffix $linesuffix = $isLast ? $suffix : ''; - - $result .= $indent.$lineprefix.'"'.$line.'"'.$linesuffix."\n"; + $result .= $indent.$lineprefix.'"'.$line.'"'.$linesuffix.' +'; } return $result; } - static private function escapeString($string) + private static function escapeString($string) { - $convert = [ - "\\" => "\\\\", - "\n" => "\\n", - "\r" => "\\r", - "\"" => "\\\"", - "\v" => "\\v", - "\e" => "\\e", - "\f" => "\\f", - "\$" => "\\$" - ]; - - $ret = ''; + $convert = array( + '\\' => '\\\\', + ' +' => '\\n', + ' +' => '\\r', + '"' => '\\"', + ' ' => '\\v', + '' => '\\e', + ' ' => '\\f', + '$' => '\\$' + ); + $ret = ''; for ($i = 0; $i < strlen($string); $i++) { $ch = $string[$i]; if (isset($convert[$ch])) { @@ -556,4 +518,21 @@ static private function escapeString($string) return $ret; } -} + + static function createSchema($queries) + { + $indent = self::TAB; + $content + = '= $level) { - echo $msg, PHP_EOL; - } - } - - static function error($msg) - { - fwrite(STDERR, $msg.PHP_EOL); - } -} - += $level) { + echo $msg, PHP_EOL; + } + } + + static function error($msg) + { + fwrite(STDERR, $msg.PHP_EOL); + } +} \ No newline at end of file diff --git a/lib/addController.class.php b/lib/addController.class.php index c595a5a..845ff97 100644 --- a/lib/addController.class.php +++ b/lib/addController.class.php @@ -1,16 +1,16 @@ - * - */ -class addController extends AbstractController -{ - public function runStrategy() - { - Helper::initVersionTable(); - } + */ +class addController extends AbstractController +{ + public function runStrategy() + { + Helper::initVersionTable(); + } } \ No newline at end of file diff --git a/lib/createController.class.php b/lib/createController.class.php index a69f154..c1f4448 100644 --- a/lib/createController.class.php +++ b/lib/createController.class.php @@ -2,17 +2,13 @@ class createController extends AbstractController { - - protected $queries = []; + protected $queries = array(); public function runStrategy() { - $db = Helper::getDbObject(); $tmpdb = Helper::getTmpDbObject(); - Helper::loadTmpDb($tmpdb); - $diff = new dbDiff($db, $tmpdb); $difference = $diff->getDifference(); if (!count($difference['up']) && !count($difference['down'])) { @@ -20,23 +16,19 @@ public function runStrategy() return false; } - $version = Helper::getCurrentVersion(); $alias = Helper::getCurrentAlias(); $filename = Helper::get('savedir')."/migration{$version}.php"; $content = Helper::createMigrationContent($version, $alias, $difference); file_put_contents($filename, $content); Output::verbose("file: {$filename} written!"); - $vTab = Helper::get('versiontable'); $db->query("INSERT INTO `{$vTab}` SET rev={$version}"); - $aTab = Helper::get('aliastable'); - if (false !== $alias && false !== $aTab){ + if (false !== $alias && false !== $aTab) { $db->query("INSERT INTO `{$aTab}` SET rev={$version}, alias='{$alias}'"); } return true; } - -} +} \ No newline at end of file diff --git a/lib/dbDiff.class.php b/lib/dbDiff.class.php index 501d7ed..ea70c9d 100644 --- a/lib/dbDiff.class.php +++ b/lib/dbDiff.class.php @@ -2,7 +2,6 @@ class dbDiff { - /** * * @var mysqli main database connection @@ -17,23 +16,7 @@ class dbDiff * * @var array */ - protected $difference = ['up' => [], 'down' => []]; - - protected function up($sql) - { - if (!strlen($sql)) { - return; - } - $this->difference['up'][] = $sql; - } - - protected function down($sql) - { - if (!strlen($sql)) { - return; - } - $this->difference['down'][] = $sql; - } + protected $difference = array('up' => array(), 'down' => array()); public function __construct($currentDbVersion, $lastPublishedDbVersion) { @@ -59,7 +42,6 @@ protected function getTablesDifference() if ($exclude_tables[0] != '/') { $exclude_tables = '/'.$exclude_tables.'/i'; } - foreach ($current_tables as $k => $table) { if (preg_match($exclude_tables, $table)) { unset($current_tables[$k]); @@ -71,19 +53,15 @@ protected function getTablesDifference() } } } - $this->createFullTableDifference($current_tables, $published_tables); - $common = array_intersect($current_tables, $published_tables); $this->createDifferenceBetweenTables($common); } protected function createFullTableDifference($current_tables, $published_tables) { - sort($current_tables); sort($published_tables); - $create = array_diff($current_tables, $published_tables); $drop = array_diff($published_tables, $current_tables); foreach ($create as $table) { @@ -101,6 +79,27 @@ protected function addCreateTable($tname, $db) $this->up(Helper::getSqlForTableCreation($tname, $db)); } + protected function down($sql) + { + if (!strlen($sql)) { + return; + } + $this->difference['down'][] = $sql; + } + + protected function dropTable($t) + { + return "DROP TABLE IF EXISTS `{$t}`"; + } + + protected function up($sql) + { + if (!strlen($sql)) { + return; + } + $this->difference['up'][] = $sql; + } + protected function addDropTable($tname, $db) { $this->up($this->dropTable($tname)); @@ -121,7 +120,7 @@ protected function createDifferenceBetweenTables($tables) protected function getColumnList(mysqli_result $result) { - $columns = []; + $columns = array(); while ($row = $result->fetch_assoc()) { unset($row['Key']); $columns[] = $row; @@ -132,10 +131,8 @@ protected function getColumnList(mysqli_result $result) protected function createDifferenceInsideTable($table, $table_current_columns, $table_published_columns) { - foreach ($table_current_columns as $current_column) { $column_for_compare = $this->checkColumnExists($current_column, $table_published_columns); - if (!$column_for_compare) { $this->up($this->addColumn($table, $current_column)); $this->down($this->dropColumn($table, $current_column)); @@ -149,18 +146,14 @@ protected function createDifferenceInsideTable($table, $table_current_columns, $ $this->down($sql); } } - - foreach ($table_published_columns as $published_column) { - $has = $this->checkColumnExists($published_column, $table_current_columns); - if (!$has) { $constraint = $this->getConstraintForColumn($this->published, $table, $published_column['Field']); //echo "COLUMNS\n\n"; var_dump($constraint); if (count($constraint)) { - $this->down($this->addConstraint(['constraint' => $constraint])); - $this->up($this->dropConstraint(['constraint' => $constraint])); + $this->down($this->addConstraint(array('constraint' => $constraint))); + $this->up($this->dropConstraint(array('constraint' => $constraint))); } $this->down($this->addColumn($table, $published_column)); $this->up($this->dropColumn($table, $published_column)); @@ -168,66 +161,108 @@ protected function createDifferenceInsideTable($table, $table_current_columns, $ } } - protected function addSqlExtras(& $sql, $column) + protected function checkColumnExists($column, $column_list) + { + foreach ($column_list as $compare_column) { + if ($compare_column['Field'] === $column['Field']) { + return $compare_column; + } + } + + return false; + } + + protected function addColumn($table, $column) + { + $sql = "ALTER TABLE `{$table}` ADD `{$column['Field']}` {$column['Type']}"; + $this->addSqlExtras($sql, $column); + + return $sql; + } + + protected function addSqlExtras(&$sql, $column) { if ($column['Null'] === 'NO') { - $sql .= " NOT NULL"; + $sql .= ' NOT NULL'; } - if (!is_null($column['Default'])) { - if (preg_match('/^bit\(/i', $column['Type'])) { + if (preg_match('/^bit\\(/i', $column['Type'])) { // BIT columns use format b'x' - so we can't wrap those $default = $column['Default']; } else { - $default = "'".$this->current->real_escape_string($column['Default'])."'"; + $default = '\''.$this->current->real_escape_string($column['Default']).'\''; } - - $sql .= " DEFAULT $default"; + $sql .= " DEFAULT {$default}"; } } - protected function changeColumn($table, $column) + protected function dropColumn($table, $column) { - $sql = "ALTER TABLE `{$table}` CHANGE "." `{$column['Field']}` `{$column['Field']}` {$column['Type']}"; - $this->addSqlExtras($sql, $column); - - return $sql; + return "ALTER TABLE `{$table}` DROP `{$column['Field']}`"; } - protected function addColumn($table, $column) + protected function changeColumn($table, $column) { - $sql = "ALTER TABLE `{$table}` ADD `{$column['Field']}` {$column['Type']}"; + $sql = "ALTER TABLE `{$table}` CHANGE "." `{$column['Field']}` `{$column['Field']}` {$column['Type']}"; $this->addSqlExtras($sql, $column); return $sql; } - protected function dropColumn($table, $column) + protected function getConstraintForColumn(mysqli $connection, $table, $col_name) { - return "ALTER TABLE `{$table}` DROP `{$column['Field']}`"; + $q = 'select database() as dbname'; + $res = $connection->query($q); + $row = $res->fetch_array(MYSQLI_ASSOC); + $dbname = $row['dbname']; + Output::verbose("DATABASE: {$row['dbname']}"); + $sql + = "SELECT k.CONSTRAINT_SCHEMA,k.CONSTRAINT_NAME,k.TABLE_NAME,k.COLUMN_NAME,k.REFERENCED_TABLE_NAME,k.REFERENCED_COLUMN_NAME, r.UPDATE_RULE, r.DELETE_RULE FROM information_schema.key_column_usage k LEFT JOIN information_schema.referential_constraints r ON r.CONSTRAINT_SCHEMA = k.CONSTRAINT_SCHEMA AND k.REFERENCED_TABLE_NAME=r.REFERENCED_TABLE_NAME LEFT JOIN information_schema.table_constraints t ON t.CONSTRAINT_SCHEMA = r.CONSTRAINT_SCHEMA WHERE k.constraint_schema='{$dbname}' AND t.CONSTRAINT_TYPE='FOREIGN KEY' AND k.TABLE_NAME='{$table}' AND r.TABLE_NAME='{$table}' AND t.TABLE_NAME='{$table}' AND k.COLUMN_NAME='{$col_name}'"; + Output::verbose($sql); + $res = $connection->query($sql); + $row = $res->fetch_array(MYSQLI_ASSOC); + if (!count($row)) { + return false; + } + $constraint = array( + 'table' => $table, + 'name' => $row['CONSTRAINT_NAME'], + 'column' => $row['COLUMN_NAME'], + 'reference' => array('table' => $row['REFERENCED_TABLE_NAME'], 'column' => $row['REFERENCED_COLUMN_NAME'], 'update' => $row['UPDATE_RULE'], 'delete' => $row['DELETE_RULE']) + ); + //echo "=================\n\n\n\========="; + //var_dump($constraint); + return $constraint; } - protected function dropTable($t) + protected function addConstraint($index) { - return "DROP TABLE IF EXISTS `{$t}`"; + if (!isset($index['constraint']['column']) || !strlen($index['constraint']['column'])) { + return ''; + } + $sql = "ALTER TABLE `{$index['constraint']['table']}` "."ADD CONSTRAINT `{$index['constraint']['name']}` "."FOREIGN KEY (`{$index['constraint']['column']}`) " + ."REFERENCES `{$index['constraint']['reference']['table']}` "."(`{$index['constraint']['reference']['column']}`) "."ON UPDATE {$index['constraint']['reference']['update']} " + ."ON DELETE {$index['constraint']['reference']['delete']} "; + //echo "ADD==================================\n$sql\n\n"; + //var_dump($index['constraint']); + return $sql; } - protected function checkColumnExists($column, $column_list) + protected function dropConstraint($index) { - foreach ($column_list as $compare_column) { - if ($compare_column['Field'] === $column['Field']) { - return $compare_column; - } + if (!isset($index['constraint']['column']) || !strlen($index['constraint']['column'])) { + return ''; } - - return false; + $sql = "ALTER TABLE `{$index['constraint']['table']}` "."DROP FOREIGN KEY `{$index['constraint']['name']}` "; + //echo "DELETE==================================\n$sql\n"; + //var_dump($index['constraint']); + return $sql; } protected function createIndexDifference($table) { $current_indexes = $this->getIndexListFromTable($table, $this->current); $published_indexes = $this->getIndexListFromTable($table, $this->published); - foreach ($current_indexes as $cur_index) { $index_for_compare = $this->checkIndexExists($cur_index, $published_indexes); if (!$index_for_compare) { @@ -239,8 +274,7 @@ protected function createIndexDifference($table) $this->up($this->addConstraint($cur_index)); } elseif ($index_for_compare === $cur_index) { continue; - } else // index exists but not identical - { + } else { $this->down($this->dropConstraint($cur_index)); $this->down($this->dropIndex($cur_index)); $this->down($this->addIndex($index_for_compare)); @@ -251,7 +285,6 @@ protected function createIndexDifference($table) $this->up($this->addConstraint($cur_index)); } } - foreach ($published_indexes as $pub_index) { if ($this->checkIndexExists($pub_index, $current_indexes) === false) { $this->down($this->dropConstraint($pub_index)); @@ -268,24 +301,20 @@ protected function getIndexListFromTable($table, mysqli $connection) { $sql = "SHOW INDEXES FROM `{$table}`"; $res = $connection->query($sql); - $indexes = []; + $indexes = array(); while ($row = $res->fetch_array(MYSQLI_ASSOC)) { if (!isset($indexes[$row['Key_name']])) { - $indexes[$row['Key_name']] = []; + $indexes[$row['Key_name']] = array(); } $indexes[$row['Key_name']]['unique'] = !intval($row['Non_unique']); $indexes[$row['Key_name']]['type'] = $row['Index_type']; $indexes[$row['Key_name']]['name'] = $row['Key_name']; $indexes[$row['Key_name']]['table'] = $row['Table']; if (!isset($indexes[$row['Key_name']]['fields'])) { - $indexes[$row['Key_name']]['fields'] = []; + $indexes[$row['Key_name']]['fields'] = array(); } - $indexes[$row['Key_name']]['fields'][$row['Seq_in_index']] = [ - 'name' => $row['Column_name'], - 'length' => $row['Sub_part'] - ]; + $indexes[$row['Key_name']]['fields'][$row['Seq_in_index']] = array('name' => $row['Column_name'], 'length' => $row['Sub_part']); $indexes[$row['Key_name']]['constraint'] = $this->getConstraintForColumn($connection, $table, $row['Column_name']); - } //var_dump($indexes); @@ -303,113 +332,52 @@ protected function checkIndexExists($index, $index_list) return false; } + protected function dropIndex($index) + { + return "DROP INDEX `{$index['name']}` ON `{$index['table']}`"; + } + protected function addIndex($index) { if ($index['name'] === 'PRIMARY') { $index_string = "ALTER TABLE `{$index['table']}` ADD PRIMARY KEY"; - $fields = []; + $fields = array(); foreach ($index['fields'] as $f) { $len = intval($f['length']) ? "({$f['length']})" : ''; $fields[] = "`{$f['name']}`".$len; } - $index_string .= "(".implode(',', $fields).")"; + $index_string .= '('.implode(',', $fields).')'; } else { - $index_string = "CREATE "; + $index_string = 'CREATE '; if ($index['type'] === 'FULLTEXT') { - $index_string .= " FULLTEXT "; + $index_string .= ' FULLTEXT '; } if ($index['unique']) { - $index_string .= " UNIQUE "; + $index_string .= ' UNIQUE '; } $index_string .= " INDEX `{$index['name']}` "; - if (in_array($index['type'], ['RTREE', 'BTREE', 'HASH',])) { + if (in_array($index['type'], array('RTREE', 'BTREE', 'HASH'))) { $index_string .= " USING {$index['type']} "; } $index_string .= " on `{$index['table']}` "; - $fields = []; + $fields = array(); foreach ($index['fields'] as $f) { $len = intval($f['length']) ? "({$f['length']})" : ''; $fields[] = "`{$f['name']}`".$len; } - $index_string .= "(".implode(',', $fields).")"; + $index_string .= '('.implode(',', $fields).')'; } return $index_string; } - protected function dropIndex($index) - { - return "DROP INDEX `{$index['name']}` ON `{$index['table']}`"; - } - - protected function getConstraintForColumn(mysqli $connection, $table, $col_name) - { - $q = "select database() as dbname"; - $res = $connection->query($q); - $row = $res->fetch_array(MYSQLI_ASSOC); - $dbname = $row['dbname']; - Output::verbose("DATABASE: {$row['dbname']}"); - - $sql - = "SELECT k.CONSTRAINT_SCHEMA,k.CONSTRAINT_NAME,k.TABLE_NAME,k.COLUMN_NAME,k.REFERENCED_TABLE_NAME,k.REFERENCED_COLUMN_NAME, r.UPDATE_RULE, r.DELETE_RULE FROM information_schema.key_column_usage k LEFT JOIN information_schema.referential_constraints r ON r.CONSTRAINT_SCHEMA = k.CONSTRAINT_SCHEMA AND k.REFERENCED_TABLE_NAME=r.REFERENCED_TABLE_NAME LEFT JOIN information_schema.table_constraints t ON t.CONSTRAINT_SCHEMA = r.CONSTRAINT_SCHEMA WHERE k.constraint_schema='$dbname' AND t.CONSTRAINT_TYPE='FOREIGN KEY' AND k.TABLE_NAME='$table' AND r.TABLE_NAME='$table' AND t.TABLE_NAME='$table' AND k.COLUMN_NAME='$col_name'"; - Output::verbose($sql); - $res = $connection->query($sql); - $row = $res->fetch_array(MYSQLI_ASSOC); - - if (!count($row)) { - return false; - } - - $constraint = [ - 'table' => $table, - 'name' => $row['CONSTRAINT_NAME'], - 'column' => $row['COLUMN_NAME'], - 'reference' => [ - 'table' => $row['REFERENCED_TABLE_NAME'], - 'column' => $row['REFERENCED_COLUMN_NAME'], - 'update' => $row['UPDATE_RULE'], - 'delete' => $row['DELETE_RULE'], - ] - ]; - //echo "=================\n\n\n\========="; - //var_dump($constraint); - return $constraint; - } - - protected function dropConstraint($index) - { - if (!isset($index['constraint']['column']) || !strlen($index['constraint']['column'])) { - return ''; - } - $sql = "ALTER TABLE `{$index['constraint']['table']}` "."DROP FOREIGN KEY `{$index['constraint']['name']}` "; - - //echo "DELETE==================================\n$sql\n"; - //var_dump($index['constraint']); - return $sql; - } - - protected function addConstraint($index) - { - if (!isset($index['constraint']['column']) || !strlen($index['constraint']['column'])) { - return ''; - } - $sql = "ALTER TABLE `{$index['constraint']['table']}` "."ADD CONSTRAINT `{$index['constraint']['name']}` "."FOREIGN KEY (`{$index['constraint']['column']}`) " - ."REFERENCES `{$index['constraint']['reference']['table']}` "."(`{$index['constraint']['reference']['column']}`) "."ON UPDATE {$index['constraint']['reference']['update']} " - ."ON DELETE {$index['constraint']['reference']['delete']} "; - //echo "ADD==================================\n$sql\n\n"; - //var_dump($index['constraint']); - return $sql; - } - protected function getRoutinesDifference($type) { $current_routines = Helper::getRoutines($type); $published_routines = Helper::getRoutines($type); - sort($current_routines); sort($published_routines); $this->createFullRoutineDifference($current_routines, $published_routines, $type); - $common = array_intersect($current_routines, $published_routines); $this->createDifferenceBetweenRoutines($common, $type); } @@ -433,6 +401,11 @@ protected function addCreateRoutine($tname, $db, $type) $this->up(Helper::getSqlForRoutineCreation($tname, $db, $type)); } + protected function dropRoutine($r, $type) + { + return "DROP {$type} IF EXISTS `{$r}`"; + } + protected function addDropRoutine($tname, $db, $type) { $this->up($this->dropRoutine($tname, $type)); @@ -440,11 +413,6 @@ protected function addDropRoutine($tname, $db, $type) $this->down(Helper::getSqlForRoutineCreation($tname, $db, $type)); } - protected function dropRoutine($r, $type) - { - return "DROP $type IF EXISTS `{$r}`"; - } - protected function createDifferenceBetweenRoutines($routines, $type) { foreach ($routines as $rname) { @@ -459,4 +427,4 @@ protected function createDifferenceBetweenRoutines($routines, $type) $this->down($publishedSql); } } -} +} \ No newline at end of file diff --git a/lib/helpController.class.php b/lib/helpController.class.php index 75ac319..5274d3b 100644 --- a/lib/helpController.class.php +++ b/lib/helpController.class.php @@ -2,26 +2,24 @@ class helpController extends AbstractController { - public function runStrategy() { $output - = <<askForRewriteInformation(); require_once $fname; $sc = new Schema(); $sc->load(Helper::getDbObject()); - } public function askForRewriteInformation() { - if (intval(Helper::get("forceyes"))) { + if (intval(Helper::get('forceyes'))) { return; } - if (intval(Helper::get("noninteractive"))) { - exit; + if (intval(Helper::get('noninteractive'))) { + die; } - $c = ''; do { - if ($c != "\n") { - echo "Can I rewrite tables in database (all data will be lost) [y/n]? "; + if ($c != ' +' + ) { + echo 'Can I rewrite tables in database (all data will be lost) [y/n]? '; } $c = fread(STDIN, 1); - if ($c === 'Y' or $c === 'y') { return; } if ($c === 'N' or $c === 'n') { - echo "\nExit without changing shema\n"; - exit; + echo ' +Exit without changing shema +'; + die; } - } while (true); } -} +} \ No newline at end of file diff --git a/lib/listController.class.php b/lib/listController.class.php index 6b8b02f..adba55a 100644 --- a/lib/listController.class.php +++ b/lib/listController.class.php @@ -2,37 +2,29 @@ class listController extends AbstractController { - - protected $queries = []; + protected $queries = array(); public function runStrategy() { - - $db = Helper::getDbObject(); - + $db = Helper::getDbObject(); $migrations = Helper::getAllMigrations(); - - $revisions = Helper::getDatabaseVersions($db); - $revision = Helper::getDatabaseVersion($db); - $aliases = Helper::getDatabaseAliases(); - + $revisions = Helper::getDatabaseVersions($db); + $revision = Helper::getDatabaseVersion($db); + $aliases = Helper::getDatabaseAliases(); foreach ($migrations as $migration) { - $prefix = ($migration == $revision) ? ' *** ' : ' '; + $prefix = $migration == $revision ? ' *** ' : ' '; $suffix = ' '; - //Mark any unapplied revisions if ($migration < $revision && !in_array($migration, $revisions)) { $prefix .= '[n] '; } else { $prefix .= ' '; } - if (array_key_exists($migration,$aliases)){ - $suffix .= '('. $aliases[$migration] . ')'; - + if (array_key_exists($migration, $aliases)) { + $suffix .= '('.$aliases[$migration].')'; } - - echo $prefix.date('r', $migration).$suffix."\n"; + echo $prefix.date('r', $migration).$suffix.' +'; } } -} - +} \ No newline at end of file diff --git a/lib/migrateController.class.php b/lib/migrateController.class.php index 987f30b..56538b5 100644 --- a/lib/migrateController.class.php +++ b/lib/migrateController.class.php @@ -2,39 +2,7 @@ class migrateController extends AbstractController { - - protected $queries = []; - - /** - * @param $migration String|Integer - * - * @return string - * @internal param $aliases - * - */ - protected static function getMigrationAlias($migration) - { - static $aliases = null; - if ($aliases === null) { - $aliases = Helper::getDatabaseAliases(); - } - if (array_key_exists($migration, $aliases)) { - $current_suffix = Helper::TAB."(\033[32m".$aliases[$migration]."\033[37m)"; - - return $current_suffix; - } else { - $current_suffix = Helper::TAB; - - return $current_suffix; - } - } - - protected static function filterValidTimestamp($timestamp) - { - return ((is_numeric($timestamp)) - && (+$timestamp <= PHP_INT_MAX) - && (+$timestamp >= ~PHP_INT_MAX) ? +$timestamp : false); - } + protected $queries = array(); /** * @return bool @@ -43,61 +11,51 @@ protected static function filterValidTimestamp($timestamp) public function runStrategy() { $db = Helper::getDbObject(); - - if (empty($this->args)) { $this->args[] = 'now'; } - - $str = implode(' ', $this->args); - + $str = implode(' ', $this->args); $target_migration = strtotime($str); - - if (false === $target_migration) { //did not specify valid time string, check if specified a timestamp + if (false === $target_migration) { + //did not specify valid time string, check if specified a timestamp $target_migration = self::filterValidTimestamp($str); - if (false === $target_migration) { //did not specify valid timestamp, check if specified an alias + if (false === $target_migration) { + //did not specify valid timestamp, check if specified an alias $target_migration = self::filterValidTimestamp(Helper::getRevByAlias($str)); - if (false === $target_migration) { //did not specify valid alias - throw new Exception("Time (or alias) is not correct"); + if (false === $target_migration) { + //did not specify valid alias + throw new Exception('Time (or alias) is not correct'); } } } - $migrations = Helper::getAllMigrations(); $revisions = Helper::getDatabaseVersions($db); - - if ($revisions === false) { throw new Exception('Could not access revisions table'); } - if (empty($revisions)) { Output::error('Revision table is empty. Initial schema not applied properly?'); return false; } - $revision = max($revisions); $unapplied_migrations = array_diff($migrations, $revisions); - - if (empty($migrations) || (empty($unapplied_migrations) && $revision == max($migrations) && $target_migration > $revision)) { - echo "\033[31m". 'No new migrations available'. "\033[37m".PHP_EOL; + if (empty($migrations) || empty($unapplied_migrations) && $revision == max($migrations) && $target_migration > $revision) { + echo ''.'No new migrations available'.''.PHP_EOL; return true; } if ($revision < min($migrations) && $target_migration < $revision) { - echo "\033[31m". 'No older migrations available'. "\033[37m".PHP_EOL; + echo ''.'No older migrations available'.''.PHP_EOL; return true; } if ($target_migration == $revision) { - echo "\033[31m".'Target migration is the current revision: ' . "\033[37m" . date('r', $target_migration).self::getMigrationAlias($target_migration).PHP_EOL; + echo ''.'Target migration is the current revision: '.''.date('r', $target_migration).self::getMigrationAlias($target_migration).PHP_EOL; return true; } - echo "Will migrate: ".date('r', $revision).self::getMigrationAlias($revision).' ---> '.date('r', $target_migration).self::getMigrationAlias($target_migration).PHP_EOL.PHP_EOL; - - + echo 'Will migrate: '.date('r', $revision).self::getMigrationAlias($revision).' ---> '.date('r', $target_migration).self::getMigrationAlias($target_migration).PHP_EOL.PHP_EOL; $direction = $revision <= $target_migration ? Helper::UP : Helper::DOWN; if ($direction === Helper::DOWN) { $migrations = array_reverse($migrations); @@ -133,5 +91,33 @@ public function runStrategy() return true; } -} + protected static function filterValidTimestamp($timestamp) + { + return is_numeric($timestamp) && +$timestamp <= PHP_INT_MAX && +$timestamp >= ~PHP_INT_MAX ? +$timestamp : false; + } + + /** + * @param $migration String|Integer + * + * @return string + * @internal param $aliases + * + */ + protected static function getMigrationAlias($migration) + { + static $aliases = null; + if ($aliases === null) { + $aliases = Helper::getDatabaseAliases(); + } + if (array_key_exists($migration, $aliases)) { + $current_suffix = Helper::TAB.'('.$aliases[$migration].')'; + + return $current_suffix; + } else { + $current_suffix = Helper::TAB; + + return $current_suffix; + } + } +} \ No newline at end of file diff --git a/lib/schemaController.class.php b/lib/schemaController.class.php index 83ec024..55b1660 100644 --- a/lib/schemaController.class.php +++ b/lib/schemaController.class.php @@ -2,47 +2,40 @@ class schemaController extends AbstractController { - - protected $queries = []; + protected $queries = array(); public function runStrategy() { Helper::initDirForSavedMigrations(); Helper::initVersionTable(); - $db = Helper::getDbObject(); - foreach (Helper::getTables($db) as $table) { $query = Helper::getSqlForTableCreation($table, $db); $this->queries[] = "DROP TABLE IF EXISTS `{$table}`"; $this->queries[] = $query; } - - foreach (Helper::getRoutines("PROCEDURE") as $routine) { + foreach (Helper::getRoutines('PROCEDURE') as $routine) { $query = Helper::getSqlForRoutineCreation($routine, $db, 'PROCEDURE'); $this->queries[] = "DROP PROCEDURE IF EXISTS `{$routine}`"; $this->queries[] = $query; } - - foreach (Helper::getRoutines("FUNCTION") as $routine) { + foreach (Helper::getRoutines('FUNCTION') as $routine) { $query = Helper::getSqlForRoutineCreation($routine, $db, 'FUNCTION'); $this->queries[] = "DROP FUNCTION IF EXISTS `{$routine}`"; $this->queries[] = $query; } - $vtab = Helper::get('versiontable'); $res = $db->query("SELECT MAX(rev) FROM `{$vtab}`"); $row = $res->fetch_array(MYSQLI_NUM); $maxrev = $row[0]; $this->queries[] = "INSERT INTO `{$vtab}` SET rev={$maxrev}"; - - $atab = Helper::get('aliastable'); + $atab = Helper::get('aliastable'); if (false !== $atab) { $aprefix = Helper::get('aliasprefix') ?: ''; $res = $db->query("SELECT `alias` FROM `{$atab}` WHERE `rev` = {$maxrev}"); $row = $res->fetch_array(MYSQLI_NUM); - $alias = isset($row[0]) && ($row[0] !== null) ? $row[0] : "{$aprefix}0"; - $this->queries[] = "INSERT INTO `{$atab}` SET rev={$maxrev}, alias='$alias'"; + $alias = isset($row[0]) && $row[0] !== null ? $row[0] : "{$aprefix}0"; + $this->queries[] = "INSERT INTO `{$atab}` SET rev={$maxrev}, alias='{$alias}'"; } return $this->writeInFile(); @@ -64,32 +57,32 @@ protected function askForRewrite($fname) if (!file_exists($fname)) { return true; } - if (intval(Helper::get("forceyes"))) { + if (intval(Helper::get('forceyes'))) { return true; } - if (intval(Helper::get("noninteractive"))) { + if (intval(Helper::get('noninteractive'))) { return false; } $c = ''; do { - if ($c != "\n") { + if ($c != ' +' + ) { echo "File: {$fname} already exists! Can I rewrite it [y/n]? "; } $c = fread(STDIN, 1); - if ($c === 'Y' or $c === 'y') { return true; } if ($c === 'N' or $c === 'n') { - echo "\nExit without saving\n"; + echo ' +Exit without saving +'; return false; } - } while (true); return true; } - - -} +} \ No newline at end of file diff --git a/migration.php b/migration.php index d8911b2..2d72b28 100755 --- a/migration.php +++ b/migration.php @@ -1,35 +1,29 @@ -#!/usr/bin/env php + #!/usr/bin/env php +runStrategy(); -} -else -{ - Output::error('mmp: unknown command "' . $cli_params['command']['name'] . '"'); - Helper::getController('help')->runStrategy(); - exit(1); -} - +if ($controller !== false) { + $controller->runStrategy(); +} else { + Output::error('mmp: unknown command "'.$cli_params['command']['name'].'"'); + Helper::getController('help')->runStrategy(); + die(1); +} \ No newline at end of file diff --git a/phing/MMPTask.php b/phing/MMPTask.php index 3a59375..0000483 100644 --- a/phing/MMPTask.php +++ b/phing/MMPTask.php @@ -5,29 +5,24 @@ * Date: 11/7/12 * Package: MPP */ - -class MMPTask extends Task { - +class MMPTask extends Task +{ /** * The params passed in the buildfile. */ private $params = array(); - /** * The config_file passed in the buildfile. */ private $config_file = null; - /** * Config options for MMP. */ private $options = array(); - /** * Migration options for MMP. */ private $action_options = null; - /** * Migration options for MMP. */ @@ -38,7 +33,8 @@ class MMPTask extends Task { * * @param $str */ - public function setHost($str) { + public function setHost($str) + { $this->params['host'] = $str; } @@ -47,7 +43,8 @@ public function setHost($str) { * * @param $str */ - public function setUser($str) { + public function setUser($str) + { $this->params['user'] = $str; } @@ -56,7 +53,8 @@ public function setUser($str) { * * @param $str */ - public function setPassword($str) { + public function setPassword($str) + { $this->params['password'] = $str; } @@ -65,7 +63,8 @@ public function setPassword($str) { * * @param $str */ - public function setDb($str) { + public function setDb($str) + { $this->params['db'] = $str; } @@ -74,7 +73,8 @@ public function setDb($str) { * * @param $str */ - public function setVersiontable($str) { + public function setVersiontable($str) + { $this->params['versiontable'] = $str; } @@ -83,7 +83,8 @@ public function setVersiontable($str) { * * @param $str */ - public function setAliastable($str) { + public function setAliastable($str) + { $this->params['aliastable'] = $str; } @@ -92,7 +93,8 @@ public function setAliastable($str) { * * @param $str */ - public function setAliasprefix($str) { + public function setAliasprefix($str) + { $this->params['aliasprefix'] = $str; } @@ -101,8 +103,9 @@ public function setAliasprefix($str) { * * @param $str */ - public function setSavedir($str) { - $this->params['savedir'] = __DIR__ . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . $str; + public function setSavedir($str) + { + $this->params['savedir'] = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.$str; } /** @@ -110,7 +113,8 @@ public function setSavedir($str) { * * @param $str */ - public function setVerbose($str) { + public function setVerbose($str) + { $this->params['verbose'] = $str; } @@ -119,8 +123,9 @@ public function setVerbose($str) { * * @param $str */ - public function setExclude_tables($str) { - $this->params['exclude_tables'] = array_filter(explode(",",preg_replace("/\s/m", "", $str))); + public function setExclude_tables($str) + { + $this->params['exclude_tables'] = array_filter(explode(',', preg_replace('/\\s/m', '', $str))); } /** @@ -128,8 +133,9 @@ public function setExclude_tables($str) { * * @param $str */ - public function setConfig_file($str) { - $this->config_file = __DIR__ . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . $str; + public function setConfig_file($str) + { + $this->config_file = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.$str; } /** @@ -137,8 +143,9 @@ public function setConfig_file($str) { * * @param $str */ - public function setAction_options($str) { - $this->action_options = explode(" ", trim($str, " ")); + public function setAction_options($str) + { + $this->action_options = explode(' ', trim($str, ' ')); } /** @@ -146,37 +153,37 @@ public function setAction_options($str) { * * @param $str */ - public function setAction($str) { + public function setAction($str) + { $this->action = $str; } /** * The init method. */ - public function init() { - require_once __DIR__ . '/../init.php'; + public function init() + { + require_once __DIR__.'/../init.php'; } /** * The main entry point method. */ - public function main() { - if(file_exists($this->config_file)){ + public function main() + { + if (file_exists($this->config_file)) { $this->options = parse_ini_file($this->config_file); } - $this->options = array_replace($this->options, $this->params); //task params overrides everything - + $this->options = array_replace($this->options, $this->params); + //task params overrides everything Helper::setConfig($this->options); - $controller = Helper::getController($this->action, $this->action_options); - - if($controller !== false){ + if ($controller !== false) { $controller->runStrategy(); - }else{ - Output::error('mmp: unknown command "' . $this->action . '"'); + } else { + Output::error('mmp: unknown command "'.$this->action.'"'); Helper::getController('help')->runStrategy(); - exit(1); + die(1); } } -} - +} \ No newline at end of file