feat(mobile): asset face v3 (#31615)
* feat(mobile): asset face v3 * fix: manually (cascade) delete asset faces
This commit is contained in:
+3601
File diff suppressed because it is too large
Load Diff
@@ -159,7 +159,7 @@ class Drift extends $Drift {
|
||||
}
|
||||
|
||||
@override
|
||||
int get schemaVersion => 32;
|
||||
int get schemaVersion => 33;
|
||||
|
||||
@override
|
||||
MigrationStrategy get migration => MigrationStrategy(
|
||||
@@ -360,6 +360,10 @@ class Drift extends $Drift {
|
||||
from31To32: (m, v32) async {
|
||||
await m.addColumn(v32.localAssetEntity, v32.localAssetEntity.previousChecksum);
|
||||
},
|
||||
from32To33: (m, v33) async {
|
||||
// Removed foreign key constraints on asset_face.assetId and asset_face.personId
|
||||
await m.alterTable(TableMigration(v33.assetFaceEntity));
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:immich_mobile/data/db/main/table/people/person.dart';
|
||||
import 'package:immich_mobile/data/db/main/table/remote/asset.dart';
|
||||
import 'package:immich_mobile/data/db/util/defaults_mixin.dart';
|
||||
|
||||
@TableIndex.sql('CREATE INDEX IF NOT EXISTS idx_asset_face_person_id ON asset_face_entity (person_id)')
|
||||
@@ -15,9 +13,9 @@ class AssetFaceEntity extends Table with DriftDefaultsMixin {
|
||||
|
||||
TextColumn get id => text()();
|
||||
|
||||
TextColumn get assetId => text().references(RemoteAssetEntity, #id, onDelete: KeyAction.cascade)();
|
||||
TextColumn get assetId => text()();
|
||||
|
||||
TextColumn get personId => text().nullable().references(PersonEntity, #id, onDelete: KeyAction.setNull)();
|
||||
TextColumn get personId => text().nullable()();
|
||||
|
||||
IntColumn get imageWidth => integer()();
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ enum ServerCapability {
|
||||
syncV2(SemVer(major: 3, minor: 0, patch: 0)),
|
||||
syncAssetEditsV1(SemVer(major: 2, minor: 6, patch: 0)),
|
||||
syncAssetFacesV2(SemVer(major: 2, minor: 6, patch: 0)),
|
||||
syncAssetFacesV3(SemVer(major: 3, minor: 3, patch: 0)),
|
||||
syncAssetOcrV1(SemVer(major: 3, minor: 0, patch: 0)),
|
||||
syncAuthUsersV2(SemVer(major: 3, minor: 3, patch: 0)),
|
||||
|
||||
|
||||
@@ -324,9 +324,8 @@ class SyncStreamService {
|
||||
case SyncEntityType.assetFaceV1:
|
||||
return _syncStreamRepository.updateAssetFacesV1(data.cast());
|
||||
case SyncEntityType.assetFaceV2:
|
||||
return _syncStreamRepository.updateAssetFacesV2(data.cast());
|
||||
case SyncEntityType.assetFaceV3:
|
||||
throw UnimplementedError('SyncEntityType.assetFaceV3 is not implemented yet');
|
||||
return _syncStreamRepository.updateAssetFacesV3(data.cast());
|
||||
case SyncEntityType.assetFaceDeleteV1:
|
||||
return _syncStreamRepository.deleteAssetFacesV1(data.cast());
|
||||
case SyncEntityType.assetOcrV1:
|
||||
|
||||
@@ -63,7 +63,11 @@ class SyncApiRepository {
|
||||
SyncRequestType.partnerStacksV1,
|
||||
SyncRequestType.userMetadataV1,
|
||||
SyncRequestType.peopleV1,
|
||||
serverVersion.supports(.syncAssetFacesV2) ? SyncRequestType.assetFacesV2 : SyncRequestType.assetFacesV1,
|
||||
serverVersion.supports(.syncAssetFacesV3)
|
||||
? SyncRequestType.assetFacesV3
|
||||
: serverVersion.supports(.syncAssetFacesV2)
|
||||
? SyncRequestType.assetFacesV2
|
||||
: SyncRequestType.assetFacesV1,
|
||||
if (serverVersion.supports(.syncAssetOcrV1)) SyncRequestType.assetOcrV1,
|
||||
],
|
||||
).toJson(),
|
||||
@@ -195,6 +199,7 @@ const _kResponseMap = <SyncEntityType, Function(Object)>{
|
||||
SyncEntityType.personDeleteV1: SyncPersonDeleteV1.fromJson,
|
||||
SyncEntityType.assetFaceV1: SyncAssetFaceV1.fromJson,
|
||||
SyncEntityType.assetFaceV2: SyncAssetFaceV3.fromJson,
|
||||
SyncEntityType.assetFaceV3: SyncAssetFaceV3.fromJson,
|
||||
SyncEntityType.assetFaceDeleteV1: SyncAssetFaceDeleteV1.fromJson,
|
||||
SyncEntityType.assetOcrV1: SyncAssetOcrV1.fromJson,
|
||||
SyncEntityType.assetOcrDeleteV1: SyncAssetOcrDeleteV1.fromJson,
|
||||
|
||||
@@ -218,6 +218,8 @@ class SyncStreamRepository extends DatabaseAccessor<Drift> with $SyncStreamRepos
|
||||
try {
|
||||
await _db.batch((batch) {
|
||||
for (final asset in data) {
|
||||
// cannot use FK here, so manually cascade
|
||||
batch.deleteWhere(_db.assetFaceEntity, (row) => row.assetId.equals(asset.assetId));
|
||||
batch.deleteWhere(_db.remoteAssetEntity, (row) => row.id.equals(asset.assetId));
|
||||
}
|
||||
});
|
||||
@@ -840,7 +842,7 @@ class SyncStreamRepository extends DatabaseAccessor<Drift> with $SyncStreamRepos
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateAssetFacesV2(Iterable<SyncAssetFaceV3> data) async {
|
||||
Future<void> updateAssetFacesV3(Iterable<SyncAssetFaceV3> data) async {
|
||||
try {
|
||||
await _db.batch((batch) {
|
||||
for (final assetFace in data) {
|
||||
@@ -866,7 +868,7 @@ class SyncStreamRepository extends DatabaseAccessor<Drift> with $SyncStreamRepos
|
||||
}
|
||||
});
|
||||
} catch (error, stack) {
|
||||
_logger.severe('Error: updateAssetFacesV2', error, stack);
|
||||
_logger.severe('Error: updateAssetFacesV3', error, stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user