Skip to content

Instantly share code, notes, and snippets.

@nomisRev
Last active November 22, 2021 09:03
Show Gist options
  • Save nomisRev/da2980c726e365f1954073ba1e287eff to your computer and use it in GitHub Desktop.
Save nomisRev/da2980c726e365f1954073ba1e287eff to your computer and use it in GitHub Desktop.
Either based transaction with Exposed. https://github.com/JetBrains/Exposed
suspend fun main() {
val q1: Query<String, Int> = query<String, Int> {
val x = "1".right().bind()
ensureNotNull(x.toIntOrNull()) { "Was not a int string" }
}
val q2: Query<String, Double> = query<String, Double> {
val int = q1.invoke().bind()
int.toDouble()
}
q2.transact()
}
import arrow.core.Either
import arrow.core.computations.EitherEffect
import arrow.core.computations.either
import kotlinx.coroutines.Dispatchers
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
typealias Query<E, A> = suspend () -> Either<E, A>
fun <E, A> query(f: suspend EitherEffect<E, *>.() -> A): Query<E, A> =
suspend { either(f) }
suspend fun <E, A> Query<E, A>.transact(): Either<E, A> =
newSuspendedTransaction(Dispatchers.IO) {
either {
try {
invoke()
.tapLeft { rollback() }
.bind()
} catch (e: Throwable) {
rollback()
throw e
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment