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 摘要。