mirror of
https://github.com/immich-app/immich.git
synced 2025-07-31 15:08:44 -04:00
feat: migrate backup albums to sqlite (#20049)
* do not migrate again on app start * migrate backup albums over to sqlite --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
parent
dee6d072fb
commit
5fc4393e7a
@ -13,6 +13,18 @@ class BackupAlbum {
|
||||
BackupAlbum(this.id, this.lastBackup, this.selection);
|
||||
|
||||
Id get isarId => fastHash(id);
|
||||
|
||||
BackupAlbum copyWith({
|
||||
String? id,
|
||||
DateTime? lastBackup,
|
||||
BackupSelection? selection,
|
||||
}) {
|
||||
return BackupAlbum(
|
||||
id ?? this.id,
|
||||
lastBackup ?? this.lastBackup,
|
||||
selection ?? this.selection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum BackupSelection {
|
||||
|
@ -56,6 +56,10 @@ class _ChangeExperiencePageState extends ConsumerState<ChangeExperiencePage> {
|
||||
ref.read(isarProvider),
|
||||
ref.read(driftProvider),
|
||||
);
|
||||
await migrateBackupAlbumsToSqlite(
|
||||
ref.read(isarProvider),
|
||||
ref.read(driftProvider),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
await ref.read(backgroundSyncProvider).cancel();
|
||||
|
@ -2,19 +2,23 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||
import 'package:immich_mobile/domain/utils/background_sync.dart';
|
||||
import 'package:immich_mobile/entities/album.entity.dart';
|
||||
import 'package:immich_mobile/entities/android_device_asset.entity.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
import 'package:immich_mobile/entities/backup_album.entity.dart'
|
||||
as isar_backup_album;
|
||||
import 'package:immich_mobile/entities/etag.entity.dart';
|
||||
import 'package:immich_mobile/entities/ios_device_asset.entity.dart';
|
||||
import 'package:immich_mobile/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/device_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_album.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||
@ -27,7 +31,7 @@ import 'package:logging/logging.dart';
|
||||
// ignore: import_rule_photo_manager
|
||||
import 'package:photo_manager/photo_manager.dart';
|
||||
|
||||
const int targetVersion = 14;
|
||||
const int targetVersion = 13;
|
||||
|
||||
Future<void> migrateDatabaseIfNeeded(Isar db) async {
|
||||
final int version = Store.get(StoreKey.version, targetVersion);
|
||||
@ -56,18 +60,6 @@ Future<void> migrateDatabaseIfNeeded(Isar db) async {
|
||||
await Store.put(StoreKey.photoManagerCustomFilter, true);
|
||||
}
|
||||
|
||||
if (version < 14) {
|
||||
if (!Store.isBetaTimelineEnabled) {
|
||||
// Try again when beta timeline is enabled and the app is restarted
|
||||
return;
|
||||
}
|
||||
final backgroundSync = BackgroundSyncManager();
|
||||
await backgroundSync.syncLocal();
|
||||
final drift = Drift();
|
||||
await migrateDeviceAssetToSqlite(db, drift);
|
||||
await drift.close();
|
||||
}
|
||||
|
||||
if (targetVersion >= 12) {
|
||||
await Store.put(StoreKey.version, targetVersion);
|
||||
return;
|
||||
@ -204,6 +196,71 @@ Future<void> migrateDeviceAssetToSqlite(Isar db, Drift drift) async {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> migrateBackupAlbumsToSqlite(
|
||||
Isar db,
|
||||
Drift drift,
|
||||
) async {
|
||||
try {
|
||||
final isarBackupAlbums = await db.backupAlbums.where().findAll();
|
||||
// Recents is a virtual album on Android, and we don't have it with the new sync
|
||||
// If recents is selected previously, select all albums during migration except the excluded ones
|
||||
if (Platform.isAndroid) {
|
||||
final recentAlbum =
|
||||
isarBackupAlbums.firstWhereOrNull((album) => album.id == 'isAll');
|
||||
if (recentAlbum != null) {
|
||||
await drift.localAlbumEntity.update().write(
|
||||
const LocalAlbumEntityCompanion(
|
||||
backupSelection: Value(BackupSelection.selected),
|
||||
),
|
||||
);
|
||||
final excluded = isarBackupAlbums
|
||||
.where(
|
||||
(album) =>
|
||||
album.selection == isar_backup_album.BackupSelection.exclude,
|
||||
)
|
||||
.map((album) => album.id)
|
||||
.toList();
|
||||
await drift.batch((batch) async {
|
||||
for (final id in excluded) {
|
||||
batch.update(
|
||||
drift.localAlbumEntity,
|
||||
const LocalAlbumEntityCompanion(
|
||||
backupSelection: Value(BackupSelection.excluded),
|
||||
),
|
||||
where: (t) => t.id.equals(id),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
await drift.batch((batch) {
|
||||
for (final album in isarBackupAlbums) {
|
||||
batch.update(
|
||||
drift.localAlbumEntity,
|
||||
LocalAlbumEntityCompanion(
|
||||
backupSelection: Value(
|
||||
switch (album.selection) {
|
||||
isar_backup_album.BackupSelection.none => BackupSelection.none,
|
||||
isar_backup_album.BackupSelection.select =>
|
||||
BackupSelection.selected,
|
||||
isar_backup_album.BackupSelection.exclude =>
|
||||
BackupSelection.excluded,
|
||||
},
|
||||
),
|
||||
),
|
||||
where: (t) => t.id.equals(album.id),
|
||||
);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
debugPrint(
|
||||
"[MIGRATION] Error while migrating backup albums to SQLite: $error",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DeviceAsset {
|
||||
final String assetId;
|
||||
final List<int>? hash;
|
||||
|
Loading…
x
Reference in New Issue
Block a user