MigrationProcessing.kt
package de.pflugradts.passbird.application.process.migration
data class PendingMigration(val id: String)
data class MigrationRequest(
val pendingMigrations: Set<PendingMigration>,
) {
val required get() = pendingMigrations.isNotEmpty()
operator fun plus(other: MigrationRequest) = MigrationRequest(pendingMigrations + other.pendingMigrations)
companion object {
fun empty() = MigrationRequest(emptySet())
}
}
interface PreLaunchMigrationDetector {
fun detect(): MigrationRequest
}
interface AuthenticatedMigrationDetector {
fun detect(): MigrationRequest
}
interface Migration {
val id: String
val order: Int
fun run()
}
class PreLaunchMigrationLocator constructor(
private val detectors: Set<PreLaunchMigrationDetector>,
) {
fun detect() = detectors.fold(MigrationRequest.empty()) { request, detector -> request + detector.detect() }
}
class AuthenticatedMigrationLocator constructor(
private val detectors: Set<AuthenticatedMigrationDetector>,
) {
fun detect() = detectors.fold(MigrationRequest.empty()) { request, detector -> request + detector.detect() }
}
class MigrationRunner constructor(
private val migrations: Set<Migration>,
) {
fun run(request: MigrationRequest) {
val registeredMigrations = migrations.associateBy(Migration::id)
check(registeredMigrations.size == migrations.size)
request.pendingMigrations
.map { pendingMigration ->
registeredMigrations[pendingMigration.id]
?: throw IllegalStateException("No migration registered for '${pendingMigration.id}'.")
}
.sortedBy(Migration::order)
.forEach(Migration::run)
}
}