AbsaOSS / AbsaOSS/fa-db

Expose ConnectionIO API for Doobie module

オープン
#110 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る
enhancement
主要言語
Scala
スター
2
フォーク
0
平均マージ
3日 18時間
マージ済み PR(30日)
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 を短くまとめたダイジェスト。