public static function generateVersion($version, $migrationsDir) { // create dir mkdir($migrationsDir . DIRECTORY_SEPARATOR . $version); // get tables $tables = Connection::getTables(); /** @var Table $table */ foreach ($tables as $table) { Generator::generateTable($version, $table); } }
public function migrate() { echo "\n" . $this->version . "\n"; $dir = Loader::dirForVersion($this->version); $files = glob($dir . "*.php"); $tableClasses = array_map(function ($element) { return basename($element, ".php"); }, $files); // Load tables foreach ($tableClasses as $table) { Loader::loadModelVersion($table, $this->version); $class = Loader::classNameForVersion($table, $this->version); $this->tables[] = new $class(); } $current = Connection::getTableNames(); $removed = array_diff($current, $tableClasses); //we don't want the db_migration table removed if (($key = array_search('db_migration', $removed)) !== false) { unset($removed[$key]); } Connection::begin(); // pre action for every table foreach ($this->tables as $table) { if (method_exists($table, 'pre')) { $table->pre(); } } $this->dropReferences(); $this->dropIndexes(); $this->doTables(); $this->createIndexes(); $this->createReferences(); echo "Dropping tables\n"; Connection::dropTables($removed); // post action for every table foreach ($this->tables as $table) { if (method_exists($table, 'post')) { $table->post(); } } Connection::commit(); echo "\n"; }
private function drop(array $array1, array $array2, $tableName, $dropType) { //$drop = $this->arrayDiffNamed($array1, $array2); $drop = $this->arrayDiffSql($array1, $array2); if (!empty($drop)) { // Prepare sql statement $query = "ALTER TABLE `" . $tableName . "`\n\t"; /** @var Descriptor $d */ $statements = []; foreach ($drop as $d) { $statements[] = "DROP {$dropType} `" . $d->getName() . "`"; } $query .= implode(",\n\t", $statements); Connection::query($query); } }
public function run(array &$output = null) { if (isset($output)) { $output[] = "Running Caribou MySQL migration"; } //create db_migration table if it doesn't exist $result = Connection::query("CREATE TABLE IF NOT EXISTS `db_migration`\n ( `db_migration_id` INT(11) NOT NULL AUTO_INCREMENT , `from` VARCHAR(5) NOT NULL ,\n `to` VARCHAR(5) NOT NULL , `status` VARCHAR(10) NOT NULL ,\n `timestamp_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , `timestamp_edited` DATETIME NULL DEFAULT NULL ,\n PRIMARY KEY (`db_migration_id`)) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_bin"); if ($result === false) { return $this->exit("Couldn't create db migration table.", $output); } //get current version of the database $result = Connection::query("SELECT * FROM `db_migration` WHERE 1 ORDER BY `db_migration_id` DESC LIMIT 1"); if ($result->num_rows == 0) { $currentVersion = '0.0.0'; } else { $lastMigration = $result->fetch_assoc(); $currentVersion = $lastMigration['to']; if ($lastMigration['status'] !== 'migrated') { return $this->exit("The last db_migration isn't finished migrating!", $output); } } if (!is_dir($this->migrationsDir)) { $message = "MigrationsDir is not a directory: " . var_export($this->migrationsDir, true); return $this->exit($message, $output); } // apply migrations one after the other $content = scandir($this->migrationsDir, SCANDIR_SORT_ASCENDING); natsort($content); $from = $currentVersion; $to = current(array_slice($content, -1)); if ($from === $to) { return $this->exit("Nothing to migrate", $output); } //insert current db migration into db_migration table within the database $result = Connection::query("INSERT INTO `db_migration`(`from`, `to`, `status`)\n VALUES ('" . $from . "', '" . $to . "', 'migrating')"); if ($result === false) { return $this->exit("Couldn't insert db migration into db_migration table", $output); } $dbMigrationId = Connection::getInsertId(); //cycle trough migrating and migrate database. $version = $currentVersion; foreach ($content as $c) { $versionDir = $this->migrationsDir . DIRECTORY_SEPARATOR . $c; if (is_dir($versionDir) && $c != "." && $c != ".." && strnatcmp($currentVersion, $c) < 0) { if (isset($output)) { if ($version != "") { $output[] = "{$version} -> {$c}"; echo "{$version} -> {$c}\n"; } else { echo "{$c}\n"; $output[] = "{$c}"; } } $migration = new Migration($c); $migration->migrate(); $version = $c; } } if (isset($output)) { $m = "Migrated"; $m .= " from " . $from; $m .= " to {$to}"; $output[] = $m; } //update status to migrated $result = Connection::query("UPDATE `db_migration`\n SET `status` = 'migrated', `timestamp_edited` = now() WHERE `db_migration_id` = '" . $dbMigrationId . "'"); if ($result === false) { return $this->exit("Couldn't update db_migration entry", $output); } }
public static function getTable($name) { $table = new Table($name); self::fillTableColumns($table); $options = Connection::getTableStatus($table->getName()); $table->setCollate($options['collate']); $table->setEngine($options['engine']); if (array_key_exists('autoIncrement', $options)) { $table->setAutoIncrement($options['autoIncrement']); } $indexes = Connection::getTableIndices($table->getName()); $table->setIndexes($indexes); $references = Connection::getTableReferences($table->getName()); $table->setReferences($references); return $table; }