Migrate rides to stable cloud identity

This commit is contained in:
bponders12-cell 2026-09-01 20:58:54 -04:00
parent a77f92eed0
commit f68c4b083d
1 changed files with 67 additions and 93 deletions

View File

@ -4,124 +4,98 @@ import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:uuid/uuid.dart';
import 'tables.dart'; import 'tables.dart';
part 'database.g.dart'; part 'database.g.dart';
@DriftDatabase(tables: [ @DriftDatabase(tables: [Rides, PerformanceRuns, TelemetrySamples, RideEvents, GarageMotorcycles, FieldTestSessions, FieldTestEvents, FieldTestSummaries, FieldTestGpsRecords, FieldTestImuRecords])
Rides,
PerformanceRuns,
TelemetrySamples,
RideEvents,
GarageMotorcycles,
FieldTestSessions,
FieldTestEvents,
FieldTestSummaries,
FieldTestGpsRecords,
FieldTestImuRecords,
])
class AppDatabase extends _$AppDatabase { class AppDatabase extends _$AppDatabase {
AppDatabase() : super(_openConnection()); AppDatabase() : super(_openConnection());
AppDatabase.forTesting(super.e); AppDatabase.forTesting(super.e);
@override static const _uuid = Uuid();
int get schemaVersion => 5;
@override @override
MigrationStrategy get migration { int get schemaVersion => 6;
return MigrationStrategy(
onCreate: (Migrator m) async { @override
await m.createAll(); MigrationStrategy get migration => MigrationStrategy(
}, onCreate: (Migrator m) async => m.createAll(),
onUpgrade: (Migrator m, int from, int to) async { onUpgrade: (Migrator m, int from, int to) async {
if (from < 2) { if (from < 2) {
// Add new columns to Rides await m.addColumn(rides, rides.distance);
await m.addColumn(rides, rides.distance); await m.addColumn(rides, rides.movingTime);
await m.addColumn(rides, rides.movingTime); await m.addColumn(rides, rides.stoppedTime);
await m.addColumn(rides, rides.stoppedTime); await m.addColumn(rides, rides.averageSpeed);
await m.addColumn(rides, rides.averageSpeed); await m.addColumn(rides, rides.topSpeed);
await m.addColumn(rides, rides.topSpeed); await m.addColumn(rides, rides.elevationGain);
await m.addColumn(rides, rides.elevationGain); await m.addColumn(rides, rides.elevationLoss);
await m.addColumn(rides, rides.elevationLoss); await m.createTable(telemetrySamples);
await m.createTable(rideEvents);
// Create new tables }
await m.createTable(telemetrySamples); if (from < 3) {
await m.createTable(rideEvents); await m.createTable(garageMotorcycles);
} await m.addColumn(rides, rides.motorcycleId);
if (from < 3) { await m.addColumn(rides, rides.motorcycleYear);
await m.createTable(garageMotorcycles); await m.addColumn(rides, rides.motorcycleMake);
await m.addColumn(rides, rides.motorcycleId); await m.addColumn(rides, rides.motorcycleModel);
await m.addColumn(rides, rides.motorcycleYear); await m.addColumn(rides, rides.motorcycleVariant);
await m.addColumn(rides, rides.motorcycleMake); }
await m.addColumn(rides, rides.motorcycleModel); if (from < 4) {
await m.addColumn(rides, rides.motorcycleVariant); await m.createTable(fieldTestSessions);
} await m.createTable(fieldTestEvents);
if (from < 4) { await m.createTable(fieldTestGpsRecords);
await m.createTable(fieldTestSessions); await m.createTable(fieldTestImuRecords);
await m.createTable(fieldTestEvents); }
await m.createTable(fieldTestGpsRecords); if (from < 5) {
await m.createTable(fieldTestImuRecords); await m.createTable(fieldTestSummaries);
} try {
if (from < 5) { await m.addColumn(fieldTestEvents, fieldTestEvents.rideId);
await m.createTable(fieldTestSummaries); await m.addColumn(fieldTestEvents, fieldTestEvents.telemetryTimestamp);
try { await m.addColumn(fieldTestEvents, fieldTestEvents.gpsAgeMs);
await m.addColumn(fieldTestEvents, fieldTestEvents.rideId); await m.addColumn(fieldTestEvents, fieldTestEvents.speed);
await m.addColumn(fieldTestEvents, fieldTestEvents.telemetryTimestamp); await m.addColumn(fieldTestEvents, fieldTestEvents.latitude);
await m.addColumn(fieldTestEvents, fieldTestEvents.gpsAgeMs); await m.addColumn(fieldTestEvents, fieldTestEvents.longitude);
await m.addColumn(fieldTestEvents, fieldTestEvents.speed); await m.addColumn(fieldTestEvents, fieldTestEvents.gpsAccuracy);
await m.addColumn(fieldTestEvents, fieldTestEvents.latitude); await m.addColumn(fieldTestEvents, fieldTestEvents.leanAngle);
await m.addColumn(fieldTestEvents, fieldTestEvents.longitude); await m.addColumn(fieldTestEvents, fieldTestEvents.longitudinalG);
await m.addColumn(fieldTestEvents, fieldTestEvents.gpsAccuracy); await m.addColumn(fieldTestEvents, fieldTestEvents.lateralG);
await m.addColumn(fieldTestEvents, fieldTestEvents.leanAngle); await m.addColumn(fieldTestEvents, fieldTestEvents.overallConfidence);
await m.addColumn(fieldTestEvents, fieldTestEvents.longitudinalG); await m.addColumn(fieldTestEvents, fieldTestEvents.metadata);
await m.addColumn(fieldTestEvents, fieldTestEvents.lateralG); } catch (_) {}
await m.addColumn(fieldTestEvents, fieldTestEvents.overallConfidence); }
await m.addColumn(fieldTestEvents, fieldTestEvents.metadata); if (from < 6) {
} catch (_) {} await m.addColumn(rides, rides.cloudRideId);
} final existingRides = await select(rides).get();
}, for (final ride in existingRides) {
); final cloudId = 'ride_${_uuid.v4()}';
} await (update(rides)..where((r) => r.id.equals(ride.id))).write(
RidesCompanion(cloudRideId: Value(cloudId)),
);
}
}
},
);
// Insert a new ride and return its ID
Future<int> startRide() async { Future<int> startRide() async {
return into(rides).insert(RidesCompanion.insert( return into(rides).insert(RidesCompanion.insert(
cloudRideId: Value('ride_${_uuid.v4()}'),
startTime: DateTime.now(), startTime: DateTime.now(),
)); ));
} }
// Complete a ride
Future<void> endRide(int rideId, RidesCompanion data) async { Future<void> endRide(int rideId, RidesCompanion data) async {
await (update(rides)..where((t) => t.id.equals(rideId))).write(data.copyWith( await (update(rides)..where((t) => t.id.equals(rideId))).write(data.copyWith(endTime: Value(DateTime.now())));
endTime: Value(DateTime.now()),
));
}
// Get all rides
Future<List<Ride>> getAllRides() => select(rides).get();
// Add a performance run
Future<int> addPerformanceRun(PerformanceRunsCompanion run) {
return into(performanceRuns).insert(run);
}
// Get best 0-60 time
Future<double?> getBest0to60() async {
final query = select(performanceRuns)
..where((t) => t.type.equals('0-60'))
..orderBy([(t) => OrderingTerm(expression: t.timeMs, mode: OrderingMode.asc)])
..limit(1);
final result = await query.getSingleOrNull();
return result?.timeMs;
} }
} }
LazyDatabase _openConnection() { LazyDatabase _openConnection() {
return LazyDatabase(() async { return LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory(); final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite')); final file = File(p.join(dbFolder.path, 'motorsignal.sqlite'));
return NativeDatabase(file); return NativeDatabase.createInBackground(file);
}); });
} }