Quill v3.11.0 Release Notes

  • 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[Connecction] 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].

    • 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:

      object MyPostgresContext extends PostgresZioJdbcContext(Literal); import MyPostgresContext._
      val zioDS = DataSourceLayer.fromPrefix("testPostgresDB")
      

    val people = quote { query[Person].filter(p => p.name == "Alex") }

    MyPostgresContext.run(people).onDataSource .tap(result => putStrLn(result.toString)) .provideCustomLayer(zioDs)

      In 3.11.0 simply remove the `.onDataSource` in order to use the new context.
      ```scala
      object MyPostgresContext extends PostgresZioJdbcContext(Literal); import MyPostgresContext._
      val zioDS = DataSourceLayer.fromPrefix("testPostgresDB")
    
      val people = quote {
        query[Person].filter(p => p.name == "Alex")
      }
    
      MyPostgresContext.run(people)  // Don't need `.onDataSource` anymore
        .tap(result => putStrLn(result.toString))
        .provideCustomLayer(zioDs)
    
    • If you are creating a Hikari DataSource directly, passing of the dependency is now also simpler. Instead having to pass the Hikari-pool-layer into DataSourceLayer, just provide the Hikari-pool-layer directly.

    From this:

      def hikariConfig = new HikariConfig(JdbcContextConfig(LoadConfig("testPostgresDB")).configProperties)
      def hikariDataSource: DataSource with Closeable = new HikariDataSource(hikariConfig)
    
      val zioConn: ZLayer[Any, Throwable, Has[Connection]] =
        Task(hikariDataSource).toLayer >>> DataSourceLayer.live
    
    
      MyPostgresContext.run(people)
        .tap(result => putStrLn(result.toString))
        .provideCustomLayer(zioConn)
    

    To this:

      def hikariConfig = new HikariConfig(JdbcContextConfig(LoadConfig("testPostgresDB")).configProperties)
      def hikariDataSource: DataSource with Closeable = new HikariDataSource(hikariConfig)
    
      val zioDS: ZLayer[Any, Throwable, Has[DataSource]] =
        Task(hikariDataSource).toLayer // Don't need `>>> DataSourceLayer.live` anymore!
    
      MyPostgresContext.run(people)
        .tap(result => putStrLn(result.toString))
        .provideCustomLayer(zioConn)
    
    • If you want to provide a java.sql.Connection to a ZIO context directly, you can still do it using the underlying variable.

      object Ctx extends PostgresZioJdbcContext(Literal); import MyPostgresContext._
      Ctx.underlying.run(qr1)
      .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).

      object Ctx extends PostgresZioJdbcContext(Literal); import MyPostgresContext._
      Ctx.underlying.run(qr1)
        .onDataSource
        .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 with the result of this value (i.e. to work with PreparedStatement), the connection that created it must still be open.