Files
Adminator 1e51ef7def Nachtrag: alle bisher untracked Ordner + hängende Änderungen mit-committen
- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/
- 12 code-workspace-Files
- STATUS-*.md
- viele M/D/R-Änderungen an bereits getrackten Files
- .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-08 02:27:02 +02:00

66 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
/**
* Prüft, dass migrations.sql idempotent ist.
* Heuristik: alle CREATE TABLE müssen IF NOT EXISTS haben,
* alle ALTER TABLE ADD COLUMN ebenfalls.
*/
function check_migrations(string $dir, array $m, Report $r): void {
$sqlPath = "$dir/db/migrations.sql";
if (!file_exists($sqlPath)) {
$r->fail("db/migrations.sql fehlt");
return;
}
$sql = file_get_contents($sqlPath);
// Kommentare entfernen
$sqlNoComments = preg_replace('/--.*$/m', '', $sql);
$sqlNoComments = preg_replace('/\/\*.*?\*\//s', '', $sqlNoComments);
// CREATE TABLE ohne IF NOT EXISTS
if (preg_match_all('/\bCREATE\s+TABLE\b(?!\s+IF\s+NOT\s+EXISTS)/i', $sqlNoComments, $m1)) {
$r->fail("CREATE TABLE muss 'IF NOT EXISTS' haben (Idempotenz)", $m1[0]);
}
// ALTER TABLE ... ADD COLUMN ohne IF NOT EXISTS
if (preg_match_all('/\bADD\s+COLUMN\b(?!\s+IF\s+NOT\s+EXISTS)/i', $sqlNoComments, $m2)) {
$r->fail("ADD COLUMN muss 'IF NOT EXISTS' haben (Idempotenz)", $m2[0]);
}
// DROP-Statements verboten (außer in Kommentaren, die wir entfernt haben)
if (preg_match('/\bDROP\s+(TABLE|COLUMN|INDEX)\b/i', $sqlNoComments)) {
$r->fail("DROP-Statements in migrations.sql verboten (additive Migration!)");
}
// TRUNCATE verboten
if (preg_match('/\bTRUNCATE\b/i', $sqlNoComments)) {
$r->fail("TRUNCATE in migrations.sql verboten");
}
// RENAME verboten
if (preg_match('/\bRENAME\b/i', $sqlNoComments)) {
$r->fail("RENAME-Statements verboten (additive Migration!)");
}
// Tabellen-Prefix prüfen
if (!empty($m['slug'])) {
$expectedPrefix = "m_{$m['slug']}_";
if (preg_match_all('/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?`?(\w+)`?/i', $sqlNoComments, $tm)) {
foreach ($tm[1] as $tbl) {
if (!str_starts_with($tbl, $expectedPrefix)) {
$r->fail("Tabelle '$tbl' muss Prefix '$expectedPrefix' haben");
}
}
}
}
// Wenn nichts gefehlerts: OK
$hasContent = trim(preg_replace('/\s+/', '', $sqlNoComments)) !== '';
if ($hasContent) {
$r->ok("migrations.sql ist idempotent (CREATE/ALTER mit IF NOT EXISTS, keine DROP/TRUNCATE/RENAME)");
} else {
$r->ok("migrations.sql ist leer (Modul ohne eigene Tabellen)");
}
}