From afa2ffb4817ea49a2a4af5e8df0d4f799c1d5980 Mon Sep 17 00:00:00 2001 From: Stefan Schallerl Date: Mon, 3 Feb 2025 16:38:53 +0100 Subject: [PATCH] Adds files to document display. --- .../filemure/repository/SqliteRepository.kt | 150 +++++++++++++++--- .../tpl/net.h34t.filemure.tpl/Frame.tpl.html | 2 +- .../net/h34t/filemure/core/entity/Types.kt | 47 +++++- 3 files changed, 166 insertions(+), 33 deletions(-) diff --git a/app/src/main/kotlin/net/h34t/filemure/repository/SqliteRepository.kt b/app/src/main/kotlin/net/h34t/filemure/repository/SqliteRepository.kt index 645fe59..11118b6 100644 --- a/app/src/main/kotlin/net/h34t/filemure/repository/SqliteRepository.kt +++ b/app/src/main/kotlin/net/h34t/filemure/repository/SqliteRepository.kt @@ -3,6 +3,7 @@ package net.h34t.filemure.repository import net.h34t.filemure.ExtId import net.h34t.filemure.LimboFile import net.h34t.filemure.core.entity.Document +import net.h34t.filemure.core.entity.FileRef import net.h34t.filemure.core.entity.Tag import java.io.InputStream import java.sql.Connection @@ -129,7 +130,9 @@ class SqliteRepository(url: String) { extId = res.getString(3), title = res.getString(4), description = res.getString(5), - tags = res.getString(6).split(",").map { Tag(it) }, + tags = res.getString(6) + ?.let { if (it.isNotBlank()) it.split(",").map { tag -> Tag(tag) } else emptyList() } + ?: emptyList(), created = LocalDateTime.parse(res.getString(7), dtf), referenceDate = LocalDateTime.parse(res.getString(8), dtf), files = emptyList() @@ -143,42 +146,139 @@ class SqliteRepository(url: String) { } fun getDocumentById(accountId: Long, id: Long): Document { - return connection.prepareStatement("""SELECT d.id, d.account_id, d.ext_id, d.title, d.description, d.tags, d.created, d.reference_date FROM document d WHERE id=? AND account_id=?""") + return connection.prepareStatement( + """ + SELECT + d.id, + d.account_id, + d.ext_id, + d.title, + d.description, + d.tags, + d.created, + d.reference_date, + f.id, + f.ext_id, + f.filename, + f.content_type, + f.content_extracted, + f.file_size + f.created + FROM + document d LEFT OUTER JOIN file f ON (d.id = f.document_id) + WHERE + id=? AND + account_id=? + """.trimIndent() + ) .use { stmt -> stmt.setLong(1, id) stmt.setLong(2, accountId) val res = stmt.executeQuery() - Document( - id = res.getLong(1), - extId = res.getString(3), - title = res.getString(4), - description = res.getString(5), - tags = res.getString(6).split(",").map { Tag(it) }, - created = LocalDateTime.parse(res.getString(7), dtf), - referenceDate = LocalDateTime.parse(res.getString(8), dtf), - // TODO load files - files = emptyList() - ) + + var document: Document? = null + val files = mutableListOf() + + while (res.next()) { + if (document == null) { + document = Document( + id = res.getLong(1), + extId = res.getString(3), + title = res.getString(4), + description = res.getString(5), + tags = res.getString(6).split(",").map { Tag(it) }, + created = LocalDateTime.parse(res.getString(7), dtf), + referenceDate = LocalDateTime.parse(res.getString(8), dtf), + files = emptyList() + ) + + val id = res.getLong(9) + if (!res.wasNull()) { + files.add( + FileRef( + id = id, + extId = res.getString(10), + filename = res.getString(11), + contentType = res.getString(12), + contentExtracted = res.getString(13), + fileSize = res.getLong(14), + created = LocalDateTime.parse(res.getString(15), dtf) + ) + ) + } + } + } + + document?.copy(files = files) ?: throw IllegalStateException("Document is null") } } fun getDocumentByExtId(accountId: Long, extId: String): Document { - return connection.prepareStatement("""SELECT d.id, d.account_id, d.ext_id, d.title, d.description, d.tags, d.created, d.reference_date FROM document d WHERE ext_id=? AND account_id=?""") + return connection.prepareStatement( + """ + SELECT + d.id, + d.account_id, + d.ext_id, + d.title, + d.description, + d.tags, + d.created, + d.reference_date, + f.id, + f.ext_id, + f.filename, + f.content_type, + f.content_extracted, + f.file_size, + f.created + FROM + document d LEFT OUTER JOIN file f ON (d.id = f.document_id) + WHERE + d.ext_id=? AND + d.account_id=? + """.trimIndent() + ) .use { stmt -> stmt.setString(1, extId) stmt.setLong(2, accountId) val res = stmt.executeQuery() - Document( - id = res.getLong(1), - extId = res.getString(3), - title = res.getString(4), - description = res.getString(5), - tags = res.getString(6).split(",").map { Tag(it) }, - created = LocalDateTime.parse(res.getString(7), dtf), - referenceDate = LocalDateTime.parse(res.getString(8), dtf), - // TODO load files - files = emptyList() - ) + var document: Document? = null + val files = mutableListOf() + + while (res.next()) { + if (document == null) { + document = Document( + id = res.getLong(1), + extId = res.getString(3), + title = res.getString(4), + description = res.getString(5), + tags = Tag.parse(res.getString(6)), + created = LocalDateTime.parse(res.getString(7), dtf), + referenceDate = LocalDateTime.parse(res.getString(8), dtf), + files = emptyList() + ) + + val fid: Long = res.getLong(9) + + if (!res.wasNull()) { + files.add( + FileRef( + id = fid, + extId = res.getString(10), + filename = res.getString(11), + contentType = res.getString(12), + contentExtracted = res.getString(13), + fileSize = res.getLong(14), + created = LocalDateTime.parse(res.getString(15), dtf) + ) + ) + } + } + } + + requireNotNull(document) + document.copy(files = files) } } } \ No newline at end of file diff --git a/app/src/main/tpl/net.h34t.filemure.tpl/Frame.tpl.html b/app/src/main/tpl/net.h34t.filemure.tpl/Frame.tpl.html index 8c9a826..1b3e3a9 100644 --- a/app/src/main/tpl/net.h34t.filemure.tpl/Frame.tpl.html +++ b/app/src/main/tpl/net.h34t.filemure.tpl/Frame.tpl.html @@ -3,7 +3,7 @@ - {*$title} + {*$title} :: Filemure diff --git a/core/src/main/kotlin/net/h34t/filemure/core/entity/Types.kt b/core/src/main/kotlin/net/h34t/filemure/core/entity/Types.kt index 87e362e..fae081d 100644 --- a/core/src/main/kotlin/net/h34t/filemure/core/entity/Types.kt +++ b/core/src/main/kotlin/net/h34t/filemure/core/entity/Types.kt @@ -2,7 +2,7 @@ package net.h34t.filemure.core.entity import java.time.LocalDateTime -class Document( +data class Document( val id: Long, val extId: String, val title: String, @@ -14,13 +14,18 @@ class Document( ) @JvmInline -value class Tag(val value: String) - -@JvmInline -value class MimeType(val value: String) { +value class Tag(val value: String) { init { - // TODO validate mime type - // require(value) + // TODO proper validation + require(value.isNotBlank()) + } + + companion object { + fun parse(ser: String?): List { + return ser?.let { if (it.isNotBlank()) it.split(",").map { Tag(it) } else emptyList() } ?: emptyList() + } + + fun List.serialize() = if (this.isEmpty()) "" else this.joinToString(",") { it.value } } } @@ -29,6 +34,34 @@ data class FileRef( val extId: String, val filename: String, val contentType: String?, + val contentExtracted: String?, + val fileSize: Long, val created: LocalDateTime, ) +data class FileContent( + val id: Long, + val extId: String, + val content: ByteArray, +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as FileContent + + if (id != other.id) return false + if (extId != other.extId) return false + if (!content.contentEquals(other.content)) return false + + return true + } + + override fun hashCode(): Int { + var result = id.hashCode() + result = 31 * result + extId.hashCode() + result = 31 * result + content.contentHashCode() + return result + } +} +