Add library categories and favorites
This commit is contained in:
1 parent
d749352333
commit
02bde7e644
9 files changed
+263
-21
No files matched your search
@@ -17,6 +17,7 @@ enum class BookImportPolicy {
|
||||
|
||||
enum class BookReadingStatus {
|
||||
NEW,
|
||||
TO_READ,
|
||||
READING,
|
||||
READ,
|
||||
NOT_INTERESTED,
|
||||
@@ -109,6 +110,7 @@ data class BookFileRecord(
|
||||
val lastModifiedMillis: Long? = null,
|
||||
val lastSeenAt: Long? = null,
|
||||
val readingStatus: BookReadingStatus = BookReadingStatus.NEW,
|
||||
val favorite: Boolean = false,
|
||||
val lastReadAt: Long? = null,
|
||||
val createdAt: Long,
|
||||
val updatedAt: Long,
|
||||
@@ -128,6 +130,7 @@ data class LibraryFileRecord(
|
||||
val storageUri: String? = null,
|
||||
val lastSeenAt: Long? = null,
|
||||
val readingStatus: BookReadingStatus = BookReadingStatus.NEW,
|
||||
val favorite: Boolean = false,
|
||||
val lastReadAt: Long? = null,
|
||||
val importedAt: Long,
|
||||
)
|
||||
@@ -210,6 +213,7 @@ interface BookFileRepository {
|
||||
fun list(limit: Int = 500, offset: Int = 0): List<BookFileRecord>
|
||||
fun listForBook(bookId: String): List<BookFileRecord>
|
||||
fun updateReadingStatus(id: String, status: BookReadingStatus): Boolean
|
||||
fun updateFavorite(id: String, favorite: Boolean): Boolean
|
||||
fun touchLastReadAt(id: String, lastReadAt: Long): Boolean
|
||||
fun delete(id: String): Boolean
|
||||
}
|
||||
|
||||
@@ -213,6 +213,7 @@ private fun migrate(connection: Connection) {
|
||||
last_modified_millis BIGINT,
|
||||
last_seen_at BIGINT,
|
||||
reading_status VARCHAR NOT NULL DEFAULT 'NEW',
|
||||
favorite BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
last_read_at BIGINT,
|
||||
imported_at BIGINT NOT NULL,
|
||||
created_at BIGINT NOT NULL,
|
||||
@@ -225,6 +226,7 @@ private fun migrate(connection: Connection) {
|
||||
)
|
||||
statement.execute("ALTER TABLE book_files ADD COLUMN IF NOT EXISTS duplicate_of_file_id VARCHAR")
|
||||
statement.execute("ALTER TABLE book_files ADD COLUMN IF NOT EXISTS reading_status VARCHAR NOT NULL DEFAULT 'NEW'")
|
||||
statement.execute("ALTER TABLE book_files ADD COLUMN IF NOT EXISTS favorite BOOLEAN NOT NULL DEFAULT FALSE")
|
||||
statement.execute("ALTER TABLE book_files ADD COLUMN IF NOT EXISTS last_read_at BIGINT")
|
||||
statement.execute("ALTER TABLE book_files ADD COLUMN IF NOT EXISTS imported_at BIGINT")
|
||||
connection.prepareStatement("UPDATE book_files SET imported_at = ? WHERE imported_at IS NULL").use { update ->
|
||||
@@ -487,9 +489,9 @@ private class JdbcBookFileRepository(private val connection: Connection) : BookF
|
||||
MERGE INTO book_files(
|
||||
id, book_id, body_id, body_cluster_id, duplicate_of_file_id, raw_sha256, format,
|
||||
mime_type, size_bytes, original_filename, storage_kind, storage_uri, content_object_id,
|
||||
last_modified_millis, last_seen_at, reading_status, last_read_at, imported_at, created_at, updated_at
|
||||
last_modified_millis, last_seen_at, reading_status, favorite, last_read_at, imported_at, created_at, updated_at
|
||||
)
|
||||
KEY(id) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
KEY(id) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""".trimIndent()
|
||||
).use { statement ->
|
||||
statement.setString(1, file.id)
|
||||
@@ -508,10 +510,11 @@ private class JdbcBookFileRepository(private val connection: Connection) : BookF
|
||||
statement.setLongOrNull(14, file.lastModifiedMillis)
|
||||
statement.setLongOrNull(15, file.lastSeenAt)
|
||||
statement.setString(16, file.readingStatus.name)
|
||||
statement.setLongOrNull(17, file.lastReadAt)
|
||||
statement.setLong(18, file.importedAt)
|
||||
statement.setLong(19, file.createdAt)
|
||||
statement.setLong(20, file.updatedAt)
|
||||
statement.setBoolean(17, file.favorite)
|
||||
statement.setLongOrNull(18, file.lastReadAt)
|
||||
statement.setLong(19, file.importedAt)
|
||||
statement.setLong(20, file.createdAt)
|
||||
statement.setLong(21, file.updatedAt)
|
||||
statement.executeUpdate()
|
||||
}
|
||||
}
|
||||
@@ -536,6 +539,7 @@ private class JdbcBookFileRepository(private val connection: Connection) : BookF
|
||||
f.storage_uri AS storage_uri,
|
||||
f.last_seen_at AS last_seen_at,
|
||||
f.reading_status AS reading_status,
|
||||
f.favorite AS favorite,
|
||||
f.last_read_at AS last_read_at,
|
||||
f.imported_at AS imported_at
|
||||
FROM book_files f
|
||||
@@ -692,6 +696,7 @@ private class JdbcBookFileRepository(private val connection: Connection) : BookF
|
||||
f.storage_uri AS storage_uri,
|
||||
f.last_seen_at AS last_seen_at,
|
||||
f.reading_status AS reading_status,
|
||||
f.favorite AS favorite,
|
||||
f.last_read_at AS last_read_at,
|
||||
f.imported_at AS imported_at
|
||||
FROM book_files f
|
||||
@@ -732,6 +737,7 @@ private class JdbcBookFileRepository(private val connection: Connection) : BookF
|
||||
f.storage_uri AS storage_uri,
|
||||
f.last_seen_at AS last_seen_at,
|
||||
f.reading_status AS reading_status,
|
||||
f.favorite AS favorite,
|
||||
f.last_read_at AS last_read_at,
|
||||
f.imported_at AS imported_at
|
||||
FROM book_files f
|
||||
@@ -771,6 +777,7 @@ private class JdbcBookFileRepository(private val connection: Connection) : BookF
|
||||
f.storage_uri AS storage_uri,
|
||||
f.last_seen_at AS last_seen_at,
|
||||
f.reading_status AS reading_status,
|
||||
f.favorite AS favorite,
|
||||
f.last_read_at AS last_read_at,
|
||||
f.imported_at AS imported_at
|
||||
FROM book_files f
|
||||
@@ -847,6 +854,24 @@ private class JdbcBookFileRepository(private val connection: Connection) : BookF
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateFavorite(id: String, favorite: Boolean): Boolean {
|
||||
val now = System.currentTimeMillis()
|
||||
return connection.prepareStatement(
|
||||
"""
|
||||
UPDATE book_files
|
||||
SET favorite = ?, updated_at = ?
|
||||
WHERE id = ?
|
||||
OR body_cluster_id = (SELECT body_cluster_id FROM book_files WHERE id = ? AND body_cluster_id IS NOT NULL)
|
||||
""".trimIndent()
|
||||
).use { statement ->
|
||||
statement.setBoolean(1, favorite)
|
||||
statement.setLong(2, now)
|
||||
statement.setString(3, id)
|
||||
statement.setString(4, id)
|
||||
statement.executeUpdate() > 0
|
||||
}
|
||||
}
|
||||
|
||||
override fun touchLastReadAt(id: String, lastReadAt: Long): Boolean {
|
||||
return connection.prepareStatement(
|
||||
"""
|
||||
@@ -1085,6 +1110,7 @@ private fun ResultSet.toLibraryFileRecord() = LibraryFileRecord(
|
||||
storageUri = getString("storage_uri"),
|
||||
lastSeenAt = getLongOrNull("last_seen_at"),
|
||||
readingStatus = getReadingStatus("reading_status"),
|
||||
favorite = getBoolean("favorite"),
|
||||
lastReadAt = getLongOrNull("last_read_at"),
|
||||
importedAt = getLong("imported_at"),
|
||||
)
|
||||
@@ -1122,6 +1148,7 @@ private fun ResultSet.toBookFileRecord() = BookFileRecord(
|
||||
lastModifiedMillis = getLongOrNull("last_modified_millis"),
|
||||
lastSeenAt = getLongOrNull("last_seen_at"),
|
||||
readingStatus = getReadingStatus("reading_status"),
|
||||
favorite = getBoolean("favorite"),
|
||||
lastReadAt = getLongOrNull("last_read_at"),
|
||||
importedAt = getLong("imported_at"),
|
||||
createdAt = getLong("created_at"),
|
||||
|
||||
@@ -122,6 +122,9 @@ class H2LibraryDatabaseTest {
|
||||
assertEquals("2024", db.files.getLibraryFile("file-1")?.date)
|
||||
assertEquals("image/jpeg", db.books.getCover("book-1")?.mimeType)
|
||||
assertEquals(BookReadingStatus.NEW, db.files.getLibraryFile("file-1")?.readingStatus)
|
||||
assertEquals(false, db.files.getLibraryFile("file-1")?.favorite)
|
||||
assertEquals(true, db.files.updateFavorite("file-1", true))
|
||||
assertEquals(true, db.files.getLibraryFile("file-1")?.favorite)
|
||||
assertEquals(true, db.files.updateReadingStatus("file-1", BookReadingStatus.READING))
|
||||
assertEquals(BookReadingStatus.READING, db.files.getLibraryFile("file-1")?.readingStatus)
|
||||
assertEquals("body-1", db.bodies.findByExactTextHash("text-sha", 1)?.id)
|
||||
@@ -299,6 +302,9 @@ class H2LibraryDatabaseTest {
|
||||
assertEquals(true, db.files.updateReadingStatus("file-zip", BookReadingStatus.READING))
|
||||
assertEquals(BookReadingStatus.READING, db.files.get("file-fb2")?.readingStatus)
|
||||
assertEquals(BookReadingStatus.READING, db.files.get("file-zip")?.readingStatus)
|
||||
assertEquals(true, db.files.updateFavorite("file-zip", true))
|
||||
assertEquals(true, db.files.get("file-fb2")?.favorite)
|
||||
assertEquals(true, db.files.get("file-zip")?.favorite)
|
||||
db.close()
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user