feat: server-handled routes and stops
This commit is contained in:
parent
efba64ea90
commit
58ee095522
61 changed files with 1634 additions and 349 deletions
|
|
@ -37,6 +37,7 @@ kotlin {
|
|||
|
||||
sourceSets {
|
||||
androidMain.dependencies {
|
||||
implementation(libs.koin.compose)
|
||||
implementation(libs.ktor.client.okhttp)
|
||||
}
|
||||
commonMain.dependencies {
|
||||
|
|
@ -48,6 +49,7 @@ kotlin {
|
|||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.kotlinx.datetime)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
implementation(libs.kotlinx.serialization.protobuf)
|
||||
implementation(libs.room.runtime)
|
||||
implementation(libs.sqlite.bundled)
|
||||
}
|
||||
|
|
|
|||
315
shared/schemas/moe.lava.banksia.room.Database/2.json
Normal file
315
shared/schemas/moe.lava.banksia.room.Database/2.json
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 2,
|
||||
"identityHash": "83ece554400bb035c267dc2414c23293",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "Route",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `type` INTEGER NOT NULL, `number` TEXT, `name` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "number",
|
||||
"columnName": "number",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "Shape",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `path` BLOB NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "path",
|
||||
"columnName": "path",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "Stop",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `lat` REAL NOT NULL, `lng` REAL NOT NULL, `parent` TEXT NOT NULL, `hasWheelChairBoarding` INTEGER NOT NULL, `level` TEXT NOT NULL, `platformCode` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lat",
|
||||
"columnName": "lat",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lng",
|
||||
"columnName": "lng",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "parent",
|
||||
"columnName": "parent",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "hasWheelChairBoarding",
|
||||
"columnName": "hasWheelChairBoarding",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "level",
|
||||
"columnName": "level",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "platformCode",
|
||||
"columnName": "platformCode",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_Stop_parent",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"parent"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_Stop_parent` ON `${TABLE_NAME}` (`parent`)"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "StopTime",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tripId` TEXT NOT NULL, `stopId` TEXT NOT NULL, `arrivalTime` INTEGER NOT NULL, `departureTime` INTEGER NOT NULL, `headsign` TEXT, `pickupType` INTEGER NOT NULL, `dropOffType` INTEGER NOT NULL, PRIMARY KEY(`tripId`, `stopId`), FOREIGN KEY(`tripId`) REFERENCES `Trip`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`stopId`) REFERENCES `Stop`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "tripId",
|
||||
"columnName": "tripId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "stopId",
|
||||
"columnName": "stopId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "arrivalTime",
|
||||
"columnName": "arrivalTime",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "departureTime",
|
||||
"columnName": "departureTime",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "headsign",
|
||||
"columnName": "headsign",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pickupType",
|
||||
"columnName": "pickupType",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dropOffType",
|
||||
"columnName": "dropOffType",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"tripId",
|
||||
"stopId"
|
||||
]
|
||||
},
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "Trip",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"tripId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "Stop",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"stopId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "Trip",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `routeId` TEXT NOT NULL, `serviceId` TEXT NOT NULL, `shapeId` TEXT, `tripHeadsign` TEXT NOT NULL, `directionId` TEXT NOT NULL, `blockId` TEXT NOT NULL, `wheelchairAccessible` TEXT NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`routeId`) REFERENCES `Route`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`shapeId`) REFERENCES `Shape`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "routeId",
|
||||
"columnName": "routeId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "serviceId",
|
||||
"columnName": "serviceId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "shapeId",
|
||||
"columnName": "shapeId",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "tripHeadsign",
|
||||
"columnName": "tripHeadsign",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "directionId",
|
||||
"columnName": "directionId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "blockId",
|
||||
"columnName": "blockId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "wheelchairAccessible",
|
||||
"columnName": "wheelchairAccessible",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_Trip_routeId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"routeId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_Trip_routeId` ON `${TABLE_NAME}` (`routeId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "Route",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"routeId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "Shape",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"shapeId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '83ece554400bb035c267dc2414c23293')"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import androidx.room.RoomDatabase
|
|||
import moe.lava.banksia.room.Database
|
||||
import org.koin.core.parameter.ParametersHolder
|
||||
import org.koin.core.scope.Scope
|
||||
import org.koin.dsl.module
|
||||
|
||||
class AndroidDatabaseBuilder(val ctx: Context) : PlatformDatabaseBuilder {
|
||||
override fun getBuilder(): RoomDatabase.Builder<Database> {
|
||||
|
|
@ -19,4 +20,6 @@ class AndroidDatabaseBuilder(val ctx: Context) : PlatformDatabaseBuilder {
|
|||
}
|
||||
|
||||
actual fun Scope.provideDatabaseBuilder(p: ParametersHolder): PlatformDatabaseBuilder =
|
||||
AndroidDatabaseBuilder(p.get())
|
||||
AndroidDatabaseBuilder(get())
|
||||
|
||||
internal actual val ExtPlatformModule = module { }
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import io.ktor.client.request.url
|
|||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.http.appendPathSegments
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
|
|
@ -22,9 +21,10 @@ import moe.lava.banksia.data.ptv.structures.PtvDeparture
|
|||
import moe.lava.banksia.data.ptv.structures.PtvDirection
|
||||
import moe.lava.banksia.data.ptv.structures.PtvRoute
|
||||
import moe.lava.banksia.data.ptv.structures.PtvRouteType
|
||||
import moe.lava.banksia.data.ptv.structures.PtvRouteType.Companion.asPtvType
|
||||
import moe.lava.banksia.data.ptv.structures.PtvRun
|
||||
import moe.lava.banksia.data.ptv.structures.PtvStop
|
||||
import moe.lava.banksia.util.CacheMap
|
||||
import moe.lava.banksia.model.RouteType
|
||||
import moe.lava.banksia.util.LoopFlow.Companion.initWith
|
||||
import moe.lava.banksia.util.error
|
||||
import moe.lava.banksia.util.log
|
||||
|
|
@ -59,16 +59,15 @@ suspend inline fun <K, V> MutableMap<K, V>.getOrPutSuspend(key: K, defaultValue:
|
|||
return this[key]!!
|
||||
}
|
||||
|
||||
class PtvService(coroutineScope: CoroutineScope) {
|
||||
class PtvService() {
|
||||
class PtvCache(
|
||||
coroutineScope: CoroutineScope,
|
||||
val directions: CacheMap<Pair<Int, Int>, PtvDirection> = CacheMap(coroutineScope),
|
||||
val routes: CacheMap<Int, PtvRoute> = CacheMap(coroutineScope),
|
||||
val runs: CacheMap<String, PtvRun> = CacheMap(coroutineScope),
|
||||
val stops: CacheMap<Int, PtvStop> = CacheMap(coroutineScope),
|
||||
val directions: MutableMap<Pair<Int, Int>, PtvDirection> = mutableMapOf(),
|
||||
val routes: MutableMap<Int, PtvRoute> = mutableMapOf(),
|
||||
val runs: MutableMap<String, PtvRun> = mutableMapOf(),
|
||||
val stops: MutableMap<Int, PtvStop> = mutableMapOf(),
|
||||
)
|
||||
|
||||
val cache = PtvCache(coroutineScope)
|
||||
val cache = PtvCache()
|
||||
|
||||
private val client = HttpClient() {
|
||||
install(ContentNegotiation) {
|
||||
|
|
@ -227,6 +226,20 @@ class PtvService(coroutineScope: CoroutineScope) {
|
|||
return cache.directions[directionId to routeId]!!
|
||||
}
|
||||
|
||||
suspend fun departures(routeType: RouteType, stopId: String): Responses.PtvDeparturesResponse =
|
||||
client
|
||||
.safeGet ("departures") {
|
||||
url {
|
||||
appendPathSegments(
|
||||
"route_type", routeType.asPtvType().ordinal.toString(),
|
||||
"stop", stopId.toString(),
|
||||
)
|
||||
parameter("expand", "Route")
|
||||
parameter("expand", "Direction")
|
||||
parameter("gtfs", "true")
|
||||
}
|
||||
}.body()
|
||||
|
||||
suspend fun departures(routeType: PtvRouteType, stopId: Int): Responses.PtvDeparturesResponse =
|
||||
client
|
||||
.safeGet ("departures") {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
|||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import moe.lava.banksia.model.RouteType
|
||||
|
||||
private object PtvRouteTypeSerialiser : KSerializer<PtvRouteType> {
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(
|
||||
|
|
@ -30,4 +31,20 @@ enum class PtvRouteType {
|
|||
BUS,
|
||||
VLINE,
|
||||
NIGHT_BUS,
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun fromModel(type: RouteType) = when (type) {
|
||||
RouteType.MetroTrain -> TRAIN
|
||||
RouteType.MetroTram -> TRAM
|
||||
RouteType.MetroBus -> BUS
|
||||
RouteType.RegionalTrain -> VLINE
|
||||
RouteType.RegionalCoach -> BUS
|
||||
RouteType.RegionalBus -> BUS
|
||||
RouteType.SkyBus -> BUS
|
||||
RouteType.Interstate -> TRAIN
|
||||
}
|
||||
|
||||
fun RouteType.asPtvType() = fromModel(this)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ val CommonModules = module {
|
|||
includes(PlatformModule)
|
||||
|
||||
single { Database.build(get<PlatformDatabaseBuilder>().getBuilder()) }
|
||||
single { get<Database>().getRouteDao() }
|
||||
single { get<Database>().getShapeDao() }
|
||||
single { get<Database>().routeDao }
|
||||
single { get<Database>().shapeDao }
|
||||
single { get<Database>().stopDao }
|
||||
single { get<Database>().stopTimeDao }
|
||||
single { get<Database>().tripDao }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package moe.lava.banksia.di
|
|||
|
||||
import androidx.room.RoomDatabase
|
||||
import moe.lava.banksia.room.Database
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.core.parameter.ParametersHolder
|
||||
import org.koin.core.scope.Scope
|
||||
import org.koin.dsl.module
|
||||
|
|
@ -12,6 +13,9 @@ interface PlatformDatabaseBuilder {
|
|||
|
||||
expect fun Scope.provideDatabaseBuilder(p: ParametersHolder): PlatformDatabaseBuilder
|
||||
|
||||
internal expect val ExtPlatformModule: Module
|
||||
|
||||
internal val PlatformModule = module {
|
||||
includes(ExtPlatformModule)
|
||||
single { provideDatabaseBuilder(it) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import kotlinx.datetime.LocalTime
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import moe.lava.banksia.model.FutureTime.Companion.asInt
|
||||
|
||||
@Serializable(FutureTimeSerialiser::class)
|
||||
data class FutureTime(
|
||||
val dayOffset: Boolean,
|
||||
val time: LocalTime,
|
||||
) {
|
||||
companion object {
|
||||
fun from(hour: Int, minute: Int, second: Int): FutureTime {
|
||||
var nHour = hour
|
||||
val nextDay = hour >= 24
|
||||
if (nextDay)
|
||||
nHour -= 24
|
||||
val time = LocalTime(nHour, minute, second)
|
||||
return FutureTime(nextDay, time)
|
||||
}
|
||||
|
||||
fun FutureTime.asInt() =
|
||||
trueHour * 3600 + minute * 60 + second
|
||||
|
||||
fun fromInt(int: Int) = FutureTime.from(
|
||||
int / 3600,
|
||||
(int / 60) % 60,
|
||||
int % 60,
|
||||
)
|
||||
}
|
||||
|
||||
val hour = time.hour
|
||||
val minute = time.minute
|
||||
val second = time.second
|
||||
val trueHour = time.hour + (if (dayOffset) 24 else 0)
|
||||
}
|
||||
|
||||
object FutureTimeSerialiser: KSerializer<FutureTime> {
|
||||
override val descriptor: SerialDescriptor =
|
||||
PrimitiveSerialDescriptor(FutureTimeSerialiser::class.qualifiedName!!, PrimitiveKind.INT)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: FutureTime) = encoder.encodeInt(value.asInt())
|
||||
override fun deserialize(decoder: Decoder) = FutureTime.fromInt(decoder.decodeInt())
|
||||
}
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Entity
|
||||
@Serializable
|
||||
data class Route(
|
||||
@PrimaryKey val id: String,
|
||||
val id: String,
|
||||
val type: RouteType,
|
||||
val number: String?,
|
||||
val name: String,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
enum class RouteType(val value: Int) {
|
||||
MetroTrain(2),
|
||||
MetroTram(3),
|
||||
|
|
@ -12,12 +13,4 @@ enum class RouteType(val value: Int) {
|
|||
SkyBus(11),
|
||||
Interstate(10),
|
||||
;
|
||||
|
||||
companion object {
|
||||
@TypeConverter
|
||||
fun from(value: Int) = RouteType.entries.first { it.value == value }
|
||||
|
||||
@TypeConverter
|
||||
fun to(routeType: RouteType) = routeType.value
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
data class Run(
|
||||
val ref: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import kotlinx.datetime.DayOfWeek
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Service(
|
||||
val id: String,
|
||||
val days: List<DayOfWeek>,
|
||||
val start: LocalDate,
|
||||
val end: LocalDate,
|
||||
)
|
||||
|
|
@ -1,16 +1,12 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.TypeConverters
|
||||
import moe.lava.banksia.room.converter.ShapeConverter
|
||||
import kotlinx.serialization.Serializable
|
||||
import moe.lava.banksia.util.Point
|
||||
|
||||
typealias ShapePath = List<Point>
|
||||
|
||||
@Entity
|
||||
@TypeConverters(ShapeConverter::class)
|
||||
@Serializable
|
||||
data class Shape(
|
||||
@PrimaryKey val id: String,
|
||||
val id: String,
|
||||
val path: ShapePath,
|
||||
)
|
||||
|
|
|
|||
15
shared/src/commonMain/kotlin/moe/lava/banksia/model/Stop.kt
Normal file
15
shared/src/commonMain/kotlin/moe/lava/banksia/model/Stop.kt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import moe.lava.banksia.util.Point
|
||||
|
||||
@Serializable
|
||||
data class Stop(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val pos: Point,
|
||||
val parent: String,
|
||||
val hasWheelChairBoarding: Boolean,
|
||||
val level: String,
|
||||
val platformCode: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class StopTime(
|
||||
val tripId: String,
|
||||
val stopId: String,
|
||||
val arrivalTime: FutureTime,
|
||||
val departureTime: FutureTime,
|
||||
val headsign: String?,
|
||||
val pickupType: Int,
|
||||
val dropOffType: Int,
|
||||
)
|
||||
15
shared/src/commonMain/kotlin/moe/lava/banksia/model/Trip.kt
Normal file
15
shared/src/commonMain/kotlin/moe/lava/banksia/model/Trip.kt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Trip(
|
||||
val id: String,
|
||||
val routeId: String,
|
||||
val serviceId: String,
|
||||
val shapeId: String?,
|
||||
val tripHeadsign: String,
|
||||
val directionId: String,
|
||||
val blockId: String,
|
||||
val wheelchairAccessible: String,
|
||||
)
|
||||
|
|
@ -1,28 +1,51 @@
|
|||
package moe.lava.banksia.room
|
||||
|
||||
import androidx.room.AutoMigration
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import moe.lava.banksia.model.Route
|
||||
import moe.lava.banksia.model.RouteType
|
||||
import moe.lava.banksia.model.Shape
|
||||
import moe.lava.banksia.room.converter.RouteTypeConverter
|
||||
import moe.lava.banksia.room.dao.RouteDao
|
||||
import moe.lava.banksia.room.dao.ShapeDao
|
||||
import moe.lava.banksia.room.dao.StopDao
|
||||
import moe.lava.banksia.room.dao.StopTimeDao
|
||||
import moe.lava.banksia.room.dao.TripDao
|
||||
import moe.lava.banksia.room.entity.RouteEntity
|
||||
import moe.lava.banksia.room.entity.ShapeEntity
|
||||
import moe.lava.banksia.room.entity.StopEntity
|
||||
import moe.lava.banksia.room.entity.StopTimeEntity
|
||||
import moe.lava.banksia.room.entity.TripEntity
|
||||
import androidx.room.Database as DatabaseAnnotation
|
||||
|
||||
@DatabaseAnnotation(entities = [Route::class, Shape::class], version = 1)
|
||||
@TypeConverters(RouteType.Companion::class)
|
||||
@DatabaseAnnotation(
|
||||
version = 2,
|
||||
entities = [
|
||||
RouteEntity::class,
|
||||
ShapeEntity::class,
|
||||
StopEntity::class,
|
||||
StopTimeEntity::class,
|
||||
TripEntity::class,
|
||||
],
|
||||
autoMigrations = [
|
||||
AutoMigration(from = 1, to = 2),
|
||||
]
|
||||
)
|
||||
@TypeConverters(RouteTypeConverter::class)
|
||||
abstract class Database : RoomDatabase() {
|
||||
abstract fun getRouteDao(): RouteDao
|
||||
abstract fun getShapeDao(): ShapeDao
|
||||
abstract val routeDao: RouteDao
|
||||
abstract val shapeDao: ShapeDao
|
||||
abstract val stopDao: StopDao
|
||||
abstract val stopTimeDao: StopTimeDao
|
||||
abstract val tripDao: TripDao
|
||||
|
||||
companion object {
|
||||
fun build(base: Builder<Database>) =
|
||||
base.fallbackToDestructiveMigrationOnDowngrade(true)
|
||||
base.fallbackToDestructiveMigration(true)
|
||||
.setDriver(BundledSQLiteDriver())
|
||||
.setQueryCoroutineContext(Dispatchers.IO)
|
||||
// .fallbackToDestructiveMigration(true)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package moe.lava.banksia.room.converter
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import moe.lava.banksia.model.RouteType
|
||||
|
||||
object RouteTypeConverter {
|
||||
@TypeConverter
|
||||
fun from(value: Int) = RouteType.entries.first { it.value == value }
|
||||
|
||||
@TypeConverter
|
||||
fun to(routeType: RouteType) = routeType.value
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ import androidx.room.TypeConverter
|
|||
import moe.lava.banksia.model.ShapePath
|
||||
import moe.lava.banksia.util.Point
|
||||
|
||||
object ShapeConverter {
|
||||
object ShapePathConverter {
|
||||
@TypeConverter
|
||||
fun from(value: ByteArray): ShapePath {
|
||||
return value
|
||||
|
|
@ -3,23 +3,47 @@ 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.model.Route
|
||||
import moe.lava.banksia.room.entity.RouteEntity
|
||||
import moe.lava.banksia.room.entity.StopEntity
|
||||
|
||||
@Dao
|
||||
interface RouteDao {
|
||||
@Query("SELECT * FROM Route")
|
||||
suspend fun getAll(): List<Route>
|
||||
suspend fun getAll(): List<RouteEntity>
|
||||
|
||||
@Query("SELECT * FROM Route WHERE id == :id")
|
||||
suspend fun get(id: String): Route?
|
||||
suspend fun get(id: String): RouteEntity?
|
||||
|
||||
@Insert
|
||||
suspend fun insertAll(vararg routes: Route)
|
||||
suspend fun insertAll(vararg routes: RouteEntity)
|
||||
|
||||
@Insert(onConflict = REPLACE)
|
||||
suspend fun insertOrReplaceAll(vararg routes: RouteEntity)
|
||||
|
||||
@Delete
|
||||
suspend fun delete(route: Route)
|
||||
suspend fun delete(route: RouteEntity)
|
||||
|
||||
@Query("DELETE FROM Route")
|
||||
suspend fun deleteAll()
|
||||
|
||||
@Query("""
|
||||
SELECT Stop.* FROM Stop
|
||||
INNER JOIN StopTime ON StopTime.stopId == Stop.id
|
||||
INNER JOIN Trip ON Trip.id == StopTime.tripId
|
||||
WHERE Trip.routeId == :id
|
||||
GROUP BY Stop.id
|
||||
""")
|
||||
suspend fun stops(id: String): List<StopEntity>
|
||||
|
||||
@Query("""
|
||||
SELECT Stop.* FROM Stop
|
||||
INNER JOIN Stop Child ON Child.parent == Stop.id
|
||||
INNER JOIN StopTime ON StopTime.stopId == Child.id
|
||||
INNER JOIN Trip ON Trip.id == StopTime.tripId
|
||||
WHERE Trip.routeId == :id
|
||||
GROUP BY Stop.id
|
||||
""")
|
||||
suspend fun stopsParent(id: String): List<StopEntity>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,18 +4,18 @@ import androidx.room.Dao
|
|||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import moe.lava.banksia.model.Shape
|
||||
import moe.lava.banksia.room.entity.ShapeEntity
|
||||
|
||||
@Dao
|
||||
interface ShapeDao {
|
||||
@Query("SELECT * FROM Shape WHERE id == :id")
|
||||
suspend fun get(id: String): Shape?
|
||||
suspend fun get(id: String): ShapeEntity?
|
||||
|
||||
@Insert
|
||||
suspend fun insertAll(vararg shapes: Shape)
|
||||
suspend fun insertAll(vararg shapes: ShapeEntity)
|
||||
|
||||
@Delete
|
||||
suspend fun delete(shape: Shape)
|
||||
suspend fun delete(shape: ShapeEntity)
|
||||
|
||||
@Query("DELETE FROM Shape")
|
||||
suspend fun deleteAll()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
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.StopEntity
|
||||
|
||||
@Dao
|
||||
interface StopDao {
|
||||
@Query("SELECT * FROM Stop")
|
||||
suspend fun getAll(): List<StopEntity>
|
||||
|
||||
@Query("SELECT * FROM Stop WHERE id == :id")
|
||||
suspend fun get(id: String): StopEntity?
|
||||
|
||||
@Query("SELECT * FROM Stop WHERE id IN (:ids)")
|
||||
suspend fun get(ids: List<String>): List<StopEntity>
|
||||
|
||||
@Insert
|
||||
suspend fun insertAll(vararg stops: StopEntity)
|
||||
|
||||
@Insert(onConflict = REPLACE)
|
||||
suspend fun insertOrReplaceAll(vararg stops: StopEntity)
|
||||
|
||||
@Delete
|
||||
suspend fun delete(stop: StopEntity)
|
||||
|
||||
@Query("DELETE FROM Stop")
|
||||
suspend fun deleteAll()
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
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.StopTimeEntity
|
||||
|
||||
@Dao
|
||||
interface StopTimeDao {
|
||||
@Query("SELECT * FROM StopTime")
|
||||
suspend fun getAll(): List<StopTimeEntity>
|
||||
|
||||
@Query("SELECT * FROM StopTime WHERE tripId == :tripId")
|
||||
suspend fun get(tripId: String): StopTimeEntity?
|
||||
|
||||
@Query("SELECT * FROM StopTime WHERE tripId IN (:tripIds)")
|
||||
suspend fun get(tripIds: List<String>): List<StopTimeEntity>
|
||||
|
||||
@Insert
|
||||
suspend fun insertAll(vararg stopTimes: StopTimeEntity)
|
||||
|
||||
@Insert(onConflict = REPLACE)
|
||||
suspend fun insertOrReplaceAll(vararg stopTimes: StopTimeEntity)
|
||||
|
||||
@Delete
|
||||
suspend fun delete(stopTime: StopTimeEntity)
|
||||
|
||||
@Query("DELETE FROM StopTime")
|
||||
suspend fun deleteAll()
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
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.TripEntity
|
||||
|
||||
@Dao
|
||||
interface TripDao {
|
||||
@Query("SELECT * FROM Trip")
|
||||
suspend fun getAll(): List<TripEntity>
|
||||
|
||||
@Query("SELECT * FROM Trip WHERE id == :id")
|
||||
suspend fun get(id: String): TripEntity?
|
||||
|
||||
@Query("SELECT * FROM Trip WHERE routeId == :id")
|
||||
suspend fun getByRoute(id: String): List<TripEntity>
|
||||
|
||||
@Insert
|
||||
suspend fun insertAll(vararg trips: TripEntity)
|
||||
|
||||
@Insert(onConflict = REPLACE)
|
||||
suspend fun insertOrReplaceAll(vararg trips: TripEntity)
|
||||
|
||||
@Delete
|
||||
suspend fun delete(trip: TripEntity)
|
||||
|
||||
@Query("DELETE FROM Trip")
|
||||
suspend fun deleteAll()
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package moe.lava.banksia.room.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import moe.lava.banksia.model.Route
|
||||
import moe.lava.banksia.model.RouteType
|
||||
|
||||
@Entity("Route")
|
||||
data class RouteEntity(
|
||||
@PrimaryKey val id: String,
|
||||
val type: RouteType,
|
||||
val number: String?,
|
||||
val name: String,
|
||||
) {
|
||||
fun asModel() = Route(id, type, number, name)
|
||||
}
|
||||
|
||||
fun Route.asEntity() = RouteEntity(id, type, number, name)
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package moe.lava.banksia.room.entity
|
||||
|
||||
import kotlinx.datetime.DayOfWeek
|
||||
import kotlinx.datetime.LocalDate
|
||||
import moe.lava.banksia.model.Service
|
||||
|
||||
data class ServiceEntity(
|
||||
val id: String,
|
||||
val days: Int,
|
||||
val start: Int,
|
||||
val end: Int,
|
||||
) {
|
||||
object Parser {
|
||||
private fun Int.check(other: Int) = (this and other) != 0
|
||||
|
||||
fun deserialiseDays(days: Int): List<DayOfWeek> = buildList {
|
||||
if (days.check(1))
|
||||
add(DayOfWeek.MONDAY)
|
||||
if (days.check(1 shl 1))
|
||||
add(DayOfWeek.TUESDAY)
|
||||
if (days.check(1 shl 2))
|
||||
add(DayOfWeek.WEDNESDAY)
|
||||
if (days.check(1 shl 3))
|
||||
add(DayOfWeek.THURSDAY)
|
||||
if (days.check(1 shl 4))
|
||||
add(DayOfWeek.FRIDAY)
|
||||
if (days.check(1 shl 5))
|
||||
add(DayOfWeek.SATURDAY)
|
||||
if (days.check(1 shl 6))
|
||||
add(DayOfWeek.SUNDAY)
|
||||
}
|
||||
fun serialiseDays(days: List<DayOfWeek>): Int =
|
||||
days.fold(0) { vl, n ->
|
||||
vl + when (n) {
|
||||
DayOfWeek.MONDAY -> 1
|
||||
DayOfWeek.TUESDAY -> 1 shl 1
|
||||
DayOfWeek.WEDNESDAY -> 1 shl 2
|
||||
DayOfWeek.THURSDAY -> 1 shl 3
|
||||
DayOfWeek.FRIDAY -> 1 shl 4
|
||||
DayOfWeek.SATURDAY -> 1 shl 5
|
||||
DayOfWeek.SUNDAY -> 1 shl 6
|
||||
}
|
||||
}
|
||||
}
|
||||
fun asModel() = Service(
|
||||
id,
|
||||
Parser.deserialiseDays(days),
|
||||
LocalDate.fromEpochDays(start),
|
||||
LocalDate.fromEpochDays(end),
|
||||
)
|
||||
}
|
||||
|
||||
fun Service.asEntity() = ServiceEntity(
|
||||
id,
|
||||
ServiceEntity.Parser.serialiseDays(days),
|
||||
start.toEpochDays().toInt(),
|
||||
end.toEpochDays().toInt(),
|
||||
)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package moe.lava.banksia.room.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.TypeConverters
|
||||
import moe.lava.banksia.model.Shape
|
||||
import moe.lava.banksia.model.ShapePath
|
||||
import moe.lava.banksia.room.converter.ShapePathConverter
|
||||
|
||||
@Entity("Shape")
|
||||
@TypeConverters(ShapePathConverter::class)
|
||||
data class ShapeEntity(
|
||||
@PrimaryKey val id: String,
|
||||
val path: ShapePath,
|
||||
) {
|
||||
fun asModel() = Shape(id, path)
|
||||
}
|
||||
|
||||
fun Shape.asEntity() = ShapeEntity(id, path)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package moe.lava.banksia.room.entity
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import moe.lava.banksia.model.Stop
|
||||
import moe.lava.banksia.util.Point
|
||||
|
||||
@Entity("Stop")
|
||||
data class StopEntity(
|
||||
@PrimaryKey val id: String,
|
||||
val name: String,
|
||||
val lat: Double,
|
||||
val lng: Double,
|
||||
@ColumnInfo(index = true) val parent: String,
|
||||
val hasWheelChairBoarding: Boolean,
|
||||
val level: String,
|
||||
val platformCode: String,
|
||||
) {
|
||||
fun asModel() = Stop(id, name, Point(lat, lng), parent, hasWheelChairBoarding, level, platformCode)
|
||||
}
|
||||
|
||||
fun Stop.asEntity() = StopEntity(id, name, pos.lat, pos.lng, parent, hasWheelChairBoarding, level, platformCode)
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package moe.lava.banksia.room.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.ForeignKey.Companion.CASCADE
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import moe.lava.banksia.model.FutureTime
|
||||
import moe.lava.banksia.model.FutureTime.Companion.asInt
|
||||
import moe.lava.banksia.model.StopTime
|
||||
|
||||
@Entity(
|
||||
"StopTime",
|
||||
primaryKeys = ["tripId", "stopId"],
|
||||
foreignKeys = [
|
||||
ForeignKey(TripEntity::class, parentColumns = ["id"], childColumns = ["tripId"], onDelete = CASCADE),
|
||||
ForeignKey(StopEntity::class, parentColumns = ["id"], childColumns = ["stopId"], onDelete = CASCADE),
|
||||
]
|
||||
)
|
||||
data class StopTimeEntity(
|
||||
val tripId: String,
|
||||
val stopId: String,
|
||||
val arrivalTime: Int,
|
||||
val departureTime: Int,
|
||||
val headsign: String?,
|
||||
val pickupType: Int,
|
||||
val dropOffType: Int,
|
||||
) {
|
||||
fun asModel() = StopTime(
|
||||
tripId,
|
||||
stopId,
|
||||
FutureTime.fromInt(arrivalTime),
|
||||
FutureTime.fromInt(departureTime),
|
||||
headsign,
|
||||
pickupType,
|
||||
dropOffType,
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
fun StopTime.asEntity() = StopTimeEntity(
|
||||
tripId,
|
||||
stopId,
|
||||
arrivalTime.asInt(),
|
||||
departureTime.asInt(),
|
||||
headsign,
|
||||
pickupType,
|
||||
dropOffType,
|
||||
)
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package moe.lava.banksia.room.entity
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.ForeignKey.Companion.CASCADE
|
||||
import androidx.room.PrimaryKey
|
||||
import moe.lava.banksia.model.Trip
|
||||
|
||||
@Entity(
|
||||
"Trip",
|
||||
foreignKeys = [
|
||||
ForeignKey(RouteEntity::class, parentColumns = ["id"], childColumns = ["routeId"], onDelete = CASCADE),
|
||||
ForeignKey(ShapeEntity::class, parentColumns = ["id"], childColumns = ["shapeId"], onDelete = CASCADE),
|
||||
],
|
||||
)
|
||||
data class TripEntity(
|
||||
@PrimaryKey val id: String,
|
||||
@ColumnInfo(index = true) val routeId: String,
|
||||
val serviceId: String,
|
||||
val shapeId: String?,
|
||||
val tripHeadsign: String,
|
||||
val directionId: String,
|
||||
val blockId: String,
|
||||
val wheelchairAccessible: String,
|
||||
) {
|
||||
fun asModel() = Trip(id, routeId, serviceId, shapeId, tripHeadsign, directionId, blockId, wheelchairAccessible)
|
||||
}
|
||||
|
||||
fun Trip.asEntity() = TripEntity(id, routeId, serviceId, shapeId, tripHeadsign, directionId, blockId, wheelchairAccessible)
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
package moe.lava.banksia.util
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Point(val lat: Double, val lng: Double)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import androidx.room.RoomDatabase
|
|||
import moe.lava.banksia.room.Database
|
||||
import org.koin.core.parameter.ParametersHolder
|
||||
import org.koin.core.scope.Scope
|
||||
import org.koin.dsl.module
|
||||
|
||||
class IosDatabaseBuilder() : PlatformDatabaseBuilder {
|
||||
override fun getBuilder(): RoomDatabase.Builder<Database> {
|
||||
|
|
@ -13,3 +14,5 @@ class IosDatabaseBuilder() : PlatformDatabaseBuilder {
|
|||
|
||||
actual fun Scope.provideDatabaseBuilder(p: ParametersHolder): PlatformDatabaseBuilder =
|
||||
IosDatabaseBuilder()
|
||||
|
||||
internal actual val ExtPlatformModule = module { }
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import androidx.room.RoomDatabase
|
|||
import moe.lava.banksia.room.Database
|
||||
import org.koin.core.parameter.ParametersHolder
|
||||
import org.koin.core.scope.Scope
|
||||
import org.koin.dsl.module
|
||||
import java.io.File
|
||||
|
||||
class JvmDatabaseBuilder() : PlatformDatabaseBuilder {
|
||||
|
|
@ -18,3 +19,5 @@ class JvmDatabaseBuilder() : PlatformDatabaseBuilder {
|
|||
|
||||
actual fun Scope.provideDatabaseBuilder(p: ParametersHolder): PlatformDatabaseBuilder =
|
||||
JvmDatabaseBuilder()
|
||||
|
||||
internal actual val ExtPlatformModule = module { }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue