Persist book status and add recent catalog section

This commit is contained in:
sergeych committed 2026-05-18 14:40:56 +03:00
1 parent 6422f814d1
commit 44cc0bbaf3
8 files changed
+136 -2

No files matched your search

@@ -205,6 +205,7 @@ interface BookFileRepository {
fun findPrimaryDuplicateTarget(bodyClusterId: String?, bodyId: String?, rawSha256: String): BookFileRecord?
fun markDuplicateFiles(): Int
fun listLibraryFiles(limit: Int = 100, offset: Int = 0): List<LibraryFileRecord>
fun listRecentlyAddedLibraryFiles(sinceImportedAt: Long, limit: Int = 50): List<LibraryFileRecord>
fun searchLibraryFiles(prefixes: List<String>, limit: Int = 100): List<LibraryFileRecord>
fun list(limit: Int = 500, offset: Int = 0): List<BookFileRecord>
fun listForBook(bookId: String): List<BookFileRecord>
@@ -715,6 +715,40 @@ private class JdbcBookFileRepository(private val connection: Connection) : BookF
}
}
override fun listRecentlyAddedLibraryFiles(sinceImportedAt: Long, limit: Int): List<LibraryFileRecord> {
markDuplicateFiles()
return connection.prepareStatement(
"""
SELECT
f.id AS file_id,
f.book_id AS book_id,
b.title AS book_title,
b.authors AS book_authors,
b.language AS book_language,
b.published_date AS book_date,
f.format AS file_format,
f.size_bytes AS size_bytes,
f.original_filename AS original_filename,
f.storage_uri AS storage_uri,
f.last_seen_at AS last_seen_at,
f.reading_status AS reading_status,
f.last_read_at AS last_read_at,
f.imported_at AS imported_at
FROM book_files f
LEFT JOIN books b ON b.id = f.book_id
WHERE f.duplicate_of_file_id IS NULL
AND f.reading_status = 'NEW'
AND f.imported_at >= ?
ORDER BY f.imported_at DESC, f.id
LIMIT ?
""".trimIndent()
).use { statement ->
statement.setLong(1, sinceImportedAt)
statement.setInt(2, limit)
statement.executeQuery().use { resultSet -> resultSet.mapRows { it.toLibraryFileRecord() } }
}
}
override fun searchLibraryFiles(prefixes: List<String>, limit: Int): List<LibraryFileRecord> {
val normalizedPrefixes = prefixes.mapNotNull { it.trim().lowercase().takeIf(String::isNotBlank) }.distinct()
if (normalizedPrefixes.isEmpty()) return emptyList()
@@ -201,6 +201,47 @@ class H2LibraryDatabaseTest {
db.close()
}
@Test
fun listsRecentlyAddedNewLibraryFiles() {
val db = H2LibraryDatabase.openMemory("listsRecentlyAddedNewLibraryFiles")
val now = 1_700_000_000_000L
db.transaction {
listOf(
Triple("book-old", "Old", BookReadingStatus.NEW),
Triple("book-newer", "Newer", BookReadingStatus.NEW),
Triple("book-newest", "Newest", BookReadingStatus.NEW),
Triple("book-read", "Read", BookReadingStatus.READ),
).forEachIndexed { index, (bookId, title, status) ->
books.upsert(BookRecord(id = bookId, title = title, createdAt = now + index, updatedAt = now + index))
files.upsert(
BookFileRecord(
id = "file-$title",
bookId = bookId,
rawSha256 = "sha-$title",
originalFilename = "$title.fb2",
storageKind = BookFileStorageKind.EXTERNAL_URI,
readingStatus = status,
importedAt = when (title) {
"Old" -> now - 1_000
"Newer" -> now + 2_000
"Newest" -> now + 3_000
else -> now + 4_000
},
createdAt = now + index,
updatedAt = now + index,
)
)
}
}
assertEquals(
listOf("Newest", "Newer"),
db.files.listRecentlyAddedLibraryFiles(now, 50).map { it.title },
)
db.close()
}
@Test
fun hidesDuplicateLibraryFilesAndPrefersZip() {
val db = H2LibraryDatabase.openMemory("hidesDuplicateLibraryFilesAndPrefersZip")