Two copies for two jobs. rippr-src/ is a browsable git archive export of the tracked tree at 2f76983 - no build outputs, no local.properties, no nested .git - which is convenient to read in gitea but carries no history and will drift. rippr-full-history.bundle is the real backup: all 18 commits, verified as "records a complete history" and test-cloned before committing. This matters because ~/dojo/rippr has no git remote and otherwise exists only on one machine. rippr-src/SNAPSHOT.md explains the difference and how to restore. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
61 lines
2.2 KiB
Kotlin
61 lines
2.2 KiB
Kotlin
package com.rippr.data
|
|
|
|
import android.content.Context
|
|
import androidx.room.Database
|
|
import androidx.room.Room
|
|
import androidx.room.RoomDatabase
|
|
import androidx.room.TypeConverter
|
|
import androidx.room.TypeConverters
|
|
|
|
class Converters {
|
|
@TypeConverter
|
|
fun toTripState(value: String): TripState = TripState.valueOf(value)
|
|
|
|
@TypeConverter
|
|
fun fromTripState(state: TripState): String = state.name
|
|
}
|
|
|
|
@Database(
|
|
entities = [Trip::class, Segment::class, TrackPoint::class],
|
|
version = 2,
|
|
exportSchema = true,
|
|
)
|
|
@TypeConverters(Converters::class)
|
|
abstract class AppDatabase : RoomDatabase() {
|
|
|
|
abstract fun tripDao(): TripDao
|
|
abstract fun segmentDao(): SegmentDao
|
|
abstract fun trackPointDao(): TrackPointDao
|
|
|
|
companion object {
|
|
@Volatile
|
|
private var INSTANCE: AppDatabase? = null
|
|
|
|
fun getDatabase(context: Context): AppDatabase =
|
|
INSTANCE ?: synchronized(this) {
|
|
INSTANCE ?: Room.databaseBuilder(
|
|
context.applicationContext,
|
|
AppDatabase::class.java,
|
|
"rippr_db"
|
|
)
|
|
// A ride is unrecoverable if a write is lost to a crash mid-flush,
|
|
// but full sync on every insert at 2 Hz burns battery. WAL with
|
|
// NORMAL sync is the standard compromise and survives app crashes;
|
|
// only an OS-level crash can lose the last few points.
|
|
.setJournalMode(JournalMode.WRITE_AHEAD_LOGGING)
|
|
// No destructive fallback. Rides recorded from v2 onward are real
|
|
// data, so any future schema change MUST ship a Migration against the
|
|
// committed schemas/com.rippr.data.AppDatabase/2.json baseline.
|
|
// Reinstating fallbackToDestructiveMigration() here would silently
|
|
// delete every stored ride on the next version bump.
|
|
.build()
|
|
.also { INSTANCE = it }
|
|
}
|
|
|
|
/** Test seam — lets instrumented tests substitute an in-memory database. */
|
|
fun overrideForTest(db: AppDatabase?) {
|
|
INSTANCE = db
|
|
}
|
|
}
|
|
}
|