Skip to content

Commit

Permalink
Merge branch 'master' into reacquire-dead-conns
Browse files Browse the repository at this point in the history
  • Loading branch information
jczuchnowski authored Jul 3, 2022
2 parents ac9cc1e + 1daf4e6 commit a26a346
Show file tree
Hide file tree
Showing 22 changed files with 810 additions and 283 deletions.
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ addCommandAlias("fmtOnce", "all scalafmtSbt scalafmt test:scalafmt")
addCommandAlias("fmt", "fmtOnce;fmtOnce")
addCommandAlias("check", "all scalafmtSbtCheck scalafmtCheck test:scalafmtCheck")

val zioVersion = "2.0.0-RC6"
val zioSchemaVersion = "0.1.9"
val zioVersion = "2.0.0"
val zioSchemaVersion = "0.2.0"
val testcontainersVersion = "1.17.2"
val testcontainersScalaVersion = "0.40.8"
val logbackVersion = "1.2.11"
Expand Down
27 changes: 27 additions & 0 deletions jdbc/src/main/scala/zio/sql/ExprSyntaxModule.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package zio.sql

import zio._
import zio.stream.ZStream
import zio.schema.Schema

trait ExprSyntaxModule { self: Jdbc =>
implicit final class ReadSyntax[A](self: Read[A]) {
def run: ZStream[SqlTransaction, Exception, A] =
ZStream.serviceWithStream(_.read(self))
}

implicit final class DeleteSyntax(self: Delete[_]) {
def run: ZIO[SqlTransaction, Exception, Int] =
ZIO.serviceWithZIO(_.delete(self))
}

implicit final class InsertSyntax[A: Schema](self: Insert[_, A]) {
def run: ZIO[SqlTransaction, Exception, Int] =
ZIO.serviceWithZIO(_.insert(self))
}

implicit final class UpdatedSyntax(self: Update[_]) {
def run: ZIO[SqlTransaction, Exception, Int] =
ZIO.serviceWithZIO(_.update(self))
}
}
24 changes: 20 additions & 4 deletions jdbc/src/main/scala/zio/sql/SqlDriverLiveModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import java.sql._
import zio._
import zio.stream.{ Stream, ZStream }
import zio.schema.Schema
import zio.IO

trait SqlDriverLiveModule { self: Jdbc =>
private[sql] trait SqlDriverCore {
Expand Down Expand Up @@ -128,13 +129,28 @@ trait SqlDriverLiveModule { self: Jdbc =>
def insert[A: Schema](insert: List[Insert[_, A]]): IO[Exception, List[Int]] =
ZIO.scoped(pool.connection.flatMap(insertOnBatch(insert, _)))

override def transact[R, A](tx: ZTransaction[R, Exception, A]): ZIO[R, Throwable, A] =
ZIO.scoped[R] {
override def transaction: ZLayer[Any, Exception, SqlTransaction] =
ZLayer.scoped {
for {
connection <- pool.connection
_ <- ZIO.attemptBlocking(connection.setAutoCommit(false)).refineToOrDie[Exception]
a <- tx.run(Txn(connection, self))
} yield a
_ <- ZIO.addFinalizerExit(c =>
ZIO.attempt(if (c.isSuccess) connection.commit() else connection.rollback()).ignore
)
} yield new SqlTransaction {
def delete(delete: Delete[_]): IO[Exception, Int] =
deleteOn(delete, connection)

def update(update: Update[_]): IO[Exception, Int] =
updateOn(update, connection)

def read[A](read: Read[A]): Stream[Exception, A] =
readOn(read, connection)

def insert[A: Schema](insert: Insert[_, A]): IO[Exception, Int] =
insertOn(insert, connection)

}
}
}
}
130 changes: 0 additions & 130 deletions jdbc/src/main/scala/zio/sql/TransactionModule.scala

This file was deleted.

26 changes: 18 additions & 8 deletions jdbc/src/main/scala/zio/sql/jdbc.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package zio.sql

import zio.{ Tag => ZTag, _ }
import zio._
import zio.stream._
import zio.schema.Schema

trait Jdbc extends zio.sql.Sql with TransactionModule with JdbcInternalModule with SqlDriverLiveModule {
trait Jdbc extends zio.sql.Sql with JdbcInternalModule with SqlDriverLiveModule with ExprSyntaxModule {
trait SqlDriver {
def delete(delete: Delete[_]): IO[Exception, Int]

Expand All @@ -16,22 +16,29 @@ trait Jdbc extends zio.sql.Sql with TransactionModule with JdbcInternalModule wi

def read[A](read: Read[A]): Stream[Exception, A]

def transact[R, A](tx: ZTransaction[R, Exception, A]): ZIO[R, Throwable, A]

def insert[A: Schema](insert: Insert[_, A]): IO[Exception, Int]

def insert[A: Schema](insert: List[Insert[_, A]]): IO[Exception, List[Int]]

def transaction: ZLayer[Any, Exception, SqlTransaction]
}
object SqlDriver {

val live: ZLayer[ConnectionPool, Nothing, SqlDriver] =
ZLayer(ZIO.serviceWith[ConnectionPool](new SqlDriverLive(_)))
}

def execute[R <: SqlDriver: ZTag, A](
tx: ZTransaction[R, Exception, A]
): ZIO[R, Throwable, A] =
ZIO.serviceWithZIO(_.transact(tx))
trait SqlTransaction {

def delete(delete: Delete[_]): IO[Exception, Int]

def update(update: Update[_]): IO[Exception, Int]

def read[A](read: Read[A]): Stream[Exception, A]

def insert[A: Schema](insert: Insert[_, A]): IO[Exception, Int]

}

def execute[A](read: Read[A]): ZStream[SqlDriver, Exception, A] =
ZStream.serviceWithStream(_.read(read))
Expand All @@ -53,4 +60,7 @@ trait Jdbc extends zio.sql.Sql with TransactionModule with JdbcInternalModule wi

def executeBatchUpdate(update: List[Update[_]]): ZIO[SqlDriver, Exception, List[Int]] =
ZIO.serviceWithZIO(_.update(update))

val transact: ZLayer[SqlDriver, Exception, SqlTransaction] =
ZLayer(ZIO.serviceWith[SqlDriver](_.transaction)).flatten
}
10 changes: 10 additions & 0 deletions jdbc/src/test/scala/zio/sql/JdbcRunnableSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import com.dimafeng.testcontainers.JdbcDatabaseContainer
import zio.test.TestEnvironment
import zio.{ Scope, ZIO, ZLayer }
import zio.test.ZIOSpecDefault
import zio.prelude.AssociativeBoth
import zio.test.Gen
import zio.prelude.Covariant
import com.dimafeng.testcontainers.SingleContainer
import java.util.Properties
import zio.test.Spec
Expand Down Expand Up @@ -55,6 +58,13 @@ trait JdbcRunnableSpec extends ZIOSpecDefault with Jdbc {
SqlDriver.live
)

protected implicit def genInstances[R]
: AssociativeBoth[({ type T[A] = Gen[R, A] })#T] with Covariant[({ type T[+A] = Gen[R, A] })#T] =
new AssociativeBoth[({ type T[A] = Gen[R, A] })#T] with Covariant[({ type T[+A] = Gen[R, A] })#T] {
def map[A, B](f: A => B): Gen[R, A] => Gen[R, B] = _.map(f)
def both[A, B](fa: => Gen[R, A], fb: => Gen[R, B]): Gen[R, (A, B)] = fa.zip(fb)
}

private[this] def testContainer: ZIO[Scope, Throwable, SingleContainer[_] with JdbcDatabaseContainer] =
ZIO.acquireRelease {
ZIO.attemptBlocking {
Expand Down
33 changes: 18 additions & 15 deletions mysql/src/main/scala/zio/sql/mysql/MysqlRenderModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,7 @@ trait MysqlRenderModule extends MysqlSqlModule { self =>
def renderDeleteImpl(delete: Delete[_])(implicit render: Renderer) = {
render("DELETE FROM ")
renderTable(delete.table)
delete.whereExpr match {
case Expr.Literal(true) => ()
case _ =>
render(" WHERE ")
renderExpr(delete.whereExpr)
}
renderWhereExpr(delete.whereExpr)
}

def renderUpdateImpl(update: Update[_])(implicit render: Renderer) =
Expand All @@ -64,8 +59,7 @@ trait MysqlRenderModule extends MysqlSqlModule { self =>
renderTable(table)
render(" SET ")
renderSet(set)
render(" WHERE ")
renderExpr(whereExpr)
renderWhereExpr(whereExpr)
}

def renderReadImpl(read: self.Read[_])(implicit render: Renderer): Unit =
Expand All @@ -89,12 +83,7 @@ trait MysqlRenderModule extends MysqlSqlModule { self =>
render(" FROM ")
renderTable(t)
}
whereExpr match {
case Expr.Literal(true) => ()
case _ =>
render(" WHERE ")
renderExpr(whereExpr)
}
renderWhereExpr(whereExpr)
groupByExprs match {
case Read.ExprSet.ExprCons(_, _) =>
render(" GROUP BY ")
Expand Down Expand Up @@ -511,7 +500,7 @@ trait MysqlRenderModule extends MysqlSqlModule { self =>
case Read.ExprSet.NoExpr => ()
}

def renderOrderingList(expr: List[Ordering[Expr[_, _, _]]])(implicit render: Renderer): Unit =
private def renderOrderingList(expr: List[Ordering[Expr[_, _, _]]])(implicit render: Renderer): Unit =
expr match {
case head :: tail =>
head match {
Expand All @@ -529,6 +518,20 @@ trait MysqlRenderModule extends MysqlSqlModule { self =>
}
case Nil => ()
}

/**
* Drops the initial Litaral(true) present at the start of every WHERE expressions by default
* and proceeds to the rest of Expr's.
*/
private def renderWhereExpr[A, B](expr: self.Expr[_, A, B])(implicit render: Renderer): Unit = expr match {
case Expr.Literal(true) => ()
case Expr.Binary(_, b, _) =>
render(" WHERE ")
renderExpr(b)
case _ =>
render(" WHERE ")
renderExpr(expr)
}
}

}
7 changes: 4 additions & 3 deletions mysql/src/test/scala/zio/sql/mysql/MysqlModuleSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import java.time._
import java.time.format.DateTimeFormatter
import java.util.UUID

import scala.language.postfixOps

import zio._
import zio.schema._
import zio.test._
import zio.test.Assertion._
import zio.test.TestAspect._

import scala.language.postfixOps

object MysqlModuleSpec extends MysqlRunnableSpec with ShopSchema {

Expand Down Expand Up @@ -270,6 +271,6 @@ object MysqlModuleSpec extends MysqlRunnableSpec with ShopSchema {
println(renderUpdate(query))
assertZIO(execute(query))(equalTo(1))
}
)
) @@ sequential

}
Loading

0 comments on commit a26a346

Please sign in to comment.