From 859c98548262037c84226b02e00bcef7548f5c73 Mon Sep 17 00:00:00 2001 From: Jules Ivanic Date: Fri, 25 Aug 2023 11:04:00 +0400 Subject: [PATCH] Remove all references to ZIO1 `Has` (#2820) * Remove all references to ZIO1 `Has` * scalafmt * Try fix CI * Fix deprecation warning * Try fix CI * Remove sbt deprecation warning --- build.sbt | 2 +- build/release.sh | 4 +- docs/changelog.md | 44 +++++++++---------- docs/contexts.md | 28 ++++++------ .../io/getquill/CassandraZioContext.scala | 2 +- .../context/qzio/ZioJdbcContext.scala | 26 +++++------ .../getquill/jdbczio/QuillBaseContext.scala | 6 +-- 7 files changed, 57 insertions(+), 55 deletions(-) diff --git a/build.sbt b/build.sbt index cc6b08aaa3..23b9a1ddaa 100644 --- a/build.sbt +++ b/build.sbt @@ -790,7 +790,7 @@ lazy val basicSettings = excludeFilterSettings ++ Seq( baseDirectory.value / "src" / "test" / "resources" ), scalacOptions ++= Seq( - "-target:jvm-1.8", + "-release:8", "-encoding", "UTF-8", "-feature", diff --git a/build/release.sh b/build/release.sh index e8e2e6849a..9268effa3a 100755 --- a/build/release.sh +++ b/build/release.sh @@ -11,6 +11,8 @@ then echo "No Artifact Specified" fi +export JAVA_OPTS="-Xms4g -Xmx4g -Xss10m" + SBT_2_12="sbt ++2.12.17 -Dquill.macro.log=false -Dquill.scala.version=2.12.17" SBT_2_13="sbt ++2.13.10 -Dquill.macro.log=false -Dquill.scala.version=2.13.10" SBT_3_3="sbt ++3.3.0 -Dquill.macro.log=false -Dquill.scala.version=3.3.0" @@ -114,7 +116,7 @@ then elif [[ $BRANCH != "master" ]] then echo "Branch build for $BRANCH - Artifact: '$ARTIFACT'" - echo "version in ThisBuild := \"$BRANCH-SNAPSHOT\"" > version.sbt + echo "ThisBuild / version := \"$BRANCH-SNAPSHOT\"" > version.sbt if [[ $ARTIFACT == "base" ]]; then $SBT_VER -Dmodules=base publish; fi if [[ $ARTIFACT == "db" ]]; then $SBT_VER -Dmodules=db publish; fi if [[ $ARTIFACT == "js" ]]; then $SBT_VER -Dmodules=js publish; fi diff --git a/docs/changelog.md b/docs/changelog.md index 1b0b76d7f5..17ac0090e6 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -229,7 +229,7 @@ The `session` entry values and keys are described in the datastax documentation: The ZioCassandraSession constructors: ```scala - val zioSessionLayer: ZLayer[Any, Throwable, Has[CassandraZioSession]] = + val zioSessionLayer: ZLayer[Any, Throwable, CassandraZioSession] = CassandraZioSession.fromPrefix("MyCassandraDb") run(query[Person]) .provideCustomLayer(zioSessionLayer) @@ -237,7 +237,7 @@ run(query[Person]) Additional parameters can be added programmatically: ```scala - val zioSessionLayer: ZLayer[Any, Throwable, Has[CassandraZioSession]] = + val zioSessionLayer: ZLayer[Any, Throwable, CassandraZioSession] = CassandraZioSession.fromContextConfig(LoadConfig("MyCassandraDb").withValue("keyspace", ConfigValueFactory.fromAnyRef("data"))) run(query[Person]) .provideCustomLayer(zioSessionLayer) @@ -280,14 +280,14 @@ The type `Runner` needs to be used by ProtoQuill to define quill-context-specifi #### Migration Notes: -All ZIO JDBC context `run` methods have now switched from have switched their dependency (i.e. `R`) from `Has[Connection]` to -`Has[DataSource]`. This should clear up many innocent errors that have happened because how this `Has[Connection]` is supposed +All ZIO JDBC context `run` methods have now switched from have switched their dependency (i.e. `R`) from `Connection` to +`DataSource`. This should clear up many innocent errors that have happened because how this `Connection` is supposed to be provided was unclear. As I have come to understand, nearly all DAO service patterns involve grabbing a connection from a pooled DataSource, doing one single crud operation, and then returning the connection back to the pool. The new JDBC ZIO context memorialize this pattern. -* The signature of `QIO[T]` has been changed from `ZIO[Has[Connection], SQLException, T]` to `ZIO[Has[DataSource], SQLException, T]`. - a new type-alias `QCIO[T]` (lit. Quill Connection IO) has been introduced that represents `ZIO[Has[Connection], SQLException, T]`. +* The signature of `QIO[T]` has been changed from `ZIO[Connection, SQLException, T]` to `ZIO[DataSource, SQLException, T]`. + a new type-alias `QCIO[T]` (lit. Quill Connection IO) has been introduced that represents `ZIO[Connection, SQLException, T]`. * If you are using the `.onDataSource` command, migration should be fairly easy. Whereas previously, a usage of quill-jdbc-zio 3.10.0 might have looked like this: @@ -325,7 +325,7 @@ memorialize this pattern. def hikariConfig = new HikariConfig(JdbcContextConfig(LoadConfig("testPostgresDB")).configProperties) def hikariDataSource: DataSource with Closeable = new HikariDataSource(hikariConfig) - val zioConn: ZLayer[Any, Throwable, Has[Connection]] = + val zioConn: ZLayer[Any, Throwable, Connection] = Task(hikariDataSource).toLayer >>> DataSourceLayer.live @@ -338,7 +338,7 @@ memorialize this pattern. def hikariConfig = new HikariConfig(JdbcContextConfig(LoadConfig("testPostgresDB")).configProperties) def hikariDataSource: DataSource with Closeable = new HikariDataSource(hikariConfig) - val zioDS: ZLayer[Any, Throwable, Has[DataSource]] = + val zioDS: ZLayer[Any, Throwable, DataSource] = Task(hikariDataSource).toLayer // Don't need `>>> DataSourceLayer.live` anymore! MyPostgresContext.run(people) @@ -353,8 +353,8 @@ memorialize this pattern. .provide(zio.Has(conn: java.sql.Connection)) ``` -* Also, when using an underlying context, you can still use `onDataSource` to go from a `Has[Connection]` dependency - back to a `Has[DataSource]` dependency (note that it no longer has to be `with Closable`). +* Also, when using an underlying context, you can still use `onDataSource` to go from a `Connection` dependency + back to a `DataSource` dependency (note that it no longer has to be `with Closable`). ``` object Ctx extends PostgresZioJdbcContext(Literal); import MyPostgresContext._ Ctx.underlying.run(qr1) @@ -362,8 +362,8 @@ memorialize this pattern. .provide(zio.Has(ds: java.sql.DataSource)) ``` -* Finally, that the `prepare` methods have been unaffected by this change. They still require a `Has[Connection]` - and have the signature `ZIO[Has[Connection], SQLException, PreparedStatement]`. This is because in order to work +* Finally, that the `prepare` methods have been unaffected by this change. They still require a `Connection` + and have the signature `ZIO[Connection, SQLException, PreparedStatement]`. This is because in order to work with the result of this value (i.e. to work with `PreparedStatement`), the connection that created it must still be open. @@ -434,8 +434,8 @@ Again, if you are using MappedEncoders for all of your custom encoding needs, yo #### Migration Notes: The `quill-jdbc-zio` contexts' `.run` method was designed to work with ZIO in an idiomatic way. As such, the environment variable of their return type including the `zio.blocking.Blocking` dependency. This added a significant amount of complexity. -Instead of `ZIO[Has[Connection], SQLException, T]`, the return type became `ZIO[Has[Connection] with Blocking, SQLException, T]`. -Instead of `ZIO[Has[DataSource with Closeable], SQLException, T]`, the return type became `ZIO[Has[DataSource with Closeable] with Blocking, SQLException, T]`. +Instead of `ZIO[Connection, SQLException, T]`, the return type became `ZIO[Connection with Blocking, SQLException, T]`. +Instead of `ZIO[DataSource with Closeable, SQLException, T]`, the return type became `ZIO[DataSource with Closeable with Blocking, SQLException, T]`. Various types such as `QConnection` and `QDataSource` were created in order to encapsulate these concepts but this only led to additional confusion. Furthermore, actually supplying a `Connection` or `DataSource with Closeable` required first peeling off the `with Blocking` clause, calling a `.provide`, and then appending it back on. The fact that a Connection needs to be opened from a Data Source (which will typically be a Hikari connection pool) @@ -443,17 +443,17 @@ further complicates the problem because this aforementioned process needs to be construct has bad ergonomics. For this reason, the ZIO team has decided to drop the concept of `with Blocking` in ZIO 2 altogether. As a result of this, I have decided to drop the `with Blocking` construct in advance. Quill queries resulting from the `run(qry)` command and -still run on the blocking pool but `with Blocking` is not included in the signature. This also means that and the need for `QConnection` and `QDataSource` disappears since they are now just `Has[Connection]` and `Has[Datasource with Closeable]` +still run on the blocking pool but `with Blocking` is not included in the signature. This also means that and the need for `QConnection` and `QDataSource` disappears since they are now just `Connection` and `Datasource with Closeable` respectively. This also means that all the constructors on the corresponding objects e.g. `QDataSource.fromPrefix("myDB")` are not consistent with any actual construct in QIO, therefore they are not needed either. Instead, I have introduced a simple layer-constructor called `DataSourceLayer` which has a `.live` implementation which converts -`ZIO[Has[Connection], SQLException, T]` to `ZIO[Has[DataSource with Closeable], SQLException, T]` by taking a connection from the +`ZIO[Connection, SQLException, T]` to `ZIO[DataSource with Closeable, SQLException, T]` by taking a connection from the data-source and returning it immediately afterward, this is the analogue of what `QDataSource.toConnection` use to do. You can use it like this: ```scala def hikariDataSource: DataSource with Closeable = ... -val zioConn: ZLayer[Any, Throwable, Has[Connection]] = +val zioConn: ZLayer[Any, Throwable, Connection] = Task(hikariDataSource).toLayer >>> DataSourceLayer.live run(people) .provideCustomLayer(zioConn) @@ -468,7 +468,7 @@ run(people) ``` Also, constructor-methods `fromPrefix`, `fromConfig`, `fromJdbcConfig` and `fromDataSource` are available on -`DataSourceLayer` to construct instances of `ZLayer[Has[DataSource with Closeable], SQLException, Has[Connection]]`. +`DataSourceLayer` to construct instances of `ZLayer[DataSource with Closeable, SQLException, Connection]`. Combined with the `toDataSource` construct, these provide a simple way to construct various Hikari pools from a corresponding typesafe-config file `application.conf`. ```scala @@ -483,8 +483,8 @@ have been added. #### Cassandra: -Similar changes have been made in quill-cassandra-zio. `Has[CassandraZioSession] with Blocking` has been replaced -with just `Has[CassandraZioSession]` so now this is much easier to provide: +Similar changes have been made in quill-cassandra-zio. `CassandraZioSession with Blocking` has been replaced +with just `CassandraZioSession` so now this is much easier to provide: ```scala val session: CassandraZioSession = _ @@ -495,7 +495,7 @@ run(people) The CassandraZioSession constructors however are all still fine to use: ```scala - val zioSessionLayer: ZLayer[Any, Throwable, Has[CassandraZioSession]] = + val zioSessionLayer: ZLayer[Any, Throwable, CassandraZioSession] = CassandraZioSession.fromPrefix("testStreamDB") run(query[Person]) .provideCustomLayer(zioSessionLayer) @@ -539,7 +539,7 @@ Similarly for quill-cassandra-zio - This state was pulled out as separate classes e.g. `SyncCache`, `AsyncFutureCache` (the ZIO equivalent of which is `AsyncZioCache`). - Then a `CassandraZioSession` is created which extends these state-containers however, it is not directly a base-class of the `CassandraZioContext`. - Instead it is returned as a dependency from the CassandraZioContext run/prepare commands as part of the type - `ZIO[Has[CassandraZioSession] with Blocking, Throwable, T]` (a.k.a `CIO[T]`). This allows the primary context CassandraZioContext to be stateless. + `ZIO[CassandraZioSession with Blocking, Throwable, T]` (a.k.a `CIO[T]`). This allows the primary context CassandraZioContext to be stateless. # 3.6.1 diff --git a/docs/contexts.md b/docs/contexts.md index f79a9d5fcd..e31bf2d3f1 100644 --- a/docs/contexts.md +++ b/docs/contexts.md @@ -470,7 +470,7 @@ run methods return a ZIO that has a DataSource resource dependency. Naturally, this should be provided later on in your application (see `ZioJdbc` for helper methods that assist in doing this). -Since resource dependency is `Has[DataSource]` the result of a `run` call is `ZIO[Has[DataSource], SQLException, T]`. +Since resource dependency is `DataSource` the result of a `run` call is `ZIO[DataSource, SQLException, T]`. This means that if you have a `DataSource` object, you can just provide it! ```scala @@ -478,16 +478,16 @@ def ds: DataSource = _ run(people).provide(Has(ds)) ``` -> Since most quill-zio methods return `ZIO[Has[DataSource], SQLException, T]` +> Since most quill-zio methods return `ZIO[DataSource, SQLException, T]` > the type `QIO[T]` i.e. Quill-IO has been defined as an alias. > -> For underlying-contexts (see below) that depend on `Has[Connection]`, +> For underlying-contexts (see below) that depend on `Connection`, > the alias `QCIO[T]` (i.e. Quill-Connection-IO) has been defined -> for `ZIO[Has[Connection], SQLException, T]`. +> for `ZIO[Connection, SQLException, T]`. Since in most JDBC use-cases, a connection-pool datasource (e.g. Hikari) is used, constructor-methods `fromPrefix`, `fromConfig`, `fromJdbcConfig` are available on -`DataSourceLayer` to construct instances of a `ZLayer[Any, SQLException, Has[DataSource]]` +`DataSourceLayer` to construct instances of a `ZLayer[Any, SQLException, DataSource]` which can be easily used to provide a DataSource dependency. You can use them like this: ```scala @@ -497,7 +497,7 @@ MyZioContext.run(query[Person]).provideCustomLayer(zioDS) ``` If in some rare cases, you wish to provide a `java.sql.Connection` to a `run` method directly, you can delegate -to the underlying-context. This is a more low-level context whose `run` methods have a `Has[Connection]` resource. +to the underlying-context. This is a more low-level context whose `run` methods have a `Connection` resource. Here is an example of how this can be done. ```scala @@ -513,7 +513,7 @@ MyZioContext.underlying.run(people).provide(Has(conn)) If you are working with an underlying-context and want to provide a DataSource instead of a connection, you can use the `onDataSource` method. Note however that this is *only* needed when working with an underlying-context. When working with a normal context, `onDataSource` is not available or necessary -(since for a normal contexts `R` will be `Has[DataSource]`). +(since for a normal contexts `R` will be `DataSource`). ```scala val ds: DataSource = _ @@ -556,14 +556,14 @@ More examples of a Quill-JDBC-ZIO app [quill-jdbc-zio/src/test/scala/io/getquill The `ZioJdbcContext` can stream using zio.ZStream: ``` -ctx.stream(query[Person]) // returns: ZStream[Has[Connection], Throwable, Person] - .run(Sink.collectAll).map(_.toList) // returns: ZIO[Has[Connection], Throwable, List[T]] +ctx.stream(query[Person]) // returns: ZStream[Connection, Throwable, Person] + .run(Sink.collectAll).map(_.toList) // returns: ZIO[Connection, Throwable, List[T]] ``` #### transactions The `ZioJdbcContext`s provide support for transactions without needing thread-local storage or similar -because they propagate the resource dependency in the ZIO effect itself (i.e. the `Has[Connection]` in `Zio[Has[Connection], _, _]`). +because they propagate the resource dependency in the ZIO effect itself (i.e. the `Connection` in `Zio[Connection, _, _]`). As with the other contexts, if an exception is thrown anywhere inside a task or sub-task within a `transaction` block, the entire block will be rolled back by the database. @@ -576,7 +576,7 @@ val trans = _ <- ctx.run(query[Person].insertValue(Person("Joe", 123))) p <- ctx.run(query[Person]) } yield p - } //returns: ZIO[Has[Connection], Throwable, List[Person]] + } //returns: ZIO[Connection, Throwable, List[Person]] val result = Runtime.default.unsafeRun(trans.onDataSource.provide(ds)) //returns: List[Person] ``` @@ -1645,8 +1645,8 @@ that require passing in a Data Source, this context takes in a `CassandraZioSess as a resource dependency which can be provided later (see the `CassandraZioSession` object for helper methods that assist in doing this). -The resource dependency itself is just a `Has[CassandraZioSession]` hence `run(qry)` and other methods in this context will return -`ZIO[Has[CassandraZioSession], Throwable, T]`. The type `CIO[T]` i.e. Cassandra-IO is an alias for this. +The resource dependency itself is just a `CassandraZioSession` hence `run(qry)` and other methods in this context will return +`ZIO[CassandraZioSession, Throwable, T]`. The type `CIO[T]` i.e. Cassandra-IO is an alias for this. Providing a `CassandraZioSession` dependency is now very simple: ```scala @@ -1659,7 +1659,7 @@ Various methods in the `io.getquill.CassandraZioSession` can assist in simplifyi provide a `Config` object instead of a `CassandraZioSession` like this: ```scala - val zioSessionLayer: ZLayer[Any, Throwable, Has[CassandraZioSession]] = + val zioSessionLayer: ZLayer[Any, Throwable, CassandraZioSession] = CassandraZioSession.fromPrefix("testStreamDB") run(query[Person]) .provideCustomLayer(zioSessionLayer) diff --git a/quill-cassandra-zio/src/main/scala/io/getquill/CassandraZioContext.scala b/quill-cassandra-zio/src/main/scala/io/getquill/CassandraZioContext.scala index 83f025fb65..9118cbfa1d 100644 --- a/quill-cassandra-zio/src/main/scala/io/getquill/CassandraZioContext.scala +++ b/quill-cassandra-zio/src/main/scala/io/getquill/CassandraZioContext.scala @@ -26,7 +26,7 @@ object CassandraZioContext { * (see the `CassandraZioSession` object for helper methods that assist in doing * this). * - * The resource dependency itself is just a Has[CassandraZioSession] + * The resource dependency itself is just a CassandraZioSession * * Various methods in the `io.getquill.CassandraZioSession` can assist in * simplifying it's creation, for example, you can provide a `Config` object diff --git a/quill-jdbc-zio/src/main/scala/io/getquill/context/qzio/ZioJdbcContext.scala b/quill-jdbc-zio/src/main/scala/io/getquill/context/qzio/ZioJdbcContext.scala index 9c12030e5c..52c545b9d7 100644 --- a/quill-jdbc-zio/src/main/scala/io/getquill/context/qzio/ZioJdbcContext.scala +++ b/quill-jdbc-zio/src/main/scala/io/getquill/context/qzio/ZioJdbcContext.scala @@ -23,16 +23,16 @@ import zio.ZIO.blocking * java.sql.Connection as a resource dependency which can be provided later (see * `ZioJdbc` for helper methods that assist in doing this). * - * The resource dependency itself is just a `Has[Connection]`. Since this is + * The resource dependency itself is just a `Connection`. Since this is * frequently used The type `QIO[T]` i.e. Quill-IO has been defined as an alias - * for `ZIO[Has[Connection], SQLException, T]`. + * for `ZIO[Connection, SQLException, T]`. * * Since in most JDBC use-cases, a connection-pool datasource i.e. Hikari is - * used it would actually be much more useful to interact with - * `ZIO[Has[DataSource], SQLException, T]`. The extension method `.onDataSource` - * in `io.getquill.context.ZioJdbc.QuillZioExt` will perform this conversion - * (for even more brevity use `onDS` which is an alias for this method). {{ - * import ZioJdbc._ val zioDs = DataSourceLayer.fromPrefix("testPostgresDB") + * used it would actually be much more useful to interact with `ZIO[DataSource, + * SQLException, T]`. The extension method `.onDataSource` in + * `io.getquill.context.ZioJdbc.QuillZioExt` will perform this conversion (for + * even more brevity use `onDS` which is an alias for this method). {{ import + * ZioJdbc._ val zioDs = DataSourceLayer.fromPrefix("testPostgresDB") * MyZioContext.run(query[Person]).onDataSource.provideCustomLayer(zioDS) }} * * If you are using a Plain Scala app however, you will need to manually run it @@ -41,9 +41,9 @@ import zio.ZIO.blocking * }} * * Note however that the one exception to these cases are the `prepare` methods - * where a `ZIO[Has[Connection], SQLException, PreparedStatement]` is being - * returned. In those situations the acquire-action-release pattern does not - * make any sense because the `PrepareStatement` is only held open while it's + * where a `ZIO[Connection, SQLException, PreparedStatement]` is being returned. + * In those situations the acquire-action-release pattern does not make any + * sense because the `PrepareStatement` is only held open while it's * host-connection exists. */ abstract class ZioJdbcContext[+Dialect <: SqlIdiom, +Naming <: NamingStrategy] @@ -179,9 +179,9 @@ abstract class ZioJdbcContext[+Dialect <: SqlIdiom, +Naming <: NamingStrategy] * the database and return the contents of the Person table immediately after * that: * {{{ - * val a = run(query[Person].insert(Person(...)): ZIO[Has[DataSource], SQLException, Long] - * val b = run(query[Person]): ZIO[Has[DataSource], SQLException, Person] - * transaction(a *> b): ZIO[Has[DataSource], SQLException, Person] + * val a = run(query[Person].insert(Person(...)): ZIO[DataSource, SQLException, Long] + * val b = run(query[Person]): ZIO[DataSource, SQLException, Person] + * transaction(a *> b): ZIO[DataSource, SQLException, Person] * }}} * * The order of operations run in the case that a new connection needs to be diff --git a/quill-jdbc-zio/src/main/scala/io/getquill/jdbczio/QuillBaseContext.scala b/quill-jdbc-zio/src/main/scala/io/getquill/jdbczio/QuillBaseContext.scala index d3944ca160..5d8515db0a 100644 --- a/quill-jdbc-zio/src/main/scala/io/getquill/jdbczio/QuillBaseContext.scala +++ b/quill-jdbc-zio/src/main/scala/io/getquill/jdbczio/QuillBaseContext.scala @@ -134,9 +134,9 @@ trait QuillBaseContext[+Dialect <: SqlIdiom, +Naming <: NamingStrategy] * the database and return the contents of the Person table immediately after * that: * {{{ - * val a = run(query[Person].insert(Person(...)): ZIO[Has[DataSource], SQLException, Long] - * val b = run(query[Person]): ZIO[Has[DataSource], SQLException, Person] - * transaction(a *> b): ZIO[Has[DataSource], SQLException, Person] + * val a = run(query[Person].insert(Person(...)): ZIO[DataSource, SQLException, Long] + * val b = run(query[Person]): ZIO[DataSource, SQLException, Person] + * transaction(a *> b): ZIO[DataSource, SQLException, Person] * }}} */ def transaction[R, A](op: ZIO[R, Throwable, A]): ZIO[R, Throwable, A] =