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); } }