110 lines
3.9 KiB
PHP
110 lines
3.9 KiB
PHP
<?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);
|
|
}
|