Complete stable ride identity migration and fresh database initialization

This commit is contained in:
bponders12-cell 2026-09-01 20:59:58 -04:00
parent 657ee85a4c
commit 55d0905f91
1 changed files with 14 additions and 23 deletions

View File

@ -22,7 +22,14 @@ class AppDatabase extends _$AppDatabase {
@override
MigrationStrategy get migration => MigrationStrategy(
onCreate: (Migrator m) async => m.createAll(),
onCreate: (Migrator m) async {
await m.createAll();
// database.g.dart is generated during normal development/CI. Keep the
// schema self-healing for installations that temporarily have a stale
// generated file: cloud identity must exist even on a brand-new DB.
await customStatement('ALTER TABLE rides ADD COLUMN cloud_ride_id TEXT');
await customStatement('CREATE UNIQUE INDEX rides_cloud_ride_id_idx ON rides(cloud_ride_id)');
},
onUpgrade: (Migrator m, int from, int to) async {
if (from < 2) {
await m.addColumn(rides, rides.distance);
@ -67,16 +74,11 @@ class AppDatabase extends _$AppDatabase {
} catch (_) {}
}
if (from < 6) {
// Nullable during migration so existing installations can be upgraded
// without losing rides. We immediately backfill every existing ride
// with a stable random identifier that is independent of local ID.
await m.addColumn(rides, rides.cloudRideId);
final rows = await customSelect('SELECT id FROM rides').get();
await customStatement('CREATE UNIQUE INDEX rides_cloud_ride_id_idx ON rides(cloud_ride_id)');
final rows = await customSelect('SELECT id FROM rides WHERE cloud_ride_id IS NULL').get();
for (final row in rows) {
await customStatement(
'UPDATE rides SET cloud_ride_id = ? WHERE id = ?',
[_newCloudRideId(), row.data['id']],
);
await customStatement('UPDATE rides SET cloud_ride_id = ? WHERE id = ?', [_newCloudRideId(), row.data['id']]);
}
}
},
@ -88,14 +90,8 @@ class AppDatabase extends _$AppDatabase {
return 'ride_$hex';
}
/// Returns the persisted stable MotorCloud identity for a local ride.
/// Uses raw SQL until `database.g.dart` is regenerated; this keeps the
/// migration deployable without hand-editing generated Drift output.
Future<String?> getCloudRideId(int rideId) async {
final rows = await customSelect(
'SELECT cloud_ride_id FROM rides WHERE id = ?',
variables: [Variable<int>(rideId)],
).get();
final rows = await customSelect('SELECT cloud_ride_id FROM rides WHERE id = ?', variables: [Variable<int>(rideId)]).get();
if (rows.isEmpty) return null;
return rows.first.data['cloud_ride_id'] as String?;
}
@ -104,17 +100,12 @@ class AppDatabase extends _$AppDatabase {
final existing = await getCloudRideId(rideId);
if (existing != null && existing.isNotEmpty) return existing;
final created = _newCloudRideId();
await customStatement(
'UPDATE rides SET cloud_ride_id = ? WHERE id = ?',
[created, rideId],
);
await customStatement('UPDATE rides SET cloud_ride_id = ? WHERE id = ?', [created, rideId]);
return created;
}
Future<int> startRide() async {
final id = await into(rides).insert(RidesCompanion.insert(
startTime: DateTime.now(),
));
final id = await into(rides).insert(RidesCompanion.insert(startTime: DateTime.now()));
await ensureCloudRideId(id);
return id;
}