simplify authors querying

This commit is contained in:
Gauthier Roebroeck 2026-02-12 15:56:46 +08:00
parent 293ac415fa
commit e4bc967a55
4 changed files with 43 additions and 104 deletions

View file

@ -0,0 +1,13 @@
package org.gotson.komga.domain.model
enum class FilterByEntity {
LIBRARY,
COLLECTION,
SERIES,
READLIST,
}
data class FilterBy(
val type: FilterByEntity,
val ids: Set<String>,
)

View file

@ -1,6 +1,8 @@
package org.gotson.komga.domain.persistence
import org.gotson.komga.domain.model.Author
import org.gotson.komga.domain.model.FilterBy
import org.gotson.komga.domain.model.SearchContext
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import java.time.LocalDate
@ -36,42 +38,11 @@ interface ReferentialRepository {
fun findAllAuthorsRoles(filterOnLibraryIds: Collection<String>?): List<String>
fun findAllAuthorsByName(
fun findAuthors(
context: SearchContext,
search: String?,
role: String?,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author>
fun findAllAuthorsByNameAndLibraries(
search: String?,
role: String?,
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author>
fun findAllAuthorsByNameAndCollection(
search: String?,
role: String?,
collectionId: String,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author>
fun findAllAuthorsByNameAndSeries(
search: String?,
role: String?,
seriesId: String,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author>
fun findAllAuthorsByNameAndReadList(
search: String?,
role: String?,
readListId: String,
filterOnLibraryIds: Collection<String>?,
filterBy: FilterBy?,
pageable: Pageable,
): Page<Author>

View file

@ -1,9 +1,12 @@
package org.gotson.komga.infrastructure.jooq.main
import org.gotson.komga.domain.model.Author
import org.gotson.komga.domain.model.FilterBy
import org.gotson.komga.domain.model.FilterByEntity
import org.gotson.komga.domain.model.SearchContext
import org.gotson.komga.domain.persistence.ReferentialRepository
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
import org.gotson.komga.infrastructure.jooq.unicode1
import org.gotson.komga.infrastructure.jooq.udfStripAccents
import org.gotson.komga.infrastructure.jooq.unicode3
import org.gotson.komga.jooq.main.Tables
import org.gotson.komga.jooq.main.tables.records.BookMetadataAggregationAuthorRecord
@ -106,87 +109,36 @@ class ReferentialDao(
.fetchInto(bmaa)
.map { it.toDomain() }
override fun findAllAuthorsByName(
override fun findAuthors(
context: SearchContext,
search: String?,
role: String?,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, null)
override fun findAllAuthorsByNameAndLibraries(
search: String?,
role: String?,
libraryIds: Set<String>,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.LIBRARY, libraryIds))
override fun findAllAuthorsByNameAndCollection(
search: String?,
role: String?,
collectionId: String,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.COLLECTION, setOf(collectionId)))
override fun findAllAuthorsByNameAndSeries(
search: String?,
role: String?,
seriesId: String,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.SERIES, setOf(seriesId)))
override fun findAllAuthorsByNameAndReadList(
search: String?,
role: String?,
readListId: String,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
): Page<Author> = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.READLIST, setOf(readListId)))
private enum class FilterByType {
LIBRARY,
COLLECTION,
SERIES,
READLIST,
}
private data class FilterBy(
val type: FilterByType,
val ids: Set<String>,
)
private fun findAuthorsByName(
search: String?,
role: String?,
filterOnLibraryIds: Collection<String>?,
pageable: Pageable,
filterBy: FilterBy?,
pageable: Pageable,
): Page<Author> {
val query =
dslRO
.selectDistinct(bmaa.NAME, bmaa.ROLE)
.from(bmaa)
.apply { if (filterOnLibraryIds != null || filterBy?.type == FilterByType.LIBRARY) leftJoin(s).on(bmaa.SERIES_ID.eq(s.ID)) }
.apply { if (filterBy?.type == FilterByType.COLLECTION) leftJoin(cs).on(bmaa.SERIES_ID.eq(cs.SERIES_ID)) }
.apply { if (!context.libraryIds.isNullOrEmpty() || filterBy?.type == FilterByEntity.LIBRARY) leftJoin(s).on(bmaa.SERIES_ID.eq(s.ID)) }
.apply { if (filterBy?.type == FilterByEntity.COLLECTION) leftJoin(cs).on(bmaa.SERIES_ID.eq(cs.SERIES_ID)) }
.apply {
if (filterBy?.type == FilterByType.READLIST)
if (filterBy?.type == FilterByEntity.READLIST)
leftJoin(b)
.on(bmaa.SERIES_ID.eq(b.SERIES_ID))
.leftJoin(rb)
.on(b.ID.eq(rb.BOOK_ID))
}.where(noCondition())
.apply { search?.let { and(bmaa.NAME.unicode1().contains(search)) } }
.apply { search?.let { and(bmaa.NAME.udfStripAccents().contains(search.stripAccents())) } }
.apply { role?.let { and(bmaa.ROLE.eq(role)) } }
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
.apply { context.libraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
.apply {
filterBy?.let {
when (it.type) {
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))
FilterByEntity.LIBRARY -> and(s.LIBRARY_ID.`in`(it.ids))
FilterByEntity.COLLECTION -> and(cs.COLLECTION_ID.`in`(it.ids))
FilterByEntity.SERIES -> and(bmaa.SERIES_ID.`in`(it.ids))
FilterByEntity.READLIST -> and(rb.READLIST_ID.`in`(it.ids))
}
}
}
@ -201,7 +153,7 @@ class ReferentialDao(
.fetchInto(a)
.map { it.toDomain() }
val pageSort = Sort.by("relevance")
val pageSort = pageable.sort
return PageImpl(
items,
if (pageable.isPaged)

View file

@ -3,6 +3,9 @@ package org.gotson.komga.interfaces.api.rest
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.tags.Tag
import org.gotson.komga.domain.model.FilterBy
import org.gotson.komga.domain.model.FilterByEntity
import org.gotson.komga.domain.model.SearchContext
import org.gotson.komga.domain.persistence.ReferentialRepository
import org.gotson.komga.infrastructure.openapi.OpenApiConfiguration
import org.gotson.komga.infrastructure.openapi.PageableWithoutSortAsQueryParam
@ -49,11 +52,11 @@ class ReferentialV2Controller(
)
return when {
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)
else -> referentialRepository.findAllAuthorsByName(search, role, principal.user.getAuthorizedLibraryIds(null), pageRequest)
libraryIds.isNotEmpty() -> referentialRepository.findAuthors(SearchContext(principal.user), search, role, FilterBy(FilterByEntity.LIBRARY, libraryIds), pageRequest)
collectionId != null -> referentialRepository.findAuthors(SearchContext(principal.user), search, role, FilterBy(FilterByEntity.COLLECTION, setOf(collectionId)), pageRequest)
seriesId != null -> referentialRepository.findAuthors(SearchContext(principal.user), search, role, FilterBy(FilterByEntity.SERIES, setOf(seriesId)), pageRequest)
readListId != null -> referentialRepository.findAuthors(SearchContext(principal.user), search, role, FilterBy(FilterByEntity.READLIST, setOf(readListId)), pageRequest)
else -> referentialRepository.findAuthors(SearchContext(principal.user), search, role, null, pageRequest)
}.map { it.toDto() }
}
}