Files
app/server/src/main/kotlin/books/db/schema/BookDAO.kt
T
2026-10-21 23:47:44 +02:00

109 lines
3.7 KiB
Kotlin

package net.keinekekse.app.books.db.schema
import net.keinekekse.app.books.model.*
import org.jetbrains.exposed.v1.core.dao.id.EntityID
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
import org.jetbrains.exposed.v1.dao.IntEntity
import org.jetbrains.exposed.v1.dao.IntEntityClass
object BooksTable : IntIdTable("books") {
var title = varchar("title", 150).index()
var subTitle = varchar("sub_title", 150).nullable()
var originalTitle = varchar("original_title", 150).nullable()
var year = integer("year")
var originalYear = integer("original_year").nullable()
var language = integer("language")
var isbn = varchar("isbn", 13).index()
var publisher = reference("publisher_id", PublisherTable.id)
var series = optReference("series_id", SeriesTable.id)
var seriesIndex = integer("seriesIndex").nullable()
var type = integer("type")
var read = bool("read").default(false)
var comments = varchar("comments", 255)
// Dieses Buch ist Teil eines Sammelbands.
// Null bedeutet: kein übergeordneter Sammelband.
var parent = optReference("parent_id", id)
val cover = blob("cover").nullable()
}
class BookDAO(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<BookDAO>(BooksTable)
var title by BooksTable.title
var subTitle by BooksTable.subTitle
var seriesIndex by BooksTable.seriesIndex
var originalTitle by BooksTable.originalTitle
var year by BooksTable.year
var originalYear by BooksTable.originalYear
var language: Languages by BooksTable.language.transform(
{ it.ordinal },
{ Languages.entries[it] })
var isbn by BooksTable.isbn
var publisher by PublisherDAO.Companion referencedOn BooksTable.publisher
var type by BooksTable.type.transform({ it.ordinal }, { BookType.entries[it] })
var read by BooksTable.read
var comments by BooksTable.comments
var cover by BooksTable.cover
var series by SeriesDAO.Companion optionalReferencedOn BooksTable.series
val artists by ArtistToBookDAO referrersOn ArtistToBookTable.bookId
val tags by TagsToBookDAO referrersOn TagsToBookTable.bookId
// Verweis auf Sammelband (falls dieses Buch ein Teilroman ist)
var parent by BookDAO optionalReferencedOn BooksTable.parent
// Enthaltene Einzelromane (falls dieses Buch der Sammelband ist)
val containedBooks by BookDAO optionalReferrersOn BooksTable.parent
val samplerEntry by SamplerDAO optionalBackReferencedOn SamplerTable.bookId
}
fun bookDaoToModel(dao: BookDAO, includeChildren: Boolean = true): Book = Book(
dao.id.value,
dao.title,
dao.subTitle,
dao.originalTitle,
dao.year,
dao.originalYear,
dao.language,
dao.isbn,
publisher = Publisher(dao.publisher.id.value, dao.publisher.name),
dao.type,
dao.read,
dao.comments,
cover = dao.cover?.bytes ?: ByteArray(0),
series = if (dao.series != null) Series(dao.series!!.id.value, dao.series!!.name) else null,
seriesIndex = dao.seriesIndex,
parentBookId = dao.parent?.id?.value,
containedBooks = if (includeChildren) {
dao.containedBooks.map { child ->
bookDaoToModel(child, includeChildren = false)
}
} else {
emptyList()
},
isSampler = dao.samplerEntry != null,
artists = dao.artists.map {
ArtistForBook(
Artist(it.artist.id.value, it.artist.name, it.artist.givenName),
ArtistRole(it.role.id.value, it.role.role)
)
},
tags = dao.tags.map {
Tag(it.tag.id.value, it.tag.tag)
},
)
fun emptyBook(title: String = "", year: Int = 0, isbn: String = ""): Book =
Book(
title = title,
year = year,
isbn = isbn,
publisher = Publisher(0, ""),
)