mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-01 02:17:43 +09:00 
			
		
		
		
	feat(server): Add album filter to search (#18985)
* - updated dtos - added inAlbums to search builder - only check isNotInAlbum if albumIds is blank/empty * - consider inAlbums as OR * - make open-api-dart * - lint & format * - remove inAlbums groupBy clause * - merge main open-api * - make open-api * - inAlbums filter AND instead of OR
This commit is contained in:
		
							
								
								
									
										11
									
								
								mobile/openapi/lib/model/metadata_search_dto.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								mobile/openapi/lib/model/metadata_search_dto.dart
									
									
									
										generated
									
									
									
								
							| @@ -13,6 +13,7 @@ part of openapi.api; | |||||||
| class MetadataSearchDto { | class MetadataSearchDto { | ||||||
|   /// Returns a new [MetadataSearchDto] instance. |   /// Returns a new [MetadataSearchDto] instance. | ||||||
|   MetadataSearchDto({ |   MetadataSearchDto({ | ||||||
|  |     this.albumIds = const [], | ||||||
|     this.checksum, |     this.checksum, | ||||||
|     this.city, |     this.city, | ||||||
|     this.country, |     this.country, | ||||||
| @@ -57,6 +58,8 @@ class MetadataSearchDto { | |||||||
|     this.withStacked, |     this.withStacked, | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|  |   List<String> albumIds; | ||||||
|  | 
 | ||||||
|   /// |   /// | ||||||
|   /// Please note: This property should have been non-nullable! Since the specification file |   /// Please note: This property should have been non-nullable! Since the specification file | ||||||
|   /// does not include a default value (using the "default:" property), however, the generated |   /// does not include a default value (using the "default:" property), however, the generated | ||||||
| @@ -346,6 +349,7 @@ class MetadataSearchDto { | |||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   bool operator ==(Object other) => identical(this, other) || other is MetadataSearchDto && |   bool operator ==(Object other) => identical(this, other) || other is MetadataSearchDto && | ||||||
|  |     _deepEquality.equals(other.albumIds, albumIds) && | ||||||
|     other.checksum == checksum && |     other.checksum == checksum && | ||||||
|     other.city == city && |     other.city == city && | ||||||
|     other.country == country && |     other.country == country && | ||||||
| @@ -392,6 +396,7 @@ class MetadataSearchDto { | |||||||
|   @override |   @override | ||||||
|   int get hashCode => |   int get hashCode => | ||||||
|     // ignore: unnecessary_parenthesis |     // ignore: unnecessary_parenthesis | ||||||
|  |     (albumIds.hashCode) + | ||||||
|     (checksum == null ? 0 : checksum!.hashCode) + |     (checksum == null ? 0 : checksum!.hashCode) + | ||||||
|     (city == null ? 0 : city!.hashCode) + |     (city == null ? 0 : city!.hashCode) + | ||||||
|     (country == null ? 0 : country!.hashCode) + |     (country == null ? 0 : country!.hashCode) + | ||||||
| @@ -436,10 +441,11 @@ class MetadataSearchDto { | |||||||
|     (withStacked == null ? 0 : withStacked!.hashCode); |     (withStacked == null ? 0 : withStacked!.hashCode); | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   String toString() => 'MetadataSearchDto[checksum=$checksum, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, description=$description, deviceAssetId=$deviceAssetId, deviceId=$deviceId, encodedVideoPath=$encodedVideoPath, id=$id, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, order=$order, originalFileName=$originalFileName, originalPath=$originalPath, page=$page, personIds=$personIds, previewPath=$previewPath, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, thumbnailPath=$thumbnailPath, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]'; |   String toString() => 'MetadataSearchDto[albumIds=$albumIds, checksum=$checksum, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, description=$description, deviceAssetId=$deviceAssetId, deviceId=$deviceId, encodedVideoPath=$encodedVideoPath, id=$id, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, order=$order, originalFileName=$originalFileName, originalPath=$originalPath, page=$page, personIds=$personIds, previewPath=$previewPath, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, thumbnailPath=$thumbnailPath, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]'; | ||||||
| 
 | 
 | ||||||
|   Map<String, dynamic> toJson() { |   Map<String, dynamic> toJson() { | ||||||
|     final json = <String, dynamic>{}; |     final json = <String, dynamic>{}; | ||||||
|  |       json[r'albumIds'] = this.albumIds; | ||||||
|     if (this.checksum != null) { |     if (this.checksum != null) { | ||||||
|       json[r'checksum'] = this.checksum; |       json[r'checksum'] = this.checksum; | ||||||
|     } else { |     } else { | ||||||
| @@ -650,6 +656,9 @@ class MetadataSearchDto { | |||||||
|       final json = value.cast<String, dynamic>(); |       final json = value.cast<String, dynamic>(); | ||||||
| 
 | 
 | ||||||
|       return MetadataSearchDto( |       return MetadataSearchDto( | ||||||
|  |         albumIds: json[r'albumIds'] is Iterable | ||||||
|  |             ? (json[r'albumIds'] as Iterable).cast<String>().toList(growable: false) | ||||||
|  |             : const [], | ||||||
|         checksum: mapValueOfType<String>(json, r'checksum'), |         checksum: mapValueOfType<String>(json, r'checksum'), | ||||||
|         city: mapValueOfType<String>(json, r'city'), |         city: mapValueOfType<String>(json, r'city'), | ||||||
|         country: mapValueOfType<String>(json, r'country'), |         country: mapValueOfType<String>(json, r'country'), | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								mobile/openapi/lib/model/random_search_dto.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								mobile/openapi/lib/model/random_search_dto.dart
									
									
									
										generated
									
									
									
								
							| @@ -13,6 +13,7 @@ part of openapi.api; | |||||||
| class RandomSearchDto { | class RandomSearchDto { | ||||||
|   /// Returns a new [RandomSearchDto] instance. |   /// Returns a new [RandomSearchDto] instance. | ||||||
|   RandomSearchDto({ |   RandomSearchDto({ | ||||||
|  |     this.albumIds = const [], | ||||||
|     this.city, |     this.city, | ||||||
|     this.country, |     this.country, | ||||||
|     this.createdAfter, |     this.createdAfter, | ||||||
| @@ -46,6 +47,8 @@ class RandomSearchDto { | |||||||
|     this.withStacked, |     this.withStacked, | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|  |   List<String> albumIds; | ||||||
|  | 
 | ||||||
|   String? city; |   String? city; | ||||||
| 
 | 
 | ||||||
|   String? country; |   String? country; | ||||||
| @@ -252,6 +255,7 @@ class RandomSearchDto { | |||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   bool operator ==(Object other) => identical(this, other) || other is RandomSearchDto && |   bool operator ==(Object other) => identical(this, other) || other is RandomSearchDto && | ||||||
|  |     _deepEquality.equals(other.albumIds, albumIds) && | ||||||
|     other.city == city && |     other.city == city && | ||||||
|     other.country == country && |     other.country == country && | ||||||
|     other.createdAfter == createdAfter && |     other.createdAfter == createdAfter && | ||||||
| @@ -287,6 +291,7 @@ class RandomSearchDto { | |||||||
|   @override |   @override | ||||||
|   int get hashCode => |   int get hashCode => | ||||||
|     // ignore: unnecessary_parenthesis |     // ignore: unnecessary_parenthesis | ||||||
|  |     (albumIds.hashCode) + | ||||||
|     (city == null ? 0 : city!.hashCode) + |     (city == null ? 0 : city!.hashCode) + | ||||||
|     (country == null ? 0 : country!.hashCode) + |     (country == null ? 0 : country!.hashCode) + | ||||||
|     (createdAfter == null ? 0 : createdAfter!.hashCode) + |     (createdAfter == null ? 0 : createdAfter!.hashCode) + | ||||||
| @@ -320,10 +325,11 @@ class RandomSearchDto { | |||||||
|     (withStacked == null ? 0 : withStacked!.hashCode); |     (withStacked == null ? 0 : withStacked!.hashCode); | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   String toString() => 'RandomSearchDto[city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, personIds=$personIds, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]'; |   String toString() => 'RandomSearchDto[albumIds=$albumIds, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, personIds=$personIds, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]'; | ||||||
| 
 | 
 | ||||||
|   Map<String, dynamic> toJson() { |   Map<String, dynamic> toJson() { | ||||||
|     final json = <String, dynamic>{}; |     final json = <String, dynamic>{}; | ||||||
|  |       json[r'albumIds'] = this.albumIds; | ||||||
|     if (this.city != null) { |     if (this.city != null) { | ||||||
|       json[r'city'] = this.city; |       json[r'city'] = this.city; | ||||||
|     } else { |     } else { | ||||||
| @@ -483,6 +489,9 @@ class RandomSearchDto { | |||||||
|       final json = value.cast<String, dynamic>(); |       final json = value.cast<String, dynamic>(); | ||||||
| 
 | 
 | ||||||
|       return RandomSearchDto( |       return RandomSearchDto( | ||||||
|  |         albumIds: json[r'albumIds'] is Iterable | ||||||
|  |             ? (json[r'albumIds'] as Iterable).cast<String>().toList(growable: false) | ||||||
|  |             : const [], | ||||||
|         city: mapValueOfType<String>(json, r'city'), |         city: mapValueOfType<String>(json, r'city'), | ||||||
|         country: mapValueOfType<String>(json, r'country'), |         country: mapValueOfType<String>(json, r'country'), | ||||||
|         createdAfter: mapDateTime(json, r'createdAfter', r''), |         createdAfter: mapDateTime(json, r'createdAfter', r''), | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								mobile/openapi/lib/model/smart_search_dto.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								mobile/openapi/lib/model/smart_search_dto.dart
									
									
									
										generated
									
									
									
								
							| @@ -13,6 +13,7 @@ part of openapi.api; | |||||||
| class SmartSearchDto { | class SmartSearchDto { | ||||||
|   /// Returns a new [SmartSearchDto] instance. |   /// Returns a new [SmartSearchDto] instance. | ||||||
|   SmartSearchDto({ |   SmartSearchDto({ | ||||||
|  |     this.albumIds = const [], | ||||||
|     this.city, |     this.city, | ||||||
|     this.country, |     this.country, | ||||||
|     this.createdAfter, |     this.createdAfter, | ||||||
| @@ -47,6 +48,8 @@ class SmartSearchDto { | |||||||
|     this.withExif, |     this.withExif, | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|  |   List<String> albumIds; | ||||||
|  | 
 | ||||||
|   String? city; |   String? city; | ||||||
| 
 | 
 | ||||||
|   String? country; |   String? country; | ||||||
| @@ -256,6 +259,7 @@ class SmartSearchDto { | |||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   bool operator ==(Object other) => identical(this, other) || other is SmartSearchDto && |   bool operator ==(Object other) => identical(this, other) || other is SmartSearchDto && | ||||||
|  |     _deepEquality.equals(other.albumIds, albumIds) && | ||||||
|     other.city == city && |     other.city == city && | ||||||
|     other.country == country && |     other.country == country && | ||||||
|     other.createdAfter == createdAfter && |     other.createdAfter == createdAfter && | ||||||
| @@ -292,6 +296,7 @@ class SmartSearchDto { | |||||||
|   @override |   @override | ||||||
|   int get hashCode => |   int get hashCode => | ||||||
|     // ignore: unnecessary_parenthesis |     // ignore: unnecessary_parenthesis | ||||||
|  |     (albumIds.hashCode) + | ||||||
|     (city == null ? 0 : city!.hashCode) + |     (city == null ? 0 : city!.hashCode) + | ||||||
|     (country == null ? 0 : country!.hashCode) + |     (country == null ? 0 : country!.hashCode) + | ||||||
|     (createdAfter == null ? 0 : createdAfter!.hashCode) + |     (createdAfter == null ? 0 : createdAfter!.hashCode) + | ||||||
| @@ -326,10 +331,11 @@ class SmartSearchDto { | |||||||
|     (withExif == null ? 0 : withExif!.hashCode); |     (withExif == null ? 0 : withExif!.hashCode); | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   String toString() => 'SmartSearchDto[city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, language=$language, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, page=$page, personIds=$personIds, query=$query, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif]'; |   String toString() => 'SmartSearchDto[albumIds=$albumIds, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, language=$language, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, page=$page, personIds=$personIds, query=$query, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif]'; | ||||||
| 
 | 
 | ||||||
|   Map<String, dynamic> toJson() { |   Map<String, dynamic> toJson() { | ||||||
|     final json = <String, dynamic>{}; |     final json = <String, dynamic>{}; | ||||||
|  |       json[r'albumIds'] = this.albumIds; | ||||||
|     if (this.city != null) { |     if (this.city != null) { | ||||||
|       json[r'city'] = this.city; |       json[r'city'] = this.city; | ||||||
|     } else { |     } else { | ||||||
| @@ -490,6 +496,9 @@ class SmartSearchDto { | |||||||
|       final json = value.cast<String, dynamic>(); |       final json = value.cast<String, dynamic>(); | ||||||
| 
 | 
 | ||||||
|       return SmartSearchDto( |       return SmartSearchDto( | ||||||
|  |         albumIds: json[r'albumIds'] is Iterable | ||||||
|  |             ? (json[r'albumIds'] as Iterable).cast<String>().toList(growable: false) | ||||||
|  |             : const [], | ||||||
|         city: mapValueOfType<String>(json, r'city'), |         city: mapValueOfType<String>(json, r'city'), | ||||||
|         country: mapValueOfType<String>(json, r'country'), |         country: mapValueOfType<String>(json, r'country'), | ||||||
|         createdAfter: mapDateTime(json, r'createdAfter', r''), |         createdAfter: mapDateTime(json, r'createdAfter', r''), | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								mobile/openapi/lib/model/statistics_search_dto.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								mobile/openapi/lib/model/statistics_search_dto.dart
									
									
									
										generated
									
									
									
								
							| @@ -13,6 +13,7 @@ part of openapi.api; | |||||||
| class StatisticsSearchDto { | class StatisticsSearchDto { | ||||||
|   /// Returns a new [StatisticsSearchDto] instance. |   /// Returns a new [StatisticsSearchDto] instance. | ||||||
|   StatisticsSearchDto({ |   StatisticsSearchDto({ | ||||||
|  |     this.albumIds = const [], | ||||||
|     this.city, |     this.city, | ||||||
|     this.country, |     this.country, | ||||||
|     this.createdAfter, |     this.createdAfter, | ||||||
| @@ -42,6 +43,8 @@ class StatisticsSearchDto { | |||||||
|     this.visibility, |     this.visibility, | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|  |   List<String> albumIds; | ||||||
|  | 
 | ||||||
|   String? city; |   String? city; | ||||||
| 
 | 
 | ||||||
|   String? country; |   String? country; | ||||||
| @@ -214,6 +217,7 @@ class StatisticsSearchDto { | |||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   bool operator ==(Object other) => identical(this, other) || other is StatisticsSearchDto && |   bool operator ==(Object other) => identical(this, other) || other is StatisticsSearchDto && | ||||||
|  |     _deepEquality.equals(other.albumIds, albumIds) && | ||||||
|     other.city == city && |     other.city == city && | ||||||
|     other.country == country && |     other.country == country && | ||||||
|     other.createdAfter == createdAfter && |     other.createdAfter == createdAfter && | ||||||
| @@ -245,6 +249,7 @@ class StatisticsSearchDto { | |||||||
|   @override |   @override | ||||||
|   int get hashCode => |   int get hashCode => | ||||||
|     // ignore: unnecessary_parenthesis |     // ignore: unnecessary_parenthesis | ||||||
|  |     (albumIds.hashCode) + | ||||||
|     (city == null ? 0 : city!.hashCode) + |     (city == null ? 0 : city!.hashCode) + | ||||||
|     (country == null ? 0 : country!.hashCode) + |     (country == null ? 0 : country!.hashCode) + | ||||||
|     (createdAfter == null ? 0 : createdAfter!.hashCode) + |     (createdAfter == null ? 0 : createdAfter!.hashCode) + | ||||||
| @@ -274,10 +279,11 @@ class StatisticsSearchDto { | |||||||
|     (visibility == null ? 0 : visibility!.hashCode); |     (visibility == null ? 0 : visibility!.hashCode); | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   String toString() => 'StatisticsSearchDto[city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, description=$description, deviceId=$deviceId, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, personIds=$personIds, rating=$rating, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility]'; |   String toString() => 'StatisticsSearchDto[albumIds=$albumIds, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, description=$description, deviceId=$deviceId, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, personIds=$personIds, rating=$rating, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility]'; | ||||||
| 
 | 
 | ||||||
|   Map<String, dynamic> toJson() { |   Map<String, dynamic> toJson() { | ||||||
|     final json = <String, dynamic>{}; |     final json = <String, dynamic>{}; | ||||||
|  |       json[r'albumIds'] = this.albumIds; | ||||||
|     if (this.city != null) { |     if (this.city != null) { | ||||||
|       json[r'city'] = this.city; |       json[r'city'] = this.city; | ||||||
|     } else { |     } else { | ||||||
| @@ -417,6 +423,9 @@ class StatisticsSearchDto { | |||||||
|       final json = value.cast<String, dynamic>(); |       final json = value.cast<String, dynamic>(); | ||||||
| 
 | 
 | ||||||
|       return StatisticsSearchDto( |       return StatisticsSearchDto( | ||||||
|  |         albumIds: json[r'albumIds'] is Iterable | ||||||
|  |             ? (json[r'albumIds'] as Iterable).cast<String>().toList(growable: false) | ||||||
|  |             : const [], | ||||||
|         city: mapValueOfType<String>(json, r'city'), |         city: mapValueOfType<String>(json, r'city'), | ||||||
|         country: mapValueOfType<String>(json, r'country'), |         country: mapValueOfType<String>(json, r'country'), | ||||||
|         createdAfter: mapDateTime(json, r'createdAfter', r''), |         createdAfter: mapDateTime(json, r'createdAfter', r''), | ||||||
|   | |||||||
| @@ -10866,6 +10866,13 @@ | |||||||
|       }, |       }, | ||||||
|       "MetadataSearchDto": { |       "MetadataSearchDto": { | ||||||
|         "properties": { |         "properties": { | ||||||
|  |           "albumIds": { | ||||||
|  |             "items": { | ||||||
|  |               "format": "uuid", | ||||||
|  |               "type": "string" | ||||||
|  |             }, | ||||||
|  |             "type": "array" | ||||||
|  |           }, | ||||||
|           "checksum": { |           "checksum": { | ||||||
|             "type": "string" |             "type": "string" | ||||||
|           }, |           }, | ||||||
| @@ -11785,6 +11792,13 @@ | |||||||
|       }, |       }, | ||||||
|       "RandomSearchDto": { |       "RandomSearchDto": { | ||||||
|         "properties": { |         "properties": { | ||||||
|  |           "albumIds": { | ||||||
|  |             "items": { | ||||||
|  |               "format": "uuid", | ||||||
|  |               "type": "string" | ||||||
|  |             }, | ||||||
|  |             "type": "array" | ||||||
|  |           }, | ||||||
|           "city": { |           "city": { | ||||||
|             "nullable": true, |             "nullable": true, | ||||||
|             "type": "string" |             "type": "string" | ||||||
| @@ -12833,6 +12847,13 @@ | |||||||
|       }, |       }, | ||||||
|       "SmartSearchDto": { |       "SmartSearchDto": { | ||||||
|         "properties": { |         "properties": { | ||||||
|  |           "albumIds": { | ||||||
|  |             "items": { | ||||||
|  |               "format": "uuid", | ||||||
|  |               "type": "string" | ||||||
|  |             }, | ||||||
|  |             "type": "array" | ||||||
|  |           }, | ||||||
|           "city": { |           "city": { | ||||||
|             "nullable": true, |             "nullable": true, | ||||||
|             "type": "string" |             "type": "string" | ||||||
| @@ -13029,6 +13050,13 @@ | |||||||
|       }, |       }, | ||||||
|       "StatisticsSearchDto": { |       "StatisticsSearchDto": { | ||||||
|         "properties": { |         "properties": { | ||||||
|  |           "albumIds": { | ||||||
|  |             "items": { | ||||||
|  |               "format": "uuid", | ||||||
|  |               "type": "string" | ||||||
|  |             }, | ||||||
|  |             "type": "array" | ||||||
|  |           }, | ||||||
|           "city": { |           "city": { | ||||||
|             "nullable": true, |             "nullable": true, | ||||||
|             "type": "string" |             "type": "string" | ||||||
|   | |||||||
| @@ -853,6 +853,7 @@ export type SearchExploreResponseDto = { | |||||||
|     items: SearchExploreItem[]; |     items: SearchExploreItem[]; | ||||||
| }; | }; | ||||||
| export type MetadataSearchDto = { | export type MetadataSearchDto = { | ||||||
|  |     albumIds?: string[]; | ||||||
|     checksum?: string; |     checksum?: string; | ||||||
|     city?: string | null; |     city?: string | null; | ||||||
|     country?: string | null; |     country?: string | null; | ||||||
| @@ -929,6 +930,7 @@ export type PlacesResponseDto = { | |||||||
|     name: string; |     name: string; | ||||||
| }; | }; | ||||||
| export type RandomSearchDto = { | export type RandomSearchDto = { | ||||||
|  |     albumIds?: string[]; | ||||||
|     city?: string | null; |     city?: string | null; | ||||||
|     country?: string | null; |     country?: string | null; | ||||||
|     createdAfter?: string; |     createdAfter?: string; | ||||||
| @@ -962,6 +964,7 @@ export type RandomSearchDto = { | |||||||
|     withStacked?: boolean; |     withStacked?: boolean; | ||||||
| }; | }; | ||||||
| export type SmartSearchDto = { | export type SmartSearchDto = { | ||||||
|  |     albumIds?: string[]; | ||||||
|     city?: string | null; |     city?: string | null; | ||||||
|     country?: string | null; |     country?: string | null; | ||||||
|     createdAfter?: string; |     createdAfter?: string; | ||||||
| @@ -996,6 +999,7 @@ export type SmartSearchDto = { | |||||||
|     withExif?: boolean; |     withExif?: boolean; | ||||||
| }; | }; | ||||||
| export type StatisticsSearchDto = { | export type StatisticsSearchDto = { | ||||||
|  |     albumIds?: string[]; | ||||||
|     city?: string | null; |     city?: string | null; | ||||||
|     country?: string | null; |     country?: string | null; | ||||||
|     createdAfter?: string; |     createdAfter?: string; | ||||||
|   | |||||||
| @@ -95,6 +95,9 @@ class BaseSearchDto { | |||||||
|   @ValidateUUID({ each: true, optional: true }) |   @ValidateUUID({ each: true, optional: true }) | ||||||
|   tagIds?: string[]; |   tagIds?: string[]; | ||||||
|  |  | ||||||
|  |   @ValidateUUID({ each: true, optional: true }) | ||||||
|  |   albumIds?: string[]; | ||||||
|  |  | ||||||
|   @Optional() |   @Optional() | ||||||
|   @IsInt() |   @IsInt() | ||||||
|   @Max(5) |   @Max(5) | ||||||
|   | |||||||
| @@ -91,6 +91,10 @@ export interface SearchTagOptions { | |||||||
|   tagIds?: string[]; |   tagIds?: string[]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export interface SearchAlbumOptions { | ||||||
|  |   albumIds?: string[]; | ||||||
|  | } | ||||||
|  |  | ||||||
| export interface SearchOrderOptions { | export interface SearchOrderOptions { | ||||||
|   orderDirection?: 'asc' | 'desc'; |   orderDirection?: 'asc' | 'desc'; | ||||||
| } | } | ||||||
| @@ -108,7 +112,8 @@ type BaseAssetSearchOptions = SearchDateOptions & | |||||||
|   SearchStatusOptions & |   SearchStatusOptions & | ||||||
|   SearchUserIdOptions & |   SearchUserIdOptions & | ||||||
|   SearchPeopleOptions & |   SearchPeopleOptions & | ||||||
|   SearchTagOptions; |   SearchTagOptions & | ||||||
|  |   SearchAlbumOptions; | ||||||
|  |  | ||||||
| export type AssetSearchOptions = BaseAssetSearchOptions & SearchRelationOptions; | export type AssetSearchOptions = BaseAssetSearchOptions & SearchRelationOptions; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -228,6 +228,20 @@ export function hasPeople<O>(qb: SelectQueryBuilder<DB, 'assets', O>, personIds: | |||||||
|   ); |   ); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export function inAlbums<O>(qb: SelectQueryBuilder<DB, 'assets', O>, albumIds: string[]) { | ||||||
|  |   return qb.innerJoin( | ||||||
|  |     (eb) => | ||||||
|  |       eb | ||||||
|  |         .selectFrom('albums_assets_assets') | ||||||
|  |         .select('assetsId') | ||||||
|  |         .where('albumsId', '=', anyUuid(albumIds!)) | ||||||
|  |         .groupBy('assetsId') | ||||||
|  |         .having((eb) => eb.fn.count('albumsId').distinct(), '=', albumIds.length) | ||||||
|  |         .as('has_album'), | ||||||
|  |     (join) => join.onRef('has_album.assetsId', '=', 'assets.id'), | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  |  | ||||||
| export function hasTags<O>(qb: SelectQueryBuilder<DB, 'assets', O>, tagIds: string[]) { | export function hasTags<O>(qb: SelectQueryBuilder<DB, 'assets', O>, tagIds: string[]) { | ||||||
|   return qb.innerJoin( |   return qb.innerJoin( | ||||||
|     (eb) => |     (eb) => | ||||||
| @@ -292,6 +306,7 @@ export function searchAssetBuilder(kysely: Kysely<DB>, options: AssetSearchBuild | |||||||
|     .withPlugin(joinDeduplicationPlugin) |     .withPlugin(joinDeduplicationPlugin) | ||||||
|     .selectFrom('assets') |     .selectFrom('assets') | ||||||
|     .where('assets.visibility', '=', visibility) |     .where('assets.visibility', '=', visibility) | ||||||
|  |     .$if(!!options.albumIds && options.albumIds.length > 0, (qb) => inAlbums(qb, options.albumIds!)) | ||||||
|     .$if(!!options.tagIds && options.tagIds.length > 0, (qb) => hasTags(qb, options.tagIds!)) |     .$if(!!options.tagIds && options.tagIds.length > 0, (qb) => hasTags(qb, options.tagIds!)) | ||||||
|     .$if(!!options.personIds && options.personIds.length > 0, (qb) => hasPeople(qb, options.personIds!)) |     .$if(!!options.personIds && options.personIds.length > 0, (qb) => hasPeople(qb, options.personIds!)) | ||||||
|     .$if(!!options.createdBefore, (qb) => qb.where('assets.createdAt', '<=', options.createdBefore!)) |     .$if(!!options.createdBefore, (qb) => qb.where('assets.createdAt', '<=', options.createdBefore!)) | ||||||
| @@ -368,7 +383,7 @@ export function searchAssetBuilder(kysely: Kysely<DB>, options: AssetSearchBuild | |||||||
|     .$if(options.isMotion !== undefined, (qb) => |     .$if(options.isMotion !== undefined, (qb) => | ||||||
|       qb.where('assets.livePhotoVideoId', options.isMotion ? 'is not' : 'is', null), |       qb.where('assets.livePhotoVideoId', options.isMotion ? 'is not' : 'is', null), | ||||||
|     ) |     ) | ||||||
|     .$if(!!options.isNotInAlbum, (qb) => |     .$if(!!options.isNotInAlbum && (!options.albumIds || options.albumIds.length === 0), (qb) => | ||||||
|       qb.where((eb) => |       qb.where((eb) => | ||||||
|         eb.not(eb.exists((eb) => eb.selectFrom('albums_assets_assets').whereRef('assetsId', '=', 'assets.id'))), |         eb.not(eb.exists((eb) => eb.selectFrom('albums_assets_assets').whereRef('assetsId', '=', 'assets.id'))), | ||||||
|       ), |       ), | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user