package com.racingapp.pitlog.data import androidx.room.Dao import androidx.room.Insert import androidx.room.Query import androidx.room.Transaction import androidx.room.Update import kotlinx.coroutines.flow.Flow @Dao interface RaceDao { @Transaction @Query("SELECT * FROM race_nights WHERE deleted = 0 AND carId = :carId ORDER BY dateEpochDay DESC, id DESC") fun observeNightsWithRuns(carId: Long): Flow> @Query("SELECT * FROM race_nights WHERE id = :id AND deleted = 0") fun observeNight(id: Long): Flow @Query("SELECT * FROM race_nights WHERE id = :id AND deleted = 0") suspend fun getNight(id: Long): RaceNight? @Query("SELECT * FROM race_nights WHERE id = :id") suspend fun nightById(id: Long): RaceNight? @Query("SELECT * FROM race_nights WHERE syncId = :syncId AND carId = :carId LIMIT 1") suspend fun nightBySyncId(syncId: String, carId: Long): RaceNight? @Query("SELECT * FROM race_nights WHERE pending = 1 AND carId = :carId") suspend fun pendingNights(carId: Long): List @Query("SELECT * FROM race_nights WHERE syncId = '' AND carId = :carId") suspend fun nightsMissingSyncId(carId: Long): List @Query( """ SELECT trackName FROM race_nights WHERE deleted = 0 AND carId = :carId AND TRIM(trackName) != '' GROUP BY trackName COLLATE NOCASE ORDER BY MAX(dateEpochDay) DESC, trackName COLLATE NOCASE """, ) fun observeTrackNames(carId: Long): Flow> @Insert suspend fun insertNight(night: RaceNight): Long @Update suspend fun updateNight(night: RaceNight) @Query("SELECT * FROM runs WHERE nightId = :nightId AND deleted = 0 ORDER BY recordedAt DESC") fun observeRuns(nightId: Long): Flow> @Query("SELECT * FROM runs WHERE nightId = :nightId") suspend fun runsForNight(nightId: Long): List @Query("SELECT * FROM runs WHERE id = :id AND deleted = 0") fun observeRun(id: Long): Flow @Query("SELECT * FROM runs WHERE id = :id AND deleted = 0") suspend fun getRun(id: Long): RunLog? @Query("SELECT * FROM runs WHERE id = :id") suspend fun runById(id: Long): RunLog? @Query("SELECT * FROM runs WHERE syncId = :syncId LIMIT 1") suspend fun runBySyncId(syncId: String): RunLog? @Query( """ SELECT * FROM runs WHERE pending = 1 AND nightId IN (SELECT id FROM race_nights WHERE carId = :carId) """, ) suspend fun pendingRuns(carId: Long): List @Query( """ SELECT * FROM runs WHERE (syncId = '' OR nightSyncId = '') AND nightId IN (SELECT id FROM race_nights WHERE carId = :carId) """, ) suspend fun runsMissingSyncId(carId: Long): List @Query("SELECT * FROM runs WHERE nightId = :nightId AND deleted = 0 ORDER BY recordedAt DESC LIMIT 1") suspend fun latestRun(nightId: Long): RunLog? @Query( "SELECT * FROM runs WHERE nightId = :nightId AND deleted = 0 AND recordedAt < :before ORDER BY recordedAt DESC LIMIT 1", ) suspend fun previousRun(nightId: Long, before: Long): RunLog? @Insert suspend fun insertRun(run: RunLog): Long @Update suspend fun updateRun(run: RunLog) @Query("SELECT * FROM setup_sheets WHERE deleted = 0 AND carId = :carId ORDER BY recordedAt ASC, id ASC") fun observeSetupSheets(carId: Long): Flow> @Query("SELECT * FROM setup_sheets WHERE id = :id") suspend fun sheetById(id: Long): SetupSheet? @Query("SELECT * FROM setup_sheets WHERE syncId = :syncId AND carId = :carId LIMIT 1") suspend fun sheetBySyncId(syncId: String, carId: Long): SetupSheet? @Query("SELECT * FROM setup_sheets WHERE pending = 1 AND carId = :carId") suspend fun pendingSheets(carId: Long): List @Query("SELECT * FROM setup_sheets WHERE syncId = '' AND carId = :carId") suspend fun sheetsMissingSyncId(carId: Long): List @Insert suspend fun insertSetupSheet(sheet: SetupSheet): Long @Update suspend fun updateSetupSheet(sheet: SetupSheet) @Query("SELECT * FROM cars WHERE deleted = 0 ORDER BY id ASC") fun observeCars(): Flow> @Query("SELECT * FROM cars ORDER BY id ASC") suspend fun everyCar(): List @Query("SELECT * FROM cars WHERE deleted = 0 ORDER BY id ASC") suspend fun activeCars(): List @Query("SELECT * FROM cars WHERE id = :id") fun observeCar(id: Long): Flow @Query("SELECT * FROM cars WHERE id = :id") suspend fun carById(id: Long): Car? @Query("UPDATE race_nights SET pending = 1 WHERE carId = :carId") suspend fun markNightsPending(carId: Long) @Query("UPDATE runs SET pending = 1 WHERE nightId IN (SELECT id FROM race_nights WHERE carId = :carId)") suspend fun markRunsPending(carId: Long) @Query("UPDATE setup_sheets SET pending = 1 WHERE carId = :carId") suspend fun markSheetsPending(carId: Long) @Query("SELECT * FROM cars WHERE token = :token LIMIT 1") suspend fun carByToken(token: String): Car? @Insert suspend fun insertCar(car: Car): Long @Update suspend fun updateCar(car: Car) }