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

jvmMain.kr.jadekim.jext.exposed.koin.module.kt Maven / Gradle / Ivy

There is a newer version: 2.1.4
Show newest version
package kr.jadekim.jext.exposed.koin

import com.zaxxer.hikari.HikariDataSource
import kr.jadekim.jext.exposed.CrudDB
import kr.jadekim.jext.exposed.DB
import kr.jadekim.jext.exposed.ReadDB
import kr.jadekim.jext.koin.extension.getInt
import kr.jadekim.jext.koin.extension.getString
import org.koin.core.module.Module
import org.koin.core.module.dsl.binds
import org.koin.core.module.dsl.withOptions
import org.koin.core.qualifier.StringQualifier
import org.koin.core.scope.Scope
import org.koin.dsl.onClose
import java.io.Closeable
import java.lang.Integer.max
import java.time.Duration
import javax.sql.DataSource

private val DSQualifier.poolSizeQualifier
    get() = StringQualifier(this.value + "-poolSize")

fun Module.dataSource(
    qualifier: DSQualifier,
    autoConnect: Boolean = true,
    autoClose: Boolean = true,
    poolSizeHint: (Scope.() -> Int)? = null,
    dataSource: Scope.() -> DataSource
) {
    single(qualifier) {
        dataSource().apply {
            if (autoConnect) {
                //initial with startup
                connection.close()
            }
        }
    }.onClose {
        if (autoClose) {
            if (it is Closeable) {
                it.close()
            } else if (it is AutoCloseable) {
                it.close()
            }
        }
    }

    if (poolSizeHint != null) {
        single(qualifier.poolSizeQualifier) { poolSizeHint() }
    }
}

fun Module.dataSource(
    qualifier: DSQualifier,
    driver: String,
    url: String,
    username: String,
    password: String,
    isReadOnly: Boolean = false,
    name: String = qualifier.name,
    poolSize: Int = 5,
    autoConnect: Boolean = true,
    configure: HikariDataSource.() -> Unit = {}
) {
    dataSource(qualifier, autoConnect, true, { poolSize }) {
        HikariDataSource().apply {
            this.driverClassName = driver
            this.jdbcUrl = url
            this.username = username
            this.password = password
            this.poolName = name
            this.isReadOnly = isReadOnly
            this.maximumPoolSize = poolSize
            connectionTimeout = Duration.ofSeconds(5).toMillis()
            configure()
        }
    }
}

fun Module.dataSource(
    qualifier: DSQualifier,
    isReadOnly: Boolean = false,
    name: String = qualifier.name,
    propertyPrefix: String = if (isReadOnly) "db.$name.readonly." else "db.$name.",
    autoConnect: Boolean = true,
    configure: HikariDataSource.() -> Unit = {}
) {
    dataSource(qualifier, autoConnect, true, { getInt(propertyPrefix + "pool.size", 5) }) {
        HikariDataSource().apply {
            driverClassName = getString(propertyPrefix + "driver")
            jdbcUrl = getString(propertyPrefix + "url")
            username = getString(propertyPrefix + "username")
            password = getString(propertyPrefix + "password")
            poolName = name
            this.maximumPoolSize = getInt(propertyPrefix + "pool.size", 5)
            this.isReadOnly = isReadOnly
            connectionTimeout = Duration.ofSeconds(5).toMillis()
            configure()
        }
    }
}

fun Module.db(
    qualifier: DBQualifier,
    crudDsQualifier: DSQualifier,
    readDSQualifier: DSQualifier,
    threadCount: Int? = null,
    shareThread: Boolean = false,
    configure: (CrudDB) -> CrudDB = { it }
) {
    single(qualifier) {
        val crudDataSource = get(crudDsQualifier)
        val readDataSource = get(readDSQualifier)

        var threadCountValue = threadCount
        if (threadCountValue == null) {
            val crudPoolSize = get(crudDsQualifier.poolSizeQualifier)
            val readPoolSize = get(readDSQualifier.poolSizeQualifier)

            threadCountValue = if (shareThread) {
                max(crudPoolSize, readPoolSize)
            } else {
                crudPoolSize + readPoolSize
            }
        }

        configure(CrudDB(crudDataSource, readDataSource, threadCountValue))
    } withOptions {
        binds(listOf(ReadDB::class))
    }
}

fun Module.db(
    qualifier: DBQualifier,
    createDataSource: Boolean = true,
    withReadOnly: Boolean = false,
    autoConnect: Boolean = true,
    threadCount: Int? = null,
    configureDataSource: HikariDataSource.() -> Unit = {},
    configure: (CrudDB) -> CrudDB = { it }
) {
    if (createDataSource) {
        dataSource(
            qualifier.crudDSQualifier,
            autoConnect = autoConnect,
            configure = configureDataSource
        )

        if (withReadOnly) {
            dataSource(
                qualifier.readDSQualifier,
                isReadOnly = true,
                autoConnect = autoConnect,
                configure = configureDataSource
            )
        } else {
            dataSource(
                qualifier.readDSQualifier,
                autoConnect,
                true,
                { get(qualifier.crudDSQualifier.poolSizeQualifier) },
                { get(qualifier.crudDSQualifier) }
            )
        }
    }

    db(qualifier, qualifier.crudDSQualifier, qualifier.readDSQualifier, threadCount, !withReadOnly, configure)
}

fun Module.readDB(
    qualifier: DBQualifier,
    dsQualifier: DSQualifier,
    threadCount: Int? = null,
    configure: (ReadDB) -> ReadDB = { it }
) {
    single(qualifier) {
        configure(ReadDB(get(dsQualifier), threadCount ?: get(dsQualifier.poolSizeQualifier)))
    }
}

fun Module.readDB(
    qualifier: DBQualifier,
    createDataSource: Boolean = true,
    autoConnect: Boolean = true,
    threadCount: Int? = null,
    configureDataSource: HikariDataSource.() -> Unit = {},
    configure: (ReadDB) -> ReadDB = { it }
) {
    if (createDataSource) {
        dataSource(
            qualifier.readDSQualifier,
            isReadOnly = true,
            autoConnect = autoConnect,
            configure = configureDataSource
        )
    }

    readDB(qualifier, qualifier.readDSQualifier, threadCount, configure)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy