feat(server/gtfs): service exception support

This commit is contained in:
Cilly Leang 2026-04-01 19:31:31 +11:00
parent c9aeeb99c1
commit 58649b6171
Signed by: cilly
GPG key ID: 6500251E087653C9
10 changed files with 595 additions and 4 deletions

View file

@ -10,6 +10,7 @@ val CommonModules = module {
single { get<Database>().versionMetadataDao }
single { get<Database>().routeDao }
single { get<Database>().serviceDao }
single { get<Database>().serviceExceptionDao }
single { get<Database>().shapeDao }
single { get<Database>().stopDao }
single { get<Database>().stopTimeDao }

View file

@ -0,0 +1,11 @@
package moe.lava.banksia.model
import kotlinx.datetime.LocalDate
import kotlinx.serialization.Serializable
@Serializable
data class ServiceException(
val serviceId: String,
val date: LocalDate,
val type: Int,
)

View file

@ -9,6 +9,7 @@ import kotlinx.coroutines.IO
import moe.lava.banksia.room.converter.RouteTypeConverter
import moe.lava.banksia.room.dao.RouteDao
import moe.lava.banksia.room.dao.ServiceDao
import moe.lava.banksia.room.dao.ServiceExceptionDao
import moe.lava.banksia.room.dao.ShapeDao
import moe.lava.banksia.room.dao.StopDao
import moe.lava.banksia.room.dao.StopTimeDao
@ -16,6 +17,7 @@ import moe.lava.banksia.room.dao.TripDao
import moe.lava.banksia.room.dao.VersionMetadataDao
import moe.lava.banksia.room.entity.RouteEntity
import moe.lava.banksia.room.entity.ServiceEntity
import moe.lava.banksia.room.entity.ServiceExceptionEntity
import moe.lava.banksia.room.entity.ShapeEntity
import moe.lava.banksia.room.entity.StopEntity
import moe.lava.banksia.room.entity.StopTimeEntity
@ -24,10 +26,11 @@ import moe.lava.banksia.room.entity.VersionMetadataEntity
import androidx.room.Database as DatabaseAnnotation
@DatabaseAnnotation(
version = 9,
version = 10,
entities = [
RouteEntity::class,
ServiceEntity::class,
ServiceExceptionEntity::class,
ShapeEntity::class,
StopEntity::class,
StopTimeEntity::class,
@ -37,6 +40,7 @@ import androidx.room.Database as DatabaseAnnotation
autoMigrations = [
AutoMigration(from = 1, to = 2),
AutoMigration(from = 2, to = 3),
AutoMigration(from = 9, to = 10),
]
)
@TypeConverters(RouteTypeConverter::class)
@ -44,6 +48,7 @@ abstract class Database : RoomDatabase() {
abstract val versionMetadataDao: VersionMetadataDao
abstract val routeDao: RouteDao
abstract val serviceDao: ServiceDao
abstract val serviceExceptionDao: ServiceExceptionDao
abstract val shapeDao: ShapeDao
abstract val stopDao: StopDao
abstract val stopTimeDao: StopTimeDao

View file

@ -0,0 +1,29 @@
package moe.lava.banksia.room.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy.Companion.REPLACE
import androidx.room.Query
import moe.lava.banksia.room.entity.ServiceExceptionEntity
@Dao
interface ServiceExceptionDao {
@Query("SELECT * FROM ServiceException")
suspend fun getAll(): List<ServiceExceptionEntity>
@Query("SELECT * FROM ServiceException WHERE serviceId == :id")
suspend fun get(id: String): List<ServiceExceptionEntity>
@Insert
suspend fun insertAll(vararg exceptions: ServiceExceptionEntity)
@Insert(onConflict = REPLACE)
suspend fun insertOrReplaceAll(vararg exceptions: ServiceExceptionEntity)
@Delete
suspend fun delete(service: ServiceExceptionEntity)
@Query("DELETE FROM ServiceException")
suspend fun deleteAll()
}

View file

@ -22,11 +22,13 @@ interface StopTimeDao {
suspend fun getForStop(stopId: String): List<StopTimeEntity>
@Query("""
SELECT * FROM StopTime
SELECT DISTINCT StopTime.* FROM StopTime
INNER JOIN Service ON Service.days & :days = :days AND :date BETWEEN Service.start AND Service.`end`
INNER JOIN Trip ON Trip.serviceId == Service.id
LEFT JOIN ServiceException ON ServiceException.serviceId == Service.id AND ServiceException.date == :date
WHERE StopTime.tripId == Trip.id
AND StopTime.stopId == :stopId
AND StopTime.stopId == :stopId
AND ServiceException.type IS NULL
""")
suspend fun getForStopDated(stopId: String, days: Int, date: Int): List<StopTimeEntity>

View file

@ -0,0 +1,28 @@
package moe.lava.banksia.room.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import kotlinx.datetime.LocalDate
import moe.lava.banksia.model.ServiceException
@Entity(
"ServiceException",
primaryKeys = ["serviceId", "date"]
)
data class ServiceExceptionEntity(
@ColumnInfo(index = true) val serviceId: String,
val date: Int,
@ColumnInfo(index = true) val type: Int,
) {
fun asModel() = ServiceException(
serviceId,
LocalDate.fromEpochDays(date),
type,
)
}
fun ServiceException.asEntity() = ServiceExceptionEntity(
serviceId,
date.toEpochDays().toInt(),
type,
)