A great example by <@U0RM4EPC7> using the new Effe...
# arrow
r
A great example by @simon.vergauwen using the new Effect interface and arrow-continuations to create a DB effect block that can rollback transactions and handle DB results in the context of Either 👏 https://twitter.com/vergauwen_simon/status/1402897198296276992
👏 7
👌 2
💯 3
🎉 6
t
@simon.vergauwen I just noticed a small error: https://gist.github.com/nomisRev/b6aced8ce552ae718791e187ebd6cdd4#file-transactioneither-kt-L33 should it be
listOf(Either.Right("test-1"), Either.Right("test-2"), Either.Right("test-3"))
instead of
listOf(Either.Right("test-1"), Either.Left("test-2"), Either.Right("test-3"))
p
that looks quite interesting, I was looking for something like this. Any idea on how complicated would be to incorporate that into some
javax.transaction
implementation so we could mark methods with
@Transactional
but having
Either
return types ? (not sure if I make myself clear)
s
@Pedro Sena does this have any programmatic API? I think with Spring we can easily do this, and IIRC the programmatic API from Spring automatically works with any surrounding
@Transactional
.
Thank you @thanh for pointing that out!!
l
@simon.vergauwen I'm trying to adapt your
transactionEither
example to recent versions of Arrow and SQLDelight but thought I'd ask, do you already have an updated example? Or has this idea ever made its way into a library?
s
This has never made it into a library. Are you looking at this gist? https://gist.github.com/nomisRev/b6aced8ce552ae718791e187ebd6cdd4
You don't really need that anymore, as you could simply do this. Important to note is that when the
either { }
is on the outside it will rollback on
Left
, and exceptions, when it's on the inside it will never rollback on
Left
but only on exceptions.
Copy code
either {
  transactionWithResult { 
   
  }
}
l
Hey @simon.vergauwen! Yes we were looking at that gist. I know it's 2 years old but it's the only reference we could find for using Arrow Either in tandem with SQLDelight transactions. Thanks for explaining it really is that simple now, without the historical perspective on how the libraries have changed we ended up over complicating it. Moving forward, we're using
either { }
on the outside of
transactionWithResult { }
as you suggested! Thank you. However we missed the simplicity of the implied right/left typing in the
either
DSL – working within the
transactionWithResult
DSL we need to provide "rolled back" results wrapped in a Left and successful results wrapped in a Right. So we made another extension function for our project that makes the types as simple as the
either
DSL but automatically rolls back the transaction if any error is raised.
Copy code
import app.cash.sqldelight.Transacter
import arrow.core.Either
import arrow.core.left
import arrow.core.raise.Raise
import arrow.core.raise.either

fun <Error, A> Transacter.transactionEither(block: Raise<Error>.() -> A): Either<Error, A> {
  return transactionWithResult { either { block() }.onLeft { error -> rollback(error.left()) } }
}
It's making it easier to establish a convention in our codebase. I thought I'd share as an example for the search results and in case anyone has an even better way to share.