#!/bin/sh # ===================================================================== # Aether — Datenbank-Migrator # # Spielt die Schemas aus /sql in fester Reihenfolge ein und merkt sich # jede angewendete Datei in der Tabelle `schema_migrations`. Ein # erneuter Lauf überspringt, was schon drin ist. # # Basis-Schemas : idempotent (CREATE TABLE IF NOT EXISTS) — Abbruch bei Fehler # updates/*.sql : Nachträge — fehlertolerant (z. B. "Duplicate column" # auf frischer DB ist unkritisch und wird nur vermerkt) # ===================================================================== set -eu HOST="${DB_HOST:-db}" DB="${DB_NAME:-aether}" SQLDIR="${SQL_DIR:-/sql}" export MYSQL_PWD="${DB_ROOT_PASSWORD:-}" # Alle Client-Aufrufe laufen als root über diesen Wrapper run() { mariadb -h "$HOST" -u root "$@"; } # --- Auf die Datenbank warten (depends_on sollte reichen, sicher ist sicher) --- echo "[migrate] warte auf ${HOST} ..." i=0 until run -e "SELECT 1" >/dev/null 2>&1; do i=$((i + 1)) if [ "$i" -gt 60 ]; then echo "[migrate] DB nicht erreichbar — Abbruch."; exit 1; fi sleep 2 done # --- Datenbank + Migrationstabelle sicherstellen --- run -e "CREATE DATABASE IF NOT EXISTS \`${DB}\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" run "$DB" -e "CREATE TABLE IF NOT EXISTS schema_migrations ( name VARCHAR(255) PRIMARY KEY, applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP );" schon_angewendet() { [ "$(run -N -s "$DB" -e "SELECT COUNT(*) FROM schema_migrations WHERE name='$1'")" != "0" ] } merken() { run "$DB" -e "INSERT IGNORE INTO schema_migrations (name) VALUES ('$1')" } # anwenden anwenden() { datei="$1"; schluessel="$2"; tolerant="${3:-0}" if schon_angewendet "$schluessel"; then echo "[migrate] ✓ ${schluessel} (bereits angewendet)" return 0 fi echo "[migrate] → ${schluessel}" if run "$DB" < "$datei"; then merken "$schluessel" echo "[migrate] ok" elif [ "$tolerant" = "1" ]; then echo "[migrate] ! Fehler ignoriert (Nachtrag evtl. schon enthalten) — als angewendet vermerkt" merken "$schluessel" else echo "[migrate] ✗ FEHLER beim Einspielen von ${schluessel} — Abbruch." exit 1 fi } # --- Basis-Schemas in fester Reihenfolge (aether zuerst) --- for f in aether.sql aether_medical.sql aether_police.sql aether_admin.sql; do [ -f "${SQLDIR}/${f}" ] && anwenden "${SQLDIR}/${f}" "$f" 0 done # --- Weitere Schemas, die evtl. später hinzukommen (alphabetisch) --- for f in "${SQLDIR}"/*.sql; do [ -f "$f" ] || continue base="$(basename "$f")" case "$base" in aether.sql|aether_medical.sql|aether_police.sql|aether_admin.sql) ;; # schon oben *) anwenden "$f" "$base" 0 ;; esac done # --- Nachträge (fehlertolerant) --- if [ -d "${SQLDIR}/updates" ]; then for f in "${SQLDIR}"/updates/*.sql; do [ -f "$f" ] && anwenden "$f" "updates/$(basename "$f")" 1 done fi echo "[migrate] fertig."