Expose ConnectionIO API for Doobie module
- Dominant language
- Scala
- Stars
- 2
- Forks
- 0
- Avg merge
- 3d 18h
- Merged PRs (30d)
- 3
Description
## Background
At the moment the DoobieEngine executes queries within a single complete transaction. Nevertheless Doobie offers also ConnectionIO API which allows to process several queries as one transaction within a for-comprehension block. In other words ConnectionIO allows for functional composition given it's a Monad.
```scala
val xa = Transactor.fromDriverManager[IO](
driver = "org.postgresql.Driver",
url = "jdbc:postgresql:world",
user = "postgres",
password = "password"
)
val program: ConnectionIO[(Int, Double)] =
for {
a <- sql"select 42".query[Int].unique // here imagine our db function invocation with connectionIO
b <- sql"select random()".query[Double].unique // here imagine our db function invocation with connectionIO
} yield (a, b)
program.transact(xa).unsafeRunSync()
```
As mentioned above the DoobieEngine currently defines the operation in terms of higher-kinded effect type F[_].
```scala
private def executeQuery[R](query: QueryType[R])(implicit readR: Read[R]): F[Seq[R]] = {
query.fragment.query[R].to[Seq].transact(transactor)
}
```
We could expose also the ConnectionIO. ConnectionIO is not tied to cats.effect.IO or any other specific effect type. ConnectionIO[A] is simply a type alias for Free[ConnectionOp, A], where ConnectionOp is a type that represents a low-level JDBC operation and Free is a type from the Cats library that represents a computation in the free monad of a functor.
```scala
private def executeQueryConnectionIO[R](query: QueryType[R])(implicit readR: Read[R]): ConnectionIO[Seq[R]] = {
query.fragment.query[R].to[Seq]
}
```
Having access to ConnectionIO API we could implement better integration tests as we could execute multiple database calls withing a single transaction.
Moreover Transactor's Strategy can be configured as needed for the purposes of testing, for instance setting auto-rollback.
```scala
val testXa = Transactor.after.set(xa, HC.rollback)
```
Compositionality of ConnectionIO together with Transactor with rollback effectively enables easy integration testing of our database functions. No additional testing library would be needed. Test assertions could be performed within a for-comprehension block (transaction boundary) and automatically rolled back.
Unfortunately Slick and Doobie have very different APIs and this posses a design challenge. Ideally we would like to keep Slick and Doobie APIs exposed by fa-db the same for features supported by both libraries and at the same time expose functionality Doobie offers.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.