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 1a274df70..ea6891614 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 @@ -206,11 +206,11 @@ class BookDtoDao( } override fun findAllDuplicates(userId: String, pageable: Pageable): Page { - val hashes = dsl.select(b.FILE_HASH, DSL.count(b.FILE_HASH)) + val hashes = dsl.select(b.FILE_HASH, DSL.count(b.ID)) .from(b) .where(b.FILE_HASH.ne("")) - .groupBy(b.FILE_HASH) - .having(DSL.count(b.FILE_HASH).gt(1)) + .groupBy(b.FILE_HASH, b.FILE_SIZE) + .having(DSL.count(b.ID).gt(1)) .fetch() .associate { it.value1() to it.value2() } 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 4c83502a9..83e47370e 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 @@ -37,6 +37,7 @@ import org.junit.jupiter.api.extension.ExtendWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.data.domain.PageRequest +import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort import org.springframework.test.context.junit.jupiter.SpringExtension import java.net.URL @@ -700,4 +701,44 @@ class BookDtoDaoTest( assertThat(found).hasSize(1) } } + + @Nested + inner class Duplicates { + @Test + fun `given books with same hash and size when searching then results are returned`() { + // given + seriesLifecycle.addBooks( + series, + listOf( + makeBook("Book 1", seriesId = series.id, libraryId = library.id).copy(fileHash = "hashed", fileSize = 10), + makeBook("Book 2", seriesId = series.id, libraryId = library.id).copy(fileHash = "hashed", fileSize = 10), + ), + ) + + // when + val found = bookDtoDao.findAllDuplicates(user.id, Pageable.unpaged(),).content + + // then + assertThat(found).hasSize(2) + assertThat(found.map { it.name }).containsExactlyInAnyOrder("Book 1", "Book 2") + } + + @Test + fun `given books with same hash but different size when searching then no results are returned`() { + // given + seriesLifecycle.addBooks( + series, + listOf( + makeBook("Book 1", seriesId = series.id, libraryId = library.id).copy(fileHash = "hashed", fileSize = 10), + makeBook("Book 2", seriesId = series.id, libraryId = library.id).copy(fileHash = "hashed", fileSize = 12), + ), + ) + + // when + val found = bookDtoDao.findAllDuplicates(user.id, Pageable.unpaged(),).content + + // then + assertThat(found).isEmpty() + } + } }