Adds SQLDelight type converters.
This commit is contained in:
parent
b4f2f51032
commit
319c58bcc2
8 changed files with 140 additions and 87 deletions
|
@ -5,7 +5,8 @@ import org.apache.commons.text.StringEscapeUtils
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
|
||||||
class TemplateModifiers : Frame.Modifiers, Limbo.Modifiers, DocumentCreateForm.Modifiers, Overview.Modifiers,
|
class TemplateModifiers : Frame.Modifiers, Limbo.Modifiers, DocumentCreateForm.Modifiers, Overview.Modifiers,
|
||||||
Document.Modifiers, FilePreview.Modifiers, DocumentEditForm.Modifiers, FileList.Modifiers {
|
FilePreview.Modifiers, DocumentEditForm.Modifiers, FileList.Modifiers,
|
||||||
|
net.h34t.filemure.tpl.Document.Modifiers {
|
||||||
|
|
||||||
fun hashPrefix(arg: String): String {
|
fun hashPrefix(arg: String): String {
|
||||||
return URLEncoder.encode(arg, Charsets.UTF_8)
|
return URLEncoder.encode(arg, Charsets.UTF_8)
|
||||||
|
|
|
@ -1,10 +1,26 @@
|
||||||
package net.h34t.filemure.core.entity
|
package net.h34t.filemure
|
||||||
|
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class ExtId(val value: String) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val chars = ('a'..'z') + ('A'..'Z') + ('0'..'9')
|
||||||
|
|
||||||
|
fun generate(): ExtId {
|
||||||
|
return ExtId((0..8).map { chars.random() }.joinToString(""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString() = value
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
data class Document(
|
data class Document(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val extId: String,
|
val extId: ExtId,
|
||||||
val title: String,
|
val title: String,
|
||||||
val description: String,
|
val description: String,
|
||||||
val tags: List<Tag>,
|
val tags: List<Tag>,
|
||||||
|
@ -20,19 +36,11 @@ value class Tag(val value: String) {
|
||||||
// TODO proper validation
|
// TODO proper validation
|
||||||
require(value.isNotBlank())
|
require(value.isNotBlank())
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun parse(ser: String?): List<Tag> {
|
|
||||||
return ser?.let { if (it.isNotBlank()) it.split(",").map { Tag(it) } else emptyList() } ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun List<Tag>.serialize() = if (this.isEmpty()) "" else this.joinToString(",") { it.value }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class FileRef(
|
data class FileRef(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val extId: String,
|
val extId: ExtId,
|
||||||
val accountId: Long,
|
val accountId: Long,
|
||||||
val documentId: Long?,
|
val documentId: Long?,
|
||||||
val filename: String,
|
val filename: String,
|
||||||
|
@ -45,7 +53,7 @@ data class FileRef(
|
||||||
|
|
||||||
data class FileContent(
|
data class FileContent(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val extId: String,
|
val extId: ExtId,
|
||||||
val filename: String,
|
val filename: String,
|
||||||
val contentType: String?,
|
val contentType: String?,
|
||||||
val contentExtracted: String?,
|
val contentExtracted: String?,
|
|
@ -36,20 +36,6 @@ fun Context.setSession(session: Session?) = this.sessionAttribute("session", ses
|
||||||
|
|
||||||
fun Context.requireSession(): Session = this.getSession() ?: throw UnauthorizedResponse("Not logged in")
|
fun Context.requireSession(): Session = this.getSession() ?: throw UnauthorizedResponse("Not logged in")
|
||||||
|
|
||||||
private val chars = ('a'..'z') + ('A'..'Z') + ('0'..'9')
|
|
||||||
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class ExtId(val value: String) {
|
|
||||||
override fun toString() = value
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun generate(): ExtId {
|
|
||||||
return ExtId((0..8).map { chars.random() }.joinToString(""))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun formatHumanReadableSize(bytes: Long) = when (bytes) {
|
fun formatHumanReadableSize(bytes: Long) = when (bytes) {
|
||||||
in 0L..<1024L -> "$bytes bytes"
|
in 0L..<1024L -> "$bytes bytes"
|
||||||
in 1025..<1024 * 1_000 -> "${bytes / 1000} kb"
|
in 1025..<1024 * 1_000 -> "${bytes / 1000} kb"
|
||||||
|
@ -57,3 +43,10 @@ fun formatHumanReadableSize(bytes: Long) = when (bytes) {
|
||||||
else -> "${bytes / 1_000_000_000} gb"
|
else -> "${bytes / 1_000_000_000} gb"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object TagAdapter {
|
||||||
|
fun parse(ser: String?): List<Tag> {
|
||||||
|
return ser?.let { if (it.isNotBlank()) it.split(",").map { Tag(it) } else emptyList() } ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Tag>.serialize() = if (this.isEmpty()) "" else this.joinToString(",") { it.value }
|
||||||
|
}
|
|
@ -5,10 +5,9 @@ import io.javalin.http.Context
|
||||||
import io.javalin.http.ForbiddenResponse
|
import io.javalin.http.ForbiddenResponse
|
||||||
import io.javalin.http.Header
|
import io.javalin.http.Header
|
||||||
import net.h34t.filemure.*
|
import net.h34t.filemure.*
|
||||||
import net.h34t.filemure.core.entity.State
|
|
||||||
import net.h34t.filemure.core.entity.Tag
|
|
||||||
import net.h34t.filemure.repository.SqliteRepository
|
import net.h34t.filemure.repository.SqliteRepository
|
||||||
import net.h34t.filemure.tpl.*
|
import net.h34t.filemure.tpl.*
|
||||||
|
import net.h34t.filemure.tpl.Document
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
@ -32,7 +31,7 @@ class DocumentController(val modifiers: TemplateModifiers, val repository: Sqlit
|
||||||
isTarget = true,
|
isTarget = true,
|
||||||
content = Document(
|
content = Document(
|
||||||
modifiers = modifiers,
|
modifiers = modifiers,
|
||||||
extId = document.extId,
|
extId = document.extId.value,
|
||||||
title = document.title,
|
title = document.title,
|
||||||
referenceDate = dtf.format(document.referenceDate),
|
referenceDate = dtf.format(document.referenceDate),
|
||||||
tags = { document.tags.map { TagsBlock(tag = it.value) }.asSequence() },
|
tags = { document.tags.map { TagsBlock(tag = it.value) }.asSequence() },
|
||||||
|
@ -43,7 +42,7 @@ class DocumentController(val modifiers: TemplateModifiers, val repository: Sqlit
|
||||||
files = {
|
files = {
|
||||||
document.files.map { file ->
|
document.files.map { file ->
|
||||||
FilesBlock(
|
FilesBlock(
|
||||||
extId = file.extId,
|
extId = file.extId.value,
|
||||||
filename = file.filename,
|
filename = file.filename,
|
||||||
contentType = file.contentType ?: "?",
|
contentType = file.contentType ?: "?",
|
||||||
size = formatHumanReadableSize(file.fileSize),
|
size = formatHumanReadableSize(file.fileSize),
|
||||||
|
@ -60,7 +59,7 @@ class DocumentController(val modifiers: TemplateModifiers, val repository: Sqlit
|
||||||
fun createDocumentForm(ctx: Context) {
|
fun createDocumentForm(ctx: Context) {
|
||||||
val session = ctx.requireSession()
|
val session = ctx.requireSession()
|
||||||
|
|
||||||
val fileIds = ctx.queryParams("file_id")
|
val fileIds = ctx.queryParams("file_id").map { ExtId(it) }
|
||||||
|
|
||||||
val limboFiles = repository.getFilesInLimbo(session.id)
|
val limboFiles = repository.getFilesInLimbo(session.id)
|
||||||
val limboFileIds = limboFiles.map { it.extId }
|
val limboFileIds = limboFiles.map { it.extId }
|
||||||
|
@ -96,7 +95,7 @@ class DocumentController(val modifiers: TemplateModifiers, val repository: Sqlit
|
||||||
files = {
|
files = {
|
||||||
selectedFiles.map { file ->
|
selectedFiles.map { file ->
|
||||||
FilesBlock(
|
FilesBlock(
|
||||||
extId = file.extId,
|
extId = file.extId.value,
|
||||||
filename = file.filename,
|
filename = file.filename,
|
||||||
contentType = file.contentType ?: "?",
|
contentType = file.contentType ?: "?",
|
||||||
size = formatHumanReadableSize(file.fileSize),
|
size = formatHumanReadableSize(file.fileSize),
|
||||||
|
@ -174,7 +173,7 @@ class DocumentController(val modifiers: TemplateModifiers, val repository: Sqlit
|
||||||
files = {
|
files = {
|
||||||
document.files.map { file ->
|
document.files.map { file ->
|
||||||
FilesBlock(
|
FilesBlock(
|
||||||
extId = file.extId,
|
extId = file.extId.value,
|
||||||
filename = file.filename,
|
filename = file.filename,
|
||||||
contentType = file.contentType ?: "?",
|
contentType = file.contentType ?: "?",
|
||||||
size = formatHumanReadableSize(file.fileSize),
|
size = formatHumanReadableSize(file.fileSize),
|
||||||
|
@ -207,7 +206,7 @@ class DocumentController(val modifiers: TemplateModifiers, val repository: Sqlit
|
||||||
id = document.id,
|
id = document.id,
|
||||||
title = title ?: "",
|
title = title ?: "",
|
||||||
referenceDate = LocalDateTime.parse(referenceDate ?: "", formDtf),
|
referenceDate = LocalDateTime.parse(referenceDate ?: "", formDtf),
|
||||||
tags = Tag.parse(tags),
|
tags = TagAdapter.parse(tags),
|
||||||
description = description
|
description = description
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ class LimboController(val modifiers: TemplateModifiers, val repository: SqliteRe
|
||||||
modifiers = modifiers, limboFileCount = files.size.toString(), file = {
|
modifiers = modifiers, limboFileCount = files.size.toString(), file = {
|
||||||
files.map { f ->
|
files.map { f ->
|
||||||
FileBlock(
|
FileBlock(
|
||||||
extId = f.extId,
|
extId = f.extId.value,
|
||||||
file = f.filename,
|
file = f.filename,
|
||||||
type = f.contentType ?: "",
|
type = f.contentType ?: "",
|
||||||
size = f.fileSize.toString(),
|
size = f.fileSize.toString(),
|
||||||
|
|
|
@ -12,7 +12,7 @@ import java.time.format.FormatStyle
|
||||||
|
|
||||||
class OverviewController(val modifiers: TemplateModifiers, val repository: SqliteRepository) {
|
class OverviewController(val modifiers: TemplateModifiers, val repository: SqliteRepository) {
|
||||||
|
|
||||||
val dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT)
|
private val htmlDtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT)
|
||||||
|
|
||||||
fun overview(ctx: Context) {
|
fun overview(ctx: Context) {
|
||||||
val session = ctx.requireSession()
|
val session = ctx.requireSession()
|
||||||
|
@ -24,7 +24,7 @@ class OverviewController(val modifiers: TemplateModifiers, val repository: Sqlit
|
||||||
ctx.tempolin(
|
ctx.tempolin(
|
||||||
Frame(
|
Frame(
|
||||||
modifiers = modifiers,
|
modifiers = modifiers,
|
||||||
title = "Filemure Overview",
|
title = "Overview",
|
||||||
isTarget = true,
|
isTarget = true,
|
||||||
content = Overview(
|
content = Overview(
|
||||||
modifiers = modifiers,
|
modifiers = modifiers,
|
||||||
|
@ -32,8 +32,8 @@ class OverviewController(val modifiers: TemplateModifiers, val repository: Sqlit
|
||||||
document = {
|
document = {
|
||||||
documents.map { document ->
|
documents.map { document ->
|
||||||
DocumentBlock(
|
DocumentBlock(
|
||||||
extId = document.extId,
|
extId = document.extId.value,
|
||||||
referenceDate = dtf.format(document.referenceDate),
|
referenceDate = htmlDtf.format(document.referenceDate),
|
||||||
title = document.title.ifBlank { "untitled" },
|
title = document.title.ifBlank { "untitled" },
|
||||||
)
|
)
|
||||||
}.asSequence()
|
}.asSequence()
|
||||||
|
|
|
@ -1,34 +1,78 @@
|
||||||
package net.h34t.filemure.repository
|
package net.h34t.filemure.repository
|
||||||
|
|
||||||
|
import app.cash.sqldelight.ColumnAdapter
|
||||||
import app.cash.sqldelight.db.SqlDriver
|
import app.cash.sqldelight.db.SqlDriver
|
||||||
import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver
|
import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver
|
||||||
import net.h34t.filemure.ExtId
|
import net.h34t.filemure.*
|
||||||
import net.h34t.filemure.core.entity.*
|
import net.h34t.filemure.TagAdapter.serialize
|
||||||
import net.h34t.filemure.core.entity.Tag.Companion.serialize
|
|
||||||
import net.h34t.filemure.db.Database
|
import net.h34t.filemure.db.Database
|
||||||
|
import net.h34t.filemure.db.File_
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
class SqliteRepository(url: String) {
|
class SqliteRepository(url: String) {
|
||||||
|
|
||||||
|
private companion object Adapters {
|
||||||
private val sqliteDtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
|
private val sqliteDtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
|
||||||
|
|
||||||
// private val connection: Connection = DriverManager.getConnection(url)
|
val localDateTimeAdapter = object : ColumnAdapter<LocalDateTime, String> {
|
||||||
|
override fun decode(databaseValue: String): LocalDateTime {
|
||||||
|
return LocalDateTime.parse(databaseValue, sqliteDtf)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun encode(value: LocalDateTime): String {
|
||||||
|
return value.format(sqliteDtf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val stateAdapter = object : ColumnAdapter<State, Long> {
|
||||||
|
override fun decode(databaseValue: Long): State = State.fromCode(databaseValue.toInt())
|
||||||
|
override fun encode(value: State): Long = value.code.toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
val tagsAdapter = object : ColumnAdapter<List<Tag>, String> {
|
||||||
|
override fun decode(databaseValue: String): List<Tag> = TagAdapter.parse(databaseValue)
|
||||||
|
override fun encode(value: List<Tag>): String = value.serialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
val extIdAdapter = object : ColumnAdapter<ExtId, String> {
|
||||||
|
override fun decode(databaseValue: String): ExtId = ExtId(databaseValue)
|
||||||
|
override fun encode(value: ExtId): String = value.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val database: Database
|
private val database: Database
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val driver: SqlDriver = JdbcSqliteDriver("jdbc:sqlite:test.db")
|
val driver: SqlDriver = JdbcSqliteDriver(url)
|
||||||
|
|
||||||
|
try {
|
||||||
Database.Schema.create(driver)
|
Database.Schema.create(driver)
|
||||||
database = Database(driver)
|
} catch (_: Exception) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toLDT(value: String) = LocalDateTime.parse(value, sqliteDtf)
|
database = Database(
|
||||||
|
driver = driver,
|
||||||
|
documentAdapter = net.h34t.filemure.db.Document.Adapter(
|
||||||
|
tagsAdapter = tagsAdapter,
|
||||||
|
createdAdapter = localDateTimeAdapter,
|
||||||
|
reference_dateAdapter = localDateTimeAdapter,
|
||||||
|
stateAdapter = stateAdapter,
|
||||||
|
ext_idAdapter = extIdAdapter
|
||||||
|
),
|
||||||
|
file_Adapter = File_.Adapter(
|
||||||
|
createdAdapter = localDateTimeAdapter,
|
||||||
|
stateAdapter = stateAdapter,
|
||||||
|
ext_idAdapter = extIdAdapter
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun addFileToLimbo(accountId: Long, filename: String, contentType: String?, size: Long, content: InputStream) {
|
fun addFileToLimbo(accountId: Long, filename: String, contentType: String?, size: Long, content: InputStream) {
|
||||||
database.databaseQueries.insertFileIntoLimbo(
|
database.databaseQueries.insertFileIntoLimbo(
|
||||||
account_id = accountId,
|
account_id = accountId,
|
||||||
ext_id = ExtId.generate().value,
|
ext_id = ExtId.generate(),
|
||||||
filename = filename,
|
filename = filename,
|
||||||
content_type = contentType,
|
content_type = contentType,
|
||||||
file_size = size,
|
file_size = size,
|
||||||
|
@ -37,12 +81,12 @@ class SqliteRepository(url: String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLimboFileCount(accountId: Long, state: State = State.ACTIVE): Long {
|
fun getLimboFileCount(accountId: Long, state: State = State.ACTIVE): Long {
|
||||||
return database.databaseQueries.getLimboFileCount(account_id = accountId, state = state.code.toLong())
|
return database.databaseQueries.getLimboFileCount(account_id = accountId, state = state)
|
||||||
.executeAsOne()
|
.executeAsOne()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFilesInLimbo(accountId: Long, state: State = State.ACTIVE): List<FileRef> {
|
fun getFilesInLimbo(accountId: Long, state: State = State.ACTIVE): List<FileRef> {
|
||||||
return database.databaseQueries.getFilesInLimbo(account_id = accountId, state = state.code.toLong())
|
return database.databaseQueries.getFilesInLimbo(account_id = accountId, state = state)
|
||||||
.executeAsList()
|
.executeAsList()
|
||||||
.map {
|
.map {
|
||||||
FileRef(
|
FileRef(
|
||||||
|
@ -54,8 +98,8 @@ class SqliteRepository(url: String) {
|
||||||
fileSize = it.file_size,
|
fileSize = it.file_size,
|
||||||
contentType = it.content_type,
|
contentType = it.content_type,
|
||||||
contentExtracted = it.content_extracted,
|
contentExtracted = it.content_extracted,
|
||||||
created = toLDT(it.created),
|
created = it.created,
|
||||||
state = State.fromCode(it.state.toInt())
|
state = it.state
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,11 +116,11 @@ class SqliteRepository(url: String) {
|
||||||
database.databaseQueries.transaction {
|
database.databaseQueries.transaction {
|
||||||
database.databaseQueries.addDocument(
|
database.databaseQueries.addDocument(
|
||||||
account_id = accountId,
|
account_id = accountId,
|
||||||
ext_id = extId.value,
|
ext_id = extId,
|
||||||
title = title,
|
title = title,
|
||||||
description = description,
|
description = description,
|
||||||
tags = tags.serialize(),
|
tags = tags,
|
||||||
reference_date = referenceDate.format(sqliteDtf)
|
reference_date = referenceDate
|
||||||
)
|
)
|
||||||
|
|
||||||
val documentId = database.databaseQueries.getLastInsertRowId().executeAsOne()
|
val documentId = database.databaseQueries.getLastInsertRowId().executeAsOne()
|
||||||
|
@ -84,7 +128,7 @@ class SqliteRepository(url: String) {
|
||||||
database.databaseQueries.attachLimboFilesToDocument(
|
database.databaseQueries.attachLimboFilesToDocument(
|
||||||
account_id = accountId,
|
account_id = accountId,
|
||||||
document_id = documentId,
|
document_id = documentId,
|
||||||
ext_id = fileExtIds.map { it.value }
|
ext_id = fileExtIds
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +136,7 @@ class SqliteRepository(url: String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDocuments(accountId: Long, state: State = State.ACTIVE): List<Document> {
|
fun getDocuments(accountId: Long, state: State = State.ACTIVE): List<Document> {
|
||||||
return database.databaseQueries.getDocuments(account_id = accountId, state = state.code.toLong())
|
return database.databaseQueries.getDocuments(account_id = accountId, state = state)
|
||||||
.executeAsList()
|
.executeAsList()
|
||||||
.map {
|
.map {
|
||||||
Document(
|
Document(
|
||||||
|
@ -100,10 +144,10 @@ class SqliteRepository(url: String) {
|
||||||
extId = it.ext_id,
|
extId = it.ext_id,
|
||||||
title = it.title,
|
title = it.title,
|
||||||
description = it.description,
|
description = it.description,
|
||||||
tags = Tag.parse(it.tags),
|
tags = it.tags,
|
||||||
created = toLDT(it.created),
|
created = it.created,
|
||||||
referenceDate = toLDT(it.reference_date),
|
referenceDate = it.reference_date,
|
||||||
state = State.fromCode(it.state.toInt()),
|
state = it.state,
|
||||||
files = emptyList()
|
files = emptyList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -121,10 +165,10 @@ class SqliteRepository(url: String) {
|
||||||
database.databaseQueries.updateDocument(
|
database.databaseQueries.updateDocument(
|
||||||
id = id,
|
id = id,
|
||||||
title = title,
|
title = title,
|
||||||
reference_date = referenceDate.format(sqliteDtf),
|
reference_date = referenceDate,
|
||||||
tags = tags.serialize(),
|
tags = tags,
|
||||||
description = description,
|
description = description,
|
||||||
state = state.code.toLong(),
|
state = state,
|
||||||
account_id = accountId,
|
account_id = accountId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -132,18 +176,18 @@ class SqliteRepository(url: String) {
|
||||||
fun getDocumentByExtId(accountId: Long, extId: ExtId, state: State): Document {
|
fun getDocumentByExtId(accountId: Long, extId: ExtId, state: State): Document {
|
||||||
return database.databaseQueries.getDocumentByExtId(
|
return database.databaseQueries.getDocumentByExtId(
|
||||||
account_id = accountId,
|
account_id = accountId,
|
||||||
ext_id = extId.value,
|
ext_id = extId,
|
||||||
state = state.code.toLong()
|
state = state
|
||||||
).executeAsOne().let { d ->
|
).executeAsOne().let { d ->
|
||||||
Document(
|
Document(
|
||||||
id = d.id,
|
id = d.id,
|
||||||
extId = d.ext_id,
|
extId = d.ext_id,
|
||||||
title = d.title,
|
title = d.title,
|
||||||
description = d.description,
|
description = d.description,
|
||||||
tags = Tag.parse(d.tags),
|
tags = d.tags,
|
||||||
created = toLDT(d.created),
|
created = d.created,
|
||||||
referenceDate = toLDT(d.reference_date),
|
referenceDate = d.reference_date,
|
||||||
state = State.fromCode(d.state.toInt()),
|
state = d.state,
|
||||||
files = database.databaseQueries.getFilesForDocument(
|
files = database.databaseQueries.getFilesForDocument(
|
||||||
document_id = d.id,
|
document_id = d.id,
|
||||||
account_id = accountId
|
account_id = accountId
|
||||||
|
@ -157,8 +201,8 @@ class SqliteRepository(url: String) {
|
||||||
contentType = f.content_type,
|
contentType = f.content_type,
|
||||||
contentExtracted = f.content_extracted,
|
contentExtracted = f.content_extracted,
|
||||||
fileSize = f.file_size,
|
fileSize = f.file_size,
|
||||||
created = toLDT(f.created),
|
created = f.created,
|
||||||
state = State.fromCode(f.state.toInt())
|
state = f.state
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -169,7 +213,7 @@ class SqliteRepository(url: String) {
|
||||||
fun loadFile(accountId: Long, extId: ExtId): FileContent {
|
fun loadFile(accountId: Long, extId: ExtId): FileContent {
|
||||||
return database
|
return database
|
||||||
.databaseQueries
|
.databaseQueries
|
||||||
.getFile(account_id = accountId, ext_id = extId.value)
|
.getFile(account_id = accountId, ext_id = extId)
|
||||||
.executeAsOne().let { f ->
|
.executeAsOne().let { f ->
|
||||||
FileContent(
|
FileContent(
|
||||||
id = f.id,
|
id = f.id,
|
||||||
|
|
|
@ -1,28 +1,36 @@
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import kotlin.collections.List;
|
||||||
|
import net.h34t.filemure.ExtId;
|
||||||
|
import net.h34t.filemure.State;
|
||||||
|
import net.h34t.filemure.Tag;
|
||||||
|
|
||||||
-- account definition
|
-- account definition
|
||||||
|
|
||||||
CREATE TABLE account (
|
CREATE TABLE account (
|
||||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
ext_id TEXT AS ExtId NOT NULL,
|
||||||
email TEXT NOT NULL,
|
email TEXT NOT NULL,
|
||||||
password TEXT NOT NULL,
|
password TEXT NOT NULL,
|
||||||
created TEXT DEFAULT (CURRENT_TIMESTAMP) NOT NULL,
|
created TEXT AS LocalDateTime DEFAULT (CURRENT_TIMESTAMP) NOT NULL,
|
||||||
state INTEGER DEFAULT (1) NOT NULL
|
state INTEGER AS State DEFAULT (1) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX account_state_IDX ON account (state);
|
CREATE INDEX account_state_IDX ON account (state);
|
||||||
CREATE UNIQUE INDEX account_email_IDX ON account (email);
|
CREATE UNIQUE INDEX account_email_IDX ON account (email);
|
||||||
|
CREATE UNIQUE INDEX account_extid_IDX ON account (ext_id);
|
||||||
|
|
||||||
-- document definition
|
-- document definition
|
||||||
|
|
||||||
CREATE TABLE document (
|
CREATE TABLE document (
|
||||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
account_id INTEGER NOT NULL,
|
account_id INTEGER NOT NULL,
|
||||||
ext_id TEXT NOT NULL,
|
ext_id TEXT AS ExtId NOT NULL,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
description TEXT NOT NULL,
|
description TEXT NOT NULL,
|
||||||
tags TEXT NOT NULL,
|
tags TEXT AS List<Tag> NOT NULL,
|
||||||
created TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created TEXT AS LocalDateTime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
reference_date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
reference_date TEXT AS LocalDateTime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
state INTEGER NOT NULL DEFAULT (1),
|
state INTEGER AS State NOT NULL DEFAULT (1),
|
||||||
CONSTRAINT document_account_FK FOREIGN KEY (account_id) REFERENCES account(id) ON DELETE CASCADE
|
CONSTRAINT document_account_FK FOREIGN KEY (account_id) REFERENCES account(id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -36,14 +44,14 @@ CREATE TABLE file (
|
||||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
account_id INTEGER NOT NULL,
|
account_id INTEGER NOT NULL,
|
||||||
document_id INTEGER DEFAULT NULL,
|
document_id INTEGER DEFAULT NULL,
|
||||||
ext_id TEXT NOT NULL,
|
ext_id TEXT AS ExtId NOT NULL,
|
||||||
filename TEXT NOT NULL,
|
filename TEXT NOT NULL,
|
||||||
file_size INTEGER NOT NULL,
|
file_size INTEGER NOT NULL,
|
||||||
content BLOB NOT NULL,
|
content BLOB NOT NULL,
|
||||||
content_type TEXT,
|
content_type TEXT,
|
||||||
content_extracted TEXT,
|
content_extracted TEXT,
|
||||||
created TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created TEXT AS LocalDateTime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
state INTEGER NOT NULL DEFAULT (1),
|
state INTEGER AS State NOT NULL DEFAULT (1),
|
||||||
CONSTRAINT file_account_FK FOREIGN KEY (account_id) REFERENCES account(id) ON DELETE CASCADE,
|
CONSTRAINT file_account_FK FOREIGN KEY (account_id) REFERENCES account(id) ON DELETE CASCADE,
|
||||||
CONSTRAINT file_document_FK FOREIGN KEY (document_id) REFERENCES document(id) ON DELETE CASCADE
|
CONSTRAINT file_document_FK FOREIGN KEY (document_id) REFERENCES document(id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue