AbsaOSS / AbsaOSS/fa-db

Expose ConnectionIO API for Doobie module

未关闭
#110 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
enhancement
主要语言
Scala
星标
2
派生
0
平均合并
3 天 18 小时
30 天内合并 PR
3

描述

## 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.

贡献指南

这个仓库没有索引到贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。