Skip to content

Commit

Permalink
Upgrades to ZIO 2.0.0-RC6 (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
gaelrenoux authored Jun 19, 2022
1 parent 6c35318 commit 421af06
Show file tree
Hide file tree
Showing 18 changed files with 125 additions and 127 deletions.
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ scalacOptions ++= allVersionsOption ++ {
}


val ZioVersion = "2.0.0-RC5"
val ZioCatsVersion = "3.3.0-RC5"
val ZioVersion = "2.0.0-RC6"
val ZioCatsVersion = "3.3.0-RC7"
val DoobieVersion = "1.0.0-RC2"
val AnormVersion = "2.6.10"
val H2Version = "1.4.200"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ object ConnectionSource {
trait Service {

def runTransaction[R, E, A](task: Connection => ZIO[R, E, A], commitOnFailure: => Boolean = false)
(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[R, Either[DbException, E], A]
(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[R, Either[DbException, E], A]

def runAutoCommit[R, E, A](task: Connection => ZIO[R, E, A])
(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[R, Either[DbException, E], A]
(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[R, Either[DbException, E], A]
}

/** ConnectionSource with standard behavior. Children class need to implement `getConnection`. */
Expand All @@ -24,11 +24,11 @@ object ConnectionSource {
) extends ConnectionSource.Service {

/** Main function: how to obtain a connection. Needs to be provided. */
protected def getConnection(implicit trace: ZTraceElement): Task[Connection]
protected def getConnection(implicit trace: Trace): Task[Connection]

def runTransaction[R, E, A](task: Connection => ZIO[R, E, A], commitOnFailure: => Boolean = false)
(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[R, Either[DbException, E], A] =
openConnection.mapError(Left(_)).acquireReleaseWith(closeConnection(_).orDie) { c: Connection =>
(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[R, Either[DbException, E], A] = {
ZIO.acquireReleaseWith(openConnection.mapError(Left(_)))(closeConnection(_).orDie) { c: Connection =>
setAutoCommit(c, autoCommit = false)
.mapError(Left(_))
.zipRight(task(c).mapError(Right(_)))
Expand All @@ -37,10 +37,11 @@ object ConnectionSource {
_ => commitConnection(c).mapError(Left(_))
)
}
}

def runAutoCommit[R, E, A](task: Connection => ZIO[R, E, A])
(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[R, Either[DbException, E], A] =
openConnection.mapError(Left(_)).acquireReleaseWith(closeConnection(_).orDie) { c: Connection =>
(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[R, Either[DbException, E], A] =
ZIO.acquireReleaseWith(openConnection.mapError(Left(_)))(closeConnection(_).orDie) { c: Connection =>
setAutoCommit(c, autoCommit = true)
.mapError(Left(_))
.zipRight {
Expand All @@ -53,34 +54,34 @@ object ConnectionSource {
private def bottomErrorStrategy(implicit errorStrategies: ErrorStrategiesRef) =
errorStrategies.orElse(defaultErrorStrategies).orElseDefault

def openConnection(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[Any, DbException, Connection] =
def openConnection(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[Any, DbException, Connection] =
wrap(bottomErrorStrategy.openConnection) {
getConnection.mapError(e => DbException.Wrapped(e))
}

def setAutoCommit(c: => Connection, autoCommit: => Boolean)
(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[Any, DbException, Unit] =
(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[Any, DbException, Unit] =
wrap(bottomErrorStrategy.setAutoCommit) {
attemptBlocking(c.setAutoCommit(autoCommit))
}

def commitConnection(c: => Connection)(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[Any, DbException, Unit] =
def commitConnection(c: => Connection)(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[Any, DbException, Unit] =
wrap(bottomErrorStrategy.commitConnection) {
attemptBlocking(c.commit())
}

def rollbackConnection(c: => Connection)(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[Any, DbException, Unit] =
def rollbackConnection(c: => Connection)(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[Any, DbException, Unit] =
wrap(bottomErrorStrategy.rollbackConnection) {
attemptBlocking(c.rollback())
}

/** Cannot fail */
def closeConnection(c: => Connection)(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[Any, DbException, Unit] =
def closeConnection(c: => Connection)(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[Any, DbException, Unit] =
wrap(bottomErrorStrategy.closeConnection) {
attemptBlocking(c.close())
}

private def wrap[R, A](es: ErrorStrategy)(z: => ZIO[Any, Throwable, A])(implicit trace: ZTraceElement) = es {
private def wrap[R, A](es: ErrorStrategy)(z: => ZIO[Any, Throwable, A])(implicit trace: Trace) = es {
z.mapError(e => DbException.Wrapped(e))
}

Expand All @@ -92,7 +93,7 @@ object ConnectionSource {
defaultErrorStrategies: ErrorStrategiesRef
) extends ServiceBase(defaultErrorStrategies) {

override def getConnection(implicit trace: ZTraceElement): RIO[Any, Connection] = attemptBlocking {
override def getConnection(implicit trace: Trace): RIO[Any, Connection] = attemptBlocking {
dataSource.getConnection()
}
}
Expand All @@ -105,18 +106,18 @@ object ConnectionSource {
defaultErrorStrategies: ErrorStrategiesRef
) extends ServiceBase(defaultErrorStrategies) {

override def getConnection(implicit trace: ZTraceElement): UIO[Connection] = UIO.succeed(connection)
override def getConnection(implicit trace: Trace): UIO[Connection] = ZIO.succeed(connection)

override def closeConnection(c: => Connection)(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[Any, Nothing, Unit] = ZIO.unit
override def closeConnection(c: => Connection)(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[Any, Nothing, Unit] = ZIO.unit

override def runTransaction[R, E, A](task: Connection => ZIO[R, E, A], commitOnFailure: => Boolean)
(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[R, Either[DbException, E], A] =
(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[R, Either[DbException, E], A] =
semaphore.withPermit {
super.runTransaction(task, commitOnFailure)
}

override def runAutoCommit[R, E, A](task: Connection => ZIO[R, E, A])
(implicit errorStrategies: ErrorStrategiesRef, trace: ZTraceElement): ZIO[R, Either[DbException, E], A] =
(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[R, Either[DbException, E], A] =
semaphore.withPermit {
super.runAutoCommit(task)
}
Expand All @@ -126,14 +127,14 @@ object ConnectionSource {
*
* When a Database method is called with no available implicit ErrorStrategiesRef, the default ErrorStrategiesRef will
* be used. */
def fromDatasource(implicit trace: ZTraceElement): ZLayer[DataSource, Nothing, ConnectionSource] =
def fromDatasource(implicit trace: Trace): ZLayer[DataSource, Nothing, ConnectionSource] =
fromDatasource(ErrorStrategies.Parent)

/** As `fromDatasource`, but provides a default ErrorStrategiesRef.
*
* When a Database method is called with no available implicit ErrorStrategiesRef, the ErrorStrategiesRef in argument
* will be used. */
def fromDatasource(errorStrategies: ErrorStrategiesRef)(implicit trace: ZTraceElement): ZLayer[DataSource, Nothing, ConnectionSource] = {
def fromDatasource(errorStrategies: ErrorStrategiesRef)(implicit trace: Trace): ZLayer[DataSource, Nothing, ConnectionSource] = {
ZLayer {
for {
source <- ZIO.service[DataSource]
Expand All @@ -142,7 +143,7 @@ object ConnectionSource {
}

/** As `fromDatasource(ErrorStrategiesRef)`, but an `ErrorStrategies` is provided through a layer instead of as a parameter. */
def fromDatasourceAndErrorStrategies(implicit trace: ZTraceElement): ZLayer[DataSource with ErrorStrategies, Nothing, ConnectionSource] = {
def fromDatasourceAndErrorStrategies(implicit trace: Trace): ZLayer[DataSource with ErrorStrategies, Nothing, ConnectionSource] = {
ZLayer {
for {
source <- ZIO.service[DataSource]
Expand All @@ -156,14 +157,14 @@ object ConnectionSource {
*
* When a Database method is called with no available implicit ErrorStrategiesRef, the default ErrorStrategiesRef will
* be used. */
def fromConnection(implicit trace: ZTraceElement): ZLayer[Connection, Nothing, ConnectionSource] =
def fromConnection(implicit trace: Trace): ZLayer[Connection, Nothing, ConnectionSource] =
fromConnection(ErrorStrategies.Parent)

/** As `fromConnection`, but provides a default ErrorStrategiesRef.
*
* When a Database method is called with no available implicit ErrorStrategiesRef, the ErrorStrategiesRef in argument
* will be used. */
def fromConnection(errorStrategiesRef: ErrorStrategiesRef)(implicit trace: ZTraceElement): ZLayer[Connection, Nothing, ConnectionSource] = {
def fromConnection(errorStrategiesRef: ErrorStrategiesRef)(implicit trace: Trace): ZLayer[Connection, Nothing, ConnectionSource] = {
ZLayer {
for {
connection <- ZIO.service[Connection]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.github.gaelrenoux.tranzactio


import zio.{Tag, ZIO, ZLayer, ZTraceElement}
import zio.{Tag, ZIO, ZLayer, Trace}

import java.sql.{Connection => JdbcConnection}
import javax.sql.DataSource
Expand All @@ -15,41 +15,41 @@ abstract class DatabaseModuleBase[Connection, Database <: DatabaseOps.ServiceOps
override def transaction[R, E, A](
zio: => ZIO[Connection with R, E, A],
commitOnFailure: => Boolean = false
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[Database with R, Either[DbException, E], A] = {
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[Database with R, Either[DbException, E], A] = {
ZIO.serviceWithZIO { db: Database =>
db.transaction[R, E, A](zio, commitOnFailure)
}
}

override def autoCommit[R, E, A](
zio: => ZIO[Connection with R, E, A]
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[Database with R, Either[DbException, E], A] = {
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[Database with R, Either[DbException, E], A] = {
ZIO.serviceWithZIO { db: Database =>
db.autoCommit[R, E, A](zio)
}
}

/** Creates a Database Layer which requires an existing ConnectionSource. */
def fromConnectionSource(implicit trace: ZTraceElement): ZLayer[ConnectionSource, Nothing, Database]
def fromConnectionSource(implicit trace: Trace): ZLayer[ConnectionSource, Nothing, Database]

/** Creates a Tranzactio Connection, given a JDBC connection and a Blocking. Useful for some utilities. */
def connectionFromJdbc(connection: => JdbcConnection)(implicit trace: ZTraceElement): ZIO[Any, Nothing, Connection]
def connectionFromJdbc(connection: => JdbcConnection)(implicit trace: Trace): ZIO[Any, Nothing, Connection]

/** Commodity method: creates a Database Layer which includes its own ConnectionSource based on a DataSource. Most
* connection pool implementations should be able to provide you a DataSource.
*
* When no implicit ErrorStrategies is available, the default ErrorStrategies will be used.
*/
final def fromDatasource(implicit trace: ZTraceElement): ZLayer[DataSource, Nothing, Database] =
final def fromDatasource(implicit trace: Trace): ZLayer[DataSource, Nothing, Database] =
ConnectionSource.fromDatasource >>> fromConnectionSource

/** As `fromDatasource`, but provides a default ErrorStrategiesRef. When a method is called with no available implicit
* ErrorStrategiesRef, the ErrorStrategiesRef in argument will be used. */
final def fromDatasource(errorStrategies: ErrorStrategiesRef)(implicit trace: ZTraceElement): ZLayer[DataSource, Nothing, Database] =
final def fromDatasource(errorStrategies: ErrorStrategiesRef)(implicit trace: Trace): ZLayer[DataSource, Nothing, Database] =
ConnectionSource.fromDatasource(errorStrategies) >>> fromConnectionSource

/** As `fromDatasource(ErrorStrategiesRef)`, but an `ErrorStrategies` is provided through a layer instead of as a parameter. */
final def fromDatasourceAndErrorStrategies(implicit trace: ZTraceElement): ZLayer[DataSource with ErrorStrategies, Nothing, Database] =
final def fromDatasourceAndErrorStrategies(implicit trace: Trace): ZLayer[DataSource with ErrorStrategies, Nothing, Database] =
ConnectionSource.fromDatasourceAndErrorStrategies >>> fromConnectionSource

}
28 changes: 14 additions & 14 deletions src/main/scala/io/github/gaelrenoux/tranzactio/DatabaseOps.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.github.gaelrenoux.tranzactio

import zio.{UIO, ZIO, ZTraceElement}
import zio.{UIO, ZIO, Trace}

/** Operations for a Database, based on a few atomic operations. Can be used both by the actual DB service, or by the DB
* component where a Database is required in the resulting ZIO.
Expand All @@ -20,42 +20,42 @@ trait DatabaseOps[Connection, R0] {
def transaction[R <: Any, E, A](
zio: => ZIO[Connection with R, E, A],
commitOnFailure: => Boolean = false
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, Either[DbException, E], A]
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, Either[DbException, E], A]

@deprecated("Use transaction instead.", since = "0.4.0")
final def transactionR[R, E, A](
zio: => ZIO[Connection with R, E, A],
commitOnFailure: => Boolean = false
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, Either[DbException, E], A] =
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, Either[DbException, E], A] =
transaction[R, E, A](zio, commitOnFailure)

/** As `transaction`, but exceptions are simply widened to a common failure type. The resulting failure type is a
* superclass of both DbException and the error type of the inital ZIO. */
final def transactionOrWiden[R, E >: DbException, A](
zio: => ZIO[Connection with R, E, A],
commitOnFailure: => Boolean = false
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, E, A] =
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, E, A] =
transaction[R, E, A](zio, commitOnFailure).mapError(_.fold(identity, identity))

@deprecated("Use transactionOrWiden instead.", since = "4.0.0")
final def transactionOrWidenR[R, E >: DbException, A](
zio: => ZIO[Connection with R, E, A],
commitOnFailure: => Boolean = false
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, E, A] =
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, E, A] =
transactionOrWiden[R, E, A](zio, commitOnFailure)

/** As `transaction`, but errors when handling the connections are treated as defects instead of failures. */
final def transactionOrDie[R, E, A](
zio: => ZIO[Connection with R, E, A],
commitOnFailure: => Boolean = false
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, E, A] =
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, E, A] =
transaction[R, E, A](zio, commitOnFailure).flatMapError(dieOnLeft)

@deprecated("Use transactionOrDie instead.", since = "4.0.0")
final def transactionOrDieR[R, E, A](
zio: => ZIO[Connection with R, E, A],
commitOnFailure: => Boolean = false
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, E, A] =
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, E, A] =
transactionOrDie[R, E, A](zio, commitOnFailure)

/** Provides that ZIO with a Connection. All DB action in the ZIO will be auto-committed. Failures in the initial
Expand All @@ -66,37 +66,37 @@ trait DatabaseOps[Connection, R0] {
*/
def autoCommit[R, E, A](
zio: => ZIO[Connection with R, E, A]
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, Either[DbException, E], A]
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, Either[DbException, E], A]

@deprecated("Use autoCommit instead.", since = "4.0.0")
final def autoCommitR[R, E, A](
zio: => ZIO[Connection with R, E, A]
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, Either[DbException, E], A] =
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, Either[DbException, E], A] =
autoCommit[R, E, A](zio)

/** As `autoCommit`, but exceptions are simply widened to a common failure type. The resulting failure type is a
* superclass of both DbException and the error type of the inital ZIO. */
final def autoCommitOrWiden[R, E >: DbException, A](
zio: => ZIO[Connection with R, E, A]
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, E, A] =
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, E, A] =
autoCommit[R, E, A](zio).mapError(_.fold(identity, identity))

@deprecated("Use autoCommitOrWiden instead.", since = "4.0.0")
final def autoCommitOrWidenR[R, E >: DbException, A](
zio: => ZIO[Connection with R, E, A]
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, E, A] =
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, E, A] =
autoCommitOrWiden[R, E, A](zio)

/** As `autoCommit`, but errors when handling the connections are treated as defects instead of failures. */
final def autoCommitOrDie[R, E, A](
zio: => ZIO[Connection with R, E, A]
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, E, A] =
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, E, A] =
autoCommit[R, E, A](zio).flatMapError(dieOnLeft)

@deprecated("Use autoCommitOrDie instead.", since = "4.0.0")
final def autoCommitOrDieR[R, E, A](
zio: => ZIO[Connection with R, E, A]
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: ZTraceElement): ZIO[R with R0, E, A] =
)(implicit errorStrategies: ErrorStrategiesRef = ErrorStrategies.Parent, trace: Trace): ZIO[R with R0, E, A] =
autoCommitOrDie[R, E, A](zio)

}
Expand All @@ -109,7 +109,7 @@ object DatabaseOps {
/** API for commodity methods needing a Database. */
trait ModuleOps[Connection, Database <: ServiceOps[Connection]] extends DatabaseOps[Connection, Database]

private def dieOnLeft[E](e: Either[DbException, E])(implicit trace: ZTraceElement): UIO[E] = e match {
private def dieOnLeft[E](e: Either[DbException, E])(implicit trace: Trace): UIO[E] = e match {
case Right(appError) => ZIO.succeed(appError)
case Left(dbError) => ZIO.die(dbError)
}
Expand Down
Loading

0 comments on commit 421af06

Please sign in to comment.