feat: runtime migrations

This commit is contained in:
Finn Linck Ryan 2025-12-13 22:02:54 +01:00
parent 4c3d939d9a
commit 42bccd95de
3 changed files with 20 additions and 1 deletions

View file

@ -4,3 +4,4 @@ HOST=localhost
DB_URL=jdbc:postgresql://localhost:5432/homepage DB_URL=jdbc:postgresql://localhost:5432/homepage
DB_USERNAME=postgres DB_USERNAME=postgres
DB_PASSWORD=postgres DB_PASSWORD=postgres
DB_MIGRATE=true

View file

@ -6,6 +6,7 @@ import at.dokkae.homepage.repository.MessageRepository
import at.dokkae.homepage.repository.impls.JooqMessageRepository import at.dokkae.homepage.repository.impls.JooqMessageRepository
import at.dokkae.homepage.templates.Index import at.dokkae.homepage.templates.Index
import io.github.cdimascio.dotenv.dotenv import io.github.cdimascio.dotenv.dotenv
import org.flywaydb.core.Flyway
import org.http4k.core.HttpHandler import org.http4k.core.HttpHandler
import org.http4k.core.Method.* import org.http4k.core.Method.*
import org.http4k.core.Response import org.http4k.core.Response
@ -33,6 +34,17 @@ import java.util.UUID
import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.CopyOnWriteArrayList
import kotlin.concurrent.thread import kotlin.concurrent.thread
fun migrateDatabase(env: Environment) {
val flyway = Flyway.configure()
.dataSource(env.dbUrl, env.dbUsername, env.dbPassword)
.locations("classpath:db/migration")
.baselineOnMigrate(true) // optional: creates baseline if no schema history exists
.load()
val result = flyway.migrate()
println("Migrated ${result.migrationsExecuted} migration${if (result.migrationsExecuted != 1) "s" else ""}")
}
data class Message( data class Message(
val author: String, val author: String,
val content: String, val content: String,
@ -56,6 +68,10 @@ fun main() {
ignoreIfMalformed = true ignoreIfMalformed = true
}) })
if (env.dbMigrate) {
migrateDatabase(env)
}
val connection = DriverManager.getConnection(env.dbUrl, env.dbUsername, env.dbPassword) val connection = DriverManager.getConnection(env.dbUrl, env.dbUsername, env.dbPassword)
val dslContext = DSL.using(connection, SQLDialect.POSTGRES) val dslContext = DSL.using(connection, SQLDialect.POSTGRES)
val messageRepository: MessageRepository = JooqMessageRepository(dslContext) val messageRepository: MessageRepository = JooqMessageRepository(dslContext)

View file

@ -8,6 +8,7 @@ data class Environment(
val dbUrl: String, val dbUrl: String,
val dbUsername: String, val dbUsername: String,
val dbPassword: String, val dbPassword: String,
val dbMigrate: Boolean,
) { ) {
companion object { companion object {
/** /**
@ -20,6 +21,7 @@ data class Environment(
dbUrl = requireEnv(dotenv, "DB_URL"), dbUrl = requireEnv(dotenv, "DB_URL"),
dbUsername = requireEnv(dotenv, "DB_USERNAME"), dbUsername = requireEnv(dotenv, "DB_USERNAME"),
dbPassword = requireEnv(dotenv, "DB_PASSWORD"), dbPassword = requireEnv(dotenv, "DB_PASSWORD"),
dbMigrate = dotenv["DB_MIGRATE"]?.toBoolean() ?: false
) )
private fun requireEnv(dotenv: Dotenv, key: String): String { private fun requireEnv(dotenv: Dotenv, key: String): String {