From 076411258d048557deef0599cea2e3bdd88e30c7 Mon Sep 17 00:00:00 2001 From: Jim Martens Date: Wed, 13 Aug 2025 08:09:00 +0200 Subject: [PATCH] change: Use ZonedDateTime for storage in DB --- .../bahnApi/jaxb/LocalDateTimeAdapter.kt | 12 +++-- .../bahnApi/mapper/BahnTimetableMapper.kt | 44 +++++++++++++++++-- .../bahnApi/model/db/BahnStationStop.kt | 12 +++++ .../bahnApi/model/db/BahnStopEvent.kt | 16 +++++++ .../bahnApi/model/db/BahnTimetable.kt | 5 +-- .../bahnApi/service/BahnDatabaseService.kt | 6 ++- 6 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnStationStop.kt create mode 100644 module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnStopEvent.kt diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/jaxb/LocalDateTimeAdapter.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/jaxb/LocalDateTimeAdapter.kt index 9e9360e..77600c8 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/jaxb/LocalDateTimeAdapter.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/jaxb/LocalDateTimeAdapter.kt @@ -7,15 +7,21 @@ import java.time.format.DateTimeParseException import java.util.* -class LocalDateTimeAdapter : XmlAdapter() { +class LocalDateTimeAdapter : XmlAdapter() { @Throws(DateTimeParseException::class) - override fun unmarshal(xmlValue: String?): LocalDateTime { + override fun unmarshal(xmlValue: String?): LocalDateTime? { + if (xmlValue == null) { + return null + } return LocalDateTime.parse(xmlValue, dateFormatter.get()) } @Throws(DateTimeParseException::class) - override fun marshal(kotlinValue: LocalDateTime): String? { + override fun marshal(kotlinValue: LocalDateTime?): String? { + if (kotlinValue == null) { + return null + } return dateFormatter.get().format(kotlinValue) } diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/mapper/BahnTimetableMapper.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/mapper/BahnTimetableMapper.kt index 208f073..d2e481f 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/mapper/BahnTimetableMapper.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/mapper/BahnTimetableMapper.kt @@ -1,11 +1,15 @@ package de.twomartens.timetable.bahnApi.mapper +import de.twomartens.timetable.bahnApi.model.db.BahnStationStop +import de.twomartens.timetable.bahnApi.model.db.BahnStopEvent import de.twomartens.timetable.bahnApi.model.db.BahnTimetable import de.twomartens.timetable.model.common.RouteId import de.twomartens.timetable.model.common.UserId import de.twomartens.timetable.types.HourAtDay import de.twomartens.timetable.types.NonEmptyString import org.mapstruct.* +import java.time.Clock +import java.time.ZonedDateTime @Mapper( collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, @@ -18,14 +22,48 @@ interface BahnTimetableMapper { @Mapping(target = "lastModified", ignore = true) fun mapToDB(dto: de.twomartens.timetable.bahnApi.model.dto.BahnTimetable, userId: UserId, routeId: RouteId, - hourAtDay: HourAtDay): BahnTimetable { + hourAtDay: HourAtDay, + clock: Clock): BahnTimetable { return BahnTimetable( userId, routeId, dto.eva, - hourAtDay, + ZonedDateTime.of(hourAtDay.dateTime, clock.zone), NonEmptyString(dto.station), - dto.stops + mapToDb(dto.stops, clock) + ) + } + + fun mapToDb(stops: List, clock: Clock): List { + return stops.map { mapToDB(it, clock) } + } + + fun mapToDB(dto: de.twomartens.timetable.bahnApi.model.dto.BahnStationStop, clock: Clock): BahnStationStop { + return BahnStationStop( + dto.eva, + dto.id, + dto.tripLabel, + mapToDB(dto.arrival, clock), + mapToDB(dto.departure, clock) + ) + } + + fun mapToDB(dto: de.twomartens.timetable.bahnApi.model.dto.BahnStopEvent?, clock: Clock): BahnStopEvent? { + if (dto == null) { + return null + } + + return BahnStopEvent( + dto.plannedDistantEndpoint, + dto.changedDistantEndpoint, + ZonedDateTime.of(dto.plannedTime, clock.zone), + ZonedDateTime.of(dto.changedTime, clock.zone), + dto.plannedPath, + dto.changedPath, + dto.plannedPlatform, + dto.changedPlatform, + dto.wings, + dto.line ) } } \ No newline at end of file diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnStationStop.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnStationStop.kt new file mode 100644 index 0000000..150a4e3 --- /dev/null +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnStationStop.kt @@ -0,0 +1,12 @@ +package de.twomartens.timetable.bahnApi.model.db + +import de.twomartens.timetable.bahnApi.model.Eva +import de.twomartens.timetable.bahnApi.model.dto.BahnTripLabel + +data class BahnStationStop( + var eva: Eva, + var id: String, + var tripLabel: BahnTripLabel, + var arrival: BahnStopEvent?, + var departure: BahnStopEvent? +) \ No newline at end of file diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnStopEvent.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnStopEvent.kt new file mode 100644 index 0000000..421eb12 --- /dev/null +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnStopEvent.kt @@ -0,0 +1,16 @@ +package de.twomartens.timetable.bahnApi.model.db + +import java.time.ZonedDateTime + +data class BahnStopEvent( + var plannedDistantEndpoint: String, + var changedDistantEndpoint: String, + var plannedTime: ZonedDateTime?, + var changedTime: ZonedDateTime?, + var plannedPath: String, + var changedPath: String, + var plannedPlatform: String, + var changedPlatform: String, + var wings: String, + var line: String +) diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnTimetable.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnTimetable.kt index 6ca7064..181ac39 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnTimetable.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnTimetable.kt @@ -1,10 +1,8 @@ package de.twomartens.timetable.bahnApi.model.db import de.twomartens.timetable.bahnApi.model.Eva -import de.twomartens.timetable.bahnApi.model.dto.BahnStationStop import de.twomartens.timetable.model.common.RouteId import de.twomartens.timetable.model.common.UserId -import de.twomartens.timetable.types.HourAtDay import de.twomartens.timetable.types.NonEmptyString import org.bson.types.ObjectId import org.springframework.data.annotation.CreatedDate @@ -13,6 +11,7 @@ import org.springframework.data.annotation.LastModifiedDate import org.springframework.data.mongodb.core.index.CompoundIndex import org.springframework.data.mongodb.core.mapping.Document import java.time.Instant +import java.time.ZonedDateTime @Document @CompoundIndex(def = "{'userId': 1, 'routeId': 1, 'eva': 1, 'hourAtDay': 1}", unique = true) @@ -20,7 +19,7 @@ data class BahnTimetable( var userId: UserId, var routeId: RouteId, var eva: Eva, - var hourAtDay: HourAtDay, + var hourAtDay: ZonedDateTime, var station: NonEmptyString, var stops: List ) { diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/BahnDatabaseService.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/BahnDatabaseService.kt index 9bbf18d..99da7ae 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/BahnDatabaseService.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/BahnDatabaseService.kt @@ -16,13 +16,15 @@ import org.springframework.data.domain.Example import org.springframework.data.mongodb.core.BulkOperations import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.stereotype.Service +import java.time.Clock @Service open class BahnDatabaseService( private val bahnStationRepository: BahnStationRepository, private val stationRepository: StationRepository, private val bahnTimetableRepository: BahnTimetableRepository, - private val mongoTemplate: MongoTemplate + private val mongoTemplate: MongoTemplate, + private val clock: Clock ) { private val bahnStationMapper = Mappers.getMapper(BahnStationMapper::class.java) private val bahnTimetableMapper = Mappers.getMapper(BahnTimetableMapper::class.java) @@ -93,7 +95,7 @@ open class BahnDatabaseService( fun storeTimetable(timetable: BahnTimetable, userId: UserId, routeId: RouteId, hourAtDay: HourAtDay) { val matcher = bahnTimetableRepository.getExampleMatcher() - val dbTimetable = bahnTimetableMapper.mapToDB(timetable, userId, routeId, hourAtDay) + val dbTimetable = bahnTimetableMapper.mapToDB(timetable, userId, routeId, hourAtDay, clock) val existingTimetable = bahnTimetableRepository.findOne(Example.of(dbTimetable, matcher)) existingTimetable .map {