#4 DB-Integration in Server - sieht gut aus, Test-Tabellen funktionieren (closes #4)

This commit is contained in:
Hartmut Bauer committed 2026-02-08 21:54:32 +01:00
1 parent 0e46bf6cf9
commit ac0fcec846
15 files changed
+224 -48

No files matched your search

+2 -2
View File
@@ -1,3 +1,3 @@
#auto generated #auto generated
#Sun Feb 08 01:38:22 CET 2026 #Sun Feb 08 21:01:42 CET 2026
build.number=35 build.number=41
@@ -7,9 +7,6 @@ import net.keinekekse.app.server.config.configureDatabase
import net.keinekekse.app.server.config.configureKoin import net.keinekekse.app.server.config.configureKoin
import net.keinekekse.app.server.config.configureRouting import net.keinekekse.app.server.config.configureRouting
import net.keinekekse.app.server.config.configureSecurity import net.keinekekse.app.server.config.configureSecurity
import net.keinekekse.app.server.testdb.db.BookTable
import org.jetbrains.exposed.v1.jdbc.SchemaUtils
import org.jetbrains.exposed.v1.jdbc.transactions.transaction
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
@@ -32,8 +29,85 @@ fun Application.module() {
configureRouting() configureRouting()
configureDatabase() configureDatabase()
// create if not exists /* // DB-Test
transaction { transaction {
SchemaUtils.create(BookTable)
// create if not exists
SchemaUtils.create(
SeriesTable,
ArtistRolesTable,
ArtistsTable,
ArtistToBookTable,
BooksTable
)
logger.debug { "Tables created" }
val auth = ArtistRoleDAO.new { role = "Autor" }
ArtistRoleDAO.new { role = "Übersetzer" }
val kia1 = ArtistDAO.new {
name = "Aigner"
givenName = "Sebastian"
}
val kia2 = ArtistDAO.new {
name = "Elizarov"
givenName = "Roman"
}
val kia3 = ArtistDAO.new {
name = "Isakova"
givenName = "Svetlana"
}
val kia4 = ArtistDAO.new {
name = "Jemerov"
givenName = "Dmitry"
}
val kp1 = ArtistDAO.new {
name = "Soshin"
givenName = "Alexey"
}
val kia = BookDAO.new {
title = "Kotlin in Action, 2nd Edition"
seriesIndex = 0
}
val kp = BookDAO.new {
title = "Kotlin Design Patterns and Best Practices"
seriesIndex = 0
}
ArtistToBookDAO.new {
book = kia
role = auth
artist = kia1
}
ArtistToBookDAO.new {
book = kia
role = auth
artist = kia2
}
ArtistToBookDAO.new {
book = kia
role = auth
artist = kia3
}
ArtistToBookDAO.new {
book = kia
role = auth
artist = kia4
}
ArtistToBookDAO.new {
book = kp
role = auth
artist = kp1
}
val books = BookDAO.all().map(::daoToModel)
books.forEach { book ->
logger.debug { "### ${book.title}:" }
book.artists.forEach { atb ->
logger.debug { "### ${atb.role.role}: ${atb.artist.givenName} ${atb.artist.name}" }
} }
} }
}
*/
}
@@ -3,14 +3,14 @@ package net.keinekekse.app.server
import net.keinekekse.version.Version import net.keinekekse.version.Version
object VERSION: Version { object VERSION: Version {
override val version = "0.1.0-beta.1+build.35" override val version = "0.1.0-beta.1+build.41"
override val fullVersion = "0.1.0-beta.1+build.35" override val fullVersion = "0.1.0-beta.1+build.41"
override val major = 0 override val major = 0
override val minor = 1 override val minor = 1
override val patch = 0 override val patch = 0
override val preRelease = "beta.1" override val preRelease = "beta.1"
override val buildMetadata = "build.35" override val buildMetadata = "build.41"
override val buildDate = "2026-02-08T00:38:22.418116Z" override val buildDate = "2026-02-08T20:01:42.481884Z"
override val displayName = "kAS" override val displayName = "kAS"
override val copyright = "Copyright (c) 2026 Hartmut Bauer" override val copyright = "Copyright (c) 2026 Hartmut Bauer"
override val name = "server" override val name = "server"
@@ -9,7 +9,6 @@ import org.jetbrains.exposed.v1.jdbc.Database
fun Application.configureDatabase() { fun Application.configureDatabase() {
val config = HikariConfig().apply { val config = HikariConfig().apply {
// jdbcUrl = "jdbc:mysql://$host:$port/$db"
dataSourceClassName = "org.postgresql.ds.PGSimpleDataSource" dataSourceClassName = "org.postgresql.ds.PGSimpleDataSource"
username = getKeyFromConfiguration("postgres.user") username = getKeyFromConfiguration("postgres.user")
password = getKeyFromConfiguration("postgres.password") password = getKeyFromConfiguration("postgres.password")
@@ -34,14 +33,4 @@ fun Application.configureDatabase() {
// set other parameters here // set other parameters here
} }
) )
// Class.forName("org.postgresql.Driver")
// val host = getKeyFromConfiguration("postgres.host", "localhost")
// val port = getKeyFromConfiguration("postgres.port", "5432")
// val user = getKeyFromConfiguration("postgres.user")
// val password = getKeyFromConfiguration("postgres.password")
// val database = getKeyFromConfiguration("postgres.database", user)
//
// // "jdbc:postgresql://host:5432/database",
// return DriverManager.getConnection("jdbc:postgresql://$host:$port/$database", user, password)
} }
@@ -0,0 +1,20 @@
package net.keinekekse.app.server.testdb.db
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 ArtistsTable : IntIdTable("artists") {
var name = varchar("name", 50)
var givenName = varchar("given_name", 50)
}
class ArtistDAO(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<ArtistDAO>(ArtistsTable)
var name by ArtistsTable.name
var givenName by ArtistsTable.givenName
}
//fun daoToModel(dao: ArtistDAO) = Artist(dao.name, dao.givenName)
@@ -0,0 +1,16 @@
package net.keinekekse.app.server.testdb.db
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 ArtistRolesTable : IntIdTable("artist_roles") {
var role = varchar("role", 50)
}
class ArtistRoleDAO(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<ArtistRoleDAO>(ArtistRolesTable)
var role by ArtistRolesTable.role
}
@@ -0,0 +1,20 @@
package net.keinekekse.app.server.testdb.db
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 ArtistToBookTable : IntIdTable("artist_to_book") {
val artistId = reference("artist_id", ArtistsTable.id)
val bookId = reference("book_id", BooksTable.id)
val role = reference("role_id", ArtistRolesTable.id)
}
class ArtistToBookDAO(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<ArtistToBookDAO>(ArtistToBookTable)
var artist by ArtistDAO referencedOn ArtistToBookTable.artistId
var book by BookDAO referencedOn ArtistToBookTable.bookId
var role by ArtistRoleDAO referencedOn ArtistToBookTable.role
}
@@ -1,25 +1,36 @@
package net.keinekekse.app.server.testdb.db package net.keinekekse.app.server.testdb.db
import net.keinekekse.app.server.testdb.model.Book import net.keinekekse.app.server.testdb.model.*
import org.jetbrains.exposed.v1.core.dao.id.EntityID import org.jetbrains.exposed.v1.core.dao.id.EntityID
import org.jetbrains.exposed.v1.core.dao.id.LongIdTable import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
import org.jetbrains.exposed.v1.dao.LongEntity import org.jetbrains.exposed.v1.dao.IntEntity
import org.jetbrains.exposed.v1.dao.LongEntityClass import org.jetbrains.exposed.v1.dao.IntEntityClass
object BookTable : LongIdTable("book") { object BooksTable : IntIdTable("books") {
var title = varchar("title", 50) var title = varchar("title", 50)
var author = varchar("author", 50) var series = optReference("series_id", SeriesTable.id)
var series = varchar("series", 50)
var seriesIndex = integer("seriesIndex") var seriesIndex = integer("seriesIndex")
} }
class BookDAO(id: EntityID<Long>) : LongEntity(id) { class BookDAO(id: EntityID<Int>) : IntEntity(id) {
companion object : LongEntityClass<BookDAO>(BookTable) companion object : IntEntityClass<BookDAO>(BooksTable)
var title by BookTable.title var title by BooksTable.title
var author by BookTable.author var seriesIndex by BooksTable.seriesIndex
var series by BookTable.series
var seriesIndex by BookTable.seriesIndex var series by SeriesDAO optionalReferencedOn BooksTable.series
val artists by ArtistToBookDAO referrersOn ArtistToBookTable.bookId
} }
fun daoToModel(dao: BookDAO) = Book(dao.title, dao.author, dao.series, dao.seriesIndex) fun daoToModel(dao: BookDAO) = Book(
dao.id.value,
dao.title,
if (dao.series != null) Series(dao.series!!.id.value, dao.series!!.name) else null,
dao.seriesIndex,
dao.artists.map {
ArtistForBook(
Artist(it.artist.id.value, it.artist.name, it.artist.givenName),
ArtistRole(it.role.id.value, it.role.role)
)
}
)
@@ -0,0 +1,16 @@
package net.keinekekse.app.server.testdb.db
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 SeriesTable : IntIdTable("series") {
var name = varchar("name", 50)
}
class SeriesDAO(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<SeriesDAO>(SeriesTable)
var name by SeriesTable.name
}
@@ -0,0 +1,10 @@
package net.keinekekse.app.server.testdb.model
import kotlinx.serialization.Serializable
@Serializable
data class Artist(
val id: Int = 0,
val name: String = "",
val givenName: String = "",
)
@@ -0,0 +1,9 @@
package net.keinekekse.app.server.testdb.model
import kotlinx.serialization.Serializable
@Serializable
data class ArtistRole(
val id: Int = 0,
val role: String = "",
)
@@ -2,10 +2,15 @@ package net.keinekekse.app.server.testdb.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable
data class ArtistForBook(val artist: Artist, val role: ArtistRole)
@Serializable @Serializable
data class Book( data class Book(
var title: String = "", val id: Int = 0,
var author: String = "", val title: String = "",
var series: String = "", val series: Series? = null,
var seriesIndex: Int = 0, val seriesIndex: Int = 0,
val artists: List<ArtistForBook> = emptyList(),
) )
@@ -2,10 +2,10 @@ package net.keinekekse.app.server.testdb.model
interface BookRepository { interface BookRepository {
suspend fun allBooks(): List<Book> suspend fun allBooks(): List<Book>
suspend fun bookById(id: Long): Book? suspend fun bookById(id: Int): Book?
suspend fun booksBySeries(series: String): List<Book> suspend fun booksBySeries(series: Series): List<Book>
suspend fun bookByTitle(title: String): List<Book> suspend fun bookByTitle(title: String): List<Book>
suspend fun bookByAuthor(author: String): List<Book> suspend fun booksByArtist(artist: Artist): List<Book>
suspend fun addTBook(book: Book) suspend fun addTBook(book: Book)
suspend fun removeBook(id: Long): Boolean suspend fun removeBook(id: Int): Boolean
} }
@@ -5,11 +5,11 @@ class BookRepositoryImpl : BookRepository {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override suspend fun bookById(id: Long): Book? { override suspend fun bookById(id: Int): Book? {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override suspend fun booksBySeries(series: String): List<Book> { override suspend fun booksBySeries(series: Series): List<Book> {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
@@ -17,7 +17,7 @@ class BookRepositoryImpl : BookRepository {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override suspend fun bookByAuthor(author: String): List<Book> { override suspend fun booksByArtist(artist: Artist): List<Book> {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
@@ -25,7 +25,7 @@ class BookRepositoryImpl : BookRepository {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override suspend fun removeBook(id: Long): Boolean { override suspend fun removeBook(id: Int): Boolean {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
} }
@@ -0,0 +1,6 @@
package net.keinekekse.app.server.testdb.model
import kotlinx.serialization.Serializable
@Serializable
data class Series(val id: Int, val name: String)