mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
add incremental migration runner to deploy recipe — execute whole SQL files (not semicolon-split), catch 'no such column' for idempotent re-runs, merge into migrate.sh
This commit is contained in:
@@ -64,38 +64,26 @@ foreach ($files as $name => $file) {
|
||||
echo "Applying: $name\n";
|
||||
$sql = file_get_contents($file);
|
||||
|
||||
// Split into individual statements to handle partial failures gracefully
|
||||
// (e.g. ALTER TABLE may fail with "duplicate column" but DROP VIEW must still run)
|
||||
$statements = array_filter(
|
||||
array_map('trim', explode(';', $sql)),
|
||||
fn($s) => $s !== ''
|
||||
);
|
||||
|
||||
$errors = [];
|
||||
foreach ($statements as $stmt) {
|
||||
try {
|
||||
$pdo->exec($stmt . ';');
|
||||
} catch (PDOException $e) {
|
||||
$msg = $e->getMessage();
|
||||
if (stripos($msg, 'duplicate column name') !== false
|
||||
|| stripos($msg, 'no such column') !== false) {
|
||||
echo " Skipping (already applied): " . substr($stmt, 0, 60) . "...\n";
|
||||
continue;
|
||||
}
|
||||
$errors[] = $msg;
|
||||
try {
|
||||
$pdo->exec($sql);
|
||||
} catch (PDOException $e) {
|
||||
$msg = $e->getMessage();
|
||||
// Ignore idempotent errors (column/trigger/index already exists or already removed)
|
||||
if (stripos($msg, 'duplicate column name') !== false
|
||||
|| stripos($msg, 'already exists') !== false
|
||||
|| stripos($msg, 'no such column') !== false) {
|
||||
echo " Skipping (already applied)\n";
|
||||
} else {
|
||||
echo " FAILED: $msg\n";
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
$pdo->prepare("INSERT OR REPLACE INTO _migrations (name) VALUES (?)")->execute([$name]);
|
||||
if (str_starts_with($file, $pendingDir)) {
|
||||
rename($file, $appliedDir . '/' . $name);
|
||||
}
|
||||
$count++;
|
||||
} else {
|
||||
echo " FAILED: " . implode(' | ', $errors) . "\n";
|
||||
throw new PDOException(implode(' | ', $errors));
|
||||
$pdo->prepare("INSERT OR REPLACE INTO _migrations (name) VALUES (?)")->execute([$name]);
|
||||
if (str_starts_with($file, $pendingDir)) {
|
||||
rename($file, $appliedDir . '/' . $name);
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
|
||||
echo "$count migration(s) applied.\n";
|
||||
|
||||
Reference in New Issue
Block a user