Skip to content

Commit

Permalink
Add ZIO module providing connect and transact mechanism adapted t…
Browse files Browse the repository at this point in the history
…o ZIO
  • Loading branch information
guizmaii committed Oct 9, 2024
1 parent eaafac8 commit 7c3d2f9
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 1 deletion.
13 changes: 12 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ val testcontainersVersion = "0.40.12"

lazy val root = project
.in(file("."))
.aggregate(magnum, magnumPg)
.aggregate(magnum, magnumPg, magnumZio)

lazy val magnum = project
.in(file("magnum"))
Expand Down Expand Up @@ -73,3 +73,14 @@ lazy val magnumPg = project
"com.dimafeng" %% "testcontainers-scala-postgresql" % testcontainersVersion % Test
)
)

lazy val magnumZio = project
.in(file("magnum-zio"))
.dependsOn(magnum)
.settings(
Test / fork := true,
publish / skip := false,
libraryDependencies ++= Seq(
"dev.zio" %% "zio" % "2.1.9" % Provided
)
)
100 changes: 100 additions & 0 deletions magnum-zio/src/main/scala/com/augustnagro/magnum/zio/zio.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package com.augustnagro.magnum.zio

import _root_.zio.{Trace, ZIO}
import com.augustnagro.magnum.*

import javax.sql.DataSource
import scala.util.control.NonFatal

/** Executes a given query on a given DataSource
*
* Re-implementation of
* [[com.augustnagro.magnum.connect(dataSource: DataSource)]] for ZIO
*
* Usage:
* {{{
* connect(datasource) { cn ?=> repo.findById(id) }
* }}}
*/
def connect[A](dataSource: DataSource)(q: DbCon ?=> A)(implicit
trace: Trace
): ZIO[Any, Throwable, A] =
connect(Transactor(dataSource))(cn ?=> q(using cn))

/** Executes a given query on a given Transactor
*
* Re-implementation of
* [[com.augustnagro.magnum.connect(dataSource: DataSource)]] for ZIO
*
* Usage:
* {{{
* connect(transactor) { cn ?=> repo.findById(id) }
* }}}
*/
def connect[A](
transactor: Transactor
)(q: DbCon ?=> A)(implicit trace: Trace): ZIO[Any, Throwable, A] =
ZIO.blocking {
ZIO.acquireReleaseWith(
acquire = ZIO.attempt(transactor.dataSource.getConnection())
)(release =
conn => ZIO.attempt(if (conn ne null) conn.close() else ()).orDie
) { cn =>
ZIO.attempt {
transactor.connectionConfig(cn)
q(using DbCon(cn, transactor.sqlLogger))
}
}
}

/** Executes a given transaction on a given DataSource
*
* Re-implementation of
* [[com.augustnagro.magnum.transact(transactor: Transactor)]] for ZIO
*
* Usage:
* {{{
* transact(dataSource) { tx ?=> repo.insertReturning(creator) }
* }}}
*/
def transact[A](dataSource: DataSource)(q: DbTx ?=> A)(implicit
trace: Trace
): ZIO[Any, Throwable, A] =
transact(Transactor(dataSource))(tx ?=> q(using tx))

/** Executes a given transaction on a given Transactor
*
* Re-implementation of
* [[com.augustnagro.magnum.transact(transactor: Transactor)]] for ZIO
*
* Usage:
* {{{
* transact(transactor) { tx ?=> repo.insertReturning(creator) }
* }}}
*/
def transact[A](
transactor: Transactor
)(q: DbTx ?=> A)(implicit trace: Trace): ZIO[Any, Throwable, A] =
ZIO.blocking {
ZIO.acquireReleaseWith(
acquire = ZIO.attempt(transactor.dataSource.getConnection())
)(release =
conn => ZIO.attempt(if (conn ne null) conn.close() else ()).orDie
) { cn =>
ZIO.uninterruptible {
ZIO.attempt {
transactor.connectionConfig(cn)
cn.setAutoCommit(false)
try {
val res = q(using DbTx(cn, transactor.sqlLogger))
cn.commit()
res
} catch {
case NonFatal(t) =>
cn.rollback()
throw t
}
}
}
}
}

0 comments on commit 7c3d2f9

Please sign in to comment.