- aether-medical: Stationen/Belegung, Intensivstation, Blutbank, Fuhrpark, Nachrichten/Aushänge, Berichte und Textbausteine (server + NUI) - aether-admin: vollständiges Server-Admin-Panel als echtes FiveM-Resource, an aether-core gekoppelt (Rechte über aether_users.admin_group), mit WebRTC-Live-Kameras (Bildschirmfreigabe) und separatem Media-Server (SFU) - Prototypen admin/ vervollständigt - SQL-Schema aether_admin.sql - Docker-Compose mit MariaDB und idempotenter Auto-Migration (schema_migrations) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
89 lines
2.9 KiB
Bash
89 lines
2.9 KiB
Bash
#!/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 <datei> <schluessel> <tolerant:0|1>
|
|
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."
|