1.0.53, 1.0.54 - 1.0.58

Update dependencies.


Add support for Scala 2.13.

(a383dff20fadc08ec9306f2f1f24b2a7e0047449 @ jdbc-driver) Synchronize access to the handlers map (#93)

(f18cf9459e071d00b1c7cbb810b44a78dfc4bd2d @ jdbc-driver) JDBC transaction handlers (#90)

(d81609665798b1c962233f588d0095f49ea33890 @ reactivemongo) Upgrade ReactiveMongo to 0.16.0 (#86)

1.0.50 & 1.0.51

Minor dependency updates.



  • Natural conversions (synchronous & async) for the loan patterns utilities.
  • Support 0.16.0


Support ReactiveMongo 0.15


Support ReactiveMongo 0.13


Support bulkInsert for ReactiveMongo testing.

1.0.44 - 1.0.45

Upgrade Scala compatibility to 2.12.2.


(ff3d73226efd3efb6f5091cdc5d6f6cc90361618 @ reactivemongo) Combinator orElse for the handlers

(b6e630fab550af1e4174ff035c7aa63d9236131d @ reactivemongo) Utility for findAndModify

1.0.39 - 1.0.42

Fix the ReactiveMongo module


Update to ReactiveMongo 0.12-RC4


(b527a212302abda6c3943aad97a60c37676a2d58 @ play-jdbc) New Play JDBC module (with DSL).

(2eb464aa7ad36a550d230c69074da2c24d21421b @ reactivemongo) Update ReactiveMongo to 0.12-RC0.


(40bfcf737112b166f2d7c2d4d56791d15178b90f @ jdbc-driver) Set opaque parameter as JDBC OTHER.


(de0179bd758b93861fb9405869743005ec31ff09 @ reactivemongo) Support ReactiveMongo 0.11.x.

(d60d07e1afb887e055c46f5d49ace4842a93946f @ jdbc-driver) Better fetch-size support.


(4f6afc2928fa3dbb469a1a54f7c556fa3e245afa @ jdbc-scala) New debugging utility in the Acolyte DSL.

import acolyte.jdbc.AcolyteDSL

AcolyteDSL.debuging() { con =>
  val stmt = con.prepareStatement("SELECT * FROM Test WHERE id = ?")
  stmt.setString(1, "foo")


(56ca676e19164a251801579397c2411a9a503505 @ jdbc-java8) Acolyte DSL for JDBC.

(05d7fbaaf2d31c96afcfed9ddcdb101555d615ea @ jdbc-driver) Add a new RowList factory for a single row with a single value.

import static acolyte.jdbc.RowLists;

RowLists.scalar("Foo"); // Scalar RowList of String

(92f72ae4bb716c1bfb853be401dc4761e8c5f251 @ jdbc-driver) Add class Driver.Property.

import acolyte.jdbc.Driver;
import acolyte.jdbc.Property;

  new Property("name1, "Foo"),
  new Property("name2", "Bar"));

(a8ed90b4c44a38626bf7e1935bca692fdc152012 @ jdbc-driver) Java 1.7+ support


(42a9ddfdccc65c175edf7d22cd677592843af0bf @ jdbc-driver) Add connection property acolyte.resultSet.initOnFirstRow to make Acolyte ResultSet iterates rows as degraded Oracle one.


(bd6763c3e1d513d05cfefbb887e20a672b1c71db @ reactivemongo) Manage connection handler per actor, so that an single ActorSystem can manage several handlers. Documentation about driver manager with SBT or Specs2.

6197ee32151ccfa03f75ce6dfef563ee39c9581b @ reactivemongo) Add clause extractor NotInClause(List(_)).


(9b641b8e3b1252611a1e9d5376b84a2580ca8f42 @ reactivemongo) Write request convenient extractors


Minor refactoring.


(ca0470eb13f5dd9a6a083fa26f2665303f96ffdb @ jdbc-driver) Support for SQL Array as statement parameter

(ccc0485199c8081b17b40d008983984e4d23dba0 @ reactivemongo) Update project doc


(c94cd5883bbef746273c5245885d5e7d22e2e8a3 @ reactivemongo) Pattern matching for request body with multiple document

(f5e58c0dbf83e3f067af8081a39575550657115a @ reactivemongo) $in extractor

(d213d6df9c7c4f158f9699f1027c363ddbafbfc8 @ reactivemongo) Refactor Request pattern matching

(8fe2ef491a7601ab1916838c92c5277b983db62c @ reactivemongo) Fix Scaladoc

(b663965aa94b91a6e573ac760a1ba3e20ea6fb0b @ reactivemongo) BSON array extractor


(646c8f57fccf605d97e2318adebb4b2540d5514b @ reactivemongo) Refactor DSL and better support for Count command.

(cb826da6c11d9eac28a9e7a392423fc28aae5a2b @ reactivemongo) Count response.


(919d248bff3afd5549e240e4d871b86a32d6f3db @ reactivemongo) Fix doc

(406cc26a029d868d74c5fd5f7e28305e31e088fc @ reactivemongo) Complete driver specifications

(d0f067434324650f09199be1b88a91c5c329aea2 @ reactivemongo) Load patterns for MongoDB resources

(f925d4ffcd64388836d6da252b3c13b3bff32aac @ reactivemongo) Convenient response maker for write operation. More specifications for Driver/Acolyte DSL, update documentation.

(14b59bc5a92637d97e60c2f2a884f4aa7037a2ef @ reactivemongo) Disable Akka reverse engineering, only use Acolyte actor system

(11832214f443bb84a54d4397aee4a68818737da5 @ reactivemongo) Driver specification

(23517d9db23b4e815205196166fd57a1fcff7351 @ reactivemongo) Update count in WriteResponse

(1f714141517f5dc547a30482cf50c1ce1f60d3f7 @ reactivemongo) specifications (connection handler), add optional code in query error

(66cc12f36f0127598f72c2c9c2cc59d01d1ba9d2 @ reactivemongo) Write response & handler specifications

(357c67663436dfa73f82e2b329c4fb7e559b447d @ reactivemongo) Documentation for pattern matching on write operator

(04355e9b1ae25c53960c49b53e842c40d8028d7a @ reactivemongo) Typeclasses WriteResponseMaker, WriteResponse and associated handler types.

(95e66462f6c225a84be1b69732a15385f61261c4 @ reactivemongo) Fallback functions for write errors

1.0.23 to 1.0.24

(1d8160dd6b26fcf964fce51096f3043994069fab @ jdbc-driver) Support for ResultSet type/scrollability

(0942aaefa304f7ef13e5260b779e2f51d65bb4be @ scalac-plugin) Recursive support ~(A(...), ~(B(...), (x, y))). Add specifications for pattern matching in val statement. Update documentation.

(d6d2a26b601fd76d09b6c626f87998f28489cd0e @ scalac-plugin) Support application other than a single value or tuple-like one as bindings:

str match {
  case str @ ~(IndexOf('/'), a :: b :: c :: _)  ??? // Support :: application
  case _  ???

(193d3bf1118dcd617cdd6bc915a597b2c550c5a1 @ scalac-plugin) Fix compatibility warning between 2.10 & 2.11

(e9c5c4777cdfa00ea5a3dfe88cf9ac7bfc8f242f @ jdbc-driver) Remove obsolete JDBC classes from base package (previously moved to acolyte.jdbc).

(194d549fca55e35ea07c175f0f12edda1c79a85a @ jdbc-driver) Support for binary types (BLOB, byte array, input stream)

(43257c1db69ceb1cf9f31c0856903255924cb880 @ jdbc-driver) Fix wasNull operation on result

(c849e2489f9e66a96760d800d5a72becf5d870e9 @ scalac-plugin) Support for literal with rich match:

str match {
  case ~(RegEx("# ([a-z]+): .*"), "start") => /* Start */ ???
  case ~(RegEx("# ([a-z]+): .*"), "stop")  => /* Stop */ ???


(a07e7306cab7b2e4eac1d4a39c90789e42065655 @ jdbc-driver) Support for binary types (BLOB, byte array, input stream)

(43257c1db69ceb1cf9f31c0856903255924cb880 @ jdbc-driver) Fix wasNull operation on result

(c849e2489f9e66a96760d800d5a72becf5d870e9 @ scalac-plugin) Support for literal with rich match:

str match {
  case ~(RegEx("# ([a-z]+): .*"), "start") => /* Start */ ???
  case ~(RegEx("# ([a-z]+): .*"), "stop")  => /* Stop */ ???


(9c261f107338c4a9d4364d89540f8965cb46c71f @ jdbc-driver) Moves classes from package acolyte to acolyte.jdbc. Classes in former package are deprecated, and will be removed in future release.

(210e6d17602af672fe4154b11d1009580cce01a3 @ jdbc-driver) Array support in query result:

import acolyte.RowLists;
import acolyte.ImmutableArray;

// List of row with 1 column,
// whose type is array of string
    new String[] { "Ab", "Cd", "Ef" }));


(210e6d17602af672fe4154b11d1009580cce01a3 @ jdbc-driver) Array support in query result:

import acolyte.RowLists;
import acolyte.ImmutableArray;

// List of row with 1 column,
// whose type is array of string
    new String[] { "Ab", "Cd", "Ef" }));


(28fff28e89368a64d4882efd7517abebc88c3edd @ scalac-plugin) Refactor recursive match:

x match {
  case y => y match {
    case ~(RichPat("x"), _) => ???

(f4acc2dc143f0f584b9142c096e0194a91ad8bb9 @ jdbc-driver) Make warning of query result accessible on raised ResultSet


(ac3415cabc01f85de1d766c0de53f0ab7e8c6c38 @ jdbc-scala) Companion function for update result with generated keys.

import acolyte.{ Acolyte, RowLists }

val res = Acolyte.updateResult(3/*count*/, RowLists.stringList("generatedKey"))

(99ac2f1d01681b01f2c236268061d498ba1217c1 @ jdbc-driver) Fix generated keys on update result.


(363aab2f67d2d7866626d750f442b61d4c728223 @ jdbc-scala) Cross build for Scala 2.11.


(a0122044eb1125fe66899582c1eb1df617cf8351 @ jdbc-driver) Fix parameter definition for null decimal/numeric (1.0.16-2).

(bf89ecec5b9b1645c347c32cf334475e39e4155c @ jdbc-driver) Simplified exception message (1.0.16-1).

(2a2093606f5c4582efa2fea4aa18de357f4b8a1c @ jdbc-driver) Batch support on statement and prepared statement.

(ce8a913be91b04759903e8dab843baf41cad7b86 @ jdbc-driver) Generated keys support for statement:

import acolyte.UpdateResult;
import acolyte.RowLists;

// to be returned from an update handler:
// update count = 1 and one generated key = 4


(65a7e3313ab5681b77cba502c0aa945ef645f68c @ jdbc-scala) Regex extractor for executed statement, usable with rich pattern:

e/* : QueryExecution */ match {
  case ~(ExecutedStatement("^SELECT"), (sql, parameters)) => // ...

(7bc9b546b3a3d05008b8ace84f3d2e47ba18d367 @ scalac-plugin) Support binding over rich pattern matching (e.g. case binding @ ~(..., ...) => ...; Fix #20)


(9b813586190f6e5f8e7c3fdcde642bcc2234e1a4 @ scalac-plugin) Documentation

(b5994bd1773f63e7c04eccc2b24b6378c10b8f4d @ scalac-plugin) Match component specifications

(88aaedde8f2d6a90bcc3e012810701f72eac3781 @ scalac-plugin) Add MatchPlugin (rich pattern matching)

(4b64595e37b5c2d70761d1a7c1307f06fdc771e6 @ studio) Fix display issue in extract table

(654575844c3386a5471c01cf2c1710ab9a29d7e4 @ studio) Fix BigDecimal issue

(c33c9b88cb58b3cce07d06f3b161eeb8fc9ff3d0 @ studio) Expert editor for column mappings.


(924ef57d29285ad49c8674d76ceee97630a25c1a @ studio) Allow Studio to connection without password (Fix #14)

(965bc416990b54b0d9421c72af769bfe75e3f31e @ studio) Fix issue with driver at system class loader (overloading those in selected driver JAR)

(6a526416ca73ffee884ad1744f6c2f3376264781 @ studio) Fix row column cursor in formatting


(f33f9c82f4e64bc3b83c9f64ab82319b47af873e @ scala) Single result case connection using withQueryResult in DSL:

val str: String = Acolyte.withQueryResult(res) { connection  ??? }

(38f0b52dc120488d1bae3a4e830a849958146fe3 @ scala) Support nullable flag for column of row list

(4edb03ec7b48e89e3219fe898f667c63cdd356a8 @ core) Support nullable flag for meta-data of row column.

import acolyte.RowList2;
import acolyte.RowLists;

RowList2.Impl<String,Float> l1 =
  RowLists.rowList2(String.class, Float.class).
  withNullable(1, true); // First column is nullable

import acolyte.RowList;
import acolyte.Column;

Column<String> meta1 = new Column<String>(String.class, "a", true);

RowList2.Impl<String,Float> l2 =
  RowLists.rowLists2(meta1, RowList.Column(Float.class, "b"));

import static acolyte.RowList.Column

RowList2.Impl<String,Float> l3 =
  RowLists.rowLists2(Column(String.class, "a").withNullable(true),
    Column(Float.class, "b"));

(c68afc6a732f50c4e8b7cea9628a335caf38583b @ core) Deprecates append-row operation on RowList, replaced by multi-value append. Prevents null inference issues.

import acolyte.RowLists;
import acolyte.Rows;

// Before
RowLists.rowList2(String.class, Integer.class).
  append(Rows.row2("str", 1)); // now deprecated

RowLists.rowList2(String.class, Integer.class).
  append("str", 1);

(dd64b526794625a65c1ca06e12492e2a4f692bd9 @ scala) Refactor Scala RowList with self-types, for better inference and implicits (operation on ScalaRowList returning ScalaRowList, not core RowList which would be converted again on next operation).

object dd64b526794625a65c1ca06e12492e2a4f692bd9 {

  // Before
  val l1a: RowList1[String] = rowList1(classOf[String])
  val l1b: RowList1[String] = l1a :+ "B" // convert on :+ ...
  // but core type RowList1 is returned

  // Now
  val l1a = rowList1(classOf[String])
  val l1b: ScalaRowList1[A] = l1a :+ "B" // convert on :+ ...
  // and keep it as pimped Scala type
  val l1c: ScalaRowList1[A] = l1b :+ "C" // no conversion required


Typesafe append operations are generated along with generated row lists, so append-row operation and related Row implicits are no longer required.

// Before
rowList3 :+ row3(a, b, c) // no supported due to inference issues

// Now
rowList3 :+ (a, b, c)

(b4d944aaee23afbeeb8aa09cd97c3741c83f7fd8 @ core) Refactor RowList with self-type trick on append/labelling operation.

// Before this change
RowList1<String> l1 = new RowList1<String>(String.class);
RowList<Row1<A>> l1updated = l1.append("str");
// Self-type RowList1<A> of l1 is lost in append operation

// Now
RowList1.Impl<String> l2 = new RowList1.Impl<String>(String.class);
RowList1.Impl<String> l2updated = l2.append("str");
// Implementation self-type is kept

(a447ac9436f4c020e6bb48a58f5e8d6558da9b75 @ core) Fix row classes naming: move Row1 from acolyte.jdbc.Row.Row1 up to acolyte.jdbc.Row1

(f87782144a691847cf4a390cced9a838cdfa2db8 @ scala) Fix inference of on scala RowList1:

import acolyte.Implicits._
import acolyte.RowLists.stringList

stringList :+ null // fixed inference of null (as String there)

(2397517f22e7642851e10f490abd2d2f99a8301f @ core) Refactor RowList.Column.defineCol as RowList.Column:

import static acolyte.RowList.Column;

Column(String.class, "colName");


(b079c0ca31f3006ce3b8e779f5e778319ce4ed72 @ studio) First GUI release

(d9d4e5c831916305c415708203d8c8ef6d6ba5ce @ core) Update groupId to publish artefacts on Central via Sonatype

(3cc594b2d3e3030e6b09c91b3384092723eb1020 @ scala) Update limit of row columns from 26 to 52

(d6e4d9a9033ede803ad863a4682ca63123ac7040 @ core) Update limit of row columns from 26 to 52


(500abb5493a1b6221b5e5c0f2fdf102a5bcf88ff @ scala) Connection properties support:

import acolyte.Acolyte.connection

connection(handler, "acolyte.parameter.untypedNull" -> "true"/* ... */)

(3b7d9151ab1d09e994f3fbbcfd7bf0610343d4f4 @ core) Fallback for untyped null parameter, configured with connection property:

import java.util.Properties;

Properties props = new Properties();
props.put("acolyte.parameter.untypedNull", "true"); // default: false

DriverManager.getConnection(jdbcUrl, props);

(1240c3956e91807a25bd6b8c2fcdfa8e745dd2f1 @ core) Add factories for single column row lists, to create a list with initial values:

import acolyte.RowLists;
import acolyte.RowList1;

// Creates a row list with 3 rows "A", "B" and "C"
RowList1<String> list = RowLists.stringList("A", "B", "C");

(9d01cedde46f13cb1d9a2224732b2e96ba9314ad @ core) Supports max rows limit on statement (and row list):

java.sql.PreparedStatement stmt = conn.prepareStatement("SQL");


// Will go through RowList.resultSet(2)
java.sql.ResultSet rs = stmt.getResultSet();

(44f9c1e4cb12ca18cd3584eed5ae16636ecb3b3e @ core) Implements statement creation with supported result set type, concurrency or holdability:

conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);

conn.prepareStatement("SQL", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
conn.prepareStatement("SQL", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);

conn.prepareCall("SQL", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);

(334711bd91f361a1ff591609911f87dccd393c28 @ scala) Move implicit conversions apart (for cleaner imports):

import acolyte.Acolyte.{ connection, handleStatement/* ... */ } // DSL
import acolyte.Implicits._ // implicit conversions

val conn = connection(handleStatement { _ => list :+ row })

(18b94e06d565b35699250af7e7dabbe4c8df9ee3 @ scala) Remove .handleQuery without argument from DSL, replaced by:

import acolyte.Acolyte._
import acolyte.{ QueryExecution, QueryResult }

handleQuery { e: QueryExecution => /* QueryResult */ }

(6b1c7602b58f2952f22e18c3408e273924572d91 @ core) Empty composite handler: acolyte.CompositeHandler.empty()

(4e7c51b26586ff6b4049b4fd7b73447561dabd07 @ scala) Update handleQuery:

acolyte.Acolyte.handleQuery { e => res }

(e3536e8a6d10d72385cf8b4880e31a583d2a2f7a @ scala) Distinct execution case classes for update or query:

  withQueryHandler({ e: QueryExecution => res }).
  withUpdateHandler({ e: UpdateExecution => res })

(3747ba9c82c25b5741ac3129a4e2fb410b5404c0 @ core) Append operation, to directly append values to row list:

RowList2<String,Integer> list = new RowList2<String,Integer>();
list.append("cell1", 2);

(764c22d87a590ec1785985e389386720f535e66a @ scala) Append operation, to add a single value as row in row list:

val list = RowLists.rowList1(classOf[String])
list :+ "row"

(18a2add4e33e7b5765e2af6d637c339343f89c2e @ core) Append operation, to add a single value as row in row list:

RowList1<String> list = new RowList1<String>();

(a7d52d131853936f4283c336058ff75e409251fa @ scala) Supports Execution => RowList[_] as query handler:

Acolyte.withQueryHandler({ e: Execution => rowList })