erste Version Online-Nennen

This commit is contained in:
stefan
2025-06-05 12:57:07 +02:00
parent 8fcc279679
commit ef59fa35b1
27 changed files with 3081 additions and 207 deletions
@@ -4,52 +4,67 @@ import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import org.jetbrains.exposed.sql.Database
import org.slf4j.LoggerFactory
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.transactions.transaction
import at.mocode.tables.TurniereTable
import at.mocode.tables.BewerbeTable
import at.mocode.tables.NennungenTable
import at.mocode.tables.NennungEventsTable
import java.io.File
/**
* Configures the database connection based on the environment.
* Supports three environments:
* - Test: Uses in-memory SQLite
* - Development (IDEA): Uses file-based SQLite
* - Production/Docker: Uses PostgreSQL with connection pooling
*/
fun configureDatabase() {
val log = LoggerFactory.getLogger("DatabaseInitialization")
var connectionSuccessful = false // Flag: Wurde irgendeine Verbindung hergestellt?
var connectionSuccessful = false // Flag: Was any connection established?
// Prüfen, ob wir in einer Testumgebung sind (z.B. über System Property)
// Check if we're in a test environment (e.g. via System Property)
val isTestEnvironment = System.getProperty("isTestEnvironment")?.toBoolean() ?: false
if (isTestEnvironment) {
log.info("Test environment detected, using in-memory H2 database (test)...")
log.info("Test environment detected, using SQLite in-memory database (test)...")
try {
// H2 im PostgreSQL-Kompatibilitätsmodus starten, kann helfen
Database.connect("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;MODE=PostgreSQL", driver = "org.h2.Driver")
log.info("Connected to H2 (test) successfully.")
Database.connect("jdbc:sqlite::memory:", driver = "org.sqlite.JDBC")
log.info("Connected to SQLite in-memory (test) successfully.")
connectionSuccessful = true
} catch (e: Exception) {
log.error("Failed to connect to H2 (test)!", e)
throw e // Fehler weiterwerfen, Test soll fehlschlagen
log.error("Failed to connect to SQLite (test)!", e)
throw e // Rethrow error, test should fail
}
} else {
// Prüfen, ob wir in IDEA laufen (keine Docker Umgebungsvariablen gesetzt)
// wir prüfen nur eine Variable, das reicht meistens
// Check if we're running in IDEA (no Docker environment variables set)
// We only check one variable, that's usually enough
val dbHostFromEnv = System.getenv("DB_HOST")
val isIdeaEnvironment = (dbHostFromEnv == null)
if (isIdeaEnvironment) {
log.info("IDEA environment detected (missing DB_HOST), using in-memory H2 database (dev)...")
// Ensure the data directory exists
val dataDir = File("data")
if (!dataDir.exists()) {
dataDir.mkdir()
}
log.info("IDEA environment detected (missing DB_HOST), using SQLite file database (dev)...")
try {
Database.connect("jdbc:h2:mem:dev;DB_CLOSE_DELAY=-1;MODE=PostgreSQL", driver = "org.h2.Driver")
log.info("Connected to H2 (dev) successfully.")
Database.connect("jdbc:sqlite:data/meldestelle.db", driver = "org.sqlite.JDBC")
log.info("Connected to SQLite file database (dev) successfully.")
connectionSuccessful = true
} catch (e: Exception) {
log.error("Failed to connect to H2 (dev)!", e)
// Hier vielleicht nicht werfen, damit App in IDE trotzdem startet? Oder doch? → Aktuell wirft es.
log.error("Failed to connect to SQLite (dev)!", e)
// Maybe don't throw here so the app starts in IDE anyway? Currently it throws.
throw e
}
} else {
// Normale Docker/Produktionsumgebung -> PostgreSQL verwenden
// Normal Docker/Production environment -> use PostgreSQL
log.info("Production/Docker environment detected, connecting to PostgreSQL...")
try {
// Lese Konfiguration direkt aus Umgebungsvariablen
val dbHost = dbHostFromEnv // Sicherer Fallback
// Read configuration directly from environment variables
val dbHost = dbHostFromEnv // Safe fallback
val dbPort = System.getenv("DB_PORT") ?: "5432"
val dbName = System.getenv("DB_NAME") ?: error("DB_NAME not set in environment")
val dbUser = System.getenv("DB_USER") ?: error("DB_USER not set in environment")
@@ -74,34 +89,24 @@ fun configureDatabase() {
connectionSuccessful = true
} catch (e: Exception) {
log.error("Failed to initialize PostgreSQL connection pool!", e)
throw e // Fehler weiterwerfen, App soll nicht starten ohne DB in Prod
throw e // Rethrow error, app should not start without DB in prod
}
}
}
// --- Schema Initialisierung (JETZT ZENTRALISIERT) ---
// Führe dies nur aus, wenn *irgendeine* DB-Verbindung erfolgreich war
transaction { // Führe Schema-Operationen in einer Transaktion aus
// --- Schema Initialization (NOW CENTRALIZED) ---
// Only execute this if *any* DB connection was successful
transaction { // Execute schema operations in a transaction
log.info("Initializing/Verifying database schema...")
try {
// Erstellt die Tabelle(n), falls sie noch nicht existieren
SchemaUtils.create(TurniereTable)
// Füge hier später weitere Tabellen hinzu:
// SchemaUtils.create(TurniereTable, NennungenTable, ...)
// Create the table(s) if they don't exist yet
SchemaUtils.create(TurniereTable, BewerbeTable, NennungenTable, NennungEventsTable)
log.info("Database schema initialized successfully (tables created/verified).")
} catch (e: Exception) {
log.error("Failed to initialize database schema!", e)
// Hier könntest du entscheiden, ob ein Fehler beim Schema kritisch ist
// throw e // Auskommentiert: App startet evtl. trotzdem, auch wenn Schema fehlt/falsch ist
// Here you could decide if a schema error is critical
// throw e // Commented out: App might start anyway, even if schema is missing/wrong
}
}
// --- TODO für den NÄCHSTEN Schritt ---
// Hier kommt später die Logik zum Erstellen der Tabellen hin,
// z.B. innerhalb einer Transaktion:
// transaction {
// SchemaUtils.create(TurniereTable) // Erstellt die Tabelle, wenn sie nicht existiert
// }
// ------------------------------------
}