Skip to content

Releases: typelevel/doobie

1.0.0-RC6

18 Sep 11:27
b5b234b
Compare
Choose a tag to compare

Warning: We have an issue in this release related to automatic derivation not using explicitly defined instances (See #2104). Please refrain from using this release and skip to 1.0.0-RC7 when it is out.

Query Cancellation

Query cancellation has been implemented via calling PreparedStatement#close() on fiber cancellation.

Big thanks to @TalkingFoxMid and contributions from @satorg @armanbilge @jatcwang!

Related PRs: #2079 #2088

Opt-in automatic derivation

Automatic derivation has been the (non-configurable) default in Doobie since the start. While convenient, it can lead to long compile times because Read/Write/Get/Put instances are derived every time it is needed.

For those who want shorter compile times, we have now made automatic derivation opt in!

  • import doobie.implicits.* will enable automatic derivation (maintaining source compatibility to ease migration).
  • import doobie.generic.auto.* to explicitly enable automatic derivation. Compared to import doobie.implicits.* this brings just the implicits/givens necessary for automatic derivation
  • Instances for tuples are still automatically derived for convenience
  • To switch to explicitly derived instances, change your import doobie.implicits.* to import doobie.syntax.all.* and gradually fix compile errors by deriving instances explicitly (see below):

To derive instances explicitly:

Scala 3:

case class Foo(a: String, b: Int) derives Read

Scala 2+:

case class Foo(a: String, b: Int)

object Foo {
  implicit val read: Read[Foo] = Read.derived
}

Related PRs:

Better type-checking with JDBC vendor types (For java.time.* and more)

In previous releases, doobie typecheck only checks against the int enum returned by java.sql.ResultSetMetaData#getColumnType (java.sql.Types). However this is inadequate for two reasons:

  • java.sql.Types doesn't cover many other possible database-specific types (e.g. JSON column type)
  • JDBC drivers often return the wrong java.sql.Types, often due to legacy

For example, for a TIMESTAMP WITH TIME ZONE column Postgres JDBC driver will report that it has the type java.sql.Types.TIMESTAMP (surprising as java.sql.Types.TIMESTAMP_WITH_TIMEZONE exists).

PostgreSQL Data Type getColumnType() getColumnTypeName()
TIMESTAMP Types.TIMESTAMP "TIMESTAMP"
TIMESTAMP WITH TIME ZONE Types.TIMESTAMP "TIMESTAMPTZ"

This means by just using the result from getColumnType typechecking couldn't differentiate between a TIMESTAMP WITH TIME ZONE column vs TIMESTAMP (WITHOUT TIMEZONE) column - which has serious implications for correctness of your program if one uses the wrong column type!

Fortunately, we can see that getColumnTypeName does differentiate between the two column types.

To help improve typechecking for java.time.* types (and generally), we have made the following changes:

1. Get and Put can now specify vendor column type name

When creating a Get or Put instance, the vendor type name can now be specified so typechecking will check against it.
When constructing instances (e.g. Get.Basic.one(..)) you can pass the expected vendor type to checkedVendorType parameter, or None if you don't need or want to check against the vendor type.

2. Move java.time.* instances into database modules

java.time.* instances are moved to their database-specific modules to handle differences in databases and their drivers.

doobie module import
doobie-postgres doobie.postgres.implicits.*
doobie-mysql doobie.mysql.implicits.*

For other databases that support Java 8 time types, you can continue to use import doobie.implicits.javatimedrivernative.* but there's no check against vendor type names.

3. Make doobie.implicits.javasql instances available by default

doobie.implicits.javasql has now been removed. You can safely remove any import doobie.implicits.javasql.* as these instances are now available without any import.

Related PRs:

Logging for streaming and updateMany queries

Query/Update which now allow queries ran through Query#stream and Update#withGeneratedKeys to be logged. As part of this work, doobie.hi.FC module also have 3 new functions: stream, executeWithResultSet and executeWithoutResultSet. Old functions that does not log (such as doobie.hi.FC.updateWithGeneratedKeys) has been deprecated and will be removed by 1.0.

Related PRs:

Other notable changes

  • Allow for different effects of HikariTransactor and its creation by @sideeffffect in #1939
  • Split methods for HikariTransactor constructed with two effects by @jatcwang in #1961
  • Add parenthesis around each expression in and/or combinator by @jatcwang in #2044
  • PostgreSQL Range Types by @tomohavvk in #2008
  • Remove lazy initialization of modules to fix potential initialization deadlocks by @jatcwang in #2046
  • Add withLogHandler method to Transactor by @sideeffffect in #1977
  • Ensure backward compatibility of Hikari Config by @sideeffffect in #1842
  • Improve analysis message + Small optimizations #2091
  • Deprecate non-logging/non-cancelling high-level methods #2090

Dependency updates

Read more

1.0.0-RC5

19 Nov 20:22
dc960d9
Compare
Choose a tag to compare

What's New

Bug fixes and improvements

New Contributors

Full Changelog: v1.0.0-RC4...v1.0.0-RC5

v1.0.0-RC4

20 Jun 16:56
aed03ca
Compare
Choose a tag to compare

v1.0.0-RC3

19 Jun 13:17
518139d
Compare
Choose a tag to compare

Java 11 & major dependency updates

  • The minimum Java version is now 11
  • slf4j version is now 2.x (In order to update to latest HikariCP)
  • Depends on cats-effect 3.5 & fs2 3.7

Effectful Logging & Transactor-level logging

In previous versions Doobie supports SQL statement logging via LogHandler. However, it has the slightly awkward interface of final case class LogHandler(unsafeRun: LogEvent => Unit) which makes it difficult to integrate with pure FP logging libraries.

We have reworked how logging works, with the two major difference being:

  • LogHandler now runs in an effect i.e. def run(logEvent: LogEvent): M[Unit]
  • Each Transactor[M] now has a single LogHandler[M] attached to it, in order to align the effect type.

To recover some of the previous functionality of per-query logging logic, you can call .queryWithLabel/.updateWithLabel (instead of .query/.update) to attach a String label to each query.
This label will be set for each LogEvent, which your LogHandler can then use to differentiate the queries being logged. (e.g. use it for metrics)

For more advanced use case where you want to pass more structured contextual information for logging purposes, you can use IOLocal (The docs on logging has an example)

Big thanks to @oyvindberg for the implementation of effectful LogHandler and @george-wilson-rea for adding query labels

Basic migration steps

  • Add a LogHandler[M] when constructing your Transactor (or pass a None if you don't want to log events)
  • Replace queryWithLogHandler/updateWithLogHandler with queryWithLabel/updateWithLabel

Tightening Postgres java.time instance typecheck

In #1735 / #1736, we tightened Meta instances for PostgreSQL java.time instances to reflect what the postgres-jdbc driver actually allows. For example, typechecking a query that tries to map a java.time.OffsetDateTime to a VARCHAR column in the database will now fail.

Instance for ZonedDateTime has also been removed as it is misleading (PostgreSQL does not support a timestamp type that stores the timezone)

All PostgreSQL users should migrate to using doobie.postgres.JavaTimeInstances which has stricter type-checking to help you catch errors. For example, it enforces that the corresponding column type of an java.time.Instant must be TIMESTAMP WITH TIME ZONE.

Thanks @guymers!

doobie-hikari: Now automatically creates the Connect ExecutionContext

doobie.hikari.HikariTransactor#fromConfig/fromHikariConfig previously requires you to pass in a connectEC: ExecutionContext parameter used when awaiting a connection from the hikari connection pool.
Since the general best practice is to set this fixed-size pool to your hikari connection pool size, we now automatically create this ExecutionContext for you based on hikariConfig.getMaximumPoolSize.

If you want to use your own connectEC like previous versions, you can use doobie.hikari.HikariTransactor#fromConfigCustomEC/fromHikariConfigCustomEC instead.

By @sideeffffect in #1690 and #1745

Improved composability and safety of fragment helpers (doobie.util.fragments.*)

  • when calling methods like and/or, we now wrap the resulting expression in parenthesis.
    This prevents scenarios where the boolean logic generated by and/or can be influenced by its surroundings due to the lack of parenthesis

For example, previously the code fr"cond1 AND ${or(cond2, cond3)}" evaluates to the SQL cond1 AND cond2 OR cond3, which is most likely not equivalent to the user's intention of cond1 AND (cond2 OR cond3) and will behave differently for certain cond1/2/3 values.

Basic migration steps

  • Fix compile errors from andOpt/orOpt, which now return an Option[Fragment].
  • Carefully check use of and/or/andOpt/orOpt if they are used in conjunction with other AND/OR. If you were previously relying on fragment helpers NOT wrapping the resulting expression in parenthesis, you should adjust your code to maintain to old behaviour**

Other additions

  • Add Semigroup and Monoid instances for ConnectionIO and friends by @Fristi in #1729
  • Add weaver test framework integration by @danielkarch in #1668
  • Added doobie.hikari.HikariTransactor.fromConfigAutoEc which automatically creates/configures the ExecutionContext which awaits connections from the pool, following best practices. By @sideeffffect in #1690

Binary Compatibility

v1.0.0-RC3 is NOT binary compatible

v1.0.0-RC2

31 Jan 22:59
8297aa8
Compare
Choose a tag to compare

New

  • Enable support for derives in Scala 3 for Read, Write and Text (#1594 by @oyvindberg)
  • Add support for JSON in H2 using circe (#1599 by @andrzejressel)
  • Add Config case class (#1541 by @sideeffffect). This allow you to more easily configure Hikari connection pool settings using libraries like Pureconfig that relies on derivation.
  • Add a cause to the munit Checker failure (#1564 by @brendanmaguire)

Fixes

Removed

  • Remove Quill integration (doobie-quill) #1587

v1.0.0-RC1

30 Aug 21:25
d99ba2b
Compare
Choose a tag to compare

This is the first 1.0.0 release candidate, built on Cats-Effect 3 on the main branch.

v0.13.4

23 May 19:02
a8021d1
Compare
Choose a tag to compare

v0.13.4 (For cats-effect 2)

Scala 3.0.0 support

Doobie is now published for Scala 3.0.0!

New integration with MUnit (doobie-munit)

Doobie now integrates with the https://scalameta.org/munit test framework via the doobie-munit module.

See https://tpolecat.github.io/doobie/docs/13-Unit-Testing.html on how to use it!

Big thanks to @Kazark and @alejandrohdezma for contributing this integration!

v1.0.0-M2

27 Apr 18:59
1b11ff7
Compare
Choose a tag to compare

Support for Scala 3 RC3, Drops RC1. (Note that Doobie 1.x integrates with cats-effect 3.x)

v0.13.1

24 Apr 11:59
c70f262
Compare
Choose a tag to compare

Now published for Scala 3 RC3

v0.12.1

10 Mar 16:01
84c8f40
Compare
Choose a tag to compare

The previous version (v0.12.0) upgraded Hikari to v4, which pulls in slf4j v2, which is incompatible with the version most people are using. So this version reverts that upgrade. No other changes.