feat(api): referential APIs accept multiple library_id for filtering

This commit is contained in:
Gauthier Roebroeck 2025-02-19 15:46:12 +08:00
parent 8b66308a5f
commit 4de763a7bf
3 changed files with 69 additions and 67 deletions

View file

@ -43,10 +43,10 @@ interface ReferentialRepository {
pageable: Pageable,
): Page<Author>
fun findAllAuthorsByNameAndLibrary(
fun findAllAuthorsByNameAndLibraries(
search: String?,
role: String?,
libraryId: String,
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author>
@ -77,8 +77,8 @@ interface ReferentialRepository {
fun findAllGenres(filterOnLibraryIds: Collection<String>?): Set<String>
fun findAllGenresByLibrary(
libraryId: String,
fun findAllGenresByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<String>
@ -89,8 +89,8 @@ interface ReferentialRepository {
fun findAllSeriesAndBookTags(filterOnLibraryIds: Collection<String>?): Set<String>
fun findAllSeriesAndBookTagsByLibrary(
libraryId: String,
fun findAllSeriesAndBookTagsByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<String>
@ -125,8 +125,8 @@ interface ReferentialRepository {
fun findAllLanguages(filterOnLibraryIds: Collection<String>?): Set<String>
fun findAllLanguagesByLibrary(
libraryId: String,
fun findAllLanguagesByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<String>
@ -142,8 +142,8 @@ interface ReferentialRepository {
pageable: Pageable,
): Page<String>
fun findAllPublishersByLibrary(
libraryId: String,
fun findAllPublishersByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<String>
@ -154,8 +154,8 @@ interface ReferentialRepository {
fun findAllAgeRatings(filterOnLibraryIds: Collection<String>?): Set<Int?>
fun findAllAgeRatingsByLibrary(
libraryId: String,
fun findAllAgeRatingsByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<Int?>
@ -166,8 +166,8 @@ interface ReferentialRepository {
fun findAllSeriesReleaseDates(filterOnLibraryIds: Collection<String>?): Set<LocalDate>
fun findAllSeriesReleaseDatesByLibrary(
libraryId: String,
fun findAllSeriesReleaseDatesByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<LocalDate>
@ -178,8 +178,8 @@ interface ReferentialRepository {
fun findAllSharingLabels(filterOnLibraryIds: Collection<String>?): Set<String>
fun findAllSharingLabelsByLibrary(
libraryId: String,
fun findAllSharingLabelsByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<String>

View file

@ -109,13 +109,13 @@ class ReferentialDao(
pageable: Pageable,
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, null)
override fun findAllAuthorsByNameAndLibrary(
override fun findAllAuthorsByNameAndLibraries(
search: String?,
role: String?,
libraryId: String,
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.LIBRARY, libraryId))
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.LIBRARY, libraryIds))
override fun findAllAuthorsByNameAndCollection(
search: String?,
@ -123,7 +123,7 @@ class ReferentialDao(
collectionId: String,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.COLLECTION, collectionId))
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.COLLECTION, setOf(collectionId)))
override fun findAllAuthorsByNameAndSeries(
search: String?,
@ -131,7 +131,7 @@ class ReferentialDao(
seriesId: String,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.SERIES, seriesId))
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.SERIES, setOf(seriesId)))
override fun findAllAuthorsByNameAndReadList(
search: String?,
@ -139,7 +139,7 @@ class ReferentialDao(
readListId: String,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.READLIST, readListId))
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.READLIST, setOf(readListId)))
private enum class FilterByType {
LIBRARY,
@ -150,7 +150,7 @@ class ReferentialDao(
private data class FilterBy(
val type: FilterByType,
val id: String,
val ids: Set<String>,
)
private fun findAuthorsByName(
@ -179,10 +179,10 @@ class ReferentialDao(
.apply {
filterBy?.let {
when (it.type) {
FilterByType.LIBRARY -> and(s.LIBRARY_ID.eq(it.id))
FilterByType.COLLECTION -> and(cs.COLLECTION_ID.eq(it.id))
FilterByType.SERIES -> and(bmaa.SERIES_ID.eq(it.id))
FilterByType.READLIST -> and(rb.READLIST_ID.eq(it.id))
FilterByType.LIBRARY -> and(s.LIBRARY_ID.`in`(it.ids))
FilterByType.COLLECTION -> and(cs.COLLECTION_ID.`in`(it.ids))
FilterByType.SERIES -> and(bmaa.SERIES_ID.`in`(it.ids))
FilterByType.READLIST -> and(rb.READLIST_ID.`in`(it.ids))
}
}
}
@ -247,8 +247,8 @@ class ReferentialDao(
}.orderBy(g.GENRE.collate(SqliteUdfDataSource.COLLATION_UNICODE_3))
.fetchSet(g.GENRE)
override fun findAllGenresByLibrary(
libraryId: String,
override fun findAllGenresByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<String> =
dsl
@ -256,7 +256,7 @@ class ReferentialDao(
.from(g)
.leftJoin(s)
.on(g.SERIES_ID.eq(s.ID))
.where(s.LIBRARY_ID.eq(libraryId))
.where(s.LIBRARY_ID.`in`(libraryIds))
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
.orderBy(g.GENRE.collate(SqliteUdfDataSource.COLLATION_UNICODE_3))
.fetchSet(g.GENRE)
@ -289,8 +289,8 @@ class ReferentialDao(
.sortedBy { it.stripAccents().lowercase() }
.toSet()
override fun findAllSeriesAndBookTagsByLibrary(
libraryId: String,
override fun findAllSeriesAndBookTagsByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<String> =
dsl
@ -298,14 +298,14 @@ class ReferentialDao(
.from(bt)
.leftJoin(b)
.on(bt.BOOK_ID.eq(b.ID))
.where(b.LIBRARY_ID.eq(libraryId))
.where(b.LIBRARY_ID.`in`(libraryIds))
.apply { filterOnLibraryIds?.let { and(b.LIBRARY_ID.`in`(it)) } }
.union(
select(st.TAG.`as`("tag"))
.from(st)
.leftJoin(s)
.on(st.SERIES_ID.eq(s.ID))
.where(s.LIBRARY_ID.eq(libraryId))
.where(s.LIBRARY_ID.`in`(libraryIds))
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } },
).fetchSet(0, String::class.java)
.sortedBy { it.stripAccents().lowercase() }
@ -419,8 +419,8 @@ class ReferentialDao(
.on(bt.BOOK_ID.eq(b.ID))
.where(b.LIBRARY_ID.`in`(it))
}
}.orderBy(st.TAG.collate(SqliteUdfDataSource.COLLATION_UNICODE_3))
.fetchSet(st.TAG)
}.orderBy(bt.TAG.collate(SqliteUdfDataSource.COLLATION_UNICODE_3))
.fetchSet(bt.TAG)
override fun findAllLanguages(filterOnLibraryIds: Collection<String>?): Set<String> =
dsl
@ -432,8 +432,8 @@ class ReferentialDao(
.orderBy(sd.LANGUAGE)
.fetchSet(sd.LANGUAGE)
override fun findAllLanguagesByLibrary(
libraryId: String,
override fun findAllLanguagesByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<String> =
dsl
@ -442,7 +442,7 @@ class ReferentialDao(
.leftJoin(s)
.on(sd.SERIES_ID.eq(s.ID))
.where(sd.LANGUAGE.ne(""))
.and(s.LIBRARY_ID.eq(libraryId))
.and(s.LIBRARY_ID.`in`(libraryIds))
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
.orderBy(sd.LANGUAGE)
.fetchSet(sd.LANGUAGE)
@ -505,8 +505,8 @@ class ReferentialDao(
)
}
override fun findAllPublishersByLibrary(
libraryId: String,
override fun findAllPublishersByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<String> =
dsl
@ -515,7 +515,7 @@ class ReferentialDao(
.leftJoin(s)
.on(sd.SERIES_ID.eq(s.ID))
.where(sd.PUBLISHER.ne(""))
.and(s.LIBRARY_ID.eq(libraryId))
.and(s.LIBRARY_ID.`in`(libraryIds))
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
.orderBy(sd.PUBLISHER.collate(SqliteUdfDataSource.COLLATION_UNICODE_3))
.fetchSet(sd.PUBLISHER)
@ -549,8 +549,8 @@ class ReferentialDao(
}.orderBy(sd.AGE_RATING)
.fetchSet(sd.AGE_RATING)
override fun findAllAgeRatingsByLibrary(
libraryId: String,
override fun findAllAgeRatingsByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<Int?> =
dsl
@ -558,7 +558,7 @@ class ReferentialDao(
.from(sd)
.leftJoin(s)
.on(sd.SERIES_ID.eq(s.ID))
.where(s.LIBRARY_ID.eq(libraryId))
.where(s.LIBRARY_ID.`in`(libraryIds))
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
.orderBy(sd.AGE_RATING)
.fetchSet(sd.AGE_RATING)
@ -588,8 +588,8 @@ class ReferentialDao(
.orderBy(bma.RELEASE_DATE.desc())
.fetchSet(bma.RELEASE_DATE)
override fun findAllSeriesReleaseDatesByLibrary(
libraryId: String,
override fun findAllSeriesReleaseDatesByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<LocalDate> =
dsl
@ -597,7 +597,7 @@ class ReferentialDao(
.from(bma)
.leftJoin(s)
.on(bma.SERIES_ID.eq(s.ID))
.where(s.LIBRARY_ID.eq(libraryId))
.where(s.LIBRARY_ID.`in`(libraryIds))
.and(bma.RELEASE_DATE.isNotNull)
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
.orderBy(bma.RELEASE_DATE.desc())
@ -632,8 +632,8 @@ class ReferentialDao(
}.orderBy(sl.LABEL.collate(SqliteUdfDataSource.COLLATION_UNICODE_3))
.fetchSet(sl.LABEL)
override fun findAllSharingLabelsByLibrary(
libraryId: String,
override fun findAllSharingLabelsByLibraries(
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
): Set<String> =
dsl
@ -641,7 +641,7 @@ class ReferentialDao(
.from(sl)
.leftJoin(s)
.on(sl.SERIES_ID.eq(s.ID))
.where(s.LIBRARY_ID.eq(libraryId))
.where(s.LIBRARY_ID.`in`(libraryIds))
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
.orderBy(sl.LABEL.collate(SqliteUdfDataSource.COLLATION_UNICODE_3))
.fetchSet(sl.LABEL)

View file

@ -50,7 +50,7 @@ class ReferentialController(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestParam(name = "search", required = false) search: String?,
@RequestParam(name = "role", required = false) role: String?,
@RequestParam(name = "library_id", required = false) libraryId: String?,
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
@RequestParam(name = "collection_id", required = false) collectionId: String?,
@RequestParam(name = "series_id", required = false) seriesId: String?,
@RequestParam(name = "readlist_id", required = false) readListId: String?,
@ -67,7 +67,7 @@ class ReferentialController(
)
return when {
libraryId != null -> referentialRepository.findAllAuthorsByNameAndLibrary(search, role, libraryId, principal.user.getAuthorizedLibraryIds(null), pageRequest)
libraryIds.isNotEmpty() -> referentialRepository.findAllAuthorsByNameAndLibraries(search, role, libraryIds, principal.user.getAuthorizedLibraryIds(null), pageRequest)
collectionId != null -> referentialRepository.findAllAuthorsByNameAndCollection(search, role, collectionId, principal.user.getAuthorizedLibraryIds(null), pageRequest)
seriesId != null -> referentialRepository.findAllAuthorsByNameAndSeries(search, role, seriesId, principal.user.getAuthorizedLibraryIds(null), pageRequest)
readListId != null -> referentialRepository.findAllAuthorsByNameAndReadList(search, role, readListId, principal.user.getAuthorizedLibraryIds(null), pageRequest)
@ -92,11 +92,11 @@ class ReferentialController(
@Operation(summary = "List genres", description = "Can be filtered by various criteria")
fun getGenres(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestParam(name = "library_id", required = false) libraryId: String?,
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
@RequestParam(name = "collection_id", required = false) collectionId: String?,
): Set<String> =
when {
libraryId != null -> referentialRepository.findAllGenresByLibrary(libraryId, principal.user.getAuthorizedLibraryIds(null))
libraryIds.isNotEmpty() -> referentialRepository.findAllGenresByLibraries(libraryIds, principal.user.getAuthorizedLibraryIds(null))
collectionId != null -> referentialRepository.findAllGenresByCollection(collectionId, principal.user.getAuthorizedLibraryIds(null))
else -> referentialRepository.findAllGenres(principal.user.getAuthorizedLibraryIds(null))
}
@ -105,11 +105,11 @@ class ReferentialController(
@Operation(summary = "List sharing labels", description = "Can be filtered by various criteria")
fun getSharingLabels(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestParam(name = "library_id", required = false) libraryId: String?,
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
@RequestParam(name = "collection_id", required = false) collectionId: String?,
): Set<String> =
when {
libraryId != null -> referentialRepository.findAllSharingLabelsByLibrary(libraryId, principal.user.getAuthorizedLibraryIds(null))
libraryIds.isNotEmpty() -> referentialRepository.findAllSharingLabelsByLibraries(libraryIds, principal.user.getAuthorizedLibraryIds(null))
collectionId != null -> referentialRepository.findAllSharingLabelsByCollection(collectionId, principal.user.getAuthorizedLibraryIds(null))
else -> referentialRepository.findAllSharingLabels(principal.user.getAuthorizedLibraryIds(null))
}
@ -118,11 +118,11 @@ class ReferentialController(
@Operation(summary = "List tags", description = "Can be filtered by various criteria")
fun getTags(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestParam(name = "library_id", required = false) libraryId: String?,
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
@RequestParam(name = "collection_id", required = false) collectionId: String?,
): Set<String> =
when {
libraryId != null -> referentialRepository.findAllSeriesAndBookTagsByLibrary(libraryId, principal.user.getAuthorizedLibraryIds(null))
libraryIds.isNotEmpty() -> referentialRepository.findAllSeriesAndBookTagsByLibraries(libraryIds, principal.user.getAuthorizedLibraryIds(null))
collectionId != null -> referentialRepository.findAllSeriesAndBookTagsByCollection(collectionId, principal.user.getAuthorizedLibraryIds(null))
else -> referentialRepository.findAllSeriesAndBookTags(principal.user.getAuthorizedLibraryIds(null))
}
@ -133,10 +133,12 @@ class ReferentialController(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestParam(name = "series_id", required = false) seriesId: String?,
@RequestParam(name = "readlist_id", required = false) readListId: String?,
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
): Set<String> =
when {
seriesId != null -> referentialRepository.findAllBookTagsBySeries(seriesId, principal.user.getAuthorizedLibraryIds(null))
readListId != null -> referentialRepository.findAllBookTagsByReadList(readListId, principal.user.getAuthorizedLibraryIds(null))
libraryIds.isNotEmpty() -> referentialRepository.findAllBookTags(principal.user.getAuthorizedLibraryIds(libraryIds))
else -> referentialRepository.findAllBookTags(principal.user.getAuthorizedLibraryIds(null))
}
@ -157,11 +159,11 @@ class ReferentialController(
@Operation(summary = "List languages", description = "Can be filtered by various criteria")
fun getLanguages(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestParam(name = "library_id", required = false) libraryId: String?,
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
@RequestParam(name = "collection_id", required = false) collectionId: String?,
): Set<String> =
when {
libraryId != null -> referentialRepository.findAllLanguagesByLibrary(libraryId, principal.user.getAuthorizedLibraryIds(null))
libraryIds.isNotEmpty() -> referentialRepository.findAllLanguagesByLibraries(libraryIds, principal.user.getAuthorizedLibraryIds(null))
collectionId != null -> referentialRepository.findAllLanguagesByCollection(collectionId, principal.user.getAuthorizedLibraryIds(null))
else -> referentialRepository.findAllLanguages(principal.user.getAuthorizedLibraryIds(null))
}
@ -170,11 +172,11 @@ class ReferentialController(
@Operation(summary = "List publishers", description = "Can be filtered by various criteria")
fun getPublishers(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestParam(name = "library_id", required = false) libraryId: String?,
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
@RequestParam(name = "collection_id", required = false) collectionId: String?,
): Set<String> =
when {
libraryId != null -> referentialRepository.findAllPublishersByLibrary(libraryId, principal.user.getAuthorizedLibraryIds(null))
libraryIds.isNotEmpty() -> referentialRepository.findAllPublishersByLibraries(libraryIds, principal.user.getAuthorizedLibraryIds(null))
collectionId != null -> referentialRepository.findAllPublishersByCollection(collectionId, principal.user.getAuthorizedLibraryIds(null))
else -> referentialRepository.findAllPublishers(principal.user.getAuthorizedLibraryIds(null))
}
@ -183,11 +185,11 @@ class ReferentialController(
@Operation(summary = "List age ratings", description = "Can be filtered by various criteria")
fun getAgeRatings(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestParam(name = "library_id", required = false) libraryId: String?,
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
@RequestParam(name = "collection_id", required = false) collectionId: String?,
): Set<String> =
when {
libraryId != null -> referentialRepository.findAllAgeRatingsByLibrary(libraryId, principal.user.getAuthorizedLibraryIds(null))
libraryIds.isNotEmpty() -> referentialRepository.findAllAgeRatingsByLibraries(libraryIds, principal.user.getAuthorizedLibraryIds(null))
collectionId != null -> referentialRepository.findAllAgeRatingsByCollection(collectionId, principal.user.getAuthorizedLibraryIds(null))
else -> referentialRepository.findAllAgeRatings(principal.user.getAuthorizedLibraryIds(null))
}.map { it?.toString() ?: "None" }.toSet()
@ -196,11 +198,11 @@ class ReferentialController(
@Operation(summary = "List series release dates", description = "Can be filtered by various criteria")
fun getSeriesReleaseDates(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestParam(name = "library_id", required = false) libraryId: String?,
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
@RequestParam(name = "collection_id", required = false) collectionId: String?,
): Set<String> =
when {
libraryId != null -> referentialRepository.findAllSeriesReleaseDatesByLibrary(libraryId, principal.user.getAuthorizedLibraryIds(null))
libraryIds.isNotEmpty() -> referentialRepository.findAllSeriesReleaseDatesByLibraries(libraryIds, principal.user.getAuthorizedLibraryIds(null))
collectionId != null -> referentialRepository.findAllSeriesReleaseDatesByCollection(collectionId, principal.user.getAuthorizedLibraryIds(null))
else -> referentialRepository.findAllSeriesReleaseDates(principal.user.getAuthorizedLibraryIds(null))
}.map { it.year.toString() }.toSet()