diff --git a/mobile/lib/infrastructure/entities/merged_asset.drift b/mobile/lib/infrastructure/entities/merged_asset.drift index 217a18b75c..2e08b6424a 100644 --- a/mobile/lib/infrastructure/entities/merged_asset.drift +++ b/mobile/lib/infrastructure/entities/merged_asset.drift @@ -90,8 +90,14 @@ FROM ( SELECT CASE - WHEN :group_by = 0 THEN STRFTIME('%Y-%m-%d', rae.local_date_time) - WHEN :group_by = 1 THEN STRFTIME('%Y-%m', rae.local_date_time) + WHEN :group_by = 0 THEN COALESCE( + STRFTIME('%Y-%m-%d', rae.local_date_time), + STRFTIME('%Y-%m-%d', rae.created_at, 'localtime') + ) + WHEN :group_by = 1 THEN COALESCE( + STRFTIME('%Y-%m', rae.local_date_time), + STRFTIME('%Y-%m', rae.created_at, 'localtime') + ) END as bucket_date FROM remote_asset_entity rae diff --git a/mobile/lib/infrastructure/entities/merged_asset.drift.dart b/mobile/lib/infrastructure/entities/merged_asset.drift.dart index cd2fe5cfcc..e88d11d442 100644 --- a/mobile/lib/infrastructure/entities/merged_asset.drift.dart +++ b/mobile/lib/infrastructure/entities/merged_asset.drift.dart @@ -79,7 +79,7 @@ class MergedAssetDrift extends i1.ModularAccessor { final expandeduserIds = $expandVar($arrayStartIndex, userIds.length); $arrayStartIndex += userIds.length; return customSelect( - 'SELECT COUNT(*) AS asset_count, bucket_date FROM (SELECT CASE WHEN ?1 = 0 THEN STRFTIME(\'%Y-%m-%d\', rae.local_date_time) WHEN ?1 = 1 THEN STRFTIME(\'%Y-%m\', rae.local_date_time) END AS bucket_date 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 CASE WHEN ?1 = 0 THEN STRFTIME(\'%Y-%m-%d\', lae.created_at, \'localtime\') WHEN ?1 = 1 THEN STRFTIME(\'%Y-%m\', lae.created_at, \'localtime\') END AS bucket_date 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, bucket_date FROM (SELECT CASE WHEN ?1 = 0 THEN COALESCE(STRFTIME(\'%Y-%m-%d\', rae.local_date_time), STRFTIME(\'%Y-%m-%d\', rae.created_at, \'localtime\')) WHEN ?1 = 1 THEN COALESCE(STRFTIME(\'%Y-%m\', rae.local_date_time), STRFTIME(\'%Y-%m\', rae.created_at, \'localtime\')) END AS bucket_date 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 CASE WHEN ?1 = 0 THEN STRFTIME(\'%Y-%m-%d\', lae.created_at, \'localtime\') WHEN ?1 = 1 THEN STRFTIME(\'%Y-%m\', lae.created_at, \'localtime\') END AS bucket_date 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(groupBy), for (var $ in userIds) i0.Variable($), diff --git a/mobile/test/infrastructure/repositories/merged_asset_drift_test.dart b/mobile/test/infrastructure/repositories/merged_asset_drift_test.dart new file mode 100644 index 0000000000..a25a9d92a7 --- /dev/null +++ b/mobile/test/infrastructure/repositories/merged_asset_drift_test.dart @@ -0,0 +1,51 @@ +import 'package:drift/drift.dart'; +import 'package:drift/native.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; +import 'package:immich_mobile/domain/models/timeline.model.dart'; +import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart'; +import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart'; +import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; + +void main() { + late Drift db; + + setUp(() { + db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true)); + }); + + tearDown(() async { + await db.close(); + }); + + test('mergedBucket falls back to createdAt when localDateTime is null', () async { + const userId = 'user-1'; + final createdAt = DateTime(2024, 1, 1, 12); + + await db + .into(db.userEntity) + .insert(UserEntityCompanion.insert(id: userId, email: 'user-1@test.dev', name: 'User 1')); + + await db + .into(db.remoteAssetEntity) + .insert( + RemoteAssetEntityCompanion.insert( + id: 'asset-1', + name: 'asset-1.jpg', + type: AssetType.image, + checksum: 'checksum-1', + ownerId: userId, + visibility: AssetVisibility.timeline, + createdAt: Value(createdAt), + updatedAt: Value(createdAt), + localDateTime: const Value(null), + ), + ); + + final buckets = await db.mergedAssetDrift.mergedBucket(groupBy: GroupAssetsBy.day.index, userIds: [userId]).get(); + + expect(buckets, hasLength(1)); + expect(buckets.single.assetCount, 1); + expect(buckets.single.bucketDate, isNotEmpty); + }); +}