migration.dart 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // ignore_for_file: deprecated_member_use_from_same_package
  2. import 'dart:async';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:hive/hive.dart';
  5. import 'package:immich_mobile/constants/hive_box.dart';
  6. import 'package:immich_mobile/modules/album/services/album_cache.service.dart';
  7. import 'package:immich_mobile/modules/backup/models/backup_album.model.dart';
  8. import 'package:immich_mobile/modules/backup/models/duplicated_asset.model.dart';
  9. import 'package:immich_mobile/modules/backup/models/hive_backup_albums.model.dart';
  10. import 'package:immich_mobile/modules/backup/models/hive_duplicated_assets.model.dart';
  11. import 'package:immich_mobile/modules/login/models/hive_saved_login_info.model.dart';
  12. import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
  13. import 'package:immich_mobile/shared/models/immich_logger_message.model.dart';
  14. import 'package:immich_mobile/shared/models/store.dart';
  15. import 'package:immich_mobile/shared/services/asset_cache.service.dart';
  16. import 'package:immich_mobile/utils/db.dart';
  17. import 'package:isar/isar.dart';
  18. Future<void> migrateHiveToStoreIfNecessary() async {
  19. await _migrateHiveBoxIfNecessary(userInfoBox, _migrateHiveUserInfoBox);
  20. await _migrateHiveBoxIfNecessary(
  21. backgroundBackupInfoBox,
  22. _migrateHiveBackgroundBackupInfoBox,
  23. );
  24. await _migrateHiveBoxIfNecessary(hiveBackupInfoBox, _migrateBackupInfoBox);
  25. await _migrateHiveBoxIfNecessary(
  26. duplicatedAssetsBox,
  27. _migrateDuplicatedAssetsBox,
  28. );
  29. await _migrateHiveBoxIfNecessary(
  30. hiveGithubReleaseInfoBox,
  31. _migrateReleaseInfoBox,
  32. );
  33. await _migrateHiveBoxIfNecessary(hiveLoginInfoBox, _migrateLoginInfoBox);
  34. await _migrateHiveBoxIfNecessary(
  35. immichLoggerBox,
  36. (Box<ImmichLoggerMessage> box) => box.deleteFromDisk(),
  37. );
  38. await _migrateHiveBoxIfNecessary(userSettingInfoBox, _migrateAppSettingsBox);
  39. }
  40. FutureOr<void> _migrateReleaseInfoBox(Box box) =>
  41. _migrateKey(box, githubReleaseInfoKey, StoreKey.githubReleaseInfo);
  42. Future<void> _migrateLoginInfoBox(Box<HiveSavedLoginInfo> box) async {
  43. final HiveSavedLoginInfo? info = box.get(savedLoginInfoKey);
  44. if (info != null) {
  45. await Store.put(StoreKey.serverUrl, info.serverUrl);
  46. await Store.put(StoreKey.accessToken, info.accessToken);
  47. }
  48. }
  49. Future<void> _migrateHiveUserInfoBox(Box box) async {
  50. await _migrateKey(box, assetEtagKey, StoreKey.assetETag);
  51. if (Store.tryGet(StoreKey.deviceId) == null) {
  52. await _migrateKey(box, deviceIdKey, StoreKey.deviceId);
  53. }
  54. await _migrateKey(box, serverEndpointKey, StoreKey.serverEndpoint);
  55. }
  56. Future<void> _migrateHiveBackgroundBackupInfoBox(Box box) async {
  57. await _migrateKey(box, backupFailedSince, StoreKey.backupFailedSince);
  58. await _migrateKey(box, backupRequireWifi, StoreKey.backupRequireWifi);
  59. await _migrateKey(box, backupRequireCharging, StoreKey.backupRequireCharging);
  60. await _migrateKey(box, backupTriggerDelay, StoreKey.backupTriggerDelay);
  61. }
  62. FutureOr<void> _migrateBackupInfoBox(Box<HiveBackupAlbums> box) {
  63. final HiveBackupAlbums? infos = box.get(backupInfoKey);
  64. if (infos != null) {
  65. final Isar? db = Isar.getInstance();
  66. if (db == null) {
  67. throw Exception("_migrateBackupInfoBox could not load database");
  68. }
  69. List<BackupAlbum> albums = [];
  70. for (int i = 0; i < infos.selectedAlbumIds.length; i++) {
  71. final album = BackupAlbum(
  72. infos.selectedAlbumIds[i],
  73. infos.lastSelectedBackupTime[i],
  74. BackupSelection.select,
  75. );
  76. albums.add(album);
  77. }
  78. for (int i = 0; i < infos.excludedAlbumsIds.length; i++) {
  79. final album = BackupAlbum(
  80. infos.excludedAlbumsIds[i],
  81. infos.lastExcludedBackupTime[i],
  82. BackupSelection.exclude,
  83. );
  84. albums.add(album);
  85. }
  86. return db.writeTxn(() => db.backupAlbums.putAll(albums));
  87. }
  88. }
  89. FutureOr<void> _migrateDuplicatedAssetsBox(Box<HiveDuplicatedAssets> box) {
  90. final HiveDuplicatedAssets? duplicatedAssets = box.get(duplicatedAssetsKey);
  91. if (duplicatedAssets != null) {
  92. final Isar? db = Isar.getInstance();
  93. if (db == null) {
  94. throw Exception("_migrateBackupInfoBox could not load database");
  95. }
  96. final duplicatedAssetIds = duplicatedAssets.duplicatedAssetIds
  97. .map((id) => DuplicatedAsset(id))
  98. .toList();
  99. return db.writeTxn(() => db.duplicatedAssets.putAll(duplicatedAssetIds));
  100. }
  101. }
  102. Future<void> _migrateAppSettingsBox(Box box) async {
  103. for (AppSettingsEnum s in AppSettingsEnum.values) {
  104. if (s.hiveKey != null) {
  105. await _migrateKey(box, s.hiveKey!, s.storeKey);
  106. }
  107. }
  108. }
  109. Future<void> _migrateHiveBoxIfNecessary<T>(
  110. String boxName,
  111. FutureOr<void> Function(Box<T>) migrate,
  112. ) async {
  113. try {
  114. if (await Hive.boxExists(boxName)) {
  115. final box = await Hive.openBox<T>(boxName);
  116. await migrate(box);
  117. await box.deleteFromDisk();
  118. }
  119. } catch (e) {
  120. debugPrint("Error while migrating $boxName $e");
  121. }
  122. }
  123. FutureOr<void> _migrateKey<T>(Box box, String hiveKey, StoreKey<T> key) {
  124. final T? value = box.get(hiveKey);
  125. if (value != null) {
  126. return Store.put(key, value);
  127. }
  128. }
  129. Future<void> migrateJsonCacheIfNecessary() async {
  130. await AlbumCacheService().invalidate();
  131. await SharedAlbumCacheService().invalidate();
  132. await AssetCacheService().invalidate();
  133. }
  134. Future<void> migrateDatabaseIfNeeded(Isar db) async {
  135. final int version = Store.get(StoreKey.version, 1);
  136. switch (version) {
  137. case 1:
  138. await _migrateV1ToV2(db);
  139. }
  140. }
  141. Future<void> _migrateV1ToV2(Isar db) async {
  142. await clearAssetsAndAlbums(db);
  143. await Store.put(StoreKey.version, 2);
  144. }