diff --git a/lib/database/app_database.dart b/lib/database/app_database.dart index b1ae3779..274b9043 100644 --- a/lib/database/app_database.dart +++ b/lib/database/app_database.dart @@ -129,14 +129,20 @@ class AppDatabase extends _$AppDatabase { ); await m.createTable(connections); - await m.create(idxConnectionsKind); + await _ignoreAlreadyExists('Index idx_connections_kind', () => m.create(idxConnectionsKind)); await m.createTable(profiles); - await m.create(idxProfilesKind); + await _ignoreAlreadyExists('Index idx_profiles_kind', () => m.create(idxProfilesKind)); await m.createTable(profileConnections); - await m.create(idxProfileConnectionsConnectionId); - await m.create(idxProfileConnectionsProfileId); + await _ignoreAlreadyExists( + 'Index idx_profile_connections_connection_id', + () => m.create(idxProfileConnectionsConnectionId), + ); + await _ignoreAlreadyExists( + 'Index idx_profile_connections_profile_id', + () => m.create(idxProfileConnectionsProfileId), + ); await _ignoreAlreadyExists('DownloadOwners table', () => m.createTable(downloadOwners)); await _ignoreAlreadyExists('Index idx_download_owners_profile', () => m.create(idxDownloadOwnersProfile)); @@ -190,7 +196,10 @@ class AppDatabase extends _$AppDatabase { ) '''); - await m.create(idxOfflineWatchProgressServer); + await _ignoreAlreadyExists( + 'Index idx_offline_watch_progress_server', + () => m.create(idxOfflineWatchProgressServer), + ); await _ignoreAlreadyExists('Index idx_sync_rules_profile', () => m.create(idxSyncRulesProfile)); await _ignoreAlreadyExists( 'Index idx_offline_watch_progress_profile', diff --git a/test/database/app_database_test.dart b/test/database/app_database_test.dart index d7601c27..716007bb 100644 --- a/test/database/app_database_test.dart +++ b/test/database/app_database_test.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:drift/drift.dart' hide isNull, isNotNull; import 'package:drift/native.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -106,6 +108,34 @@ class _AppDatabaseTestSuite { containsAll(['idx_profiles_kind', 'idx_profile_connections_profile_id', 'idx_offline_watch_progress_server']), ); }); + + test('retried v14 migration tolerates existing indices', () async { + await db.close(); + final tempDir = await Directory.systemTemp.createTemp('plezy_db_migration_test_'); + final file = File('${tempDir.path}/plezy_downloads.db'); + AppDatabase? seeded; + AppDatabase? reopened; + + try { + seeded = AppDatabase.forTesting(NativeDatabase(file)); + await seeded.select(seeded.connections).get(); + await seeded.customStatement('PRAGMA user_version = 13'); + await seeded.close(); + seeded = null; + + reopened = AppDatabase.forTesting(NativeDatabase(file)); + expect(await reopened.select(reopened.connections).get(), isEmpty); + final rows = await reopened + .customSelect("SELECT name FROM sqlite_master WHERE type = 'index' AND name = 'idx_connections_kind'") + .get(); + expect(rows, hasLength(1)); + } finally { + await reopened?.close(); + await seeded?.close(); + await tempDir.delete(recursive: true); + db = AppDatabase.forTesting(NativeDatabase.memory()); + } + }); }); }