From e4bc967a55d1b2a083cdb775fc7de3bca729e4f9 Mon Sep 17 00:00:00 2001 From: Gauthier Roebroeck Date: Thu, 12 Feb 2026 15:56:46 +0800 Subject: [PATCH] simplify authors querying --- .../org/gotson/komga/domain/model/FilterBy.kt | 13 +++ .../persistence/ReferentialRepository.kt | 39 ++------- .../jooq/main/ReferentialDao.kt | 82 ++++--------------- .../api/rest/ReferentialV2Controller.kt | 13 +-- 4 files changed, 43 insertions(+), 104 deletions(-) create mode 100644 komga/src/main/kotlin/org/gotson/komga/domain/model/FilterBy.kt diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/model/FilterBy.kt b/komga/src/main/kotlin/org/gotson/komga/domain/model/FilterBy.kt new file mode 100644 index 000000000..33cc8e2ea --- /dev/null +++ b/komga/src/main/kotlin/org/gotson/komga/domain/model/FilterBy.kt @@ -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, +) diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/persistence/ReferentialRepository.kt b/komga/src/main/kotlin/org/gotson/komga/domain/persistence/ReferentialRepository.kt index 898291281..16694a8eb 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/persistence/ReferentialRepository.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/persistence/ReferentialRepository.kt @@ -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?): List - fun findAllAuthorsByName( + fun findAuthors( + context: SearchContext, search: String?, role: String?, - filterOnLibraryIds: Collection?, - pageable: Pageable, - ): Page - - fun findAllAuthorsByNameAndLibraries( - search: String?, - role: String?, - libraryIds: Set, - filterOnLibraryIds: Collection?, - pageable: Pageable, - ): Page - - fun findAllAuthorsByNameAndCollection( - search: String?, - role: String?, - collectionId: String, - filterOnLibraryIds: Collection?, - pageable: Pageable, - ): Page - - fun findAllAuthorsByNameAndSeries( - search: String?, - role: String?, - seriesId: String, - filterOnLibraryIds: Collection?, - pageable: Pageable, - ): Page - - fun findAllAuthorsByNameAndReadList( - search: String?, - role: String?, - readListId: String, - filterOnLibraryIds: Collection?, + filterBy: FilterBy?, pageable: Pageable, ): Page diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/main/ReferentialDao.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/main/ReferentialDao.kt index a6b51911c..fa15685e0 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/main/ReferentialDao.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/main/ReferentialDao.kt @@ -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?, - pageable: Pageable, - ): Page = findAuthorsByName(search, role, filterOnLibraryIds, pageable, null) - - override fun findAllAuthorsByNameAndLibraries( - search: String?, - role: String?, - libraryIds: Set, - filterOnLibraryIds: Collection?, - pageable: Pageable, - ): Page = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.LIBRARY, libraryIds)) - - override fun findAllAuthorsByNameAndCollection( - search: String?, - role: String?, - collectionId: String, - filterOnLibraryIds: Collection?, - pageable: Pageable, - ): Page = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.COLLECTION, setOf(collectionId))) - - override fun findAllAuthorsByNameAndSeries( - search: String?, - role: String?, - seriesId: String, - filterOnLibraryIds: Collection?, - pageable: Pageable, - ): Page = findAuthorsByName(search, role, filterOnLibraryIds, pageable, FilterBy(FilterByType.SERIES, setOf(seriesId))) - - override fun findAllAuthorsByNameAndReadList( - search: String?, - role: String?, - readListId: String, - filterOnLibraryIds: Collection?, - pageable: Pageable, - ): Page = 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, - ) - - private fun findAuthorsByName( - search: String?, - role: String?, - filterOnLibraryIds: Collection?, - pageable: Pageable, filterBy: FilterBy?, + pageable: Pageable, ): Page { 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) diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/rest/ReferentialV2Controller.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/rest/ReferentialV2Controller.kt index 0d18e5fa2..82222a624 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/rest/ReferentialV2Controller.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/rest/ReferentialV2Controller.kt @@ -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() } } }