diff --git a/mobile/lib/domain/utils/migrate_cloud_ids.dart b/mobile/lib/domain/utils/migrate_cloud_ids.dart index 188ee9afbd..5c6f2dfb28 100644 --- a/mobile/lib/domain/utils/migrate_cloud_ids.dart +++ b/mobile/lib/domain/utils/migrate_cloud_ids.dart @@ -61,19 +61,13 @@ Future> _fetchCloudIdMappings(Drift drift, String userId) drift.localAssetEntity.checksum.equalsExp(drift.remoteAssetEntity.checksum), useColumns: false, ), - leftOuterJoin( - drift.remoteAssetMetadataEntity, - drift.remoteAssetMetadataEntity.assetId.equalsExp(drift.remoteAssetEntity.id) & - drift.remoteAssetMetadataEntity.key.equals(RemoteAssetMetadataKey.mobileApp.key), - useColumns: false, - ), ]) ..addColumns([drift.remoteAssetEntity.id, drift.localAssetEntity.cloudId]) ..where( - drift.remoteAssetEntity.ownerId.equals(userId) & - drift.localAssetEntity.id.isNotNull() & + drift.localAssetEntity.id.isNotNull() & drift.localAssetEntity.cloudId.isNotNull() & - drift.remoteAssetMetadataEntity.cloudId.isNull(), + drift.remoteAssetEntity.ownerId.equals(userId) & + drift.remoteAssetEntity.cloudId.isNull(), ); return query .map( diff --git a/mobile/lib/infrastructure/entities/merged_asset.drift b/mobile/lib/infrastructure/entities/merged_asset.drift index d1377f6685..1886648eab 100644 --- a/mobile/lib/infrastructure/entities/merged_asset.drift +++ b/mobile/lib/infrastructure/entities/merged_asset.drift @@ -7,7 +7,8 @@ import 'local_album_asset.entity.dart'; mergedAsset: SELECT rae.id as remote_id, - (SELECT lae.id FROM local_asset_entity lae WHERE lae.checksum = rae.checksum LIMIT 1) as local_id, + (SELECT lae.id FROM local_asset_entity lae + WHERE lae.checksum = rae.checksum OR lae.cloud_id = rae.cloud_id LIMIT 1) as local_id, rae.name, rae."type", rae.created_at as created_at, @@ -57,7 +58,8 @@ SELECT FROM local_asset_entity lae WHERE NOT EXISTS ( - SELECT 1 FROM remote_asset_entity rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN :user_ids + SELECT 1 FROM remote_asset_entity rae WHERE + (rae.checksum = lae.checksum OR rae.cloud_id = lae.cloud_id) AND rae.owner_id IN :user_ids ) AND EXISTS ( SELECT 1 FROM local_album_asset_entity laa @@ -101,7 +103,8 @@ FROM FROM local_asset_entity lae WHERE NOT EXISTS ( - SELECT 1 FROM remote_asset_entity rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN :user_ids + SELECT 1 FROM remote_asset_entity rae + WHERE (rae.checksum = lae.checksum OR rae.cloud_id = lae.cloud_id) AND rae.owner_id IN :user_ids ) AND EXISTS ( SELECT 1 FROM local_album_asset_entity laa diff --git a/mobile/lib/infrastructure/entities/merged_asset.drift.dart b/mobile/lib/infrastructure/entities/merged_asset.drift.dart index 5a091c349c..172642c303 100644 --- a/mobile/lib/infrastructure/entities/merged_asset.drift.dart +++ b/mobile/lib/infrastructure/entities/merged_asset.drift.dart @@ -29,7 +29,7 @@ class MergedAssetDrift extends i1.ModularAccessor { ); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT rae.id AS remote_id, (SELECT lae.id FROM local_asset_entity AS lae WHERE lae.checksum = rae.checksum LIMIT 1) AS local_id, rae.name, rae.type, rae.created_at AS created_at, rae.updated_at, rae.width, rae.height, rae.duration_in_seconds, rae.is_favorite, rae.thumb_hash, rae.checksum, rae.owner_id, rae.live_photo_video_id, 0 AS orientation, rae.stack_id FROM remote_asset_entity AS rae LEFT JOIN stack_entity AS se ON rae.stack_id = se.id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = se.primary_asset_id)UNION ALL SELECT NULL AS remote_id, lae.id AS local_id, lae.name, lae.type, lae.created_at AS created_at, lae.updated_at, lae.width, lae.height, lae.duration_in_seconds, lae.is_favorite, NULL AS thumb_hash, lae.checksum, NULL AS owner_id, NULL AS live_photo_video_id, lae.orientation, NULL AS stack_id FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2) ORDER BY created_at DESC ${generatedlimit.sql}', + 'SELECT rae.id AS remote_id, (SELECT lae.id FROM local_asset_entity AS lae WHERE lae.checksum = rae.checksum OR lae.cloud_id = rae.cloud_id LIMIT 1) AS local_id, rae.name, rae.type, rae.created_at AS created_at, rae.updated_at, rae.width, rae.height, rae.duration_in_seconds, rae.is_favorite, rae.thumb_hash, rae.checksum, rae.owner_id, rae.live_photo_video_id, 0 AS orientation, rae.stack_id FROM remote_asset_entity AS rae LEFT JOIN stack_entity AS se ON rae.stack_id = se.id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = se.primary_asset_id)UNION ALL SELECT NULL AS remote_id, lae.id AS local_id, lae.name, lae.type, lae.created_at AS created_at, lae.updated_at, lae.width, lae.height, lae.duration_in_seconds, lae.is_favorite, NULL AS thumb_hash, lae.checksum, NULL AS owner_id, NULL AS live_photo_video_id, lae.orientation, NULL AS stack_id FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE(rae.checksum = lae.checksum OR rae.cloud_id = lae.cloud_id)AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2) ORDER BY created_at DESC ${generatedlimit.sql}', variables: [ for (var $ in userIds) i0.Variable($), ...generatedlimit.introducedVariables, @@ -74,7 +74,7 @@ class MergedAssetDrift extends i1.ModularAccessor { final expandeduserIds = $expandVar($arrayStartIndex, userIds.length); $arrayStartIndex += userIds.length; return customSelect( - 'SELECT COUNT(*) AS asset_count, CASE WHEN ?1 = 0 THEN STRFTIME(\'%Y-%m-%d\', created_at, \'localtime\') WHEN ?1 = 1 THEN STRFTIME(\'%Y-%m\', created_at, \'localtime\') END AS bucket_date FROM (SELECT rae.created_at FROM remote_asset_entity AS rae LEFT JOIN stack_entity AS se ON rae.stack_id = se.id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = se.primary_asset_id)UNION ALL SELECT lae.created_at FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2)) GROUP BY bucket_date ORDER BY bucket_date DESC', + 'SELECT COUNT(*) AS asset_count, CASE WHEN ?1 = 0 THEN STRFTIME(\'%Y-%m-%d\', created_at, \'localtime\') WHEN ?1 = 1 THEN STRFTIME(\'%Y-%m\', created_at, \'localtime\') END AS bucket_date FROM (SELECT rae.created_at FROM remote_asset_entity AS rae LEFT JOIN stack_entity AS se ON rae.stack_id = se.id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = se.primary_asset_id)UNION ALL SELECT lae.created_at FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE(rae.checksum = lae.checksum OR rae.cloud_id = lae.cloud_id)AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2)) GROUP BY bucket_date ORDER BY bucket_date DESC', variables: [ i0.Variable(groupBy), for (var $ in userIds) i0.Variable($), diff --git a/mobile/lib/infrastructure/entities/remote_asset.entity.dart b/mobile/lib/infrastructure/entities/remote_asset.entity.dart index 4426974413..54c2a6415a 100644 --- a/mobile/lib/infrastructure/entities/remote_asset.entity.dart +++ b/mobile/lib/infrastructure/entities/remote_asset.entity.dart @@ -19,6 +19,7 @@ ON remote_asset_entity (owner_id, library_id, checksum) WHERE (library_id IS NOT NULL); ''') @TableIndex.sql('CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)') +@TableIndex.sql('CREATE INDEX IF NOT EXISTS idx_remote_asset_cloud_id ON remote_asset_entity (cloud_id);') class RemoteAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin { const RemoteAssetEntity(); @@ -44,6 +45,8 @@ class RemoteAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin TextColumn get libraryId => text().nullable()(); + TextColumn get cloudId => text().nullable()(); + @override Set get primaryKey => {id}; } diff --git a/mobile/lib/infrastructure/entities/remote_asset.entity.drift.dart b/mobile/lib/infrastructure/entities/remote_asset.entity.drift.dart index eab7f95f64..3f4b8b9336 100644 --- a/mobile/lib/infrastructure/entities/remote_asset.entity.drift.dart +++ b/mobile/lib/infrastructure/entities/remote_asset.entity.drift.dart @@ -31,6 +31,7 @@ typedef $$RemoteAssetEntityTableCreateCompanionBuilder = required i2.AssetVisibility visibility, i0.Value stackId, i0.Value libraryId, + i0.Value cloudId, }); typedef $$RemoteAssetEntityTableUpdateCompanionBuilder = i1.RemoteAssetEntityCompanion Function({ @@ -52,6 +53,7 @@ typedef $$RemoteAssetEntityTableUpdateCompanionBuilder = i0.Value visibility, i0.Value stackId, i0.Value libraryId, + i0.Value cloudId, }); final class $$RemoteAssetEntityTableReferences @@ -196,6 +198,11 @@ class $$RemoteAssetEntityTableFilterComposer builder: (column) => i0.ColumnFilters(column), ); + i0.ColumnFilters get cloudId => $composableBuilder( + column: $table.cloudId, + builder: (column) => i0.ColumnFilters(column), + ); + i5.$$UserEntityTableFilterComposer get ownerId { final i5.$$UserEntityTableFilterComposer composer = $composerBuilder( composer: this, @@ -318,6 +325,11 @@ class $$RemoteAssetEntityTableOrderingComposer builder: (column) => i0.ColumnOrderings(column), ); + i0.ColumnOrderings get cloudId => $composableBuilder( + column: $table.cloudId, + builder: (column) => i0.ColumnOrderings(column), + ); + i5.$$UserEntityTableOrderingComposer get ownerId { final i5.$$UserEntityTableOrderingComposer composer = $composerBuilder( composer: this, @@ -417,6 +429,9 @@ class $$RemoteAssetEntityTableAnnotationComposer i0.GeneratedColumn get libraryId => $composableBuilder(column: $table.libraryId, builder: (column) => column); + i0.GeneratedColumn get cloudId => + $composableBuilder(column: $table.cloudId, builder: (column) => column); + i5.$$UserEntityTableAnnotationComposer get ownerId { final i5.$$UserEntityTableAnnotationComposer composer = $composerBuilder( composer: this, @@ -497,6 +512,7 @@ class $$RemoteAssetEntityTableTableManager const i0.Value.absent(), i0.Value stackId = const i0.Value.absent(), i0.Value libraryId = const i0.Value.absent(), + i0.Value cloudId = const i0.Value.absent(), }) => i1.RemoteAssetEntityCompanion( name: name, type: type, @@ -516,6 +532,7 @@ class $$RemoteAssetEntityTableTableManager visibility: visibility, stackId: stackId, libraryId: libraryId, + cloudId: cloudId, ), createCompanionCallback: ({ @@ -537,6 +554,7 @@ class $$RemoteAssetEntityTableTableManager required i2.AssetVisibility visibility, i0.Value stackId = const i0.Value.absent(), i0.Value libraryId = const i0.Value.absent(), + i0.Value cloudId = const i0.Value.absent(), }) => i1.RemoteAssetEntityCompanion.insert( name: name, type: type, @@ -556,6 +574,7 @@ class $$RemoteAssetEntityTableTableManager visibility: visibility, stackId: stackId, libraryId: libraryId, + cloudId: cloudId, ), withReferenceMapper: (p0) => p0 .map( @@ -844,6 +863,17 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity type: i0.DriftSqlType.string, requiredDuringInsert: false, ); + static const i0.VerificationMeta _cloudIdMeta = const i0.VerificationMeta( + 'cloudId', + ); + @override + late final i0.GeneratedColumn cloudId = i0.GeneratedColumn( + 'cloud_id', + aliasedName, + true, + type: i0.DriftSqlType.string, + requiredDuringInsert: false, + ); @override List get $columns => [ name, @@ -864,6 +894,7 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity visibility, stackId, libraryId, + cloudId, ]; @override String get aliasedName => _alias ?? actualTableName; @@ -987,6 +1018,12 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity libraryId.isAcceptableOrUnknown(data['library_id']!, _libraryIdMeta), ); } + if (data.containsKey('cloud_id')) { + context.handle( + _cloudIdMeta, + cloudId.isAcceptableOrUnknown(data['cloud_id']!, _cloudIdMeta), + ); + } return context; } @@ -1075,6 +1112,10 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity i0.DriftSqlType.string, data['${effectivePrefix}library_id'], ), + cloudId: attachedDatabase.typeMapping.read( + i0.DriftSqlType.string, + data['${effectivePrefix}cloud_id'], + ), ); } @@ -1115,6 +1156,7 @@ class RemoteAssetEntityData extends i0.DataClass final i2.AssetVisibility visibility; final String? stackId; final String? libraryId; + final String? cloudId; const RemoteAssetEntityData({ required this.name, required this.type, @@ -1134,6 +1176,7 @@ class RemoteAssetEntityData extends i0.DataClass required this.visibility, this.stackId, this.libraryId, + this.cloudId, }); @override Map toColumns(bool nullToAbsent) { @@ -1182,6 +1225,9 @@ class RemoteAssetEntityData extends i0.DataClass if (!nullToAbsent || libraryId != null) { map['library_id'] = i0.Variable(libraryId); } + if (!nullToAbsent || cloudId != null) { + map['cloud_id'] = i0.Variable(cloudId); + } return map; } @@ -1213,6 +1259,7 @@ class RemoteAssetEntityData extends i0.DataClass ), stackId: serializer.fromJson(json['stackId']), libraryId: serializer.fromJson(json['libraryId']), + cloudId: serializer.fromJson(json['cloudId']), ); } @override @@ -1241,6 +1288,7 @@ class RemoteAssetEntityData extends i0.DataClass ), 'stackId': serializer.toJson(stackId), 'libraryId': serializer.toJson(libraryId), + 'cloudId': serializer.toJson(cloudId), }; } @@ -1263,6 +1311,7 @@ class RemoteAssetEntityData extends i0.DataClass i2.AssetVisibility? visibility, i0.Value stackId = const i0.Value.absent(), i0.Value libraryId = const i0.Value.absent(), + i0.Value cloudId = const i0.Value.absent(), }) => i1.RemoteAssetEntityData( name: name ?? this.name, type: type ?? this.type, @@ -1288,6 +1337,7 @@ class RemoteAssetEntityData extends i0.DataClass visibility: visibility ?? this.visibility, stackId: stackId.present ? stackId.value : this.stackId, libraryId: libraryId.present ? libraryId.value : this.libraryId, + cloudId: cloudId.present ? cloudId.value : this.cloudId, ); RemoteAssetEntityData copyWithCompanion(i1.RemoteAssetEntityCompanion data) { return RemoteAssetEntityData( @@ -1319,6 +1369,7 @@ class RemoteAssetEntityData extends i0.DataClass : this.visibility, stackId: data.stackId.present ? data.stackId.value : this.stackId, libraryId: data.libraryId.present ? data.libraryId.value : this.libraryId, + cloudId: data.cloudId.present ? data.cloudId.value : this.cloudId, ); } @@ -1342,7 +1393,8 @@ class RemoteAssetEntityData extends i0.DataClass ..write('livePhotoVideoId: $livePhotoVideoId, ') ..write('visibility: $visibility, ') ..write('stackId: $stackId, ') - ..write('libraryId: $libraryId') + ..write('libraryId: $libraryId, ') + ..write('cloudId: $cloudId') ..write(')')) .toString(); } @@ -1367,6 +1419,7 @@ class RemoteAssetEntityData extends i0.DataClass visibility, stackId, libraryId, + cloudId, ); @override bool operator ==(Object other) => @@ -1389,7 +1442,8 @@ class RemoteAssetEntityData extends i0.DataClass other.livePhotoVideoId == this.livePhotoVideoId && other.visibility == this.visibility && other.stackId == this.stackId && - other.libraryId == this.libraryId); + other.libraryId == this.libraryId && + other.cloudId == this.cloudId); } class RemoteAssetEntityCompanion @@ -1412,6 +1466,7 @@ class RemoteAssetEntityCompanion final i0.Value visibility; final i0.Value stackId; final i0.Value libraryId; + final i0.Value cloudId; const RemoteAssetEntityCompanion({ this.name = const i0.Value.absent(), this.type = const i0.Value.absent(), @@ -1431,6 +1486,7 @@ class RemoteAssetEntityCompanion this.visibility = const i0.Value.absent(), this.stackId = const i0.Value.absent(), this.libraryId = const i0.Value.absent(), + this.cloudId = const i0.Value.absent(), }); RemoteAssetEntityCompanion.insert({ required String name, @@ -1451,6 +1507,7 @@ class RemoteAssetEntityCompanion required i2.AssetVisibility visibility, this.stackId = const i0.Value.absent(), this.libraryId = const i0.Value.absent(), + this.cloudId = const i0.Value.absent(), }) : name = i0.Value(name), type = i0.Value(type), id = i0.Value(id), @@ -1476,6 +1533,7 @@ class RemoteAssetEntityCompanion i0.Expression? visibility, i0.Expression? stackId, i0.Expression? libraryId, + i0.Expression? cloudId, }) { return i0.RawValuesInsertable({ if (name != null) 'name': name, @@ -1496,6 +1554,7 @@ class RemoteAssetEntityCompanion if (visibility != null) 'visibility': visibility, if (stackId != null) 'stack_id': stackId, if (libraryId != null) 'library_id': libraryId, + if (cloudId != null) 'cloud_id': cloudId, }); } @@ -1518,6 +1577,7 @@ class RemoteAssetEntityCompanion i0.Value? visibility, i0.Value? stackId, i0.Value? libraryId, + i0.Value? cloudId, }) { return i1.RemoteAssetEntityCompanion( name: name ?? this.name, @@ -1538,6 +1598,7 @@ class RemoteAssetEntityCompanion visibility: visibility ?? this.visibility, stackId: stackId ?? this.stackId, libraryId: libraryId ?? this.libraryId, + cloudId: cloudId ?? this.cloudId, ); } @@ -1602,6 +1663,9 @@ class RemoteAssetEntityCompanion if (libraryId.present) { map['library_id'] = i0.Variable(libraryId.value); } + if (cloudId.present) { + map['cloud_id'] = i0.Variable(cloudId.value); + } return map; } @@ -1625,7 +1689,8 @@ class RemoteAssetEntityCompanion ..write('livePhotoVideoId: $livePhotoVideoId, ') ..write('visibility: $visibility, ') ..write('stackId: $stackId, ') - ..write('libraryId: $libraryId') + ..write('libraryId: $libraryId, ') + ..write('cloudId: $cloudId') ..write(')')) .toString(); } @@ -1643,3 +1708,7 @@ i0.Index get idxRemoteAssetChecksum => i0.Index( 'idx_remote_asset_checksum', 'CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)', ); +i0.Index get idxRemoteAssetCloudId => i0.Index( + 'idx_remote_asset_cloud_id', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_cloud_id ON remote_asset_entity (cloud_id)', +); diff --git a/mobile/lib/infrastructure/entities/remote_asset_metadata.entity.dart b/mobile/lib/infrastructure/entities/remote_asset_metadata.entity.dart deleted file mode 100644 index a50ff94a1a..0000000000 --- a/mobile/lib/infrastructure/entities/remote_asset_metadata.entity.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:drift/drift.dart'; -import 'package:drift/extensions/json1.dart'; -import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart'; -import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart'; - -@TableIndex.sql(''' -CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_asset_metadata_cloud_id ON remote_asset_metadata_entity (cloud_id) WHERE ("key" = 'mobile-app'); -''') -class RemoteAssetMetadataEntity extends Table with DriftDefaultsMixin { - const RemoteAssetMetadataEntity(); - - TextColumn get assetId => text().references(RemoteAssetEntity, #id, onDelete: KeyAction.cascade)(); - - TextColumn get key => text()(); - - BlobColumn get value => blob().map(assetMetadataConverter)(); - - TextColumn get cloudId => text().generatedAs(value.jsonExtract(r'$.iCloudId'), stored: true).nullable()(); - - @override - Set get primaryKey => {assetId, key}; -} - -final JsonTypeConverter2, Uint8List, Object?> assetMetadataConverter = TypeConverter.jsonb( - fromJson: (json) => json as Map, -); diff --git a/mobile/lib/infrastructure/entities/remote_asset_metadata.entity.drift.dart b/mobile/lib/infrastructure/entities/remote_asset_metadata.entity.drift.dart deleted file mode 100644 index b605239b2d..0000000000 --- a/mobile/lib/infrastructure/entities/remote_asset_metadata.entity.drift.dart +++ /dev/null @@ -1,671 +0,0 @@ -// dart format width=80 -// ignore_for_file: type=lint -import 'package:drift/drift.dart' as i0; -import 'package:immich_mobile/infrastructure/entities/remote_asset_metadata.entity.drift.dart' - as i1; -import 'dart:typed_data' as i2; -import 'package:immich_mobile/infrastructure/entities/remote_asset_metadata.entity.dart' - as i3; -import 'package:drift/extensions/json1.dart' as i4; -import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart' - as i5; -import 'package:drift/internal/modular.dart' as i6; - -typedef $$RemoteAssetMetadataEntityTableCreateCompanionBuilder = - i1.RemoteAssetMetadataEntityCompanion Function({ - required String assetId, - required String key, - required Map value, - }); -typedef $$RemoteAssetMetadataEntityTableUpdateCompanionBuilder = - i1.RemoteAssetMetadataEntityCompanion Function({ - i0.Value assetId, - i0.Value key, - i0.Value> value, - }); - -final class $$RemoteAssetMetadataEntityTableReferences - extends - i0.BaseReferences< - i0.GeneratedDatabase, - i1.$RemoteAssetMetadataEntityTable, - i1.RemoteAssetMetadataEntityData - > { - $$RemoteAssetMetadataEntityTableReferences( - super.$_db, - super.$_table, - super.$_typedResult, - ); - - static i5.$RemoteAssetEntityTable _assetIdTable(i0.GeneratedDatabase db) => - i6.ReadDatabaseContainer(db) - .resultSet('remote_asset_entity') - .createAlias( - i0.$_aliasNameGenerator( - i6.ReadDatabaseContainer(db) - .resultSet( - 'remote_asset_metadata_entity', - ) - .assetId, - i6.ReadDatabaseContainer( - db, - ).resultSet('remote_asset_entity').id, - ), - ); - - i5.$$RemoteAssetEntityTableProcessedTableManager get assetId { - final $_column = $_itemColumn('asset_id')!; - - final manager = i5 - .$$RemoteAssetEntityTableTableManager( - $_db, - i6.ReadDatabaseContainer( - $_db, - ).resultSet('remote_asset_entity'), - ) - .filter((f) => f.id.sqlEquals($_column)); - final item = $_typedResult.readTableOrNull(_assetIdTable($_db)); - if (item == null) return manager; - return i0.ProcessedTableManager( - manager.$state.copyWith(prefetchedData: [item]), - ); - } -} - -class $$RemoteAssetMetadataEntityTableFilterComposer - extends - i0.Composer { - $$RemoteAssetMetadataEntityTableFilterComposer({ - required super.$db, - required super.$table, - super.joinBuilder, - super.$addJoinBuilderToRootComposer, - super.$removeJoinBuilderFromRootComposer, - }); - i0.ColumnFilters get key => $composableBuilder( - column: $table.key, - builder: (column) => i0.ColumnFilters(column), - ); - - i0.ColumnWithTypeConverterFilters< - Map, - Map, - i2.Uint8List - > - get value => $composableBuilder( - column: $table.value, - builder: (column) => i0.ColumnWithTypeConverterFilters(column), - ); - - i0.ColumnFilters get cloudId => $composableBuilder( - column: $table.cloudId, - builder: (column) => i0.ColumnFilters(column), - ); - - i5.$$RemoteAssetEntityTableFilterComposer get assetId { - final i5.$$RemoteAssetEntityTableFilterComposer composer = $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.assetId, - referencedTable: i6.ReadDatabaseContainer( - $db, - ).resultSet('remote_asset_entity'), - getReferencedColumn: (t) => t.id, - builder: - ( - joinBuilder, { - $addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer, - }) => i5.$$RemoteAssetEntityTableFilterComposer( - $db: $db, - $table: i6.ReadDatabaseContainer( - $db, - ).resultSet('remote_asset_entity'), - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - ), - ); - return composer; - } -} - -class $$RemoteAssetMetadataEntityTableOrderingComposer - extends - i0.Composer { - $$RemoteAssetMetadataEntityTableOrderingComposer({ - required super.$db, - required super.$table, - super.joinBuilder, - super.$addJoinBuilderToRootComposer, - super.$removeJoinBuilderFromRootComposer, - }); - i0.ColumnOrderings get key => $composableBuilder( - column: $table.key, - builder: (column) => i0.ColumnOrderings(column), - ); - - i0.ColumnOrderings get value => $composableBuilder( - column: $table.value, - builder: (column) => i0.ColumnOrderings(column), - ); - - i0.ColumnOrderings get cloudId => $composableBuilder( - column: $table.cloudId, - builder: (column) => i0.ColumnOrderings(column), - ); - - i5.$$RemoteAssetEntityTableOrderingComposer get assetId { - final i5.$$RemoteAssetEntityTableOrderingComposer composer = - $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.assetId, - referencedTable: i6.ReadDatabaseContainer( - $db, - ).resultSet('remote_asset_entity'), - getReferencedColumn: (t) => t.id, - builder: - ( - joinBuilder, { - $addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer, - }) => i5.$$RemoteAssetEntityTableOrderingComposer( - $db: $db, - $table: i6.ReadDatabaseContainer( - $db, - ).resultSet('remote_asset_entity'), - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - ), - ); - return composer; - } -} - -class $$RemoteAssetMetadataEntityTableAnnotationComposer - extends - i0.Composer { - $$RemoteAssetMetadataEntityTableAnnotationComposer({ - required super.$db, - required super.$table, - super.joinBuilder, - super.$addJoinBuilderToRootComposer, - super.$removeJoinBuilderFromRootComposer, - }); - i0.GeneratedColumn get key => - $composableBuilder(column: $table.key, builder: (column) => column); - - i0.GeneratedColumnWithTypeConverter, i2.Uint8List> - get value => - $composableBuilder(column: $table.value, builder: (column) => column); - - i0.GeneratedColumn get cloudId => - $composableBuilder(column: $table.cloudId, builder: (column) => column); - - i5.$$RemoteAssetEntityTableAnnotationComposer get assetId { - final i5.$$RemoteAssetEntityTableAnnotationComposer composer = - $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.assetId, - referencedTable: i6.ReadDatabaseContainer( - $db, - ).resultSet('remote_asset_entity'), - getReferencedColumn: (t) => t.id, - builder: - ( - joinBuilder, { - $addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer, - }) => i5.$$RemoteAssetEntityTableAnnotationComposer( - $db: $db, - $table: i6.ReadDatabaseContainer( - $db, - ).resultSet('remote_asset_entity'), - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - ), - ); - return composer; - } -} - -class $$RemoteAssetMetadataEntityTableTableManager - extends - i0.RootTableManager< - i0.GeneratedDatabase, - i1.$RemoteAssetMetadataEntityTable, - i1.RemoteAssetMetadataEntityData, - i1.$$RemoteAssetMetadataEntityTableFilterComposer, - i1.$$RemoteAssetMetadataEntityTableOrderingComposer, - i1.$$RemoteAssetMetadataEntityTableAnnotationComposer, - $$RemoteAssetMetadataEntityTableCreateCompanionBuilder, - $$RemoteAssetMetadataEntityTableUpdateCompanionBuilder, - ( - i1.RemoteAssetMetadataEntityData, - i1.$$RemoteAssetMetadataEntityTableReferences, - ), - i1.RemoteAssetMetadataEntityData, - i0.PrefetchHooks Function({bool assetId}) - > { - $$RemoteAssetMetadataEntityTableTableManager( - i0.GeneratedDatabase db, - i1.$RemoteAssetMetadataEntityTable table, - ) : super( - i0.TableManagerState( - db: db, - table: table, - createFilteringComposer: () => - i1.$$RemoteAssetMetadataEntityTableFilterComposer( - $db: db, - $table: table, - ), - createOrderingComposer: () => - i1.$$RemoteAssetMetadataEntityTableOrderingComposer( - $db: db, - $table: table, - ), - createComputedFieldComposer: () => - i1.$$RemoteAssetMetadataEntityTableAnnotationComposer( - $db: db, - $table: table, - ), - updateCompanionCallback: - ({ - i0.Value assetId = const i0.Value.absent(), - i0.Value key = const i0.Value.absent(), - i0.Value> value = const i0.Value.absent(), - }) => i1.RemoteAssetMetadataEntityCompanion( - assetId: assetId, - key: key, - value: value, - ), - createCompanionCallback: - ({ - required String assetId, - required String key, - required Map value, - }) => i1.RemoteAssetMetadataEntityCompanion.insert( - assetId: assetId, - key: key, - value: value, - ), - withReferenceMapper: (p0) => p0 - .map( - (e) => ( - e.readTable(table), - i1.$$RemoteAssetMetadataEntityTableReferences(db, table, e), - ), - ) - .toList(), - prefetchHooksCallback: ({assetId = false}) { - return i0.PrefetchHooks( - db: db, - explicitlyWatchedTables: [], - addJoins: - < - T extends i0.TableManagerState< - dynamic, - dynamic, - dynamic, - dynamic, - dynamic, - dynamic, - dynamic, - dynamic, - dynamic, - dynamic, - dynamic - > - >(state) { - if (assetId) { - state = - state.withJoin( - currentTable: table, - currentColumn: table.assetId, - referencedTable: i1 - .$$RemoteAssetMetadataEntityTableReferences - ._assetIdTable(db), - referencedColumn: i1 - .$$RemoteAssetMetadataEntityTableReferences - ._assetIdTable(db) - .id, - ) - as T; - } - - return state; - }, - getPrefetchedDataCallback: (items) async { - return []; - }, - ); - }, - ), - ); -} - -typedef $$RemoteAssetMetadataEntityTableProcessedTableManager = - i0.ProcessedTableManager< - i0.GeneratedDatabase, - i1.$RemoteAssetMetadataEntityTable, - i1.RemoteAssetMetadataEntityData, - i1.$$RemoteAssetMetadataEntityTableFilterComposer, - i1.$$RemoteAssetMetadataEntityTableOrderingComposer, - i1.$$RemoteAssetMetadataEntityTableAnnotationComposer, - $$RemoteAssetMetadataEntityTableCreateCompanionBuilder, - $$RemoteAssetMetadataEntityTableUpdateCompanionBuilder, - ( - i1.RemoteAssetMetadataEntityData, - i1.$$RemoteAssetMetadataEntityTableReferences, - ), - i1.RemoteAssetMetadataEntityData, - i0.PrefetchHooks Function({bool assetId}) - >; -i0.Index get uQRemoteAssetMetadataCloudId => i0.Index( - 'UQ_remote_asset_metadata_cloud_id', - 'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_asset_metadata_cloud_id ON remote_asset_metadata_entity (cloud_id) WHERE("key" = \'mobile-app\')', -); - -class $RemoteAssetMetadataEntityTable extends i3.RemoteAssetMetadataEntity - with - i0.TableInfo< - $RemoteAssetMetadataEntityTable, - i1.RemoteAssetMetadataEntityData - > { - @override - final i0.GeneratedDatabase attachedDatabase; - final String? _alias; - $RemoteAssetMetadataEntityTable(this.attachedDatabase, [this._alias]); - static const i0.VerificationMeta _assetIdMeta = const i0.VerificationMeta( - 'assetId', - ); - @override - late final i0.GeneratedColumn assetId = i0.GeneratedColumn( - 'asset_id', - aliasedName, - false, - type: i0.DriftSqlType.string, - requiredDuringInsert: true, - defaultConstraints: i0.GeneratedColumn.constraintIsAlways( - 'REFERENCES remote_asset_entity (id) ON DELETE CASCADE', - ), - ); - static const i0.VerificationMeta _keyMeta = const i0.VerificationMeta('key'); - @override - late final i0.GeneratedColumn key = i0.GeneratedColumn( - 'key', - aliasedName, - false, - type: i0.DriftSqlType.string, - requiredDuringInsert: true, - ); - @override - late final i0.GeneratedColumnWithTypeConverter< - Map, - i2.Uint8List - > - value = - i0.GeneratedColumn( - 'value', - aliasedName, - false, - type: i0.DriftSqlType.blob, - requiredDuringInsert: true, - ).withConverter>( - i1.$RemoteAssetMetadataEntityTable.$convertervalue, - ); - static const i0.VerificationMeta _cloudIdMeta = const i0.VerificationMeta( - 'cloudId', - ); - @override - late final i0.GeneratedColumn cloudId = i0.GeneratedColumn( - 'cloud_id', - aliasedName, - true, - generatedAs: i0.GeneratedAs( - i4.JsonbExtensions(value).jsonExtract(r'$.iCloudId'), - true, - ), - type: i0.DriftSqlType.string, - requiredDuringInsert: false, - ); - @override - List get $columns => [assetId, key, value, cloudId]; - @override - String get aliasedName => _alias ?? actualTableName; - @override - String get actualTableName => $name; - static const String $name = 'remote_asset_metadata_entity'; - @override - i0.VerificationContext validateIntegrity( - i0.Insertable instance, { - bool isInserting = false, - }) { - final context = i0.VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('asset_id')) { - context.handle( - _assetIdMeta, - assetId.isAcceptableOrUnknown(data['asset_id']!, _assetIdMeta), - ); - } else if (isInserting) { - context.missing(_assetIdMeta); - } - if (data.containsKey('key')) { - context.handle( - _keyMeta, - key.isAcceptableOrUnknown(data['key']!, _keyMeta), - ); - } else if (isInserting) { - context.missing(_keyMeta); - } - if (data.containsKey('cloud_id')) { - context.handle( - _cloudIdMeta, - cloudId.isAcceptableOrUnknown(data['cloud_id']!, _cloudIdMeta), - ); - } - return context; - } - - @override - Set get $primaryKey => {assetId, key}; - @override - i1.RemoteAssetMetadataEntityData map( - Map data, { - String? tablePrefix, - }) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return i1.RemoteAssetMetadataEntityData( - assetId: attachedDatabase.typeMapping.read( - i0.DriftSqlType.string, - data['${effectivePrefix}asset_id'], - )!, - key: attachedDatabase.typeMapping.read( - i0.DriftSqlType.string, - data['${effectivePrefix}key'], - )!, - value: i1.$RemoteAssetMetadataEntityTable.$convertervalue.fromSql( - attachedDatabase.typeMapping.read( - i0.DriftSqlType.blob, - data['${effectivePrefix}value'], - )!, - ), - cloudId: attachedDatabase.typeMapping.read( - i0.DriftSqlType.string, - data['${effectivePrefix}cloud_id'], - ), - ); - } - - @override - $RemoteAssetMetadataEntityTable createAlias(String alias) { - return $RemoteAssetMetadataEntityTable(attachedDatabase, alias); - } - - static i0.JsonTypeConverter2, i2.Uint8List, Object?> - $convertervalue = i3.assetMetadataConverter; - @override - bool get withoutRowId => true; - @override - bool get isStrict => true; -} - -class RemoteAssetMetadataEntityData extends i0.DataClass - implements i0.Insertable { - final String assetId; - final String key; - final Map value; - final String? cloudId; - const RemoteAssetMetadataEntityData({ - required this.assetId, - required this.key, - required this.value, - this.cloudId, - }); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['asset_id'] = i0.Variable(assetId); - map['key'] = i0.Variable(key); - { - map['value'] = i0.Variable( - i1.$RemoteAssetMetadataEntityTable.$convertervalue.toSql(value), - ); - } - return map; - } - - factory RemoteAssetMetadataEntityData.fromJson( - Map json, { - i0.ValueSerializer? serializer, - }) { - serializer ??= i0.driftRuntimeOptions.defaultSerializer; - return RemoteAssetMetadataEntityData( - assetId: serializer.fromJson(json['assetId']), - key: serializer.fromJson(json['key']), - value: i1.$RemoteAssetMetadataEntityTable.$convertervalue.fromJson( - serializer.fromJson(json['value']), - ), - cloudId: serializer.fromJson(json['cloudId']), - ); - } - @override - Map toJson({i0.ValueSerializer? serializer}) { - serializer ??= i0.driftRuntimeOptions.defaultSerializer; - return { - 'assetId': serializer.toJson(assetId), - 'key': serializer.toJson(key), - 'value': serializer.toJson( - i1.$RemoteAssetMetadataEntityTable.$convertervalue.toJson(value), - ), - 'cloudId': serializer.toJson(cloudId), - }; - } - - i1.RemoteAssetMetadataEntityData copyWith({ - String? assetId, - String? key, - Map? value, - i0.Value cloudId = const i0.Value.absent(), - }) => i1.RemoteAssetMetadataEntityData( - assetId: assetId ?? this.assetId, - key: key ?? this.key, - value: value ?? this.value, - cloudId: cloudId.present ? cloudId.value : this.cloudId, - ); - @override - String toString() { - return (StringBuffer('RemoteAssetMetadataEntityData(') - ..write('assetId: $assetId, ') - ..write('key: $key, ') - ..write('value: $value, ') - ..write('cloudId: $cloudId') - ..write(')')) - .toString(); - } - - @override - int get hashCode => Object.hash(assetId, key, value, cloudId); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is i1.RemoteAssetMetadataEntityData && - other.assetId == this.assetId && - other.key == this.key && - other.value == this.value && - other.cloudId == this.cloudId); -} - -class RemoteAssetMetadataEntityCompanion - extends i0.UpdateCompanion { - final i0.Value assetId; - final i0.Value key; - final i0.Value> value; - const RemoteAssetMetadataEntityCompanion({ - this.assetId = const i0.Value.absent(), - this.key = const i0.Value.absent(), - this.value = const i0.Value.absent(), - }); - RemoteAssetMetadataEntityCompanion.insert({ - required String assetId, - required String key, - required Map value, - }) : assetId = i0.Value(assetId), - key = i0.Value(key), - value = i0.Value(value); - static i0.Insertable custom({ - i0.Expression? assetId, - i0.Expression? key, - i0.Expression? value, - }) { - return i0.RawValuesInsertable({ - if (assetId != null) 'asset_id': assetId, - if (key != null) 'key': key, - if (value != null) 'value': value, - }); - } - - i1.RemoteAssetMetadataEntityCompanion copyWith({ - i0.Value? assetId, - i0.Value? key, - i0.Value>? value, - }) { - return i1.RemoteAssetMetadataEntityCompanion( - assetId: assetId ?? this.assetId, - key: key ?? this.key, - value: value ?? this.value, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (assetId.present) { - map['asset_id'] = i0.Variable(assetId.value); - } - if (key.present) { - map['key'] = i0.Variable(key.value); - } - if (value.present) { - map['value'] = i0.Variable( - i1.$RemoteAssetMetadataEntityTable.$convertervalue.toSql(value.value), - ); - } - return map; - } - - @override - String toString() { - return (StringBuffer('RemoteAssetMetadataEntityCompanion(') - ..write('assetId: $assetId, ') - ..write('key: $key, ') - ..write('value: $value') - ..write(')')) - .toString(); - } -} diff --git a/mobile/lib/infrastructure/repositories/backup.repository.dart b/mobile/lib/infrastructure/repositories/backup.repository.dart index 057c7a7bf6..b8998a8c40 100644 --- a/mobile/lib/infrastructure/repositories/backup.repository.dart +++ b/mobile/lib/infrastructure/repositories/backup.repository.dart @@ -64,7 +64,8 @@ class DriftBackupRepository extends DriftDatabaseRepository { ), leftOuterJoin( _db.remoteAssetEntity, - _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) & + (_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) | + _db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId)) & _db.remoteAssetEntity.ownerId.equals(userId), useColumns: false, ), @@ -94,7 +95,8 @@ class DriftBackupRepository extends DriftDatabaseRepository { ), innerJoin( _db.remoteAssetEntity, - _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum), + _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) | + _db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId), useColumns: false, ), ]) @@ -116,7 +118,7 @@ class DriftBackupRepository extends DriftDatabaseRepository { final query = _db.localAssetEntity.select() ..where( (lae) => - lae.checksum.isNotNull() & + (lae.checksum.isNotNull() | lae.cloudId.isNotNull()) & existsQuery( _db.localAlbumAssetEntity.selectOnly() ..addColumns([_db.localAlbumAssetEntity.assetId]) @@ -129,7 +131,9 @@ class DriftBackupRepository extends DriftDatabaseRepository { _db.remoteAssetEntity.selectOnly() ..addColumns([_db.remoteAssetEntity.checksum]) ..where( - _db.remoteAssetEntity.checksum.equalsExp(lae.checksum) & _db.remoteAssetEntity.ownerId.equals(userId), + (_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) | + _db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId)) & + _db.remoteAssetEntity.ownerId.equals(userId), ), ) & lae.id.isNotInQuery(_getExcludedSubquery()), diff --git a/mobile/lib/infrastructure/repositories/db.repository.dart b/mobile/lib/infrastructure/repositories/db.repository.dart index 4b7bf9c5e8..c2a2f5dc04 100644 --- a/mobile/lib/infrastructure/repositories/db.repository.dart +++ b/mobile/lib/infrastructure/repositories/db.repository.dart @@ -17,7 +17,6 @@ import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart'; import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.dart'; import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.dart'; import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart'; -import 'package:immich_mobile/infrastructure/entities/remote_asset_metadata.entity.dart'; import 'package:immich_mobile/infrastructure/entities/stack.entity.dart'; import 'package:immich_mobile/infrastructure/entities/store.entity.dart'; import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; @@ -51,7 +50,6 @@ class IsarDatabaseRepository implements IDatabaseRepository { LocalAssetEntity, LocalAlbumAssetEntity, RemoteAssetEntity, - RemoteAssetMetadataEntity, RemoteExifEntity, RemoteAlbumEntity, RemoteAlbumAssetEntity, @@ -129,9 +127,9 @@ class Drift extends $Drift implements IDatabaseRepository { // Add cloudId column to local_asset_entity await m.addColumn(v9.localAssetEntity, v9.localAssetEntity.cloudId); await m.createIndex(v9.idxLocalAssetCloudId); - // Create new table - await m.createTable(v9.remoteAssetMetadataEntity); - await m.createIndex(v9.uQRemoteAssetMetadataCloudId); + // Add cloudId column to remote_asset_entity + await m.addColumn(v9.remoteAssetEntity, v9.remoteAssetEntity.cloudId); + await m.createIndex(v9.idxRemoteAssetCloudId); }, from8To9: (m, v9) async { await m.addColumn(v9.localAlbumEntity, v9.localAlbumEntity.linkedRemoteAlbumId); diff --git a/mobile/lib/infrastructure/repositories/local_asset.repository.dart b/mobile/lib/infrastructure/repositories/local_asset.repository.dart index 5865447064..eba603dce8 100644 --- a/mobile/lib/infrastructure/repositories/local_asset.repository.dart +++ b/mobile/lib/infrastructure/repositories/local_asset.repository.dart @@ -13,7 +13,8 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository { final query = _db.localAssetEntity.select().addColumns([_db.remoteAssetEntity.id]).join([ leftOuterJoin( _db.remoteAssetEntity, - _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum), + _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) | + _db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId), useColumns: false, ), ])..where(_db.localAssetEntity.id.equals(id)); diff --git a/mobile/lib/infrastructure/repositories/remote_asset.repository.dart b/mobile/lib/infrastructure/repositories/remote_asset.repository.dart index 3ed7dddfe8..1984e6ffdc 100644 --- a/mobile/lib/infrastructure/repositories/remote_asset.repository.dart +++ b/mobile/lib/infrastructure/repositories/remote_asset.repository.dart @@ -34,7 +34,8 @@ class RemoteAssetRepository extends DriftDatabaseRepository { _db.remoteAssetEntity.select().addColumns([_db.localAssetEntity.id]).join([ leftOuterJoin( _db.localAssetEntity, - _db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum), + _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) | + _db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId), useColumns: false, ), ]) diff --git a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart index a5cbc53abc..bf538e4c0e 100644 --- a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart @@ -15,14 +15,13 @@ import 'package:immich_mobile/infrastructure/entities/remote_album.entity.drift. import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart'; -import 'package:immich_mobile/infrastructure/entities/remote_asset_metadata.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.drift.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:logging/logging.dart'; import 'package:openapi/api.dart' as api show AssetVisibility, AlbumUserRole, UserMetadataKey; -import 'package:openapi/api.dart' hide AssetVisibility, AlbumUserRole, UserMetadataKey, AssetMetadataKey; +import 'package:openapi/api.dart' hide AssetVisibility, AlbumUserRole, UserMetadataKey; class SyncStreamRepository extends DriftDatabaseRepository { final Logger _logger = Logger('DriftSyncStreamRepository'); @@ -183,10 +182,13 @@ class SyncStreamRepository extends DriftDatabaseRepository { try { await _db.batch((batch) { for (final metadata in data) { - batch.deleteWhere( - _db.remoteAssetMetadataEntity, - (row) => row.assetId.equals(metadata.assetId) & row.key.equals(metadata.key.value), - ); + if (metadata.key == AssetMetadataKey.mobileApp) { + batch.update( + _db.remoteAssetEntity, + const RemoteAssetEntityCompanion(cloudId: Value(null)), + where: (row) => row.id.equals(metadata.assetId), + ); + } } }); } catch (error, stack) { @@ -199,16 +201,14 @@ class SyncStreamRepository extends DriftDatabaseRepository { try { await _db.batch((batch) { for (final metadata in data) { - final companion = RemoteAssetMetadataEntityCompanion( - key: Value(metadata.key.value), - value: Value(metadata.value as Map), - ); - - batch.insert( - _db.remoteAssetMetadataEntity, - companion.copyWith(assetId: Value(metadata.assetId)), - onConflict: DoUpdate((_) => companion), - ); + if (metadata.key == AssetMetadataKey.mobileApp) { + final map = metadata.value as Map; + batch.update( + _db.remoteAssetEntity, + RemoteAssetEntityCompanion(cloudId: Value(map['iCloudId']?.toString())), + where: (row) => row.id.equals(metadata.assetId), + ); + } } }); } catch (error, stack) { diff --git a/mobile/lib/infrastructure/repositories/timeline.repository.dart b/mobile/lib/infrastructure/repositories/timeline.repository.dart index 61428ede92..fe572a6128 100644 --- a/mobile/lib/infrastructure/repositories/timeline.repository.dart +++ b/mobile/lib/infrastructure/repositories/timeline.repository.dart @@ -117,7 +117,8 @@ class DriftTimelineRepository extends DriftDatabaseRepository { ), leftOuterJoin( _db.remoteAssetEntity, - _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum), + _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) | + _db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId), useColumns: false, ), ]) @@ -143,7 +144,8 @@ class DriftTimelineRepository extends DriftDatabaseRepository { ), leftOuterJoin( _db.remoteAssetEntity, - _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum), + _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) | + _db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId), useColumns: false, ), ]) @@ -538,7 +540,8 @@ class DriftTimelineRepository extends DriftDatabaseRepository { _db.remoteAssetEntity.select().join([ leftOuterJoin( _db.localAssetEntity, - _db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum), + _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) | + _db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId), useColumns: false, ), ])