All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.fuelyour.vertxkuickstartcore.tools.DbAccess.kt Maven / Gradle / Ivy

There is a newer version: 0.0.19
Show newest version
package dev.fuelyour.vertxkuickstartcore.tools

import io.vertx.core.Vertx
import io.vertx.core.json.JsonObject
import io.vertx.kotlin.pgclient.pgConnectOptionsOf
import io.vertx.kotlin.sqlclient.getConnectionAwait
import io.vertx.kotlin.sqlclient.poolOptionsOf
import io.vertx.pgclient.PgPool
import io.vertx.sqlclient.SqlClient

class DbAccessFactory(private val core: DbAccessCore) {
    fun  createWithContext(
        dbContextInit: (SqlClient) -> A
    ): DbAccess =
        DbAccess(core, dbContextInit)
}

class DbAccess(
    private val core: DbAccessCore,
    private val dbContextInit: (SqlClient) -> A
) {

    /**
     * Get a connection to the database.
     *
     * @param dbAction code block in which a connection to the database is
     * available
     */
    suspend fun  withConnection(dbAction: suspend A.() -> T): T =
        core.withConnection(dbContextInit, dbAction)

    /**
     * Get a transactional connection to the database. On success the
     * transaction is committed. On error the transaction is rolled back.
     *
     * @param dbAction code block in which a connection to the database is
     * available
     */
    suspend fun  inTransaction(dbAction: suspend A.() -> T): T =
        core.inTransaction(dbContextInit, dbAction)
}

interface DbContext

class BasicDbContext(val connection: SqlClient) : DbContext

interface DbAccessCore {
    suspend fun  withConnection(
        dbContextInit: (SqlClient) -> A,
        dbAction: suspend A.() -> T
    ): T

    suspend fun  inTransaction(
        dbContextInit: (SqlClient) -> A,
        dbAction: suspend A.() -> T
    ): T
}

/**
 * Establishes a connection to the database specified in the config,
 * and maintains a connection pool to that database.
 */
class DbAccessCoreImpl(config: JsonObject, vertx: Vertx) : DbAccessCore {
    private val pool: PgPool

    init {
        val connectionOptions = pgConnectOptionsOf(
            port = config.getInteger("SERVICE_DB_PORT"),
            host = config.getString("SERVICE_DB_HOST"),
            database = config.getString("SERVICE_DB_NAME"),
            user = config.getString("SERVICE_DB_USER"),
            password = config.getString("SERVICE_DB_PASSWORD"),
            properties = mapOf(
                "search_path" to config.getString(
                    "schema",
                    "public"
                )
            )
        )
        val poolOptions = poolOptionsOf(maxSize = 10)
        pool = PgPool.pool(vertx, connectionOptions, poolOptions)
    }

    override suspend fun  withConnection(
        dbContextInit: (SqlClient) -> A,
        dbAction: suspend A.() -> T
    ): T {
        val connection = pool.getConnectionAwait()
        val dbContext = dbContextInit(connection)
        val result: T
        try {
            result = dbContext.dbAction()
        } catch (ex: Exception) {
            throw ex
        } finally {
            try {
                connection.close()
            } catch (ignore: Exception) {
            }
        }
        return result
    }

    override suspend fun  inTransaction(
        dbContextInit: (SqlClient) -> A,
        dbAction: suspend A.() -> T
    ): T {
        val connection = pool.getConnectionAwait()
        val transaction = connection.begin()
        val dbContext = dbContextInit(connection)
        val result: T
        try {
            result = dbContext.dbAction()
            transaction.commit()
        } catch (ex: Exception) {
            transaction.rollback()
            throw ex
        } finally {
            try {
                connection.close()
            } catch (ignore: Exception) {
            }
        }
        return result
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy