mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
optimize, refactor code
remove redundant code and checking getTrashedAssetsForAlbum for iOS tests for hash trashed assets
This commit is contained in:
parent
3839e72028
commit
3eb2bf0342
24 changed files with 393 additions and 793 deletions
|
|
@ -14,41 +14,45 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
|
||||
const DriftTrashedLocalAssetRepository(this._db) : super(_db);
|
||||
|
||||
Future<void> updateChecksums(Iterable<TrashedAsset> assets) {
|
||||
if (assets.isEmpty) {
|
||||
Future<void> updateHashes(Map<String, String> hashes) {
|
||||
if (hashes.isEmpty) {
|
||||
return Future.value();
|
||||
}
|
||||
final now = DateTime.now();
|
||||
return _db.batch((batch) async {
|
||||
for (final asset in assets) {
|
||||
for (final entry in hashes.entries) {
|
||||
batch.update(
|
||||
_db.trashedLocalAssetEntity,
|
||||
TrashedLocalAssetEntityCompanion(checksum: Value(asset.checksum), updatedAt: Value(now)),
|
||||
where: (e) => e.id.equals(asset.id),
|
||||
TrashedLocalAssetEntityCompanion(checksum: Value(entry.value), updatedAt: Value(now)),
|
||||
where: (e) => e.id.equals(entry.key),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<Iterable<TrashedAsset>> getToHash(Iterable<String> albumIds) {
|
||||
Future<Iterable<TrashedAsset>> getAssetsToHash(Iterable<String> albumIds) {
|
||||
final query = _db.trashedLocalAssetEntity.select()..where((r) => r.albumId.isIn(albumIds) & r.checksum.isNull());
|
||||
return query.map((row) => row.toDto()).get();
|
||||
}
|
||||
|
||||
Future<Iterable<TrashedAsset>> getToRestore() async {
|
||||
final trashed = _db.trashedLocalAssetEntity;
|
||||
final remote = _db.remoteAssetEntity;
|
||||
final album = _db.localAlbumEntity;
|
||||
final selectedAlbumIds = (_db.selectOnly(_db.localAlbumEntity)
|
||||
..addColumns([_db.localAlbumEntity.id])
|
||||
..where(_db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected)));
|
||||
|
||||
final selectedAlbumIds = (_db.selectOnly(album)
|
||||
..addColumns([album.id])
|
||||
..where(album.backupSelection.equalsValue(BackupSelection.selected)));
|
||||
final rows =
|
||||
await (_db.select(_db.trashedLocalAssetEntity).join([
|
||||
innerJoin(
|
||||
_db.remoteAssetEntity,
|
||||
_db.remoteAssetEntity.checksum.equalsExp(_db.trashedLocalAssetEntity.checksum),
|
||||
),
|
||||
])..where(
|
||||
_db.trashedLocalAssetEntity.albumId.isInQuery(selectedAlbumIds) &
|
||||
_db.remoteAssetEntity.deletedAt.isNull(),
|
||||
))
|
||||
.get();
|
||||
|
||||
final rows = await (_db.select(trashed).join([
|
||||
innerJoin(remote, remote.checksum.equalsExp(trashed.checksum)),
|
||||
])..where(trashed.albumId.isInQuery(selectedAlbumIds) & remote.deletedAt.isNull())).get();
|
||||
|
||||
return rows.map((result) => result.readTable(trashed).toDto());
|
||||
return rows.map((result) => result.readTable(_db.trashedLocalAssetEntity).toDto());
|
||||
}
|
||||
|
||||
/// Applies resulted snapshot of trashed assets:
|
||||
|
|
@ -61,41 +65,46 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
}
|
||||
|
||||
return _db.transaction(() async {
|
||||
final table = _db.trashedLocalAssetEntity;
|
||||
await _db.batch((batch) {
|
||||
for (final asset in assets) {
|
||||
final companion = TrashedLocalAssetEntityCompanion.insert(
|
||||
id: asset.id,
|
||||
albumId: albumId,
|
||||
checksum: asset.checksum == null ? const Value.absent() : Value(asset.checksum),
|
||||
name: asset.name,
|
||||
type: asset.type,
|
||||
createdAt: Value(asset.createdAt),
|
||||
updatedAt: Value(asset.updatedAt),
|
||||
width: Value(asset.width),
|
||||
height: Value(asset.height),
|
||||
durationInSeconds: Value(asset.durationInSeconds),
|
||||
isFavorite: Value(asset.isFavorite),
|
||||
orientation: Value(asset.orientation),
|
||||
);
|
||||
|
||||
final companions = assets.map(
|
||||
(a) => TrashedLocalAssetEntityCompanion.insert(
|
||||
id: a.id,
|
||||
albumId: albumId,
|
||||
volume: a.volume == null ? const Value.absent() : Value(a.volume),
|
||||
checksum: a.checksum == null ? const Value.absent() : Value(a.checksum),
|
||||
name: a.name,
|
||||
type: a.type,
|
||||
createdAt: Value(a.createdAt),
|
||||
updatedAt: Value(a.updatedAt),
|
||||
width: Value(a.width),
|
||||
height: Value(a.height),
|
||||
durationInSeconds: Value(a.durationInSeconds),
|
||||
isFavorite: Value(a.isFavorite),
|
||||
orientation: Value(a.orientation),
|
||||
),
|
||||
);
|
||||
|
||||
for (final slice in companions.slices(400)) {
|
||||
await _db.batch((b) {
|
||||
b.insertAllOnConflictUpdate(table, slice);
|
||||
});
|
||||
}
|
||||
batch.insert<$TrashedLocalAssetEntityTable, TrashedLocalAssetEntityData>(
|
||||
_db.trashedLocalAssetEntity,
|
||||
companion,
|
||||
onConflict: DoUpdate((_) => companion, where: (old) => old.updatedAt.isNotValue(asset.updatedAt)),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
final keepIds = assets.map((asset) => asset.id);
|
||||
if (keepIds.length <= 900) {
|
||||
await (_db.delete(table)..where((row) => row.id.isNotIn(keepIds))).go();
|
||||
|
||||
if (keepIds.length <= 32000) {
|
||||
await (_db.delete(_db.trashedLocalAssetEntity)..where((row) => row.id.isNotIn(keepIds))).go();
|
||||
} else {
|
||||
final existingIds = await (_db.selectOnly(table)..addColumns([table.id])).map((r) => r.read(table.id)!).get();
|
||||
final toDelete = existingIds.where((id) => !keepIds.contains(id));
|
||||
for (final slice in toDelete.slices(400)) {
|
||||
await (_db.delete(table)..where((row) => row.id.isIn(slice))).go();
|
||||
}
|
||||
final keepIdsSet = keepIds.toSet();
|
||||
final existingIds = await (_db.selectOnly(
|
||||
_db.trashedLocalAssetEntity,
|
||||
)..addColumns([_db.trashedLocalAssetEntity.id])).map((r) => r.read(_db.trashedLocalAssetEntity.id)!).get();
|
||||
final idToDelete = existingIds.where((id) => !keepIdsSet.contains(id));
|
||||
await _db.batch((batch) {
|
||||
for (final id in idToDelete) {
|
||||
batch.deleteWhere(_db.trashedLocalAssetEntity, (row) => row.id.equals(id));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -104,42 +113,43 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
if (trashUpdates.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final companions = trashUpdates.map(
|
||||
(a) => TrashedLocalAssetEntityCompanion.insert(
|
||||
id: a.id,
|
||||
volume: a.volume == null ? const Value.absent() : Value(a.volume),
|
||||
albumId: a.albumId,
|
||||
name: a.name,
|
||||
type: a.type,
|
||||
checksum: a.checksum == null ? const Value.absent() : Value(a.checksum),
|
||||
createdAt: Value(a.createdAt),
|
||||
width: Value(a.width),
|
||||
height: Value(a.height),
|
||||
durationInSeconds: Value(a.durationInSeconds),
|
||||
isFavorite: Value(a.isFavorite),
|
||||
orientation: Value(a.orientation),
|
||||
),
|
||||
);
|
||||
|
||||
for (final slice in companions.slices(200)) {
|
||||
await _db.batch((b) {
|
||||
b.insertAllOnConflictUpdate(_db.trashedLocalAssetEntity, slice);
|
||||
});
|
||||
}
|
||||
await _db.batch((batch) {
|
||||
for (final asset in trashUpdates) {
|
||||
final companion = TrashedLocalAssetEntityCompanion.insert(
|
||||
id: asset.id,
|
||||
albumId: asset.albumId,
|
||||
name: asset.name,
|
||||
type: asset.type,
|
||||
checksum: asset.checksum == null ? const Value.absent() : Value(asset.checksum),
|
||||
createdAt: Value(asset.createdAt),
|
||||
width: Value(asset.width),
|
||||
height: Value(asset.height),
|
||||
durationInSeconds: Value(asset.durationInSeconds),
|
||||
isFavorite: Value(asset.isFavorite),
|
||||
orientation: Value(asset.orientation),
|
||||
);
|
||||
batch.insert<$TrashedLocalAssetEntityTable, TrashedLocalAssetEntityData>(
|
||||
_db.trashedLocalAssetEntity,
|
||||
companion,
|
||||
onConflict: DoUpdate((_) => companion, where: (old) => old.updatedAt.isNotValue(asset.updatedAt)),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Stream<int> watchCount() {
|
||||
final t = _db.trashedLocalAssetEntity;
|
||||
return (_db.selectOnly(t)..addColumns([t.id.count()])).watchSingle().map((row) => row.read<int>(t.id.count()) ?? 0);
|
||||
return (_db.selectOnly(_db.trashedLocalAssetEntity)..addColumns([_db.trashedLocalAssetEntity.id.count()]))
|
||||
.watchSingle()
|
||||
.map((row) => row.read<int>(_db.trashedLocalAssetEntity.id.count()) ?? 0);
|
||||
}
|
||||
|
||||
Stream<int> watchHashedCount() {
|
||||
final t = _db.trashedLocalAssetEntity;
|
||||
return (_db.selectOnly(t)
|
||||
..addColumns([t.id.count()])
|
||||
..where(t.checksum.isNotNull()))
|
||||
return (_db.selectOnly(_db.trashedLocalAssetEntity)
|
||||
..addColumns([_db.trashedLocalAssetEntity.id.count()])
|
||||
..where(_db.trashedLocalAssetEntity.checksum.isNotNull()))
|
||||
.watchSingle()
|
||||
.map((row) => row.read<int>(t.id.count()) ?? 0);
|
||||
.map((row) => row.read<int>(_db.trashedLocalAssetEntity.id.count()) ?? 0);
|
||||
}
|
||||
|
||||
Future<void> trashLocalAsset(Map<AlbumId, List<LocalAsset>> assetsByAlbums) async {
|
||||
|
|
@ -150,14 +160,14 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
final companions = <TrashedLocalAssetEntityCompanion>[];
|
||||
final idToDelete = <String>{};
|
||||
|
||||
assetsByAlbums.forEach((albumId, assets) {
|
||||
for (final asset in assets) {
|
||||
for (final entry in assetsByAlbums.entries) {
|
||||
for (final asset in entry.value) {
|
||||
idToDelete.add(asset.id);
|
||||
companions.add(
|
||||
TrashedLocalAssetEntityCompanion(
|
||||
id: Value(asset.id),
|
||||
name: Value(asset.name),
|
||||
albumId: Value(albumId),
|
||||
albumId: Value(entry.key),
|
||||
checksum: asset.checksum == null ? const Value.absent() : Value(asset.checksum),
|
||||
type: Value(asset.type),
|
||||
width: Value(asset.width),
|
||||
|
|
@ -168,17 +178,18 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await _db.transaction(() async {
|
||||
for (final slice in companions.slices(200)) {
|
||||
await _db.batch((batch) {
|
||||
await _db.batch((batch) {
|
||||
for (final slice in companions.slices(32000)) {
|
||||
batch.insertAllOnConflictUpdate(_db.trashedLocalAssetEntity, slice);
|
||||
});
|
||||
}
|
||||
for (final slice in idToDelete.slices(800)) {
|
||||
await (_db.delete(_db.localAssetEntity)..where((e) => e.id.isIn(slice))).go();
|
||||
}
|
||||
}
|
||||
|
||||
for (final id in idToDelete) {
|
||||
batch.deleteWhere(_db.localAssetEntity, (row) => row.id.equals(id));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -212,8 +223,8 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
await _db.transaction(() async {
|
||||
await _db.batch((batch) {
|
||||
batch.insertAllOnConflictUpdate(_db.localAssetEntity, localAssets);
|
||||
for (final slice in ids.slices(32000)) {
|
||||
batch.deleteWhere(_db.trashedLocalAssetEntity, (tbl) => tbl.id.isIn(slice));
|
||||
for (final id in ids) {
|
||||
batch.deleteWhere(_db.trashedLocalAssetEntity, (row) => row.id.equals(id));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue