diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDao.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDao.kt index 5873bea2d..92e94bbdd 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDao.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDao.kt @@ -120,16 +120,9 @@ class BookDtoDao( else -> b.ID.`in`(dsl.selectTempStrings()) } - // we can handle paging from the search results directly to reduce the sql query complexity - val (bookIdsPaged, pagingBySearch) = when { - bookIds.isNullOrEmpty() -> emptyList() to false - pageable.isPaged -> bookIds.drop(pageable.pageSize * pageable.pageNumber).take(pageable.pageSize) to true - else -> bookIds to false - } - val orderBy = pageable.sort.mapNotNull { - if (it.property == "relevance" && !bookIds.isNullOrEmpty()) b.ID.sortByValues(bookIdsPaged, it.isAscending) + if (it.property == "relevance" && !bookIds.isNullOrEmpty()) b.ID.sortByValues(bookIds, it.isAscending) else it.toSortField(sorts) } @@ -151,15 +144,12 @@ class BookDtoDao( .groupBy(b.ID), ) - // adjust temp table if we are paging by search results - if (pagingBySearch) dsl.insertTempStrings(batchSize, bookIdsPaged) - val dtos = selectBase(userId, selectReadListNumber) .where(conditions) .and(searchCondition) .apply { filterOnLibraryIds?.let { and(b.LIBRARY_ID.`in`(it)) } } .orderBy(orderBy) - .apply { if (!pagingBySearch && pageable.isPaged) limit(pageable.pageSize).offset(pageable.offset) } + .apply { if (pageable.isPaged) limit(pageable.pageSize).offset(pageable.offset) } .fetchAndMap() count to dtos diff --git a/komga/src/test/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDaoTest.kt b/komga/src/test/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDaoTest.kt index f183d1ce0..7cf69fba2 100644 --- a/komga/src/test/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDaoTest.kt +++ b/komga/src/test/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDaoTest.kt @@ -416,6 +416,60 @@ class BookDtoDaoTest( assertThat(found.map { it.name }).containsExactly("Batman", "Batman and Robin", "The incredible adventures of Batman, the man who is also a bat!") } + @Test + fun `given books when searching by term and sort order then results are ordered by sort order`() { + // given + seriesLifecycle.addBooks( + series, + listOf( + makeBook("Book 3", seriesId = series.id, libraryId = library.id), + makeBook("Book 1", seriesId = series.id, libraryId = library.id), + makeBook("Book 2", seriesId = series.id, libraryId = library.id), + ), + ) + + searchIndexLifecycle.rebuildIndex() + + // when + val found = bookDtoDao.findAll( + BookSearchWithReadProgress(searchTerm = "book"), + user.id, + UnpagedSorted(Sort.by("name")), + ).content + val pages = (0..2).map { + bookDtoDao.findAll( + BookSearchWithReadProgress(searchTerm = "book"), + user.id, + PageRequest.of(it, 1, Sort.by("name")), + ) + } + val page0 = bookDtoDao.findAll( + BookSearchWithReadProgress(searchTerm = "book"), + user.id, + PageRequest.of(0, 2, Sort.by("name")), + ) + val page1 = bookDtoDao.findAll( + BookSearchWithReadProgress(searchTerm = "book"), + user.id, + PageRequest.of(1, 2, Sort.by("name")), + ) + + // then + assertThat(found).hasSize(3) + assertThat(found.map { it.name }).containsExactly("Book 1", "Book 2", "Book 3") + + assertThat(pages).hasSize(3) + assertThat(pages.map { it.totalPages }).containsOnly(3) + assertThat(pages.map { it.totalElements }).containsOnly(3) + assertThat(pages.map { it.size }).containsOnly(1) + assertThat(pages.flatMap { it.content }.map { it.name }).containsExactly("Book 1", "Book 2", "Book 3") + + assertThat(page0).hasSize(2) + assertThat(page0.content.map { it.name }).containsExactly("Book 1", "Book 2") + assertThat(page1).hasSize(1) + assertThat(page1.content.map { it.name }).containsExactly("Book 3") + } + @Test fun `given books when searching by term with accent then results are matched accent insensitive`() { // given