From 781d846806f1a403bba02681ac0ed96c902ece32 Mon Sep 17 00:00:00 2001 From: Ming Ming Date: Sat, 15 Jan 2022 18:40:34 +0800 Subject: [PATCH] Drop db if failed migrating --- lib/app_db.dart | 8 +++++ lib/use_case/db_compat/v5.dart | 63 +++++++++++++++++++--------------- test/mock_type.dart | 5 +++ 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/lib/app_db.dart b/lib/app_db.dart index c7667877..aacc4362 100644 --- a/lib/app_db.dart +++ b/lib/app_db.dart @@ -45,6 +45,14 @@ class AppDb { }); } + Future delete() async { + _log.warning("[delete] Deleting database"); + return await _lock.synchronized(() async { + final dbFactory = platform.getDbFactory(); + await dbFactory.deleteDatabase(dbName); + }); + } + /// Open the database Future _open() { if (platform_k.isWeb) { diff --git a/lib/use_case/db_compat/v5.dart b/lib/use_case/db_compat/v5.dart index 3e9489d9..7c9d1d22 100644 --- a/lib/use_case/db_compat/v5.dart +++ b/lib/use_case/db_compat/v5.dart @@ -27,36 +27,43 @@ class DbCompatV5 { static Future migrate(AppDb appDb) async { _log.info("[migrate] Migrate AppDb"); - await appDb.use((db) async { - final transaction = db.transaction( - [AppDb.file2StoreName, AppDb.metaStoreName], idbModeReadWrite); - try { - final fileStore = transaction.objectStore(AppDb.file2StoreName); - await for (final c in fileStore.openCursor()) { - final item = c.value as Map; - // migrate file entry: add bestDateTime - final fileEntry = item.cast().run((json) { - final f = File.fromJson(json["file"].cast()); - return AppDbFile2Entry( - json["server"], - (json["userId"] as String).toCi(), - json["strippedPath"], - f.bestDateTime.millisecondsSinceEpoch, - File.fromJson(json["file"].cast()), - ); - }); - await c.update(fileEntry.toJson()); + try { + await appDb.use((db) async { + final transaction = db.transaction( + [AppDb.file2StoreName, AppDb.metaStoreName], idbModeReadWrite); + try { + final fileStore = transaction.objectStore(AppDb.file2StoreName); + await for (final c in fileStore.openCursor()) { + final item = c.value as Map; + // migrate file entry: add bestDateTime + final fileEntry = item.cast().run((json) { + final f = File.fromJson(json["file"].cast()); + return AppDbFile2Entry( + json["server"], + (json["userId"] as String).toCi(), + json["strippedPath"], + f.bestDateTime.millisecondsSinceEpoch, + File.fromJson(json["file"].cast()), + ); + }); + await c.update(fileEntry.toJson()); - c.next(); + c.next(); + } + final metaStore = transaction.objectStore(AppDb.metaStoreName); + await metaStore + .put(const AppDbMetaEntryDbCompatV5(true).toEntry().toJson()); + } catch (_) { + transaction.abort(); + rethrow; } - final metaStore = transaction.objectStore(AppDb.metaStoreName); - await metaStore - .put(const AppDbMetaEntryDbCompatV5(true).toEntry().toJson()); - } catch (_) { - transaction.abort(); - rethrow; - } - }); + }); + } catch (e, stackTrace) { + _log.shout( + "[migrate] Failed while migrating, drop db instead", e, stackTrace); + await appDb.delete(); + rethrow; + } } static final _log = Logger("use_case.db_compat.v5.DbCompatV5"); diff --git a/test/mock_type.dart b/test/mock_type.dart index 807fd398..d8acedd7 100644 --- a/test/mock_type.dart +++ b/test/mock_type.dart @@ -117,6 +117,11 @@ class MockAppDb implements AppDb { } } + @override + Future delete() async { + throw UnimplementedError(); + } + static void _createDb( Database db, { bool hasAlbumStore = true,