[history] Scopes for transaction and prepared statement

This commit is contained in:
Andrew Golovashevich 2024-08-19 05:23:00 +03:00
commit b75b9ef415
2 changed files with 65 additions and 0 deletions

View File

@ -0,0 +1,9 @@
package ru.landgrafhomyak.db.jdbc_kotlin_extensions
import java.sql.PreparedStatement
import java.sql.ResultSet
public interface PreparedStatementPrepareAndFetch<R> {
public fun prepare(ps: PreparedStatement)
public fun mapOne(rs: ResultSet): R
}

View File

@ -0,0 +1,56 @@
@file:JvmName("ExtensionsKt")
@file:Suppress("SqlSourceToSinkFlow")
@file:OptIn(ExperimentalContracts::class)
package ru.landgrafhomyak.db.jdbc_kotlin_extensions
import java.sql.Connection
import java.sql.PreparedStatement
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
public fun <R> Connection.mapQuery(sql: String, action: PreparedStatementPrepareAndFetch<R>, to: MutableList<R>) {
this.prepareStatement(sql).use { ps ->
action.prepare(ps)
ps.executeQuery().use { rs ->
while (rs.next()) {
to.add(action.mapOne(rs))
}
}
}
}
public fun <R> Connection.mapQuery(sql: String, action: PreparedStatementPrepareAndFetch<R>): List<R> {
val out = ArrayList<R>()
this.mapQuery(sql, action, out)
return out
}
public inline fun <R> Connection.transaction(t: (Connection) -> R): R {
contract {
callsInPlace(t)
}
this.prepareStatement("BEGIN TRANSACTION").use { ps -> ps.executeUpdate() }
val r: R
try {
r = t(this)
} catch (e1: Throwable) {
try {
this.prepareStatement("ROLLBACK TRANSACTION").use { ps -> ps.executeUpdate() }
} catch (e2: Throwable) {
e1.addSuppressed(e2)
}
throw e1
}
this.prepareStatement("COMMIT TRANSACTION").use { ps -> ps.executeUpdate() }
return r
}
public inline fun <R> Connection.prepareStatement(sql: String, action: (PreparedStatement) -> R): R {
contract {
callsInPlace(action)
}
this.prepareStatement(sql).use { ps -> return action(ps) }
}