Final prep for production
This commit is contained in:
+109
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* Database Migration Runner
|
||||
* Usage: php migrate.php
|
||||
*
|
||||
* - Scans migrations/*.sql in filename order
|
||||
* - Skips files already recorded in wms.schema_migrations
|
||||
* - Each .sql file must declare its target DB on the first line:
|
||||
* -- db: wms
|
||||
* or
|
||||
* -- db: wms2
|
||||
* - Stops on first error and reports the failed file
|
||||
*/
|
||||
|
||||
define('ROOT', __DIR__);
|
||||
|
||||
require ROOT . '/app/config.php';
|
||||
|
||||
// ── Connections ────────────────────────────────────────────────────────────
|
||||
function connect(string $host, string $user, string $pass, string $db): PDO
|
||||
{
|
||||
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass, [
|
||||
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
|
||||
]);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
$pdo_wms = connect($db_server, $db_user, $db_pass, $db_database);
|
||||
$pdo_wms2 = connect($db_server2, $db_user2, $db_pass2, $db_database2);
|
||||
|
||||
// ── Ensure tracking table exists ───────────────────────────────────────────
|
||||
$pdo_wms->exec("
|
||||
CREATE TABLE IF NOT EXISTS `schema_migrations` (
|
||||
`version` varchar(64) NOT NULL,
|
||||
`applied_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||
PRIMARY KEY (`version`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
|
||||
");
|
||||
|
||||
// ── Load already-applied versions ─────────────────────────────────────────
|
||||
$applied = $pdo_wms->query("SELECT version FROM schema_migrations")
|
||||
->fetchAll(PDO::FETCH_COLUMN);
|
||||
$applied = array_flip($applied);
|
||||
|
||||
// ── Scan migration files ───────────────────────────────────────────────────
|
||||
$files = glob(ROOT . '/migrations/*.sql');
|
||||
sort($files);
|
||||
|
||||
if (empty($files)) {
|
||||
echo "No migration files found in migrations/\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$pending = array_filter($files, fn($f) => !isset($applied[basename($f)]));
|
||||
|
||||
if (empty($pending)) {
|
||||
echo "Nothing to migrate — all migrations already applied.\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// ── Run pending migrations ─────────────────────────────────────────────────
|
||||
foreach ($pending as $file) {
|
||||
$name = basename($file);
|
||||
$sql = file_get_contents($file);
|
||||
|
||||
// Read target DB from first line: -- db: wms or -- db: wms2
|
||||
$first_line = strtok($sql, "\n");
|
||||
if (!preg_match('/^--\s*db:\s*(wms2?)\s*$/i', $first_line, $m)) {
|
||||
echo "[SKIP] $name — missing '-- db: wms' or '-- db: wms2' on line 1\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$target = strtolower($m[1]);
|
||||
$pdo = ($target === 'wms2') ? $pdo_wms2 : $pdo_wms;
|
||||
|
||||
echo "[RUN] $name → $target ... ";
|
||||
|
||||
try {
|
||||
foreach (split_statements($sql) as $stmt) {
|
||||
if (trim($stmt) !== '') {
|
||||
$st = $pdo->query($stmt);
|
||||
if ($st) $st->closeCursor();
|
||||
}
|
||||
}
|
||||
|
||||
$pdo_wms->prepare("INSERT INTO schema_migrations (version) VALUES (?)")
|
||||
->execute([$name]);
|
||||
|
||||
echo "OK\n";
|
||||
|
||||
} catch (PDOException $e) {
|
||||
echo "FAILED\n";
|
||||
echo "[ERROR] " . $e->getMessage() . "\n";
|
||||
echo "Migration halted. Fix $name and re-run.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
echo "Done.\n";
|
||||
|
||||
// ── Helpers ────────────────────────────────────────────────────────────────
|
||||
function split_statements(string $sql): array
|
||||
{
|
||||
// Strip comments, then split on semicolons
|
||||
$sql = preg_replace('/--[^\n]*\n/', "\n", $sql);
|
||||
$sql = preg_replace('/\/\*.*?\*\//s', '', $sql);
|
||||
return explode(';', $sql);
|
||||
}
|
||||
Reference in New Issue
Block a user