🚧 Starts rework of database
This commit is contained in:
parent
42544a2478
commit
aa3e82010f
@ -33,7 +33,7 @@ dependencies {
|
|||||||
implementation("io.ktor:ktor-serialization-kotlinx-json")
|
implementation("io.ktor:ktor-serialization-kotlinx-json")
|
||||||
implementation("org.jetbrains.exposed:exposed-core:$exposed_version")
|
implementation("org.jetbrains.exposed:exposed-core:$exposed_version")
|
||||||
implementation("org.jetbrains.exposed:exposed-jdbc:$exposed_version")
|
implementation("org.jetbrains.exposed:exposed-jdbc:$exposed_version")
|
||||||
implementation("com.h2database:h2:$h2_version")
|
implementation("org.postgresql:postgresql:42.7.2")
|
||||||
implementation("io.github.flaxoos:ktor-server-rate-limiting:2.2.1")
|
implementation("io.github.flaxoos:ktor-server-rate-limiting:2.2.1")
|
||||||
implementation("io.ktor:ktor-server-compression")
|
implementation("io.ktor:ktor-server-compression")
|
||||||
implementation("io.ktor:ktor-server-netty")
|
implementation("io.ktor:ktor-server-netty")
|
||||||
|
14
backend/compose.yaml
Normal file
14
backend/compose.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
version: "3.3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:17
|
||||||
|
restart: on-failure
|
||||||
|
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: "user"
|
||||||
|
POSTGRES_PASSWORD: "password"
|
||||||
|
POSTGRES_DB: "db"
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
@ -10,6 +10,7 @@ import dev.svitan.plugins.configureHTTP
|
|||||||
import dev.svitan.plugins.configureMonitoring
|
import dev.svitan.plugins.configureMonitoring
|
||||||
import dev.svitan.plugins.configureRouting
|
import dev.svitan.plugins.configureRouting
|
||||||
import dev.svitan.plugins.configureSecurity
|
import dev.svitan.plugins.configureSecurity
|
||||||
|
import dev.svitan.plugins.configureSerialization
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
embeddedServer(
|
embeddedServer(
|
||||||
@ -25,8 +26,9 @@ fun Application.module() {
|
|||||||
|
|
||||||
configureHTTP()
|
configureHTTP()
|
||||||
configureRouting()
|
configureRouting()
|
||||||
configureDatabases()
|
|
||||||
configureMonitoring()
|
configureMonitoring()
|
||||||
|
configureSerialization()
|
||||||
configureAdministration()
|
configureAdministration()
|
||||||
configureSecurity(dotenv)
|
configureSecurity(dotenv)
|
||||||
|
configureDatabases(dotenv)
|
||||||
}
|
}
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
package dev.svitan
|
|
||||||
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import org.jetbrains.exposed.sql.*
|
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
|
||||||
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
|
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class ExposedUser(val name: String, val age: Int)
|
|
||||||
|
|
||||||
class UserService(database: Database) {
|
|
||||||
object Users : Table() {
|
|
||||||
val id = integer("id").autoIncrement()
|
|
||||||
val name = varchar("name", length = 50)
|
|
||||||
val age = integer("age")
|
|
||||||
|
|
||||||
override val primaryKey = PrimaryKey(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
transaction(database) {
|
|
||||||
SchemaUtils.create(Users)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun create(user: ExposedUser): Int = dbQuery {
|
|
||||||
Users.insert {
|
|
||||||
it[name] = user.name
|
|
||||||
it[age] = user.age
|
|
||||||
}[Users.id]
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun read(id: Int): ExposedUser? {
|
|
||||||
return dbQuery {
|
|
||||||
Users.selectAll()
|
|
||||||
.where { Users.id eq id }
|
|
||||||
.map { ExposedUser(it[Users.name], it[Users.age]) }
|
|
||||||
.singleOrNull()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun update(id: Int, user: ExposedUser) {
|
|
||||||
dbQuery {
|
|
||||||
Users.update({ Users.id eq id }) {
|
|
||||||
it[name] = user.name
|
|
||||||
it[age] = user.age
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun delete(id: Int) {
|
|
||||||
dbQuery {
|
|
||||||
Users.deleteWhere { Users.id.eq(id) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun <T> dbQuery(block: suspend () -> T): T =
|
|
||||||
newSuspendedTransaction(Dispatchers.IO) { block() }
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +1,34 @@
|
|||||||
package dev.svitan.plugins
|
package dev.svitan.plugins
|
||||||
|
|
||||||
|
import dev.svitan.schemas.UserDTO
|
||||||
|
import dev.svitan.schemas.UserService
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import io.ktor.server.request.*
|
import io.ktor.server.request.*
|
||||||
import io.ktor.server.response.*
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
import org.jetbrains.exposed.sql.Database
|
import org.jetbrains.exposed.sql.Database
|
||||||
import dev.svitan.ExposedUser
|
import io.github.cdimascio.dotenv.Dotenv
|
||||||
import dev.svitan.UserService
|
|
||||||
|
|
||||||
fun Application.configureDatabases() {
|
fun Application.configureDatabases(dotenv: Dotenv) {
|
||||||
val database = Database.connect(
|
val dbHost = dotenv["DB_HOST"] ?: throw Exception("DB_HOST not found")
|
||||||
url = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1",
|
val dbPort = dotenv["DB_PORT"] ?: throw Exception("DB_PORT not found")
|
||||||
user = "root",
|
val dbName = dotenv["DB_NAME"] ?: throw Exception("DB_NAME not found")
|
||||||
driver = "org.h2.Driver",
|
val dbUser = dotenv["DB_USER"] ?: throw Exception("DB_USER not found")
|
||||||
password = "",
|
val dbPassword = dotenv["DB_PASSWORD"] ?: throw Exception("DB_PASSWORD not found")
|
||||||
|
|
||||||
|
Database.connect(
|
||||||
|
url = "jdbc:postgresql://${dbHost}:${dbPort}/${dbName}",
|
||||||
|
driver = "org.postgresql.Driver",
|
||||||
|
user = dbUser,
|
||||||
|
password = dbPassword
|
||||||
)
|
)
|
||||||
val userService = UserService(database)
|
val userService = UserService()
|
||||||
|
|
||||||
routing {
|
routing {
|
||||||
// Create user
|
// Create user
|
||||||
post("/users") {
|
post("/users") {
|
||||||
val user = call.receive<ExposedUser>()
|
val user = call.receive<UserDTO>()
|
||||||
val id = userService.create(user)
|
val id = userService.create(user)
|
||||||
call.respond(HttpStatusCode.Created, id)
|
call.respond(HttpStatusCode.Created, id)
|
||||||
}
|
}
|
||||||
@ -39,7 +47,7 @@ fun Application.configureDatabases() {
|
|||||||
// Update user
|
// Update user
|
||||||
put("/users/{id}") {
|
put("/users/{id}") {
|
||||||
val id = call.parameters["id"]?.toInt() ?: throw IllegalArgumentException("Invalid ID")
|
val id = call.parameters["id"]?.toInt() ?: throw IllegalArgumentException("Invalid ID")
|
||||||
val user = call.receive<ExposedUser>()
|
val user = call.receive<UserDTO>()
|
||||||
userService.update(id, user)
|
userService.update(id, user)
|
||||||
call.respond(HttpStatusCode.OK)
|
call.respond(HttpStatusCode.OK)
|
||||||
}
|
}
|
||||||
|
12
backend/src/main/kotlin/plugins/Serialization.kt
Normal file
12
backend/src/main/kotlin/plugins/Serialization.kt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package dev.svitan.plugins
|
||||||
|
|
||||||
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
|
import io.ktor.server.application.Application
|
||||||
|
import io.ktor.server.application.install
|
||||||
|
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
|
||||||
|
|
||||||
|
fun Application.configureSerialization() {
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
}
|
56
backend/src/main/kotlin/schemas/UsersSchema.kt
Normal file
56
backend/src/main/kotlin/schemas/UsersSchema.kt
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package dev.svitan.schemas
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.jetbrains.exposed.sql.*
|
||||||
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class UserDTO(val name: String, val age: Int)
|
||||||
|
|
||||||
|
class UserService {
|
||||||
|
object Users : Table("users") {
|
||||||
|
val id = integer("id").autoIncrement()
|
||||||
|
val name = varchar("name", length = 50)
|
||||||
|
val age = integer("age")
|
||||||
|
|
||||||
|
override val primaryKey = PrimaryKey(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
transaction {
|
||||||
|
SchemaUtils.create(Users)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(user: UserDTO): Int =
|
||||||
|
transaction {
|
||||||
|
Users.insert {
|
||||||
|
it[name] = user.name
|
||||||
|
it[age] = user.age
|
||||||
|
}[Users.id]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun read(id: Int): UserDTO? =
|
||||||
|
transaction {
|
||||||
|
Users.selectAll()
|
||||||
|
.where { Users.id eq id }
|
||||||
|
.map { UserDTO(it[Users.name], it[Users.age]) }
|
||||||
|
.singleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update(id: Int, user: UserDTO) {
|
||||||
|
transaction {
|
||||||
|
Users.update({ Users.id eq id }) {
|
||||||
|
it[name] = user.name
|
||||||
|
it[age] = user.age
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun delete(id: Int) {
|
||||||
|
transaction {
|
||||||
|
Users.deleteWhere { Users.id.eq(id) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user