Steuerkram/scripts/migrate.php

99 lines
3.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Automatisches Migrations-Script
* Wird beim Start des web-Containers ausgeführt (nach DB-Healthcheck).
* Prüft welche migrations/*.sql noch nicht angewendet wurden und führt sie aus.
*/
$host = getenv('DB_HOST') ?: 'db';
$dbName = getenv('DB_NAME') ?: 'steuerkram';
$dbUser = getenv('DB_USER') ?: 'steuerkram';
$dbPass = getenv('DB_PASS') ?: 'steuerkram';
$migrDir = __DIR__ . '/../migrations';
function mlog(string $msg): void {
echo '[migrate] ' . $msg . PHP_EOL;
}
mlog('Starte Migrations-Prüfung...');
try {
$pdo = new PDO(
"mysql:host=$host;dbname=$dbName;charset=utf8mb4",
$dbUser,
$dbPass,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (PDOException $e) {
echo '[migrate] FEHLER: DB-Verbindung fehlgeschlagen: ' . $e->getMessage() . PHP_EOL;
exit(1);
}
// schema_migrations anlegen falls nicht vorhanden
$pdo->exec('CREATE TABLE IF NOT EXISTS schema_migrations (
migration VARCHAR(255) NOT NULL PRIMARY KEY,
applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
)');
// Alle vorhandenen Migrations-Dateien ermitteln (alphabetisch)
$files = glob($migrDir . '/*.sql');
sort($files);
if (empty($files)) {
mlog('Keine Migrations-Dateien gefunden.');
exit(0);
}
// Prüfen ob schema_migrations leer ist, aber belege bereits existiert
// → bestehender Server: alle Dateien als applied markieren ohne Ausführung
$migrationCount = (int)$pdo->query('SELECT COUNT(*) FROM schema_migrations')->fetchColumn();
$belegeExists = (int)$pdo->query(
"SELECT COUNT(*) FROM information_schema.tables
WHERE table_schema = DATABASE() AND table_name = 'belege'"
)->fetchColumn();
if ($migrationCount === 0 && $belegeExists === 1) {
mlog('Bestehende Datenbank erkannt – markiere vorhandene Migrations-Dateien als applied...');
$stmt = $pdo->prepare('INSERT IGNORE INTO schema_migrations (migration) VALUES (?)');
foreach ($files as $file) {
$name = basename($file);
$stmt->execute([$name]);
mlog(' markiert: ' . $name);
}
mlog('Fertig – keine Migrationen ausgeführt.');
exit(0);
}
// Bereits angewendete Migrationen laden
$applied = $pdo->query('SELECT migration FROM schema_migrations')
->fetchAll(PDO::FETCH_COLUMN);
$applied = array_flip($applied);
// Neue Migrationen ausführen
$count = 0;
foreach ($files as $file) {
$name = basename($file);
if (isset($applied[$name])) {
continue;
}
mlog('Führe aus: ' . $name);
$sql = file_get_contents($file);
try {
// Mehrteilige SQL-Dateien (mehrere Statements) aufteilen und einzeln ausführen
$pdo->exec($sql);
$pdo->prepare('INSERT INTO schema_migrations (migration) VALUES (?)')
->execute([$name]);
$count++;
} catch (PDOException $e) {
echo '[migrate] FEHLER bei ' . $name . ': ' . $e->getMessage() . PHP_EOL;
exit(1);
}
}
if ($count === 0) {
mlog('Datenbank ist aktuell – keine Migrationen notwendig.');
} else {
mlog($count . ' Migration(en) erfolgreich angewendet.');
}