99 lines
3.1 KiB
PHP
99 lines
3.1 KiB
PHP
<?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.');
|
||
}
|