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) : IntEntity(id) { companion object : IntEntityClass(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, ""), )