From f5a47bc83cc3f292213670904b0e00d943eb8586 Mon Sep 17 00:00:00 2001 From: bponders12-cell Date: Tue, 1 Sep 2026 21:03:35 -0400 Subject: [PATCH] Preserve legacy cloud IDs during ride identity migration --- lib/database/database.dart | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/lib/database/database.dart b/lib/database/database.dart index 39002b9..3c8d75c 100644 --- a/lib/database/database.dart +++ b/lib/database/database.dart @@ -23,12 +23,9 @@ class AppDatabase extends _$AppDatabase { @override MigrationStrategy get migration => MigrationStrategy( onCreate: (Migrator m) async { + // cloudRideId is part of the generated Drift schema. Do not manually + // ALTER this column here: generated sources are authoritative for fresh DBs. 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) { @@ -75,15 +72,32 @@ class AppDatabase extends _$AppDatabase { } if (from < 6) { await m.addColumn(rides, rides.cloudRideId); - 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(); + await customStatement('CREATE UNIQUE INDEX IF NOT EXISTS rides_cloud_ride_id_idx ON rides(cloud_ride_id)'); + + // Existing MotorCloud records were keyed by the deterministic legacy + // identity ride__. Preserve that identity + // for pre-v6 rides so their cloud records remain addressable. New rides + // receive a reinstall-safe random stable ID in startRide(). + final rows = await customSelect('SELECT id, start_time 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']]); + final id = row.data['id']; + final rawStart = row.data['start_time']; + if (id is! int || rawStart == null) continue; + final startTime = DateTime.tryParse(rawStart.toString())?.toUtc(); + if (startTime == null) continue; + final legacyId = _legacyCloudRideId(id, startTime); + await customStatement('UPDATE rides SET cloud_ride_id = ? WHERE id = ?', [legacyId, id]); } } }, ); + String _legacyCloudRideId(int localRideId, DateTime startTimeUtc) { + String two(int value) => value.toString().padLeft(2, '0'); + final stamp = '${startTimeUtc.year.toString().padLeft(4, '0')}${two(startTimeUtc.month)}${two(startTimeUtc.day)}_${two(startTimeUtc.hour)}${two(startTimeUtc.minute)}${two(startTimeUtc.second)}'; + return 'ride_${localRideId}_$stamp'; + } + String _newCloudRideId() { final bytes = List.generate(16, (_) => _random.nextInt(256)); final hex = bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();