feat(server): better support for parent stops
- add datafixer to add parent stops for likely candidates
- this is mainly for bus hubs, the heuristic is the existence of a
platform code and missing parent
- use parent stops as default in route_stops
- support parent stops for stoptime querying
This commit is contained in:
parent
58649b6171
commit
c55e3a3232
11 changed files with 616 additions and 13 deletions
|
|
@ -8,7 +8,7 @@ data class Stop(
|
|||
val id: String,
|
||||
val name: String,
|
||||
val pos: Point,
|
||||
val parent: String,
|
||||
val parent: String?,
|
||||
val hasWheelChairBoarding: Boolean,
|
||||
val level: String,
|
||||
val platformCode: String,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@ package moe.lava.banksia.room
|
|||
import androidx.room.AutoMigration
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.room.util.foreignKeyCheck
|
||||
import androidx.sqlite.SQLiteConnection
|
||||
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
|
||||
import androidx.sqlite.execSQL
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import moe.lava.banksia.room.converter.RouteTypeConverter
|
||||
|
|
@ -26,7 +30,7 @@ import moe.lava.banksia.room.entity.VersionMetadataEntity
|
|||
import androidx.room.Database as DatabaseAnnotation
|
||||
|
||||
@DatabaseAnnotation(
|
||||
version = 10,
|
||||
version = 11,
|
||||
entities = [
|
||||
RouteEntity::class,
|
||||
ServiceEntity::class,
|
||||
|
|
@ -59,7 +63,21 @@ abstract class Database : RoomDatabase() {
|
|||
base.fallbackToDestructiveMigration(true)
|
||||
.setDriver(BundledSQLiteDriver())
|
||||
.setQueryCoroutineContext(Dispatchers.IO)
|
||||
.addMigrations(MIGRATION_10_11)
|
||||
// .fallbackToDestructiveMigration(true)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
val MIGRATION_10_11 = object : Migration(10, 11) {
|
||||
override fun migrate(connection: SQLiteConnection) {
|
||||
connection.execSQL("CREATE TABLE IF NOT EXISTS `_new_Stop` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `lat` REAL NOT NULL, `lng` REAL NOT NULL, `parent` TEXT, `hasWheelChairBoarding` INTEGER NOT NULL, `level` TEXT NOT NULL, `platformCode` TEXT NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`parent`) REFERENCES `Stop`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED)")
|
||||
connection.execSQL("INSERT INTO `_new_Stop` (`id`,`name`,`lat`,`lng`,`parent`,`hasWheelChairBoarding`,`level`,`platformCode`) SELECT `id`,`name`,`lat`,`lng`,`parent`,`hasWheelChairBoarding`,`level`,`platformCode` FROM `Stop`")
|
||||
connection.execSQL("UPDATE `_new_Stop` SET `parent` = NULL WHERE `parent` == \"\"")
|
||||
connection.execSQL("DROP TABLE `Stop`")
|
||||
connection.execSQL("ALTER TABLE `_new_Stop` RENAME TO `Stop`")
|
||||
connection.execSQL("CREATE INDEX IF NOT EXISTS `index_Stop_parent` ON `Stop` (`parent`)")
|
||||
connection.execSQL("CREATE INDEX IF NOT EXISTS `index_Trip_serviceId` ON `Trip` (`serviceId`)")
|
||||
foreignKeyCheck(connection, "Stop")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,13 +37,22 @@ interface RouteDao {
|
|||
""")
|
||||
suspend fun stops(id: String): List<StopEntity>
|
||||
|
||||
// I vibecoded this, sorry
|
||||
@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
|
||||
WITH Tree AS (
|
||||
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
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT s.*
|
||||
FROM Stop s
|
||||
INNER JOIN Tree t ON s.id = t.parent
|
||||
)
|
||||
SELECT DISTINCT * FROM Tree WHERE parent IS NULL;
|
||||
""")
|
||||
suspend fun stopsParent(id: String): List<StopEntity>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,13 @@ interface StopDao {
|
|||
@Query("SELECT * FROM Stop")
|
||||
suspend fun getAll(): List<StopEntity>
|
||||
|
||||
@Query("""
|
||||
SELECT * FROM Stop
|
||||
WHERE platformCode <> ""
|
||||
AND parent == ""
|
||||
""")
|
||||
suspend fun getAllParentless(): List<StopEntity>
|
||||
|
||||
@Query("SELECT * FROM Stop WHERE id == :id")
|
||||
suspend fun get(id: String): StopEntity?
|
||||
|
||||
|
|
@ -29,4 +36,7 @@ interface StopDao {
|
|||
|
||||
@Query("DELETE FROM Stop")
|
||||
suspend fun deleteAll()
|
||||
|
||||
@Query("UPDATE Stop SET parent = :parent WHERE id IN (:ids)")
|
||||
suspend fun updateParents(ids: List<String>, parent: String)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ interface StopTimeDao {
|
|||
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 IN (SELECT Stop.id FROM Stop WHERE Stop.parent == :stopId OR Stop.id == :stopId)
|
||||
AND ServiceException.type IS NULL
|
||||
""")
|
||||
suspend fun getForStopDated(stopId: String, days: Int, date: Int): List<StopTimeEntity>
|
||||
|
|
|
|||
|
|
@ -2,17 +2,30 @@ package moe.lava.banksia.room.entity
|
|||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.ForeignKey.Companion.SET_NULL
|
||||
import androidx.room.PrimaryKey
|
||||
import moe.lava.banksia.model.Stop
|
||||
import moe.lava.banksia.util.Point
|
||||
|
||||
@Entity("Stop")
|
||||
@Entity(
|
||||
"Stop",
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
StopEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["parent"],
|
||||
onDelete = SET_NULL,
|
||||
deferred = true,
|
||||
),
|
||||
]
|
||||
)
|
||||
data class StopEntity(
|
||||
@PrimaryKey val id: String,
|
||||
val name: String,
|
||||
val lat: Double,
|
||||
val lng: Double,
|
||||
@ColumnInfo(index = true) val parent: String,
|
||||
@ColumnInfo(index = true) val parent: String?,
|
||||
val hasWheelChairBoarding: Boolean,
|
||||
val level: String,
|
||||
val platformCode: String,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import moe.lava.banksia.model.Trip
|
|||
ForeignKey(ServiceEntity::class, parentColumns = ["id"], childColumns = ["serviceId"], onDelete = CASCADE),
|
||||
ForeignKey(ShapeEntity::class, parentColumns = ["id"], childColumns = ["shapeId"], onDelete = CASCADE),
|
||||
],
|
||||
indices = [Index("shapeId")],
|
||||
indices = [Index("shapeId"), Index("serviceId")],
|
||||
)
|
||||
data class TripEntity(
|
||||
@PrimaryKey val id: String,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue