[history] Scopes for transaction and prepared statement
This commit is contained in:
commit
b75b9ef415
@ -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
|
||||||
|
}
|
@ -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) }
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user