Changelog

v1.2.0 (2024-10-20)

Pekko support (#807)

neotypes now can be used with pekko! :tada:
The neotypes-pekko-stream module behaves identical to the neotypes-akka-stream module.

Thanks @turb !

Fix ResultMapper on ordered tuple (#808)

Improved the consistency of ResultMappers based on a NeoMap.

v1.1.0 (2024-06-07)

Add support for AuthTokenManager when creating the Driver (#763)

Allows creating a Driver using an AuthTokenManager.

Thanks @kbreidenbach !

v1.0.0 (2024-02-10)

Finally, the final v1.0.0 release :tada:

This release is mostly idential to v1.0.0-M3 but includes many dependency updates.
Please, read the changelong of the milestones for details on the changes introduced in this version.

Again, thanks a lot to everyone involved in making this release possible! :D :rocket:

v1.0.0-M3 (2023-09-15)

Scala 3 support!

This thirds milestone brings mostly dependency updates, as well as Scala 3 support! :tada:

Cross compile core module (Scala 3) (#666)

Cross compile generic module (Scala 3) (#667)

Cross compile extra modules (Scala 3) (#673)

Cross compile enumeratum module (Scala 3) (#680)

Cross compile refined module (Scala 3) (#690)

Again, thanks a lot @i10416 for all the effort!

v1.0.0-M2 (2023-08-26)

We start the road for Scala 3 support!

This second milestone brings mostly dependency updates, as well as some internal changes in preparation for Scala 3 support.

Prepare for scala 3 (#665)

Thanks @i10416!

v1.0.0-M1 (2023-06-05)

We start the road for the first stable version of Neotypes!

This first milestone introduces a bunch of breaking changes, especially with everything related to ResultMapper.

Neotypes-Schema — Explicit decoders (#584)

We not longer use ResultMapper as a typeclass, rather the query method expects an explicit mapper; which you may construct based on the the provided ones and combinators.
See supported types for more information.

Miscellaneous

Additionally, we made a couple of renames to make everything more consistent.

A non exhaustive list of renames are:

  • GraphDatabase.driver -> GraphDatabase.asyncDriver
  • GraphDatabase.streamingDriver -> GraphDatabase.streamDriver
  • query.query[Unit].execute(driver) -> query.execute.void(driver)
  • query.query[ResultSummary].execute(driver) -> query.execute.resultSummary(driver)
  • import neotypes.implicits.syntax.all._ -> import neotypes.syntax.all._
  • import neotypes.generic.auto._ -> import neotypes.generic.implicits._

v0.23.3 (2023-06-04)

This release only bumps dependencies.
It also will be the final release before the 1.0.0 milestones begin.

v0.23.2 (2023-01-24)

This release mostly bumps dependencies. But also adds a minor improvement.

Allow using heterogeneous lists and maps as parameters (#595)

We added a passthrough ParameterMapper for QueryParam, which allow interpolating lists and maps of QueryParams.

v0.23.1 (2022-11-29)

Update neo4j-java-driver to 5.3.0 & bump dependencies (#576)

This release only updates a couple of dependencies.

The most relevant one is the the neo4j-java-driver, since this version introduced a new factory function to construct the underlying Session

v0.23.0 (2022-10-15)

Upgrade to neo4j 5 (#563)

We upgraded the Neo4j Java driver to version 5.0.0

This version deprecated the internal RxSession and replaced it with a new ReactiveSession, which is based on the Flow api provided by the Java stdlib since Java 9.
Also, such artifact was published only for Java 17.

Thus, this release drops support for Java 8 & Java 11 and only supports Java 17 onwards.

v0.22.0 (2022-08-03)

Separate subproject for generic (#548)

In preparation for supporting Scala 3, we decided to move the generic package to its own module.
If you were using the generic derivation remember to add neotypes-generic as a new dependency.

PS: This also means that now the core module does not longer depend on Shapeless.

Thanks to @tjarvstrand for tackling this!

Fix bug using readOnlyTransact in DeferredQuery#execute (01383667433d29e2119170052b2a9b19eea32999)

We were using Driver#readOnlyTransact in the implementation of DeferredQuery#execute(Driver[F], TransactionConfig) by accident; which, obviously was wrong and was causing issues.

This new release fixes it and correctly uses Driver#transact instead.

Apologies for the inconveniences this may have caused.

v0.21.1 (2022-07-12)

This release only updates dependencies.
The most notable changes are:

Update ZIO to 2.0.0 (#525)

The ZIO module of neotypes now uses the official 2.0.0 stable release.

Thanks to @masonedmison for initiating this PR (again)!

Update neo4j-java-driver to 4.4.9 (#539)

The latest version of the Neo4j Java driver deprecated the routingDriver factories; since the connection model changed. And, as such, we removed the proxies of such factories.

v0.21.0 (2022-06-22)

Ready only transactions (#523)

neotypes now provides some “read only” alternatives to operations that create and use Transactions under the hood; like transact or query
The readOnly variations automatically override the withAccessMode property of the provided TransactionConfig with the AccessMode.READ value.

A readOnly operation can be routed to a read server, for more information check the Neo4j docs.

ZIO 2 support (#524)

The ZIO module of neotypes not longer supports ZIO 1.x, but rather requires the a 2.x release of the library.

This version uses 2.0.0-RC6, check 0.21.1 (or upwards) for a release that depends on a stable release.

Thanks to @masonedmison for initiating this PR!

v0.20.0 (2022-03-31)

Add plain string interpolation (#493)

You can now use #$ to tell the cypher string interpolator that the following value should be interpreted as a plain string.

For example:

import neotypes.implicits.syntax.cypher._ // Adds the `c` interpolator into the scope.

val name = "John"
val LABEL = "User"

c"CREATE (a: #${LABEL} { name: ${name} })".query[Unit]
// res: neotypes.DeferredQuery[Unit] = DeferredQuery(
//   "CREATE (a: User { name: p1 })",
//   Map("p1" -> neotypes.types.QueryParam("John"))
// )

v0.19.1 (2022-03-08)

This was a test release to validate some changes to the release process
It only includes a couple of dependencies bumps.

v0.19.0 (2022-03-07)

Update to CE3 (#481)

We updated the cats-effect and the fs2 modules to their latest CE3 versions.
The monix and monix-stream modules still depend on CE2.

v0.18.3 (2021-06-25)

Reverting the neo4j#797 workaround (#364)

This is just an internal code refactor thanks to a bug fix in the underlying Java driver.

However, this refactor implies that users need to update their underlying Java driver to the latest patch versions.
As of the writing date: 4.3.2, 4.2.7 & 4.1.4; 4.0 seems to be not longer maintained.

v0.18.2 (2021-06-16)

Don’t override driver’s tx-config from DeferredQuery (#362)

This a bug fix that complements #341

It ensures that when you run a query using the standard DeferredQuery syntax, it would respect the current Driver’s default config.

v0.18.1 (2021-06-08)

Update organization id (#359)

This is the first version to be released to io.github.neotypes rather than to com.dimafeng

This releases also changed the name of the core module from just neotypes to neotypes-core

Ensuring all casting errors during mapping are encapsulated in a NeotypesException (#345)

This is basically a bug fix that ensures that any exception thrown during the “casting” of Neo4j values to Scala ones are catch by the underlying ValueMapper and wrapped in the optional cause of a neotypes.exceptions.IncoercibleException

We also removed neotypes.exceptions.ConversionException and replaced its only usage with a neotypes.exceptions.IncoercibleException for consistency.

Add cypher interpolation of DeferredQueryBuilder (#344)

We added the capability to embedded DeferredQueryBuilders inside other queries, which helps a lot to share and reuse common (sub) queries.

Which means that the following examples now compile out-of-the-box and behave as expected.

import neotypes.implicits.syntax.cypher._

// Two sub-queries.
val subQuery1Param = 1
val subQuery1 = c"user.id = ${subQuery1Param}"
val subQuery2Param = "Luis"
val subQuery2 = c"user.name = ${subQuery2Param}"
val query1 = c"MATCH (user: User) WHERE ${subQuery1} OR ${subQuery2} RETURN user"

// Sub.query with a sub-query.
val subSubQueryParam = 1
val subSubQuery = c"user.id = ${subSubQueryParam}"
val subQuery = c"""${subSubQuery} OR user.name = "Luis""""
val query2 = c"MATCH (user: User) WHERE ${subQuery} RETURN user"

Special thanks to @tjarvstrand for all the hard work in this PR!

Make default transaction config configurable (#341)

We added a new withTransactionConfig method to the Driver interface, this method can be used to crate a new Driver[F] whose default TransactionConfig will be the one passed to the previous method.

This is very useful when you need to use a custom config across all the application, or for tests.

v0.18.0 (2021-06-08)

DO NOT USE!

v0.18.0 was published by accident, use v0.18.1 which contains all the planned changes for this version.

v0.17.0 (2021-04-04)

Adding the enumeratum module (#291)

We added a new neotypes-enumeratum module which allow the use of Enumeratum enums.

import enumeratum.{Enum, EnumEntry}
import enumeratum.values.{StringEnum, StringEnumEntry}
import neotypes.enumeratum.{NeotypesEnum, NeotypesKeyEnum, NeotypesStringEnum}

sealed trait SimpleEnum extends EnumEntry with Product with Serializable
object SimpleEnum extends Enum[SimpleEnum] with NeotypesEnum[SimpleEnum] {
  case object Foo extends SimpleEnum
  case object Bar extends SimpleEnum
  case object Baz extends SimpleEnum

  val values = findValues
}
implicitly[neotypes.mappers.ResultMapper[SimpleEnum]]
implicitly[neotypes.mappers.ParameterMapper[SimpleEnum]]

sealed trait KeyEnum extends EnumEntry with Product with Serializable
object KeyEnum extends Enum[KeyEnum] with NeotypesKeyEnum[KeyEnum] {
  case object Key1 extends KeyEnum
  case object Key2 extends KeyEnum
  case object Key3 extends KeyEnum

  val values = findValues
}
implicitly[neotypes.mappers.ParameterMapper[Map[KeyEnum, Int]]]

sealed abstract class KeyStringEnum (val value: String) extends StringEnumEntry with Product with Serializable
object KeyStringEnum extends StringEnum[KeyStringEnum] with NeotypesStringEnum[KeyStringEnum] {
  case object KeyA extends KeyStringEnum(value = "keyA")
  case object KeyB extends KeyStringEnum(value = "keyB")
  case object KeyC extends KeyStringEnum(value = "keyC")

  val values = findValues
}
implicitly[neotypes.mappers.ParameterMapper[Map[KeyStringEnum, Int]]]
implicitly[neotypes.mappers.ValueMapper[KeyStringEnum]]

For more information, please read supported types.

Adding UnwrappedMappers semiauto derivation (#294)

We added a new semiauto derivation of mappers for AnyVal case classes that act like the underlying type.

import neotypes.generic.semiauto
import neotypes.mappers.{ParameterMapper, ValueMapper}

final case class Id(value: String) extends AnyVal
implicit final val idParameterMapper: ParameterMapper[Id] = semiauto.deriveUnwrappedParameterMapper
implicit final val idValueMapper: ValueMapper[Id] = semiauto.deriveUnwrappedValueMapper

For more information, please read supported types.

Adding version scheme (#281)

Since this version, neotypes artifacts include its version scheme which can be read by sbt to produce more accurate eviction errors.

For more information, please read this blog post.

v0.16.0 (2021-02-09)

Removing Session & Using the new Rx module for Streaming (#221)

We replaced our in-house implementation of Streaming with wrappers for the new Rx module of the Java driver.

During this change we also removed Session since it wasn’t actually needed.

This change implies that now you can chose between a normal Driver[F] or a StreamingDriver[S, F], the latter can be used to create both a normal Transaction[F] or a StreamingTransaction[S, F]. The first one no longer supports streaming data from the database, but the second one implies that even no-streaming operations like single are implemented in terms of ReactiveStreams.
However, if you use single query + auto-commit syntax provided by DeferredQuery then you will use normal (asynchronous) Transactions for most operations and Streaming Transactions only for stream queries.

This is quite a big change, because now the Stream typeclass doesn’t need to be in scope when calling stream, but rather when creating the Driver; By calling GraphDatabase.streamingDriver[S[_]]

// Replace this:
val driverR: Resource[IO, neotypes.Driver[IO]] = ???

val sessionR = driverR.flatMap(_.session)

val data = fs2.Stream.resource(sessionR).flatMap { s =>
  "MATCH (p:Person) RETURN p.name".query[String].stream[Fs2IoStream](s)
}
// With this:
val driverR: Resource[IO, StreamingDriver[Fs2IoStream, IO]] =
  GraphDatabase.streamingDriver[Fs2IoStream]("bolt://localhost:7687", AuthTokens.basic("neo4j", "****"))

val data = for {
  driver <- fs2.Stream.resource(driverR)
  name <- "MATCH (p:Person) RETURN p.name".query[String].stream(driver)
} yield name

For more information, please read streaming.

Rollback on cancellation (c6c43d24f8e0c82db40387fa600490c4b85fa297)

Cancelling an effectual operation that was using a Transaction will now rollback the Transaction instead of commit it.

Note: This should have been its own PR but due the problems on #164 it ended up being a commit on #221.

Add auto and semiauto derivation (#199)

Automatic derivation of Mappers for case classes is now opt-in, and Mappers for primitive values are now always on the implicit scope (without needing any import).

Also, we now provide some semiauto.derive methods which can be used to cache Mapper instances for case classes (and product types).

This change also gives higher priority to custom Mappers on the companion objects of the target types, over automatically derived ones.

If you want to keep using automatic derivation you only need to:

- import import neotypes.implicits.mappers.all._
+ import neotypes.generic.auto._

For more information, please read supported types.

Support case class by cypher string interpolator (#201)

Now you can pass case class instances directly to cypher string interpolator, this will add all their properties as parameters of the query.

For example:

import neotypes.generic.auto._ // Provides automatic derivation of ParameterMapper for any case class.
import neotypes.implicits.syntax.cypher._ // Adds the ` interpolator into the scope.

final case class User(name: String, age: Int)
val user = User("my name", 33)
val query = c"""CREATE (u: User { $user }) RETURN u"""
// CREATE (u: User { name: "my name", age: 33 }) RETURN u

For more information, please read parameterized queries.

v0.15.1 (2020-09-08)

Fix id handling (#174)

neotypes now ensures that if you have a custom id property, that one takes precedence over the system (neo4j) one.

For more information, please read neo4j id.

v0.15.0 (2020-07-30)

Making Session thread safe (#163)

neotypes.Session is now thread safe, by ensuring only one active neotypes.Transaction per session.

For more information, please read thread safety.

v0.14.0 (2020-07-10)

Upgrade neo4j java driver to version 4 (#140)

neotypes is now published for the v4 version of the Java driver, instead of the 1.7.x version.

v0.13.2 (2020-02-23)

Case class mapper for maps (#60)

You can now query for a case class when returning a node or a map projection.

Fix composite types (#61)

neotypes now supports all composite types.

v0.13.1 (2020-01-09)

Bug fixes and improvements to the docs.

Special thanks to @geoffjohn11

v0.13.0 (2019-09-11)

Scala 2.13 support (#45)

neotypes is now cross compiled for Scala 2.12 & 2.13, instead of for 2.11 & 2.12.

v0.12.0 (2019-08-25)