Migrate UUID handling in VeranstaltungRepositoryImpl: standardize conversion functions, update methods for entity mapping, and refactor queries for enhanced consistency and type safety.

This commit is contained in:
2026-04-08 23:00:23 +02:00
parent bb4b5924d1
commit 5d1c89438c
@@ -4,14 +4,19 @@ package at.mocode.events.infrastructure.persistence
import at.mocode.core.domain.model.SparteE import at.mocode.core.domain.model.SparteE
import at.mocode.events.domain.model.Veranstaltung import at.mocode.events.domain.model.Veranstaltung
import at.mocode.events.domain.repository.VeranstaltungRepository import at.mocode.events.domain.repository.VeranstaltungRepository
import at.mocode.core.utils.database.DatabaseFactory
import kotlin.uuid.Uuid import kotlin.uuid.Uuid
import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.v1.core.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.v1.jdbc.*
import org.jetbrains.exposed.sql.statements.UpdateBuilder import org.jetbrains.exposed.v1.core.statements.UpdateBuilder
import at.mocode.backend.infrastructure.persistence.readTransaction
import at.mocode.backend.infrastructure.persistence.writeTransaction
import at.mocode.backend.infrastructure.persistence.getOrNull
import at.mocode.core.utils.database.DatabaseFactory
import java.util.UUID
import kotlin.time.Clock
import kotlin.time.Instant
/** /**
* Exposed-based implementation of VeranstaltungRepository. * Exposed-based implementation of VeranstaltungRepository.
@@ -21,8 +26,11 @@ import org.jetbrains.exposed.sql.statements.UpdateBuilder
*/ */
class VeranstaltungRepositoryImpl : VeranstaltungRepository { class VeranstaltungRepositoryImpl : VeranstaltungRepository {
private fun Uuid.toJavaUuid(): UUID = UUID.fromString(this.toString())
private fun UUID.toKotlinUuid(): Uuid = Uuid.parse(this.toString())
override suspend fun findById(id: Uuid): Veranstaltung? = DatabaseFactory.dbQuery { override suspend fun findById(id: Uuid): Veranstaltung? = DatabaseFactory.dbQuery {
VeranstaltungTable.selectAll().where { VeranstaltungTable.id eq id } VeranstaltungTable.selectAll().where { VeranstaltungTable.id eq id.toJavaUuid() }
.map { rowToVeranstaltung(it) } .map { rowToVeranstaltung(it) }
.singleOrNull() .singleOrNull()
} }
@@ -36,78 +44,77 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
} }
override suspend fun findByVeranstalterVereinId(vereinId: Uuid, activeOnly: Boolean): List<Veranstaltung> = DatabaseFactory.dbQuery { override suspend fun findByVeranstalterVereinId(vereinId: Uuid, activeOnly: Boolean): List<Veranstaltung> = DatabaseFactory.dbQuery {
val query = VeranstaltungTable.selectAll().where { VeranstaltungTable.veranstalterVereinId eq vereinId } var query = VeranstaltungTable.selectAll().where { VeranstaltungTable.veranstalterVereinId eq vereinId.toJavaUuid() }
if (activeOnly) { if (activeOnly) {
query.andWhere { VeranstaltungTable.istAktiv eq true } query = query.andWhere { VeranstaltungTable.istAktiv eq true }
} else { }
query query.orderBy(VeranstaltungTable.startDatum, SortOrder.DESC)
}.orderBy(VeranstaltungTable.startDatum, SortOrder.DESC)
.map { rowToVeranstaltung(it) } .map { rowToVeranstaltung(it) }
} }
override suspend fun findByDateRange(startDate: LocalDate, endDate: LocalDate, activeOnly: Boolean): List<Veranstaltung> = DatabaseFactory.dbQuery { override suspend fun findByDateRange(startDate: LocalDate, endDate: LocalDate, activeOnly: Boolean): List<Veranstaltung> = DatabaseFactory.dbQuery {
val query = VeranstaltungTable.selectAll().where { var query = VeranstaltungTable.selectAll().where {
(VeranstaltungTable.startDatum greaterEq startDate) and (VeranstaltungTable.startDatum greaterEq startDate) and
(VeranstaltungTable.endDatum lessEq endDate) (VeranstaltungTable.endDatum lessEq endDate)
} }
if (activeOnly) { if (activeOnly) {
query.andWhere { VeranstaltungTable.istAktiv eq true } query = query.andWhere { VeranstaltungTable.istAktiv eq true }
} else { }
query query.orderBy(VeranstaltungTable.startDatum)
}.orderBy(VeranstaltungTable.startDatum)
.map { rowToVeranstaltung(it) } .map { rowToVeranstaltung(it) }
} }
override suspend fun findByStartDate(date: LocalDate, activeOnly: Boolean): List<Veranstaltung> = DatabaseFactory.dbQuery { override suspend fun findByStartDate(date: LocalDate, activeOnly: Boolean): List<Veranstaltung> = DatabaseFactory.dbQuery {
val query = VeranstaltungTable.selectAll().where { VeranstaltungTable.startDatum eq date } var query = VeranstaltungTable.selectAll().where { VeranstaltungTable.startDatum eq date }
if (activeOnly) { if (activeOnly) {
query.andWhere { VeranstaltungTable.istAktiv eq true } query = query.andWhere { VeranstaltungTable.istAktiv eq true }
} else { }
query query.orderBy(VeranstaltungTable.name)
}.orderBy(VeranstaltungTable.name)
.map { rowToVeranstaltung(it) } .map { rowToVeranstaltung(it) }
} }
override suspend fun findAllActive(limit: Int, offset: Int): List<Veranstaltung> = DatabaseFactory.dbQuery { override suspend fun findAllActive(limit: Int, offset: Int): List<Veranstaltung> = DatabaseFactory.dbQuery {
VeranstaltungTable.selectAll().where { VeranstaltungTable.istAktiv eq true } VeranstaltungTable.selectAll().where { VeranstaltungTable.istAktiv eq true }
.orderBy(VeranstaltungTable.startDatum, SortOrder.DESC) .orderBy(VeranstaltungTable.startDatum, SortOrder.DESC)
.limit(limit, offset.toLong()) .limit(limit)
.offset(offset.toLong())
.map { rowToVeranstaltung(it) } .map { rowToVeranstaltung(it) }
} }
override suspend fun findPublicEvents(activeOnly: Boolean): List<Veranstaltung> = DatabaseFactory.dbQuery { override suspend fun findPublicEvents(activeOnly: Boolean): List<Veranstaltung> = DatabaseFactory.dbQuery {
val query = VeranstaltungTable.selectAll().where { VeranstaltungTable.istOeffentlich eq true } var query = VeranstaltungTable.selectAll().where { VeranstaltungTable.istOeffentlich eq true }
if (activeOnly) { if (activeOnly) {
query.andWhere { VeranstaltungTable.istAktiv eq true } query = query.andWhere { VeranstaltungTable.istAktiv eq true }
} else { }
query query.orderBy(VeranstaltungTable.startDatum, SortOrder.DESC)
}.orderBy(VeranstaltungTable.startDatum, SortOrder.DESC)
.map { rowToVeranstaltung(it) } .map { rowToVeranstaltung(it) }
} }
override suspend fun save(veranstaltung: Veranstaltung): Veranstaltung = DatabaseFactory.dbQuery { override suspend fun save(veranstaltung: Veranstaltung): Veranstaltung = DatabaseFactory.dbQuery {
val now = Clock.System.now() val now = Clock.System.now()
// Ensure now is kotlinx.datetime.Instant as expected by Domain
val updatedVeranstaltung = veranstaltung.copy(updatedAt = now) val updatedVeranstaltung = veranstaltung.copy(updatedAt = now)
val vId = veranstaltung.veranstaltungId.toJavaUuid()
// Check if a record exists // Check if a record exists
val existingRecord = VeranstaltungTable.selectAll() val existingRecord = VeranstaltungTable.selectAll()
.where { VeranstaltungTable.id eq veranstaltung.veranstaltungId } .where { VeranstaltungTable.id eq vId }
.singleOrNull() .singleOrNull()
if (existingRecord != null) { if (existingRecord != null) {
// Update existing record // Update existing record
VeranstaltungTable.update({ VeranstaltungTable.id eq veranstaltung.veranstaltungId }) { VeranstaltungTable.update({ VeranstaltungTable.id eq vId }) {
veranstaltungToStatement(it, updatedVeranstaltung) veranstaltungToStatement(it, updatedVeranstaltung)
} }
updatedVeranstaltung updatedVeranstaltung
} else { } else {
// Insert a new record // Insert a new record
VeranstaltungTable.insert { VeranstaltungTable.insert {
it[id] = veranstaltung.veranstaltungId it[id] = vId
veranstaltungToStatement(it, updatedVeranstaltung) veranstaltungToStatement(it, updatedVeranstaltung)
} }
updatedVeranstaltung updatedVeranstaltung
@@ -115,7 +122,7 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
} }
override suspend fun delete(id: Uuid): Boolean = DatabaseFactory.dbQuery { override suspend fun delete(id: Uuid): Boolean = DatabaseFactory.dbQuery {
val deletedRows = VeranstaltungTable.deleteWhere { VeranstaltungTable.id eq id } val deletedRows = VeranstaltungTable.deleteWhere { VeranstaltungTable.id eq id.toJavaUuid() }
deletedRows > 0 deletedRows > 0
} }
@@ -125,13 +132,12 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
} }
override suspend fun countByVeranstalterVereinId(vereinId: Uuid, activeOnly: Boolean): Long = DatabaseFactory.dbQuery { override suspend fun countByVeranstalterVereinId(vereinId: Uuid, activeOnly: Boolean): Long = DatabaseFactory.dbQuery {
val query = VeranstaltungTable.selectAll().where { VeranstaltungTable.veranstalterVereinId eq vereinId } var query = VeranstaltungTable.selectAll().where { VeranstaltungTable.veranstalterVereinId eq vereinId.toJavaUuid() }
if (activeOnly) { if (activeOnly) {
query.andWhere { VeranstaltungTable.istAktiv eq true } query = query.andWhere { VeranstaltungTable.istAktiv eq true }
} else { }
query query.count()
}.count()
} }
/** /**
@@ -151,7 +157,7 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
} }
return Veranstaltung( return Veranstaltung(
veranstaltungId = row[VeranstaltungTable.id].value, veranstaltungId = row[VeranstaltungTable.id].toKotlinUuid(),
name = row[VeranstaltungTable.name], name = row[VeranstaltungTable.name],
untertitel = row[VeranstaltungTable.untertitel], untertitel = row[VeranstaltungTable.untertitel],
beschreibung = row[VeranstaltungTable.beschreibung], beschreibung = row[VeranstaltungTable.beschreibung],
@@ -160,7 +166,7 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
startDatum = row[VeranstaltungTable.startDatum], startDatum = row[VeranstaltungTable.startDatum],
endDatum = row[VeranstaltungTable.endDatum], endDatum = row[VeranstaltungTable.endDatum],
ort = row[VeranstaltungTable.ort], ort = row[VeranstaltungTable.ort],
veranstalterVereinId = row[VeranstaltungTable.veranstalterVereinId], veranstalterVereinId = row[VeranstaltungTable.veranstalterVereinId].toKotlinUuid(),
sparten = sparten, sparten = sparten,
istAktiv = row[VeranstaltungTable.istAktiv], istAktiv = row[VeranstaltungTable.istAktiv],
istOeffentlich = row[VeranstaltungTable.istOeffentlich], istOeffentlich = row[VeranstaltungTable.istOeffentlich],
@@ -183,7 +189,7 @@ class VeranstaltungRepositoryImpl : VeranstaltungRepository {
statement[VeranstaltungTable.startDatum] = veranstaltung.startDatum statement[VeranstaltungTable.startDatum] = veranstaltung.startDatum
statement[VeranstaltungTable.endDatum] = veranstaltung.endDatum statement[VeranstaltungTable.endDatum] = veranstaltung.endDatum
statement[VeranstaltungTable.ort] = veranstaltung.ort statement[VeranstaltungTable.ort] = veranstaltung.ort
statement[VeranstaltungTable.veranstalterVereinId] = veranstaltung.veranstalterVereinId statement[VeranstaltungTable.veranstalterVereinId] = veranstaltung.veranstalterVereinId.toJavaUuid()
statement[VeranstaltungTable.sparten] = Json.encodeToString(veranstaltung.sparten) statement[VeranstaltungTable.sparten] = Json.encodeToString(veranstaltung.sparten)
statement[VeranstaltungTable.istAktiv] = veranstaltung.istAktiv statement[VeranstaltungTable.istAktiv] = veranstaltung.istAktiv
statement[VeranstaltungTable.istOeffentlich] = veranstaltung.istOeffentlich statement[VeranstaltungTable.istOeffentlich] = veranstaltung.istOeffentlich