refactor: optimisation around stoptimes
- moved stoptime related functionality into new core:data:stoptime module
- will feature all the different realtime stoptime sources to be
integrated later
- create proper database schema for future migrations
- deduplicate trips into stoppingpatterns, since many trips share the
exact same stopping pattern
- stoptimes are now linked to stoppingpatterns instead
- stoppingpattern ids are generated from a hash composed of all stoptimes
- stoptimes now use deltas for arrival time to save space
This commit is contained in:
parent
f1770744db
commit
102c028407
39 changed files with 396 additions and 223 deletions
|
|
@ -27,6 +27,7 @@ kotlin {
|
|||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
implementation(projects.core)
|
||||
api(projects.core.data.stoptime)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,16 +10,12 @@ import kotlinx.serialization.json.Json
|
|||
import moe.lava.banksia.core.Constants
|
||||
import moe.lava.banksia.core.data.repositories.ClientRouteRepository
|
||||
import moe.lava.banksia.core.data.repositories.ClientStopRepository
|
||||
import moe.lava.banksia.core.data.repositories.ClientStopTimeRepository
|
||||
import moe.lava.banksia.core.data.repositories.RouteRepository
|
||||
import moe.lava.banksia.core.data.repositories.StopRepository
|
||||
import moe.lava.banksia.core.data.repositories.StopTimeRepository
|
||||
import moe.lava.banksia.core.data.sources.route.RouteLocalDataSource
|
||||
import moe.lava.banksia.core.data.sources.route.RouteRemoteDataSource
|
||||
import moe.lava.banksia.core.data.sources.stop.StopLocalDataSource
|
||||
import moe.lava.banksia.core.data.sources.stop.StopRemoteDataSource
|
||||
import moe.lava.banksia.core.data.sources.stoptime.StopTimeLocalDataSource
|
||||
import moe.lava.banksia.core.data.sources.stoptime.StopTimeRemoteDataSource
|
||||
import moe.lava.banksia.core.sqld.sqldDiModule
|
||||
import moe.lava.banksia.core.util.log
|
||||
import moe.lava.banksia.data.ptv.PtvService
|
||||
|
|
@ -29,6 +25,7 @@ import org.koin.dsl.module
|
|||
|
||||
val clientDataDiModule = module {
|
||||
includes(sqldDiModule)
|
||||
includes(stopTimeDataDiModule)
|
||||
|
||||
// HTTP Clients
|
||||
singleOf(::PtvService)
|
||||
|
|
@ -56,11 +53,8 @@ val clientDataDiModule = module {
|
|||
singleOf(::RouteRemoteDataSource)
|
||||
singleOf(::StopLocalDataSource)
|
||||
singleOf(::StopRemoteDataSource)
|
||||
singleOf(::StopTimeLocalDataSource)
|
||||
singleOf(::StopTimeRemoteDataSource)
|
||||
|
||||
// Repositories
|
||||
singleOf(::ClientRouteRepository) bind RouteRepository::class
|
||||
singleOf(::ClientStopRepository) bind StopRepository::class
|
||||
singleOf(::ClientStopTimeRepository) bind StopTimeRepository::class
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
package moe.lava.banksia.core.data.repositories
|
||||
|
||||
import moe.lava.banksia.core.data.sources.stoptime.StopTimeLocalDataSource
|
||||
import moe.lava.banksia.core.data.sources.stoptime.StopTimeRemoteDataSource
|
||||
import moe.lava.banksia.core.model.StopTimeDated
|
||||
|
||||
internal class ClientStopTimeRepository internal constructor(
|
||||
private val local: StopTimeLocalDataSource,
|
||||
private val remote: StopTimeRemoteDataSource,
|
||||
) : StopTimeRepository {
|
||||
override suspend fun getForStop(id: String): List<StopTimeDated> {
|
||||
return local
|
||||
.getAtStop(id)
|
||||
.ifEmpty { remote.getAtStop(id) }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
package moe.lava.banksia.core.data.sources.trip
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.datetime.DayOfWeek
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.todayIn
|
||||
import moe.lava.banksia.core.model.Trip
|
||||
import kotlin.time.Clock
|
||||
|
||||
internal class TripRemoteDataSource(
|
||||
private val client: HttpClient,
|
||||
) {
|
||||
suspend fun get(
|
||||
day: DayOfWeek? = Clock.System.todayIn(TimeZone.currentSystemDefault()).dayOfWeek,
|
||||
): List<Trip> {
|
||||
return listOf()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
package moe.lava.banksia.core.data.repositories
|
||||
|
||||
import moe.lava.banksia.core.model.StopTimeDated
|
||||
|
||||
interface StopTimeRepository {
|
||||
suspend fun getForStop(id: String): List<StopTimeDated>
|
||||
}
|
||||
60
core/data/stoptime/build.gradle.kts
Normal file
60
core/data/stoptime/build.gradle.kts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlinMultiplatform)
|
||||
alias(libs.plugins.kotlinSerialization)
|
||||
alias(libs.plugins.androidMultiplatformLibrary)
|
||||
alias(libs.plugins.ksp)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
android {
|
||||
namespace = "moe.lava.banksia.core.data.stoptime"
|
||||
compileSdk = libs.versions.android.compileSdk.get().toInt()
|
||||
|
||||
compilerOptions {
|
||||
jvmTarget.set(JvmTarget.JVM_11)
|
||||
}
|
||||
}
|
||||
|
||||
compilerOptions {
|
||||
freeCompilerArgs.add("-opt-in=kotlin.time.ExperimentalTime")
|
||||
freeCompilerArgs.add("-Xexpect-actual-classes")
|
||||
}
|
||||
|
||||
iosArm64()
|
||||
iosSimulatorArm64()
|
||||
|
||||
jvm()
|
||||
|
||||
sourceSets {
|
||||
val clientMain by creating {
|
||||
dependsOn(commonMain.get())
|
||||
}
|
||||
|
||||
androidMain.get().dependsOn(clientMain)
|
||||
iosArm64Main.get().dependsOn(clientMain)
|
||||
iosSimulatorArm64Main.get().dependsOn(clientMain)
|
||||
|
||||
androidMain.dependencies {
|
||||
implementation(libs.ktor.client.okhttp)
|
||||
}
|
||||
commonMain.dependencies {
|
||||
implementation(libs.okio)
|
||||
implementation(libs.koin.core)
|
||||
implementation(libs.ktor.client.core)
|
||||
implementation(libs.ktor.client.contentnegotiation)
|
||||
implementation(libs.ktor.serialization.kotlinx.json)
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.kotlinx.datetime)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
implementation(libs.kotlinx.serialization.protobuf)
|
||||
|
||||
implementation(projects.core)
|
||||
implementation(projects.core.sqld)
|
||||
}
|
||||
iosMain.dependencies {
|
||||
implementation(libs.ktor.client.darwin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package moe.lava.banksia.core.data
|
||||
|
||||
import moe.lava.banksia.core.data.repositories.StopTimeRepository
|
||||
import moe.lava.banksia.core.data.sources.stoptime.StopTimeRemoteDataSource
|
||||
import org.koin.core.module.dsl.singleOf
|
||||
import org.koin.dsl.module
|
||||
|
||||
internal actual val platformModule = module {
|
||||
singleOf(::StopTimeRepository)
|
||||
singleOf(::StopTimeRemoteDataSource)
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package moe.lava.banksia.core.data.repositories
|
||||
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.datetime.LocalDate
|
||||
import moe.lava.banksia.core.data.sources.stoptime.StopTimeLocalDataSource
|
||||
import moe.lava.banksia.core.data.sources.stoptime.StopTimeRemoteDataSource
|
||||
|
||||
actual class StopTimeRepository internal constructor(
|
||||
private val local: StopTimeLocalDataSource,
|
||||
private val remote: StopTimeRemoteDataSource,
|
||||
) {
|
||||
actual suspend fun getForStop(id: String, date: LocalDate) = flow {
|
||||
emit(local.getAtStop(id, date))
|
||||
|
||||
remote.getAtStop(id, date)
|
||||
.takeIf { it.isNotEmpty() }
|
||||
?.let { emit(it) }
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import io.ktor.client.request.parameter
|
|||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.todayIn
|
||||
import moe.lava.banksia.core.model.StopTimeDated
|
||||
import moe.lava.banksia.core.model.StopTime
|
||||
import kotlin.time.Clock
|
||||
|
||||
internal class StopTimeRemoteDataSource(
|
||||
|
|
@ -16,21 +16,9 @@ internal class StopTimeRemoteDataSource(
|
|||
suspend fun getAtStop(
|
||||
stopId: String,
|
||||
date: LocalDate? = Clock.System.todayIn(TimeZone.currentSystemDefault()),
|
||||
): List<StopTimeDated> {
|
||||
): List<StopTime.Dated> {
|
||||
return client.get("stoptimes/by_stop/${stopId}") {
|
||||
parameter("date", date)
|
||||
}.body<List<StopTimeDated>>()
|
||||
}.body<List<StopTime.Dated>>()
|
||||
}
|
||||
|
||||
/*suspend fun get(
|
||||
stop: String? = null,
|
||||
trip: String? = null,
|
||||
day: DayOfWeek? = Clock.System.todayIn(TimeZone.currentSystemDefault()).dayOfWeek,
|
||||
): List<StopTime> {
|
||||
return client.get("stoptimes") {
|
||||
stop?.let { parameter("stop", it) }
|
||||
trip?.let { parameter("trip", it) }
|
||||
day?.let { parameter("day", it) }
|
||||
}.body<List<StopTime>>()
|
||||
}*/
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package moe.lava.banksia.core.data
|
||||
|
||||
import moe.lava.banksia.core.data.sources.stoptime.StopTimeLocalDataSource
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.core.module.dsl.singleOf
|
||||
import org.koin.dsl.module
|
||||
|
||||
internal expect val platformModule: Module;
|
||||
|
||||
val stopTimeDataDiModule = module {
|
||||
includes(platformModule)
|
||||
singleOf(::StopTimeLocalDataSource)
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package moe.lava.banksia.core.data.repositories
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.todayIn
|
||||
import moe.lava.banksia.core.model.StopTime
|
||||
import kotlin.time.Clock
|
||||
|
||||
expect class StopTimeRepository {
|
||||
suspend fun getForStop(
|
||||
id: String,
|
||||
date: LocalDate = Clock.System.todayIn(TimeZone.currentSystemDefault()),
|
||||
): Flow<List<StopTime.Dated>>
|
||||
}
|
||||
|
|
@ -4,23 +4,19 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.todayIn
|
||||
import moe.lava.banksia.core.model.StopTimeDated
|
||||
import moe.lava.banksia.core.model.StopTime
|
||||
import moe.lava.banksia.core.model.atDate
|
||||
import moe.lava.banksia.core.sqld.StopTimeQueries
|
||||
import moe.lava.banksia.core.sqld.mappers.asModel
|
||||
import moe.lava.banksia.core.util.serialise
|
||||
import kotlin.time.Clock
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.get
|
||||
|
||||
internal class StopTimeLocalDataSource(
|
||||
private val queries: StopTimeQueries,
|
||||
) {
|
||||
suspend fun getAtStop(
|
||||
stopId: String,
|
||||
date: LocalDate = Clock.System.todayIn(TimeZone.currentSystemDefault()),
|
||||
): List<StopTimeDated> {
|
||||
return withContext(Dispatchers.IO) {
|
||||
internal class StopTimeLocalDataSource : KoinComponent {
|
||||
private val queries get() = get<StopTimeQueries>()
|
||||
|
||||
suspend fun getAtStop(stopId: String, date: LocalDate): List<StopTime.Dated> {
|
||||
return withContext(context = Dispatchers.IO) {
|
||||
queries
|
||||
.getForStopDated(
|
||||
listOf(date.dayOfWeek).serialise().toLong(),
|
||||
|
|
@ -29,7 +25,7 @@ internal class StopTimeLocalDataSource(
|
|||
)
|
||||
.executeAsList()
|
||||
.map { it.asModel().atDate(date) }
|
||||
.sortedBy { it.departureTime }
|
||||
.sortedBy { it.time.departure }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package moe.lava.banksia.core.data
|
||||
|
||||
import moe.lava.banksia.core.data.repositories.StopTimeRepository
|
||||
import org.koin.core.module.dsl.singleOf
|
||||
import org.koin.dsl.module
|
||||
|
||||
internal actual val platformModule = module {
|
||||
singleOf(::StopTimeRepository)
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package moe.lava.banksia.core.data.repositories
|
||||
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.datetime.LocalDate
|
||||
import moe.lava.banksia.core.data.sources.stoptime.StopTimeLocalDataSource
|
||||
|
||||
actual class StopTimeRepository internal constructor(
|
||||
private val local: StopTimeLocalDataSource,
|
||||
) {
|
||||
actual suspend fun getForStop(id: String, date: LocalDate) = flow {
|
||||
emit(local.getAtStop(id, date))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue