Files
vst-ui-base/src/jvmMain/kotlin/nl/astraeus/vst/base/db/Database.kt
2024-08-09 19:54:36 +02:00

85 lines
2.0 KiB
Kotlin

package nl.astraeus.vst.base.db
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import nl.astraeus.vst.base.Settings
import java.sql.Connection
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
val DATABASE_MIGRATIONS = arrayOf<Migration>(
Migration.Query(
"""
CREATE TABLE DATABASE_VERSION (
ID INTEGER PRIMARY KEY,
QUERY TEXT,
EXECUTED TIMESTAMP
)
""".trimIndent()
),
Migration.Query(PATCH_CREATE_QUERY),
)
object Database {
private var ds: HikariDataSource? = null
private val currentConnection = ThreadLocal<Connection>()
fun start() {
Class.forName("nl.astraeus.jdbc.Driver")
val properties = Properties()
properties["journal_mode"] = "WAL"
val config = HikariConfig().apply {
driverClassName = Settings.jdbcDriver
jdbcUrl = Settings.jdbcConnectionUrl
username = Settings.jdbcUser
password = Settings.jdbcPassword
maximumPoolSize = 25
isAutoCommit = false
validate()
}
config.dataSourceProperties = properties
config.addDataSourceProperty("cachePrepStmts", "true")
config.addDataSourceProperty("prepStmtCacheSize", "250")
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048")
ds = HikariDataSource(config)
Migrations.databaseVersionTableCreated = AtomicBoolean(false)
Migrations.updateDatabaseIfNeeded(DATABASE_MIGRATIONS)
}
private fun getConnection() = ds?.connection ?: error("Database has not been initialized!")
fun <T> transaction(
block: (Connection) -> T
): T {
val hasConnection = currentConnection.get() != null
if (!hasConnection) {
currentConnection.set(getConnection())
}
val connection = currentConnection.get()
try {
val result = block(connection)
if (!hasConnection) {
connection.commit()
}
return result
} finally {
if (!hasConnection) {
connection.close()
currentConnection.remove()
}
}
}
}