migrate hashes from remote asset table

This commit is contained in:
shenlong-tanwen
2025-09-05 04:15:16 +05:30
parent b11ea52704
commit 5236a72fb3
12 changed files with 78 additions and 62 deletions
@@ -7,8 +7,7 @@ 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 OR lae.cloud_id = rae.cloud_id LIMIT 1) as local_id,
(SELECT lae.id FROM local_asset_entity lae WHERE lae.checksum = rae.checksum LIMIT 1) as local_id,
rae.name,
rae."type",
rae.created_at as created_at,
@@ -60,8 +59,7 @@ SELECT
FROM
local_asset_entity lae
WHERE NOT EXISTS (
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
SELECT 1 FROM remote_asset_entity rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN :user_ids
)
AND EXISTS (
SELECT 1 FROM local_album_asset_entity laa
@@ -105,8 +103,7 @@ FROM
FROM
local_asset_entity lae
WHERE NOT EXISTS (
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
SELECT 1 FROM remote_asset_entity rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN :user_ids
)
AND EXISTS (
SELECT 1 FROM local_album_asset_entity laa
+2 -2
View File
@@ -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 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, rae.cloud_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, lae.cloud_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}',
'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, rae.cloud_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, lae.cloud_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}',
variables: [
for (var $ in userIds) i0.Variable<String>($),
...generatedlimit.introducedVariables,
@@ -75,7 +75,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 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',
'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',
variables: [
i0.Variable<int>(groupBy),
for (var $ in userIds) i0.Variable<String>($),
@@ -64,8 +64,7 @@ class DriftBackupRepository extends DriftDatabaseRepository {
),
leftOuterJoin(
_db.remoteAssetEntity,
(_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) |
_db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId)) &
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) &
_db.remoteAssetEntity.ownerId.equals(userId),
useColumns: false,
),
@@ -95,8 +94,7 @@ class DriftBackupRepository extends DriftDatabaseRepository {
),
innerJoin(
_db.remoteAssetEntity,
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) |
_db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId),
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum),
useColumns: false,
),
])
@@ -118,7 +116,7 @@ class DriftBackupRepository extends DriftDatabaseRepository {
final query = _db.localAssetEntity.select()
..where(
(lae) =>
(lae.checksum.isNotNull() | lae.cloudId.isNotNull()) &
lae.checksum.isNotNull() &
existsQuery(
_db.localAlbumAssetEntity.selectOnly()
..addColumns([_db.localAlbumAssetEntity.assetId])
@@ -131,9 +129,7 @@ class DriftBackupRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity.selectOnly()
..addColumns([_db.remoteAssetEntity.checksum])
..where(
(_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) |
_db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId)) &
_db.remoteAssetEntity.ownerId.equals(userId),
_db.remoteAssetEntity.checksum.equalsExp(lae.checksum) & _db.remoteAssetEntity.ownerId.equals(userId),
),
) &
lae.id.isNotInQuery(_getExcludedSubquery()),
@@ -5,6 +5,8 @@ import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
typedef LocalAssetHashMapping = ({String assetId, String checksum});
class DriftLocalAssetRepository extends DriftDatabaseRepository {
final Drift _db;
const DriftLocalAssetRepository(this._db) : super(_db);
@@ -13,8 +15,7 @@ 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.cloudId.equalsExp(_db.remoteAssetEntity.cloudId),
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum),
useColumns: false,
),
])..where(_db.localAssetEntity.id.equals(id));
@@ -29,17 +30,17 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
Stream<LocalAsset?> watch(String id) => _assetSelectable(id).watchSingleOrNull();
Future<void> updateHashes(Iterable<LocalAsset> hashes) {
Future<void> updateHashes(Iterable<LocalAssetHashMapping> hashes) {
if (hashes.isEmpty) {
return Future.value();
}
return _db.batch((batch) async {
for (final asset in hashes) {
for (final mapping in hashes) {
batch.update(
_db.localAssetEntity,
LocalAssetEntityCompanion(checksum: Value(asset.checksum)),
where: (e) => e.id.equals(asset.id),
LocalAssetEntityCompanion(checksum: Value(mapping.checksum)),
where: (e) => e.id.equals(mapping.assetId),
);
}
});
@@ -70,4 +71,22 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
Future<int> getHashedCount() {
return _db.managers.localAssetEntity.filter((e) => e.checksum.isNull().not()).count();
}
Future<List<LocalAssetHashMapping>> getHashMappingFromCloudId() async {
final query =
_db.localAssetEntity.selectOnly().join([
leftOuterJoin(
_db.remoteAssetEntity,
_db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId),
useColumns: false,
),
])
..addColumns([_db.localAssetEntity.id, _db.remoteAssetEntity.checksum])
..where(_db.remoteAssetEntity.cloudId.isNotNull() & _db.localAssetEntity.checksum.isNull());
return query
.map(
(row) => (assetId: row.read(_db.localAssetEntity.id)!, checksum: row.read(_db.remoteAssetEntity.checksum)!),
)
.get();
}
}
@@ -34,8 +34,7 @@ class RemoteAssetRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity.select().addColumns([_db.localAssetEntity.id]).join([
leftOuterJoin(
_db.localAssetEntity,
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) |
_db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId),
_db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum),
useColumns: false,
),
])
@@ -118,8 +118,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
),
leftOuterJoin(
_db.remoteAssetEntity,
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) |
_db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId),
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum),
useColumns: false,
),
])
@@ -145,8 +144,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
),
leftOuterJoin(
_db.remoteAssetEntity,
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) |
_db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId),
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum),
useColumns: false,
),
])
@@ -541,8 +539,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity.select().join([
leftOuterJoin(
_db.localAssetEntity,
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) |
_db.localAssetEntity.cloudId.equalsExp(_db.remoteAssetEntity.cloudId),
_db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum),
useColumns: false,
),
])