Last active
July 15, 2023 12:42
-
-
Save felix19350/bcb39e50820dcc6872f624d2e925dd9a to your computer and use it in GitHub Desktop.
Revisions
-
felix19350 revised this gist
Feb 21, 2019 . 1 changed file with 6 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -27,7 +27,7 @@ data class CreateMyAppUserCommand(val email: String, val realName: String) // Core service definition internal interface MyAppUserService { suspend fun list(): List<MyAppUser> suspend fun create(newUserCmd: CreateMyAppUserCommand): MyAppUser } // Data store connection setup shennanigans @@ -80,11 +80,11 @@ internal class MyAppUserServiceImpl(private val dbc: DatastoreConnection) : MyAp } } override suspend fun create(newUserCmd: CreateMyAppUserCommand): MyAppUser { return dbc.query { MyAppUserDAO.new { this.email = newUserCmd.email this.realName = newUserCmd.realName }.toModel() } } @@ -100,8 +100,8 @@ fun Route.sampleApi() { } post("/myUsers") { //Don't forget to validate the input... val newUser = service.create(call.receive()) call.respond(HttpStatusCode.OK, newUser) } } -
felix19350 created this gist
Feb 21, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,107 @@ package org.example import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.HikariDataSource import io.ktor.application.call import io.ktor.http.HttpStatusCode import io.ktor.request.receive import io.ktor.response.respond import io.ktor.routing.Route import io.ktor.routing.get import io.ktor.routing.post import kotlinx.coroutines.experimental.Dispatchers import kotlinx.coroutines.experimental.withContext import org.jetbrains.exposed.dao.EntityID import org.jetbrains.exposed.dao.LongEntity import org.jetbrains.exposed.dao.LongEntityClass import org.jetbrains.exposed.dao.LongIdTable import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.transactions.transaction import javax.sql.DataSource // Data model - data classes for input and output formats data class MyAppUser(val email: String, val realName: String) data class CreateMyAppUserCommand(val email: String, val realName: String) // Core service definition internal interface MyAppUserService { suspend fun list(): List<MyAppUser> suspend fun create(email: String, realName: String): MyAppUser } // Data store connection setup shennanigans fun quickNDirtyDb(): DataSource { return HikariDataSource(HikariConfig().apply { poolName = "HIKARI-POOL" driverClassName = "org.h2.Driver" jdbcUrl = "jdbc:h2:mem:test" maximumPoolSize = 5 isAutoCommit = false transactionIsolation = "TRANSACTION_READ_COMMITTED" validate() }) } class DatastoreConnection(private val dataSource: DataSource) { private val database: Database by lazy { Database.connect(dataSource) } suspend fun <T> query(block: () -> T): T = withContext(Dispatchers.IO) { transaction(database) { block() } } } // Object relational mapping internal object MyAppUserTable : LongIdTable("my_app_user_table") { val email = varchar("user_email", 255).uniqueIndex() val realName = varchar("real_name", 255) } internal class MyAppUserDAO(id: EntityID<Long>) : LongEntity(id) { companion object : LongEntityClass<MyAppUserDAO>(MyAppUserTable) var email by MyAppUserTable.email var realName by MyAppUserTable.realName fun toModel(): MyAppUser { return MyAppUser(email, realName) } } // Service implementation for datastore of choice internal class MyAppUserServiceImpl(private val dbc: DatastoreConnection) : MyAppUserService { override suspend fun list(): List<MyAppUser> { return dbc.query { MyAppUserDAO.all().map { it.toModel() } } } override suspend fun create(email: String, realName: String): MyAppUser { return dbc.query { MyAppUserDAO.new { this.email = email this.realName = realName }.toModel() } } } //REST-ish API fun Route.sampleApi() { val service: MyAppUserService = MyAppUserServiceImpl(DatastoreConnection(quickNDirtyDb())) get("/myUsers") { call.respond(HttpStatusCode.OK, service.list()) } post("/myUsers") { val command: CreateMyAppUserCommand = call.receive() val newUser = service.create(command.email, command.realName) call.respond(HttpStatusCode.OK, newUser) } }