chore: refactor the way edits are joined

This commit is contained in:
bwees
2026-01-13 12:38:26 -06:00
parent 7baf58ef6d
commit 9a280b0140
10 changed files with 242 additions and 118 deletions
@@ -30,7 +30,7 @@ class LocalAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin {
} }
extension LocalAssetEntityDataDomainExtension on LocalAssetEntityData { extension LocalAssetEntityDataDomainExtension on LocalAssetEntityData {
LocalAsset toDto(bool isEdited, {String? remoteId}) => LocalAsset( LocalAsset toDto({required bool isEdited, String? remoteId}) => LocalAsset(
id: id, id: id,
name: name, name: name,
checksum: checksum, checksum: checksum,
@@ -49,7 +49,7 @@ class RemoteAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin
} }
extension RemoteAssetEntityDataDomainEx on RemoteAssetEntityData { extension RemoteAssetEntityDataDomainEx on RemoteAssetEntityData {
RemoteAsset toDto(bool isEdited, {String? localId}) => RemoteAsset( RemoteAsset toDto({required bool isEdited, String? localId}) => RemoteAsset(
id: id, id: id,
name: name, name: name,
ownerId: ownerId, ownerId: ownerId,
@@ -112,13 +112,16 @@ class DriftBackupRepository extends DriftDatabaseRepository {
query.where((lae) => lae.checksum.isNotNull()); query.where((lae) => lae.checksum.isNotNull());
} }
final hasEdits = _db.assetEditEntity.id.isNotNull();
final assetsQuery = query.join([ final assetsQuery = query.join([
leftOuterJoin(_db.remoteAssetEntity, _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum)), leftOuterJoin(_db.remoteAssetEntity, _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum)),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
]); _db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
])..addColumns([hasEdits]);
return assetsQuery return assetsQuery.map((row) => row.readTable(_db.localAssetEntity).toDto(isEdited: row.read(hasEdits)!)).get();
.map((row) => row.readTable(_db.localAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null))
.get();
} }
} }
@@ -185,6 +185,7 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository {
} }
Future<List<LocalAsset>> getAssets(String albumId) { Future<List<LocalAsset>> getAssets(String albumId) {
final hasEdits = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.localAlbumAssetEntity.select().join([ _db.localAlbumAssetEntity.select().join([
innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)), innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)),
@@ -192,13 +193,17 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity, _db.remoteAssetEntity,
_db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum), _db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum),
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]) ])
..addColumns([hasEdits])
..where(_db.localAlbumAssetEntity.albumId.equals(albumId)) ..where(_db.localAlbumAssetEntity.albumId.equals(albumId))
..orderBy([OrderingTerm.asc(_db.localAssetEntity.id)]); ..orderBy([OrderingTerm.asc(_db.localAssetEntity.id)]);
return query
.map((row) => row.readTable(_db.localAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null)) return query.map((row) => row.readTable(_db.localAssetEntity).toDto(isEdited: row.read(hasEdits)!)).get();
.get();
} }
Future<List<String>> getAssetIds(String albumId) { Future<List<String>> getAssetIds(String albumId) {
@@ -243,6 +248,7 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository {
} }
Future<List<LocalAsset>> getAssetsToHash(String albumId) { Future<List<LocalAsset>> getAssetsToHash(String albumId) {
final hasEdits = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.localAlbumAssetEntity.select().join([ _db.localAlbumAssetEntity.select().join([
innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)), innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)),
@@ -250,14 +256,17 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity, _db.remoteAssetEntity,
_db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum), _db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum),
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]) ])
..addColumns([hasEdits])
..where(_db.localAlbumAssetEntity.albumId.equals(albumId) & _db.localAssetEntity.checksum.isNull()) ..where(_db.localAlbumAssetEntity.albumId.equals(albumId) & _db.localAssetEntity.checksum.isNull())
..orderBy([OrderingTerm.asc(_db.localAssetEntity.id)]); ..orderBy([OrderingTerm.asc(_db.localAssetEntity.id)]);
return query return query.map((row) => row.readTable(_db.localAssetEntity).toDto(isEdited: row.read(hasEdits)!)).get();
.map((row) => row.readTable(_db.localAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null))
.get();
} }
Future<void> updateCloudMapping(Map<String, String> cloudMapping) { Future<void> updateCloudMapping(Map<String, String> cloudMapping) {
@@ -428,6 +437,8 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository {
} }
Future<LocalAsset?> getThumbnail(String albumId) async { Future<LocalAsset?> getThumbnail(String albumId) async {
final hasEdits = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.localAlbumAssetEntity.select().join([ _db.localAlbumAssetEntity.select().join([
innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)), innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)),
@@ -435,14 +446,19 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity, _db.remoteAssetEntity,
_db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum), _db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum),
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]) ])
..addColumns([hasEdits])
..where(_db.localAlbumAssetEntity.albumId.equals(albumId)) ..where(_db.localAlbumAssetEntity.albumId.equals(albumId))
..orderBy([OrderingTerm.desc(_db.localAssetEntity.createdAt)]) ..orderBy([OrderingTerm.desc(_db.localAssetEntity.createdAt)])
..limit(1); ..limit(1);
final results = await query final results = await query
.map((row) => row.readTable(_db.localAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null)) .map((row) => row.readTable(_db.localAssetEntity).toDto(isEdited: row.read(hasEdits)!))
.get(); .get();
return results.isNotEmpty ? results.first : null; return results.isNotEmpty ? results.first : null;
@@ -17,17 +17,22 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
const DriftLocalAssetRepository(this._db) : super(_db); const DriftLocalAssetRepository(this._db) : super(_db);
SingleOrNullSelectable<LocalAsset?> _assetSelectable(String id) { SingleOrNullSelectable<LocalAsset?> _assetSelectable(String id) {
final query = _db.localAssetEntity.select().addColumns([_db.remoteAssetEntity.id]).join([ final hasEdits = _db.assetEditEntity.id.isNotNull();
final query = _db.localAssetEntity.select().addColumns([_db.remoteAssetEntity.id, hasEdits]).join([
leftOuterJoin( leftOuterJoin(
_db.remoteAssetEntity, _db.remoteAssetEntity,
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum), _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum),
useColumns: false, useColumns: false,
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
])..where(_db.localAssetEntity.id.equals(id)); ])..where(_db.localAssetEntity.id.equals(id));
return query.map((row) { return query.map((row) {
final asset = row.readTable(_db.localAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null); final asset = row.readTable(_db.localAssetEntity).toDto(isEdited: row.read(hasEdits)!);
return asset.copyWith(remoteId: row.read(_db.remoteAssetEntity.id)); return asset.copyWith(remoteId: row.read(_db.remoteAssetEntity.id));
}); });
} }
@@ -35,14 +40,24 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
Future<LocalAsset?> get(String id) => _assetSelectable(id).getSingleOrNull(); Future<LocalAsset?> get(String id) => _assetSelectable(id).getSingleOrNull();
Future<List<LocalAsset?>> getByChecksum(String checksum) { Future<List<LocalAsset?>> getByChecksum(String checksum) {
final query = _db.localAssetEntity.select().join([ final hasEdits = _db.assetEditEntity.id.isNotNull();
leftOuterJoin(_db.remoteAssetEntity, _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum)),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)),
])..where(_db.localAssetEntity.checksum.equals(checksum));
return query final query =
.map((row) => row.readTable(_db.localAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null)) _db.localAssetEntity.select().join([
.get(); leftOuterJoin(
_db.remoteAssetEntity,
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum),
),
leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
])
..where(_db.localAssetEntity.checksum.equals(checksum))
..addColumns([hasEdits]);
return query.map((row) => row.readTable(_db.localAssetEntity).toDto(isEdited: row.read(hasEdits)!)).get();
} }
Stream<LocalAsset?> watch(String id) => _assetSelectable(id).watchSingleOrNull(); Stream<LocalAsset?> watch(String id) => _assetSelectable(id).watchSingleOrNull();
@@ -76,13 +91,24 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
} }
Future<LocalAsset?> getById(String id) { Future<LocalAsset?> getById(String id) {
final query = _db.localAssetEntity.select().join([ final hasEdits = _db.assetEditEntity.id.isNotNull();
leftOuterJoin(_db.remoteAssetEntity, _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum)), final query =
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), _db.localAssetEntity.select().join([
])..where(_db.localAssetEntity.id.equals(id)); leftOuterJoin(
_db.remoteAssetEntity,
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum),
),
leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
])
..where(_db.localAssetEntity.id.equals(id))
..addColumns([hasEdits]);
return query return query
.map((row) => row.readTable(_db.localAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null)) .map((row) => row.readTable(_db.localAssetEntity).toDto(isEdited: row.read(hasEdits)!))
.getSingleOrNull(); .getSingleOrNull();
} }
@@ -119,27 +145,34 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
} }
final result = <String, List<LocalAsset>>{}; final result = <String, List<LocalAsset>>{};
final hasEdits = _db.assetEditEntity.id.isNotNull();
for (final slice in checksums.toSet().slices(kDriftMaxChunk)) { for (final slice in checksums.toSet().slices(kDriftMaxChunk)) {
final rows = final rows =
await (_db.select(_db.localAlbumAssetEntity).join([ await (_db.select(_db.localAlbumAssetEntity).join([
innerJoin(_db.localAlbumEntity, _db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id)), innerJoin(_db.localAlbumEntity, _db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id)),
innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)), innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)),
leftOuterJoin( leftOuterJoin(
_db.remoteAssetEntity, _db.remoteAssetEntity,
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum), _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum),
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
])..where( _db.assetEditEntity,
_db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected) & _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
_db.localAssetEntity.checksum.isIn(slice), useColumns: false,
)) ),
])
..addColumns([hasEdits])
..where(
_db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected) &
_db.localAssetEntity.checksum.isIn(slice),
))
.get(); .get();
for (final row in rows) { for (final row in rows) {
final albumId = row.readTable(_db.localAlbumAssetEntity).albumId; final albumId = row.readTable(_db.localAlbumAssetEntity).albumId;
final assetData = row.readTable(_db.localAssetEntity); final assetData = row.readTable(_db.localAssetEntity);
final asset = assetData.toDto(row.readTableOrNull(_db.assetEditEntity) != null); final asset = assetData.toDto(isEdited: row.read(hasEdits)!);
(result[albumId] ??= <LocalAsset>[]).add(asset); (result[albumId] ??= <LocalAsset>[]).add(asset);
} }
} }
@@ -152,8 +185,9 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
AssetFilterType filterType = AssetFilterType.all, AssetFilterType filterType = AssetFilterType.all,
bool keepFavorites = true, bool keepFavorites = true,
}) async { }) async {
final hasEdits = _db.assetEditEntity.id.isNotNull();
final iosSharedAlbumAssets = _db.localAlbumAssetEntity.selectOnly() final iosSharedAlbumAssets = _db.localAlbumAssetEntity.selectOnly()
..addColumns([_db.localAlbumAssetEntity.assetId]) ..addColumns([_db.localAlbumAssetEntity.assetId, hasEdits])
..join([ ..join([
innerJoin( innerJoin(
_db.localAlbumEntity, _db.localAlbumEntity,
@@ -165,7 +199,11 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
final query = _db.localAssetEntity.select().join([ final query = _db.localAssetEntity.select().join([
innerJoin(_db.remoteAssetEntity, _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum)), innerJoin(_db.remoteAssetEntity, _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum)),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]); ]);
Expression<bool> whereClause = Expression<bool> whereClause =
@@ -189,9 +227,7 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
query.where(whereClause); query.where(whereClause);
final rows = await query.get(); final rows = await query.get();
return rows return rows.map((row) => row.readTable(_db.localAssetEntity).toDto(isEdited: row.read(hasEdits)!)).toList();
.map((row) => row.readTable(_db.localAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null))
.toList();
} }
Future<List<LocalAsset>> getEmptyCloudIdAssets() { Future<List<LocalAsset>> getEmptyCloudIdAssets() {
@@ -12,9 +12,9 @@ class DriftMemoryRepository extends DriftDatabaseRepository {
Future<List<DriftMemory>> getAll(String ownerId) async { Future<List<DriftMemory>> getAll(String ownerId) async {
final now = DateTime.now(); final now = DateTime.now();
final localUtc = DateTime.utc(now.year, now.month, now.day, 0, 0, 0); final localUtc = DateTime.utc(now.year, now.month, now.day, 0, 0, 0);
final hasEdits = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.select(_db.memoryEntity).join([ _db.select(_db.memoryEntity).addColumns([hasEdits]).join([
innerJoin(_db.memoryAssetEntity, _db.memoryAssetEntity.memoryId.equalsExp(_db.memoryEntity.id)), innerJoin(_db.memoryAssetEntity, _db.memoryAssetEntity.memoryId.equalsExp(_db.memoryEntity.id)),
innerJoin( innerJoin(
_db.remoteAssetEntity, _db.remoteAssetEntity,
@@ -22,7 +22,11 @@ class DriftMemoryRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity.deletedAt.isNull() & _db.remoteAssetEntity.deletedAt.isNull() &
_db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline), _db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline),
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]) ])
..where(_db.memoryEntity.ownerId.equals(ownerId)) ..where(_db.memoryEntity.ownerId.equals(ownerId))
..where(_db.memoryEntity.deletedAt.isNull()) ..where(_db.memoryEntity.deletedAt.isNull())
@@ -43,9 +47,9 @@ class DriftMemoryRepository extends DriftDatabaseRepository {
final existingMemory = memoriesMap[memory.id]; final existingMemory = memoriesMap[memory.id];
if (existingMemory != null) { if (existingMemory != null) {
existingMemory.assets.add(asset.toDto(row.readTableOrNull(_db.assetEditEntity) != null)); existingMemory.assets.add(asset.toDto(isEdited: row.read(hasEdits)!));
} else { } else {
final assets = [asset.toDto(row.readTableOrNull(_db.assetEditEntity) != null)]; final assets = [asset.toDto(isEdited: row.read(hasEdits)!)];
memoriesMap[memory.id] = memory.toDto().copyWith(assets: assets); memoriesMap[memory.id] = memory.toDto().copyWith(assets: assets);
} }
} }
@@ -54,8 +58,9 @@ class DriftMemoryRepository extends DriftDatabaseRepository {
} }
Future<DriftMemory?> get(String memoryId) async { Future<DriftMemory?> get(String memoryId) async {
final hasEdits = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.select(_db.memoryEntity).join([ _db.select(_db.memoryEntity).addColumns([hasEdits]).join([
leftOuterJoin(_db.memoryAssetEntity, _db.memoryAssetEntity.memoryId.equalsExp(_db.memoryEntity.id)), leftOuterJoin(_db.memoryAssetEntity, _db.memoryAssetEntity.memoryId.equalsExp(_db.memoryEntity.id)),
leftOuterJoin( leftOuterJoin(
_db.remoteAssetEntity, _db.remoteAssetEntity,
@@ -63,7 +68,11 @@ class DriftMemoryRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity.deletedAt.isNull() & _db.remoteAssetEntity.deletedAt.isNull() &
_db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline), _db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline),
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]) ])
..where(_db.memoryEntity.id.equals(memoryId)) ..where(_db.memoryEntity.id.equals(memoryId))
..where(_db.memoryEntity.deletedAt.isNull()) ..where(_db.memoryEntity.deletedAt.isNull())
@@ -80,7 +89,7 @@ class DriftMemoryRepository extends DriftDatabaseRepository {
for (final row in rows) { for (final row in rows) {
final asset = row.readTable(_db.remoteAssetEntity); final asset = row.readTable(_db.remoteAssetEntity);
assets.add(asset.toDto(row.readTableOrNull(_db.assetEditEntity) != null)); assets.add(asset.toDto(isEdited: row.read(hasEdits)!));
} }
return memory.toDto().copyWith(assets: assets); return memory.toDto().copyWith(assets: assets);
@@ -231,14 +231,17 @@ class DriftRemoteAlbumRepository extends DriftDatabaseRepository {
} }
Future<List<RemoteAsset>> getAssets(String albumId) { Future<List<RemoteAsset>> getAssets(String albumId) {
final query = _db.remoteAlbumAssetEntity.select().join([ final isEdited = _db.assetEditEntity.id.isNotNull();
final query = _db.remoteAlbumAssetEntity.select().addColumns([isEdited]).join([
innerJoin(_db.remoteAssetEntity, _db.remoteAssetEntity.id.equalsExp(_db.remoteAlbumAssetEntity.assetId)), innerJoin(_db.remoteAssetEntity, _db.remoteAssetEntity.id.equalsExp(_db.remoteAlbumAssetEntity.assetId)),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
])..where(_db.remoteAlbumAssetEntity.albumId.equals(albumId)); ])..where(_db.remoteAlbumAssetEntity.albumId.equals(albumId));
return query return query.map((row) => row.readTable(_db.remoteAssetEntity).toDto(isEdited: row.read(isEdited)!)).get();
.map((row) => row.readTable(_db.remoteAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null))
.get();
} }
Future<int> addAssets(String albumId, List<String> assetIds) async { Future<int> addAssets(String albumId, List<String> assetIds) async {
@@ -17,9 +17,15 @@ class RemoteAssetRepository extends DriftDatabaseRepository {
/// For testing purposes /// For testing purposes
Future<List<RemoteAsset>> getSome(String userId) { Future<List<RemoteAsset>> getSome(String userId) {
final isEdited = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.remoteAssetEntity.select().join([ _db.remoteAssetEntity.select().addColumns([isEdited]).join([
leftOuterJoin(_db.assetEditEntity, _db.remoteAssetEntity.id.equalsExp(_db.assetEditEntity.assetId)), leftOuterJoin(
_db.assetEditEntity,
_db.remoteAssetEntity.id.equalsExp(_db.assetEditEntity.assetId),
useColumns: false,
),
]) ])
..where( ..where(
_db.remoteAssetEntity.ownerId.equals(userId) & _db.remoteAssetEntity.ownerId.equals(userId) &
@@ -29,27 +35,29 @@ class RemoteAssetRepository extends DriftDatabaseRepository {
..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)]) ..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)])
..limit(10); ..limit(10);
return query return query.map((row) => row.readTable(_db.remoteAssetEntity).toDto(isEdited: row.read(isEdited)!)).get();
.map((row) => row.readTable(_db.remoteAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null))
.get();
} }
SingleOrNullSelectable<RemoteAsset?> _assetSelectable(String id) { SingleOrNullSelectable<RemoteAsset?> _assetSelectable(String id) {
final hasEdits = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.remoteAssetEntity.select().addColumns([_db.localAssetEntity.id]).join([ _db.remoteAssetEntity.select().addColumns([_db.localAssetEntity.id, hasEdits]).join([
leftOuterJoin( leftOuterJoin(
_db.localAssetEntity, _db.localAssetEntity,
_db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum), _db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum),
useColumns: false, useColumns: false,
), ),
leftOuterJoin(_db.assetEditEntity, _db.remoteAssetEntity.id.equalsExp(_db.assetEditEntity.assetId)), leftOuterJoin(
_db.assetEditEntity,
_db.remoteAssetEntity.id.equalsExp(_db.assetEditEntity.assetId),
useColumns: false,
),
]) ])
..where(_db.remoteAssetEntity.id.equals(id)) ..where(_db.remoteAssetEntity.id.equals(id))
..limit(1); ..limit(1);
return query.map((row) { return query.map((row) {
final isEdited = row.readTableOrNull(_db.assetEditEntity) != null; final asset = row.readTable(_db.remoteAssetEntity).toDto(isEdited: row.read(hasEdits)!);
final asset = row.readTable(_db.remoteAssetEntity).toDto(isEdited);
return asset.copyWith(localId: row.read(_db.localAssetEntity.id)); return asset.copyWith(localId: row.read(_db.localAssetEntity.id));
}); });
} }
@@ -63,12 +71,18 @@ class RemoteAssetRepository extends DriftDatabaseRepository {
} }
Future<RemoteAsset?> getByChecksum(String checksum) { Future<RemoteAsset?> getByChecksum(String checksum) {
final query = _db.remoteAssetEntity.select().join([ final isEdited = _db.assetEditEntity.id.isNotNull();
leftOuterJoin(_db.assetEditEntity, _db.remoteAssetEntity.id.equalsExp(_db.assetEditEntity.assetId)),
final query = _db.remoteAssetEntity.select().addColumns([isEdited]).join([
leftOuterJoin(
_db.assetEditEntity,
_db.remoteAssetEntity.id.equalsExp(_db.assetEditEntity.assetId),
useColumns: false,
),
])..where(_db.remoteAssetEntity.checksum.equals(checksum)); ])..where(_db.remoteAssetEntity.checksum.equals(checksum));
return query return query
.map((row) => row.readTable(_db.remoteAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null)) .map((row) => row.readTable(_db.remoteAssetEntity).toDto(isEdited: row.read(isEdited)!))
.getSingleOrNull(); .getSingleOrNull();
} }
@@ -78,16 +92,20 @@ class RemoteAssetRepository extends DriftDatabaseRepository {
return Future.value(const []); return Future.value(const []);
} }
final isEdited = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.remoteAssetEntity.select().join([ _db.remoteAssetEntity.select().addColumns([isEdited]).join([
leftOuterJoin(_db.assetEditEntity, _db.remoteAssetEntity.id.equalsExp(_db.assetEditEntity.assetId)), leftOuterJoin(
_db.assetEditEntity,
_db.remoteAssetEntity.id.equalsExp(_db.assetEditEntity.assetId),
useColumns: false,
),
]) ])
..where(_db.remoteAssetEntity.stackId.equals(stackId) & _db.remoteAssetEntity.id.equals(asset.id).not()) ..where(_db.remoteAssetEntity.stackId.equals(stackId) & _db.remoteAssetEntity.id.equals(asset.id).not())
..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)]); ..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)]);
return query return query.map((row) => row.readTable(_db.remoteAssetEntity).toDto(isEdited: row.read(isEdited)!)).get();
.map((row) => row.readTable(_db.remoteAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null))
.get();
} }
Future<ExifInfo?> getExif(String id) { Future<ExifInfo?> getExif(String id) {
@@ -138,6 +138,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
} }
Future<List<BaseAsset>> _getLocalAlbumBucketAssets(String albumId, {required int offset, required int count}) { Future<List<BaseAsset>> _getLocalAlbumBucketAssets(String albumId, {required int offset, required int count}) {
final isEdited = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.localAssetEntity.select().join([ _db.localAssetEntity.select().join([
innerJoin( innerJoin(
@@ -150,9 +151,13 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum), _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum),
useColumns: false, useColumns: false,
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]) ])
..addColumns([_db.remoteAssetEntity.id]) ..addColumns([_db.remoteAssetEntity.id, isEdited])
..where(_db.localAlbumAssetEntity.albumId.equals(albumId)) ..where(_db.localAlbumAssetEntity.albumId.equals(albumId))
..orderBy([OrderingTerm.desc(_db.localAssetEntity.createdAt)]) ..orderBy([OrderingTerm.desc(_db.localAssetEntity.createdAt)])
..limit(count, offset: offset); ..limit(count, offset: offset);
@@ -161,7 +166,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
.map( .map(
(row) => row (row) => row
.readTable(_db.localAssetEntity) .readTable(_db.localAssetEntity)
.toDto(row.readTableOrNull(_db.assetEditEntity) != null, remoteId: row.read(_db.remoteAssetEntity.id)), .toDto(isEdited: row.read(isEdited)!, remoteId: row.read(_db.remoteAssetEntity.id)),
) )
.get(); .get();
} }
@@ -231,8 +236,9 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
} }
final isAscending = albumData.order == AlbumAssetOrder.asc; final isAscending = albumData.order == AlbumAssetOrder.asc;
final isEdited = _db.assetEditEntity.id.isNotNull();
final query = _db.remoteAssetEntity.select().addColumns([_db.localAssetEntity.id]).join([ final query = _db.remoteAssetEntity.select().addColumns([_db.localAssetEntity.id, isEdited]).join([
innerJoin( innerJoin(
_db.remoteAlbumAssetEntity, _db.remoteAlbumAssetEntity,
_db.remoteAlbumAssetEntity.assetId.equalsExp(_db.remoteAssetEntity.id), _db.remoteAlbumAssetEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
@@ -243,7 +249,11 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum), _db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum),
useColumns: false, useColumns: false,
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
])..where(_db.remoteAssetEntity.deletedAt.isNull() & _db.remoteAlbumAssetEntity.albumId.equals(albumId)); ])..where(_db.remoteAssetEntity.deletedAt.isNull() & _db.remoteAlbumAssetEntity.albumId.equals(albumId));
if (isAscending) { if (isAscending) {
@@ -258,7 +268,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
.map( .map(
(row) => row (row) => row
.readTable(_db.remoteAssetEntity) .readTable(_db.remoteAssetEntity)
.toDto(row.readTableOrNull(_db.assetEditEntity) != null, localId: row.read(_db.localAssetEntity.id)), .toDto(isEdited: row.read(isEdited)!, localId: row.read(_db.localAssetEntity.id)),
) )
.get(); .get();
} }
@@ -381,6 +391,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
} }
Future<List<BaseAsset>> _getPlaceBucketAssets(String place, {required int offset, required int count}) { Future<List<BaseAsset>> _getPlaceBucketAssets(String place, {required int offset, required int count}) {
final isEdited = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.remoteAssetEntity.select().join([ _db.remoteAssetEntity.select().join([
innerJoin( innerJoin(
@@ -388,8 +399,13 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
_db.remoteExifEntity.assetId.equalsExp(_db.remoteAssetEntity.id), _db.remoteExifEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false, useColumns: false,
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]) ])
..addColumns([isEdited])
..where( ..where(
_db.remoteAssetEntity.deletedAt.isNull() & _db.remoteAssetEntity.deletedAt.isNull() &
_db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline) & _db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline) &
@@ -397,9 +413,8 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
) )
..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)]) ..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)])
..limit(count, offset: offset); ..limit(count, offset: offset);
return query
.map((row) => row.readTable(_db.remoteAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null)) return query.map((row) => row.readTable(_db.remoteAssetEntity).toDto(isEdited: row.read(isEdited)!)).get();
.get();
} }
Stream<List<Bucket>> _watchPersonBucket(String userId, String personId, {GroupAssetsBy groupBy = GroupAssetsBy.day}) { Stream<List<Bucket>> _watchPersonBucket(String userId, String personId, {GroupAssetsBy groupBy = GroupAssetsBy.day}) {
@@ -460,6 +475,8 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
required int offset, required int offset,
required int count, required int count,
}) { }) {
final isEdited = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.remoteAssetEntity.select().join([ _db.remoteAssetEntity.select().join([
innerJoin( innerJoin(
@@ -467,7 +484,11 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
_db.assetFaceEntity.assetId.equalsExp(_db.remoteAssetEntity.id), _db.assetFaceEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false, useColumns: false,
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]) ])
..where( ..where(
_db.remoteAssetEntity.deletedAt.isNull() & _db.remoteAssetEntity.deletedAt.isNull() &
@@ -475,12 +496,11 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline) & _db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline) &
_db.assetFaceEntity.personId.equals(personId), _db.assetFaceEntity.personId.equals(personId),
) )
..addColumns([isEdited])
..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)]) ..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)])
..limit(count, offset: offset); ..limit(count, offset: offset);
return query return query.map((row) => row.readTable(_db.remoteAssetEntity).toDto(isEdited: row.read(isEdited)!)).get();
.map((row) => row.readTable(_db.remoteAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null))
.get();
} }
TimelineQuery map(String userId, LatLngBounds bounds, GroupAssetsBy groupBy) => ( TimelineQuery map(String userId, LatLngBounds bounds, GroupAssetsBy groupBy) => (
@@ -533,6 +553,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
required int offset, required int offset,
required int count, required int count,
}) { }) {
final isEdited = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.remoteAssetEntity.select().join([ _db.remoteAssetEntity.select().join([
innerJoin( innerJoin(
@@ -540,7 +561,11 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
_db.remoteExifEntity.assetId.equalsExp(_db.remoteAssetEntity.id), _db.remoteExifEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false, useColumns: false,
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]) ])
..where( ..where(
_db.remoteAssetEntity.ownerId.equals(userId) & _db.remoteAssetEntity.ownerId.equals(userId) &
@@ -548,11 +573,11 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline) & _db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline) &
_db.remoteAssetEntity.deletedAt.isNull(), _db.remoteAssetEntity.deletedAt.isNull(),
) )
..addColumns([isEdited])
..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)]) ..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)])
..limit(count, offset: offset); ..limit(count, offset: offset);
return query
.map((row) => row.readTable(_db.remoteAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null)) return query.map((row) => row.readTable(_db.remoteAssetEntity).toDto(isEdited: row.read(isEdited)!)).get();
.get();
} }
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -603,6 +628,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
bool joinLocal = false, bool joinLocal = false,
}) { }) {
if (joinLocal) { if (joinLocal) {
final isEdited = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.remoteAssetEntity.select().join([ _db.remoteAssetEntity.select().join([
leftOuterJoin( leftOuterJoin(
@@ -610,9 +636,13 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
_db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum), _db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum),
useColumns: false, useColumns: false,
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
_db.assetEditEntity,
_db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
useColumns: false,
),
]) ])
..addColumns([_db.localAssetEntity.id]) ..addColumns([_db.localAssetEntity.id, isEdited])
..where(filter(_db.remoteAssetEntity)) ..where(filter(_db.remoteAssetEntity))
..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)]) ..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)])
..limit(count, offset: offset); ..limit(count, offset: offset);
@@ -621,21 +651,25 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
.map( .map(
(row) => row (row) => row
.readTable(_db.remoteAssetEntity) .readTable(_db.remoteAssetEntity)
.toDto(row.readTableOrNull(_db.assetEditEntity) != null, localId: row.read(_db.localAssetEntity.id)), .toDto(isEdited: row.read(isEdited)!, localId: row.read(_db.localAssetEntity.id)),
) )
.get(); .get();
} else { } else {
final isEdited = _db.assetEditEntity.id.isNotNull();
final query = final query =
_db.remoteAssetEntity.select().join([ _db.remoteAssetEntity.select().join([
leftOuterJoin(_db.assetEditEntity, _db.remoteAssetEntity.id.equalsExp(_db.assetEditEntity.assetId)), leftOuterJoin(
_db.assetEditEntity,
_db.remoteAssetEntity.id.equalsExp(_db.assetEditEntity.assetId),
useColumns: false,
),
]) ])
..addColumns([isEdited])
..where(filter(_db.remoteAssetEntity)) ..where(filter(_db.remoteAssetEntity))
..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)]) ..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)])
..limit(count, offset: offset); ..limit(count, offset: offset);
return query return query.map((row) => row.readTable(_db.remoteAssetEntity).toDto(isEdited: row.read(isEdited)!)).get();
.map((row) => row.readTable(_db.remoteAssetEntity).toDto(row.readTableOrNull(_db.assetEditEntity) != null))
.get();
} }
} }
} }
@@ -262,26 +262,31 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
Future<Map<String, List<LocalAsset>>> getToTrash() async { Future<Map<String, List<LocalAsset>>> getToTrash() async {
final result = <String, List<LocalAsset>>{}; final result = <String, List<LocalAsset>>{};
final hasEdits = _db.assetEditEntity.id.isNotNull();
final rows = final rows =
await (_db.select(_db.localAlbumAssetEntity).join([ await (_db.select(_db.localAlbumAssetEntity).join([
innerJoin(_db.localAlbumEntity, _db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id)), innerJoin(_db.localAlbumEntity, _db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id)),
innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)), innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)),
leftOuterJoin( leftOuterJoin(
_db.remoteAssetEntity, _db.remoteAssetEntity,
_db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum), _db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum),
), ),
leftOuterJoin(_db.assetEditEntity, _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id)), leftOuterJoin(
])..where( _db.assetEditEntity,
_db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected) & _db.assetEditEntity.assetId.equalsExp(_db.remoteAssetEntity.id),
_db.remoteAssetEntity.deletedAt.isNotNull(), useColumns: false,
)) ),
])
..addColumns([hasEdits])
..where(
_db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected) &
_db.remoteAssetEntity.deletedAt.isNotNull(),
))
.get(); .get();
for (final row in rows) { for (final row in rows) {
final albumId = row.readTable(_db.localAlbumAssetEntity).albumId; final albumId = row.readTable(_db.localAlbumAssetEntity).albumId;
final hasEdits = row.readTableOrNull(_db.assetEditEntity) != null; final asset = row.readTable(_db.localAssetEntity).toDto(isEdited: row.read(hasEdits)!);
final asset = row.readTable(_db.localAssetEntity).toDto(hasEdits);
(result[albumId] ??= <LocalAsset>[]).add(asset); (result[albumId] ??= <LocalAsset>[]).add(asset);
} }