You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by pa...@apache.org on 2017/07/17 14:00:06 UTC

[3/9] polygene-java git commit: Rename entitystore-sql to entitystore-sqlkv

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTest.java
deleted file mode 100644
index 83e8a21..0000000
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *
- */
-package org.apache.polygene.entitystore.sql;
-
-import org.apache.polygene.api.common.Visibility;
-import org.apache.polygene.bootstrap.AssemblyException;
-import org.apache.polygene.bootstrap.ModuleAssembly;
-import org.apache.polygene.entitystore.sql.assembly.SQLiteEntityStoreAssembler;
-import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
-import org.apache.polygene.library.sql.dbcp.DBCPDataSourceServiceAssembler;
-import org.apache.polygene.test.EntityTestAssembler;
-import org.apache.polygene.test.entity.AbstractEntityStoreTest;
-import org.junit.BeforeClass;
-
-import static org.apache.polygene.test.util.Assume.assumeNoIbmJdk;
-
-public class SQLiteEntityStoreTest extends AbstractEntityStoreTest
-{
-    @BeforeClass
-    public static void beforeClass_IBMJDK()
-    {
-        assumeNoIbmJdk();
-    }
-
-    @Override
-    // START SNIPPET: assembly
-    public void assemble( ModuleAssembly module )
-        throws AssemblyException
-    {
-        // END SNIPPET: assembly
-        super.assemble( module );
-        ModuleAssembly config = module.layer().module( "config" );
-        new EntityTestAssembler().defaultServicesVisibleIn( Visibility.layer ).assemble( config );
-
-        // START SNIPPET: assembly
-        // DataSourceService
-        new DBCPDataSourceServiceAssembler()
-            .identifiedBy( "sqlite-datasource-service" )
-            .visibleIn( Visibility.module )
-            .withConfig( config, Visibility.layer )
-            .assemble( module );
-
-        // DataSource
-        new DataSourceAssembler()
-            .withDataSourceServiceIdentity( "sqlite-datasource-service" )
-            .identifiedBy( "sqlite-datasource" )
-            .visibleIn( Visibility.module )
-            .withCircuitBreaker()
-            .assemble( module );
-
-        // SQL EntityStore
-        new SQLiteEntityStoreAssembler()
-            .visibleIn( Visibility.application )
-            .withConfig( config, Visibility.layer )
-            .assemble( module );
-    }
-    // END SNIPPET: assembly
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTestSuite.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTestSuite.java
deleted file mode 100644
index 6dc5fbe..0000000
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTestSuite.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *
- */
-package org.apache.polygene.entitystore.sql;
-
-import org.apache.polygene.api.common.Visibility;
-import org.apache.polygene.bootstrap.ModuleAssembly;
-import org.apache.polygene.entitystore.sql.assembly.SQLiteEntityStoreAssembler;
-import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
-import org.apache.polygene.library.sql.dbcp.DBCPDataSourceServiceAssembler;
-import org.apache.polygene.test.entity.model.EntityStoreTestSuite;
-import org.junit.BeforeClass;
-
-import static org.apache.polygene.test.util.Assume.assumeNoIbmJdk;
-
-public class SQLiteEntityStoreTestSuite extends EntityStoreTestSuite
-{
-    @BeforeClass
-    public static void beforeClass_IBMJDK()
-    {
-        assumeNoIbmJdk();
-    }
-
-    @Override
-    protected void defineStorageModule( ModuleAssembly module )
-    {
-        module.defaultServices();
-        // DataSourceService
-        new DBCPDataSourceServiceAssembler()
-            .identifiedBy( "sqlite-datasource-service" )
-            .visibleIn( Visibility.module )
-            .withConfig( configModule, Visibility.application )
-            .assemble( module );
-
-        // DataSource
-        new DataSourceAssembler()
-            .withDataSourceServiceIdentity( "sqlite-datasource-service" )
-            .identifiedBy( "sqlite-datasource" )
-            .visibleIn( Visibility.module )
-            .withCircuitBreaker()
-            .assemble( module );
-
-        // SQL EntityStore
-        new SQLiteEntityStoreAssembler()
-            .visibleIn( Visibility.application )
-            .withConfig( configModule, Visibility.application )
-            .assemble( module );
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sql/src/test/resources/derby-datasource.properties
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/resources/derby-datasource.properties b/extensions/entitystore-sql/src/test/resources/derby-datasource.properties
deleted file mode 100644
index 35261ab..0000000
--- a/extensions/entitystore-sql/src/test/resources/derby-datasource.properties
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-#  Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-#
-#
-
-enabled=true
-url=jdbc:derby:memory:testdb;create=true
-driver=org.apache.derby.jdbc.EmbeddedDriver
-username=
-password=

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sql/src/test/resources/h2-datasource.properties
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/resources/h2-datasource.properties b/extensions/entitystore-sql/src/test/resources/h2-datasource.properties
deleted file mode 100644
index 74abf51..0000000
--- a/extensions/entitystore-sql/src/test/resources/h2-datasource.properties
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-#  Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-#
-#
-
-enabled=true
-url=jdbc:h2:mem:test
-driver=org.h2.Driver
-username=
-password=

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sql/src/test/resources/logback.xml
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/resources/logback.xml b/extensions/entitystore-sql/src/test/resources/logback.xml
deleted file mode 100644
index 03fb4dd..0000000
--- a/extensions/entitystore-sql/src/test/resources/logback.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~  Licensed to the Apache Software Foundation (ASF) under one
-  ~  or more contributor license agreements.  See the NOTICE file
-  ~  distributed with this work for additional information
-  ~  regarding copyright ownership.  The ASF licenses this file
-  ~  to you under the Apache License, Version 2.0 (the
-  ~  "License"); you may not use this file except in compliance
-  ~  with the License.  You may obtain a copy of the License at
-  ~
-  ~       http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~  Unless required by applicable law or agreed to in writing, software
-  ~  distributed under the License is distributed on an "AS IS" BASIS,
-  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~  See the License for the specific language governing permissions and
-  ~  limitations under the License.
-  ~
-  ~
-  -->
-<configuration>
-
-    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
-        <layout class="ch.qos.logback.classic.PatternLayout">
-            <Pattern>[@%-10thread] %-5level %logger{42} - %msg%n</Pattern>
-        </layout>
-    </appender>
-
-    <root level="info">
-        <appender-ref ref="stdout" />
-    </root>
-
-    <logger name="org.apache.polygene.entitystore.sql" level="debug"/>
-
-</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sql/src/test/resources/mysql-datasource.properties
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/resources/mysql-datasource.properties b/extensions/entitystore-sql/src/test/resources/mysql-datasource.properties
deleted file mode 100644
index a2f4175..0000000
--- a/extensions/entitystore-sql/src/test/resources/mysql-datasource.properties
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-#  Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-#
-#
-
-enabled=true
-#url=jdbc:mysql://localhost:3306/jdbc_test_db?profileSQL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true
-driver=com.mysql.cj.jdbc.Driver
-username=root
-password=

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sql/src/test/resources/postgresql-datasource.properties
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/resources/postgresql-datasource.properties b/extensions/entitystore-sql/src/test/resources/postgresql-datasource.properties
deleted file mode 100644
index bdda284..0000000
--- a/extensions/entitystore-sql/src/test/resources/postgresql-datasource.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-#  Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-#
-#
-
-enabled=true
-driver=org.postgresql.Driver
-username=jdbc_test_login
-password=password

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sql/src/test/resources/sqlite-datasource.properties
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/resources/sqlite-datasource.properties b/extensions/entitystore-sql/src/test/resources/sqlite-datasource.properties
deleted file mode 100644
index 17e52b5..0000000
--- a/extensions/entitystore-sql/src/test/resources/sqlite-datasource.properties
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-#  Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-#
-#
-
-enabled=true
-url=jdbc:sqlite::memory:
-driver=org.sqlite.JDBC
-username=
-password=

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/build.gradle
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/build.gradle b/extensions/entitystore-sqlkv/build.gradle
new file mode 100644
index 0000000..b13b95a
--- /dev/null
+++ b/extensions/entitystore-sqlkv/build.gradle
@@ -0,0 +1,46 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+apply plugin: 'polygene-extension'
+
+description = "Apache Polygene™ SQL Key/Value EntityStore Extension"
+
+jar { manifest { name = "Apache Polygene™ Extension - EntityStore - SQL Key/Value" } }
+
+dependencies {
+  api polygene.core.bootstrap
+  api polygene.library( 'sql' )
+  api libraries.jooq
+
+  implementation polygene.library( 'sql-liquibase' )
+
+  runtimeOnly polygene.core.runtime
+
+  testImplementation polygene.internals.testsupport
+  testImplementation polygene.library( 'sql-dbcp' )
+  testImplementation libraries.docker_junit
+
+  testRuntimeOnly libraries.logback
+  testRuntimeOnly libraries.derby
+  testRuntimeOnly libraries.h2
+  testRuntimeOnly libraries.mysql_connector
+  testRuntimeOnly libraries.postgres
+  testRuntimeOnly libraries.sqlite
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/dev-status.xml
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/dev-status.xml b/extensions/entitystore-sqlkv/dev-status.xml
new file mode 100644
index 0000000..8d582e2
--- /dev/null
+++ b/extensions/entitystore-sqlkv/dev-status.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~  Licensed to the Apache Software Foundation (ASF) under one
+  ~  or more contributor license agreements.  See the NOTICE file
+  ~  distributed with this work for additional information
+  ~  regarding copyright ownership.  The ASF licenses this file
+  ~  to you under the Apache License, Version 2.0 (the
+  ~  "License"); you may not use this file except in compliance
+  ~  with the License.  You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing, software
+  ~  distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  ~
+  -->
+<module xmlns="http://polygene.apache.org/schemas/2008/dev-status/1"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://polygene.apache.org/schemas/2008/dev-status/1
+        http://polygene.apache.org/schemas/2008/dev-status/1/dev-status.xsd">
+  <status>
+        <!--none,early,beta,stable,mature-->
+        <codebase>stable</codebase>
+
+        <!-- none, brief, good, complete -->
+        <documentation>good</documentation>
+
+        <!-- none, some, good, complete -->
+        <unittests>good</unittests>
+    </status>
+    <licenses>
+        <license>ALv2</license>
+    </licenses>
+</module>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/docs/es-sqlkv.txt
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/docs/es-sqlkv.txt b/extensions/entitystore-sqlkv/src/docs/es-sqlkv.txt
new file mode 100644
index 0000000..f36e39d
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/docs/es-sqlkv.txt
@@ -0,0 +1,166 @@
+///////////////////////////////////////////////////////////////
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+///////////////////////////////////////////////////////////////
+
+[[extension-es-sqlkv, SQL Key/Value EntityStore]]
+= SQL Key/Value EntityStore =
+
+[devstatus]
+--------------
+source=extensions/entitystore-sqlkv/dev-status.xml
+--------------
+
+EntityStore service backed by a SQL database with a simple schema where entities are stored in a key/value fashion.
+
+This extension fully leverage the <<library-sql>> meaning that you must use it to assemble your DataSource and that you
+get <<library-circuitbreaker,Circuit Breaker>> and <<library-jmx, JMX>> integration for free.
+
+The database schema is managed using <<library-sql-liquibase>>.
+
+TIP: See the <<sample-sql-support>> that demonstrate combined use of <<library-sql>>, <<extension-es-sql>> and
+<<extension-indexing-sql>>.
+
+The following SQL databases are supported:
+
+- http://www.postgresql.org/[PostgreSQL]
+- http://www.mysql.com/[MySQL] and http://mariadb.org/[MariaDB]
+- http://www.sqlite.org/[SQLite]
+- http://www.h2database.com/[H2 Database Engine]
+- http://db.apache.org/derby/[Apache Derby] and http://www.oracle.com/technetwork/java/javadb/overview/index.htm[Oracle JavaDB]
+
+Each entity state is stored as a single row so maximum number of entities is the maximum number of rows per table
+supported by the underlying SQL database.
+
+include::../../build/docs/buildinfo/artifact.txt[]
+
+== Configuration ==
+
+Here are the available configuration properties:
+
+[snippet,java]
+----
+source=extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLMapEntityStoreConfiguration.java
+tag=config
+----
+
+The assembly snippets below show the DataSource assembly alongside the SQL EntityStore assembly. Remember to configure
+the DataSource properly, see <<library-sql>> and <<howto-configure-service>>.
+
+
+== PostgreSQL ==
+
+Maximum number of entities is unlimited.
+
+Assembly is done using the provided Assembler:
+
+[snippet,java]
+----
+source=extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
+tag=assembly
+----
+
+Sample DataSource configuration defaults:
+
+[source,java]
+----
+include::../test/resources/postgresql-datasource.properties[]
+----
+
+
+== MySQL and MariaDB ==
+
+Maximum number of entities depends on the choosen storage engine.
+
+Assembly is done using the provided Assembler:
+
+[snippet,java]
+----
+source=extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
+tag=assembly
+----
+
+Sample DataSource configuration defaults:
+
+[source,java]
+----
+include::../test/resources/mysql-datasource.properties[]
+----
+
+
+== SQLite ==
+
+Maximum number of entities is unlimited.
+
+The http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC[Xerial SQLite JDBC] driver is recommended.
+It provides native support on Linux, Windows and MaxOSX, pure Java on other OSes.
+
+Assembly is done using the provided Assembler:
+
+[snippet,java]
+----
+source=extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTest.java
+tag=assembly
+----
+
+Sample DataSource configuration defaults:
+
+[source,java]
+----
+include::../test/resources/sqlite-datasource.properties[]
+----
+
+
+== H2 Database Engine ==
+
+Maximum number of entities is 2^64.
+
+Assembly is done using the provided Assembler:
+
+[snippet,java]
+----
+source=extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
+tag=assembly
+----
+
+Sample DataSource configuration defaults:
+
+[source,java]
+----
+include::../test/resources/h2-datasource.properties[]
+----
+
+
+
+== Apache Derby and Oracle JavaDB ==
+
+Maximum number of entities is unlimited.
+
+Assembly is done using the provided Assembler:
+
+[snippet,java]
+----
+source=extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
+tag=assembly
+----
+
+Sample DataSource configuration defaults:
+
+[source,java]
+----
+include::../test/resources/derby-datasource.properties[]
+----

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreConfiguration.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreConfiguration.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreConfiguration.java
new file mode 100644
index 0000000..19658ea
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreConfiguration.java
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.entitystore.sql;
+
+import org.apache.polygene.api.common.UseDefaults;
+import org.apache.polygene.api.property.Property;
+import org.apache.polygene.library.sql.common.SQLConfiguration;
+
+// START SNIPPET: config
+public interface SQLEntityStoreConfiguration extends SQLConfiguration
+{
+    /**
+     * Name of the database schema to use.
+     * Ignored on SQL databases that don't support schemas.
+     */
+    @UseDefaults( "POLYGENE_ES" )
+    @Override
+    Property<String> schemaName();
+
+    /**
+     * Name of the entities table.
+     */
+    @UseDefaults( "POLYGENE_ENTITIES" )
+    Property<String> entityTableName();
+
+    /**
+     * Defines whether the database schema and table should be created if not already present.
+     */
+    @UseDefaults( "true" )
+    Property<Boolean> createIfMissing();
+}
+// END SNIPPET: config

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreMixin.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreMixin.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreMixin.java
new file mode 100644
index 0000000..293ce58
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreMixin.java
@@ -0,0 +1,244 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.entitystore.sql;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+import javax.sql.DataSource;
+import liquibase.Contexts;
+import liquibase.Liquibase;
+import liquibase.database.Database;
+import liquibase.database.ObjectQuotingStrategy;
+import liquibase.exception.LiquibaseException;
+import org.apache.polygene.api.configuration.Configuration;
+import org.apache.polygene.api.entity.EntityDescriptor;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.injection.scope.Service;
+import org.apache.polygene.api.injection.scope.This;
+import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.service.ServiceActivation;
+import org.apache.polygene.api.service.ServiceDescriptor;
+import org.apache.polygene.library.sql.liquibase.LiquibaseService;
+import org.apache.polygene.serialization.javaxjson.JavaxJsonFactories;
+import org.apache.polygene.spi.entitystore.EntityNotFoundException;
+import org.apache.polygene.spi.entitystore.helpers.JSONKeys;
+import org.apache.polygene.spi.entitystore.helpers.MapEntityStore;
+import org.jooq.DSLContext;
+import org.jooq.Field;
+import org.jooq.Query;
+import org.jooq.Record;
+import org.jooq.SQLDialect;
+import org.jooq.Schema;
+import org.jooq.Table;
+import org.jooq.conf.Settings;
+import org.jooq.impl.DSL;
+
+public class SQLEntityStoreMixin
+    implements ServiceActivation, MapEntityStore
+{
+    private static final String TABLE_NAME_LIQUIBASE_PARAMETER = "es-sql.table";
+    private static final String IDENTITY_COLUMN_NAME = "ENTITY_IDENTITY";
+    private static final String VERSION_COLUMN_NAME = "ENTITY_VERSION";
+    private static final String STATE_COLUMN_NAME = "ENTITY_STATE";
+
+    @Service
+    private DataSource dataSource;
+
+    @Service
+    private LiquibaseService liquibaseService;
+
+    @Service
+    private JavaxJsonFactories jsonFactories;
+
+    @Uses
+    private ServiceDescriptor descriptor;
+
+    @This
+    private Configuration<SQLEntityStoreConfiguration> configuration;
+
+    private Schema schema;
+    private Table<Record> table;
+    private Field<String> identityColumn;
+    private Field<String> versionColumn;
+    private Field<String> stateColumn;
+    private DSLContext dsl;
+
+    @Override
+    public void activateService() throws Exception
+    {
+        configuration.refresh();
+        SQLEntityStoreConfiguration config = configuration.get();
+
+        // Prepare jooq DSL
+        SQLDialect dialect = descriptor.metaInfo( SQLDialect.class );
+        Settings settings = descriptor.metaInfo( Settings.class );
+        String schemaName = config.schemaName().get();
+        String tableName = config.entityTableName().get();
+        schema = DSL.schema( DSL.name( schemaName ) );
+        table = DSL.table(
+            dialect.equals( SQLDialect.SQLITE )
+            ? DSL.name( tableName )
+            : DSL.name( schema.getName(), tableName )
+        );
+        identityColumn = DSL.field( DSL.name( IDENTITY_COLUMN_NAME ), String.class );
+        versionColumn = DSL.field( DSL.name( VERSION_COLUMN_NAME ), String.class );
+        stateColumn = DSL.field( DSL.name( STATE_COLUMN_NAME ), String.class );
+        dsl = DSL.using( dataSource, dialect, settings );
+
+        // Eventually create schema and apply Liquibase changelog
+        if( config.createIfMissing().get() )
+        {
+            if( !dialect.equals( SQLDialect.SQLITE )
+                && dsl.meta().getSchemas().stream().noneMatch( s -> schema.getName().equalsIgnoreCase( s.getName() ) ) )
+            {
+                dsl.createSchema( schema ).execute();
+            }
+
+            applyLiquibaseChangelog( dialect );
+        }
+    }
+
+    private void applyLiquibaseChangelog( SQLDialect dialect ) throws SQLException, LiquibaseException
+    {
+        Liquibase liquibase = liquibaseService.newConnectedLiquibase();
+        Database db = liquibase.getDatabase();
+        db.setObjectQuotingStrategy( ObjectQuotingStrategy.QUOTE_ALL_OBJECTS );
+        try
+        {
+            if( !dialect.equals( SQLDialect.SQLITE ) )
+            {
+                if( db.supportsSchemas() )
+                {
+                    db.setDefaultSchemaName( schema.getName() );
+                    db.setLiquibaseSchemaName( schema.getName() );
+                }
+                if( db.supportsCatalogs() )
+                {
+                    db.setDefaultCatalogName( schema.getName() );
+                    db.setLiquibaseCatalogName( schema.getName() );
+                }
+            }
+            liquibase.getChangeLogParameters().set( TABLE_NAME_LIQUIBASE_PARAMETER, table.getName() );
+            liquibase.update( new Contexts() );
+        }
+        finally
+        {
+            db.close();
+        }
+    }
+
+    @Override
+    public void passivateService() throws Exception
+    {
+        dsl = null;
+        schema = null;
+        table = null;
+        identityColumn = null;
+        versionColumn = null;
+        stateColumn = null;
+    }
+
+    @Override
+    public Reader get( EntityReference entityReference )
+    {
+        String state = dsl.select( stateColumn )
+                          .from( table )
+                          .where( identityColumn.equal( entityReference.identity().toString() ) )
+                          .fetchOptional( stateColumn )
+                          .orElseThrow( () -> new EntityNotFoundException( entityReference ) );
+        return new StringReader( state );
+    }
+
+    @Override
+    public Stream<Reader> entityStates()
+    {
+        return dsl.select( stateColumn )
+                  .from( table )
+                  .fetch( stateColumn )
+                  .stream()
+                  .map( StringReader::new );
+    }
+
+    @Override
+    public void applyChanges( MapChanges changes ) throws Exception
+    {
+        List<Query> operations = new ArrayList<>();
+        changes.visitMap( new MapChanger()
+        {
+            @Override
+            public Writer newEntity( EntityReference ref, EntityDescriptor entityDescriptor )
+            {
+                return new StringWriter( 1000 )
+                {
+                    @Override
+                    public void close() throws IOException
+                    {
+                        super.close();
+                        String state = toString();
+                        String version = jsonFactories.readerFactory().createReader( new StringReader( state ) )
+                                                      .readObject()
+                                                      .getString( JSONKeys.VERSION );
+                        operations.add(
+                            dsl.insertInto( table )
+                               .columns( identityColumn, versionColumn, stateColumn )
+                               .values( ref.identity().toString(), version, state )
+                        );
+                    }
+                };
+            }
+
+            @Override
+            public Writer updateEntity( MapChange mapChange )
+            {
+                return new StringWriter( 1000 )
+                {
+                    @Override
+                    public void close() throws IOException
+                    {
+                        super.close();
+                        String state = toString();
+                        operations.add(
+                            dsl.update( table )
+                               .set( versionColumn, mapChange.newVersion() )
+                               .set( stateColumn, state )
+                               .where( identityColumn.equal( mapChange.reference().identity().toString() ) )
+                               .and( versionColumn.equal( mapChange.previousVersion() ) )
+                        );
+                    }
+                };
+            }
+
+            @Override
+            public void removeEntity( EntityReference ref, EntityDescriptor entityDescriptor )
+            {
+                operations.add(
+                    dsl.deleteFrom( table )
+                       .where( identityColumn.equal( ref.identity().toString() ) )
+                );
+            }
+        } );
+        dsl.batch( operations ).execute();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreService.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreService.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreService.java
new file mode 100644
index 0000000..9e4e0e7
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreService.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.entitystore.sql;
+
+import org.apache.polygene.api.concern.Concerns;
+import org.apache.polygene.api.configuration.Configuration;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.service.ServiceActivation;
+import org.apache.polygene.spi.entitystore.ConcurrentModificationCheckConcern;
+import org.apache.polygene.spi.entitystore.EntityStateVersions;
+import org.apache.polygene.spi.entitystore.EntityStore;
+import org.apache.polygene.spi.entitystore.StateChangeNotificationConcern;
+import org.apache.polygene.spi.entitystore.helpers.JSONMapEntityStoreActivation;
+import org.apache.polygene.spi.entitystore.helpers.JSONMapEntityStoreMixin;
+
+/**
+ * SQL EntityStore service.
+ */
+@Concerns( { StateChangeNotificationConcern.class, ConcurrentModificationCheckConcern.class } )
+@Mixins( { JSONMapEntityStoreMixin.class, SQLEntityStoreMixin.class } )
+public interface SQLEntityStoreService
+    extends ServiceActivation,
+    JSONMapEntityStoreActivation,
+    EntityStore,
+    EntityStateVersions,
+    Configuration
+{
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
new file mode 100644
index 0000000..24e8ec5
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
@@ -0,0 +1,98 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.apache.polygene.api.identity.Identity;
+import org.apache.polygene.api.identity.StringIdentity;
+import org.apache.polygene.bootstrap.Assemblers;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.SQLEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sql.SQLEntityStoreService;
+import org.apache.polygene.library.sql.liquibase.LiquibaseAssembler;
+import org.apache.polygene.library.sql.liquibase.LiquibaseConfiguration;
+import org.jooq.SQLDialect;
+import org.jooq.conf.RenderNameStyle;
+import org.jooq.conf.Settings;
+
+/**
+ * Base SQL EntityStore assembly.
+ */
+public abstract class AbstractSQLEntityStoreAssembler<AssemblerType>
+    extends Assemblers.VisibilityIdentityConfig<AssemblerType>
+{
+    public static final Identity DEFAULT_ENTITYSTORE_IDENTITY = StringIdentity.identityOf( "entitystore-sqlkv" );
+    private static final String DEFAULT_CHANGELOG_PATH = "org/apache/polygene/entitystore/sql/changelog.xml";
+
+    private String changelogPath = DEFAULT_CHANGELOG_PATH;
+
+    @Override
+    public void assemble( ModuleAssembly module )
+    {
+        super.assemble( module );
+        SQLDialect dialect = getSQLDialect();
+        if( dialect == null )
+        {
+            throw new AssemblyException( "SQLDialect must not be null" );
+        }
+        Settings settings = getSettings();
+        if( settings == null )
+        {
+            throw new AssemblyException( "Settings must not be null" );
+        }
+
+        String identity = ( hasIdentity() ? identity() : DEFAULT_ENTITYSTORE_IDENTITY ).toString();
+
+        LiquibaseAssembler liquibase = new LiquibaseAssembler().identifiedBy( identity + "-liquibase" );
+        if( hasConfig() )
+        {
+            liquibase.withConfig( configModule(), configVisibility() );
+            LiquibaseConfiguration liquibaseconfig = configModule().forMixin( LiquibaseConfiguration.class )
+                                                                   .declareDefaults();
+            liquibaseconfig.changeLog().set( changelogPath );
+        }
+        liquibase.assemble( module );
+
+        module.services( SQLEntityStoreService.class )
+              .identifiedBy( identity )
+              .visibleIn( visibility() )
+              .setMetaInfo( dialect )
+              .setMetaInfo( settings );
+
+        if( hasConfig() )
+        {
+            configModule().entities( SQLEntityStoreConfiguration.class ).visibleIn( configVisibility() );
+        }
+    }
+
+    public AssemblerType withLiquibaseChangelog( String changelogPath )
+    {
+        this.changelogPath = changelogPath;
+        return (AssemblerType) this;
+    }
+
+    protected Settings getSettings()
+    {
+        return new Settings().withRenderNameStyle( RenderNameStyle.QUOTED );
+    }
+
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.DEFAULT;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/DerbySQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/DerbySQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/DerbySQLEntityStoreAssembler.java
new file mode 100644
index 0000000..4e88d01
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/DerbySQLEntityStoreAssembler.java
@@ -0,0 +1,35 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+/**
+ * Derby EntityStore assembly.
+ */
+public class DerbySQLEntityStoreAssembler
+    extends AbstractSQLEntityStoreAssembler<DerbySQLEntityStoreAssembler>
+{
+    @Override
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.DERBY;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/H2SQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/H2SQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/H2SQLEntityStoreAssembler.java
new file mode 100644
index 0000000..928e660
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/H2SQLEntityStoreAssembler.java
@@ -0,0 +1,35 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+/**
+ * H2 EntityStore assembly.
+ */
+public class H2SQLEntityStoreAssembler
+    extends AbstractSQLEntityStoreAssembler<H2SQLEntityStoreAssembler>
+{
+    @Override
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.H2;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/MySQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/MySQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/MySQLEntityStoreAssembler.java
new file mode 100644
index 0000000..dec7be5
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/MySQLEntityStoreAssembler.java
@@ -0,0 +1,35 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+/**
+ * MySQL EntityStore assembly.
+ */
+public class MySQLEntityStoreAssembler
+    extends AbstractSQLEntityStoreAssembler<MySQLEntityStoreAssembler>
+{
+    @Override
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.MYSQL;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/PostgreSQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/PostgreSQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/PostgreSQLEntityStoreAssembler.java
new file mode 100644
index 0000000..8e3e31f
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/PostgreSQLEntityStoreAssembler.java
@@ -0,0 +1,35 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+/**
+ * PostgreSQL EntityStore assembly.
+ */
+public class PostgreSQLEntityStoreAssembler
+    extends AbstractSQLEntityStoreAssembler<PostgreSQLEntityStoreAssembler>
+{
+    @Override
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.POSTGRES;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLEntityStoreAssembler.java
new file mode 100644
index 0000000..1477c6b
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLEntityStoreAssembler.java
@@ -0,0 +1,28 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql.assembly;
+
+/**
+ * This is a dummy Assembler to support the Yeoman Polygene Generator, which require naming conventions for
+ * the systems that it supports.
+ */
+public class SQLEntityStoreAssembler extends H2SQLEntityStoreAssembler
+{}
+

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLiteEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLiteEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLiteEntityStoreAssembler.java
new file mode 100644
index 0000000..2615316
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLiteEntityStoreAssembler.java
@@ -0,0 +1,35 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+/**
+ * SQLite EntityStore assembly.
+ */
+public class SQLiteEntityStoreAssembler
+    extends AbstractSQLEntityStoreAssembler<SQLiteEntityStoreAssembler>
+{
+    @Override
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.SQLITE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/package.html
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/package.html b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/package.html
new file mode 100644
index 0000000..a93cf6f
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/package.html
@@ -0,0 +1,24 @@
+<!--
+  ~  Licensed to the Apache Software Foundation (ASF) under one
+  ~  or more contributor license agreements.  See the NOTICE file
+  ~  distributed with this work for additional information
+  ~  regarding copyright ownership.  The ASF licenses this file
+  ~  to you under the Apache License, Version 2.0 (the
+  ~  "License"); you may not use this file except in compliance
+  ~  with the License.  You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing, software
+  ~  distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  ~
+  -->
+<html>
+    <body>
+        <h2>SQL EntityStore Assembly.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/package.html
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/package.html b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/package.html
new file mode 100644
index 0000000..a90af3e
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/package.html
@@ -0,0 +1,24 @@
+<!--
+  ~  Licensed to the Apache Software Foundation (ASF) under one
+  ~  or more contributor license agreements.  See the NOTICE file
+  ~  distributed with this work for additional information
+  ~  regarding copyright ownership.  The ASF licenses this file
+  ~  to you under the Apache License, Version 2.0 (the
+  ~  "License"); you may not use this file except in compliance
+  ~  with the License.  You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing, software
+  ~  distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  ~
+  -->
+<html>
+    <body>
+        <h2>SQL EntityStore.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/main/resources/org/apache/polygene/entitystore/sql/changelog.xml
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/resources/org/apache/polygene/entitystore/sql/changelog.xml b/extensions/entitystore-sqlkv/src/main/resources/org/apache/polygene/entitystore/sql/changelog.xml
new file mode 100644
index 0000000..47ef554
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/resources/org/apache/polygene/entitystore/sql/changelog.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Licensed to the Apache Software Foundation (ASF) under one
+  ~  or more contributor license agreements.  See the NOTICE file
+  ~  distributed with this work for additional information
+  ~  regarding copyright ownership.  The ASF licenses this file
+  ~  to you under the Apache License, Version 2.0 (the
+  ~  "License"); you may not use this file except in compliance
+  ~  with the License.  You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing, software
+  ~  distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  -->
+<databaseChangeLog
+        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd"
+        objectQuotingStrategy="QUOTE_ALL_OBJECTS">
+    <changeSet id="0" author="paul">
+        <createTable tableName="${es-sql.table}">
+            <column name="ENTITY_IDENTITY" type="varchar(64)">
+                <constraints primaryKey="true" nullable="false"/>
+            </column>
+            <column name="ENTITY_VERSION" type="varchar(64)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="ENTITY_STATE" type="varchar(10240)">
+                <constraints nullable="false"/>
+            </column>
+        </createTable>
+    </changeSet>
+</databaseChangeLog>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
new file mode 100644
index 0000000..4bd1578
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
@@ -0,0 +1,101 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql;
+
+import java.sql.Connection;
+import java.sql.Statement;
+import javax.sql.DataSource;
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.unitofwork.UnitOfWork;
+import org.apache.polygene.api.usecase.UsecaseBuilder;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.assembly.DerbySQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
+import org.apache.polygene.library.sql.dbcp.DBCPDataSourceServiceAssembler;
+import org.apache.polygene.test.EntityTestAssembler;
+import org.apache.polygene.test.entity.AbstractEntityStoreTest;
+
+import static org.apache.polygene.entitystore.sql.assembly.DerbySQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
+
+public class DerbySQLEntityStoreTest
+    extends AbstractEntityStoreTest
+{
+    @Override
+    // START SNIPPET: assembly
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        // END SNIPPET: assembly
+        super.assemble( module );
+        ModuleAssembly config = module.layer().module( "config" );
+        new EntityTestAssembler().defaultServicesVisibleIn( Visibility.layer ).assemble( config );
+
+        // START SNIPPET: assembly
+        // DataSourceService
+        new DBCPDataSourceServiceAssembler()
+            .identifiedBy( "derby-datasource-service" )
+            .visibleIn( Visibility.module )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+
+        // DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "derby-datasource-service" )
+            .identifiedBy( "derby-datasource" )
+            .visibleIn( Visibility.module )
+            .withCircuitBreaker()
+            .assemble( module );
+
+        // SQL EntityStore
+        new DerbySQLEntityStoreAssembler()
+            .visibleIn( Visibility.application )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+    }
+    // END SNIPPET: assembly
+
+    @Override
+    public void tearDown()
+        throws Exception
+    {
+        UnitOfWork uow = this.unitOfWorkFactory.newUnitOfWork( UsecaseBuilder.newUsecase(
+            "Delete " + getClass().getSimpleName() + " test data" ) );
+        try
+        {
+            SQLEntityStoreConfiguration config = uow.get( SQLEntityStoreConfiguration.class,
+                                                          DEFAULT_ENTITYSTORE_IDENTITY );
+            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
+            connection.setAutoCommit( false );
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DELETE FROM %s.%s",
+                                             config.schemaName().get(),
+                                             config.entityTableName().get() ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..7fbfb2a
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java
@@ -0,0 +1,94 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql;
+
+import java.sql.Connection;
+import java.sql.Statement;
+import javax.sql.DataSource;
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.structure.Module;
+import org.apache.polygene.api.unitofwork.UnitOfWork;
+import org.apache.polygene.api.unitofwork.UnitOfWorkFactory;
+import org.apache.polygene.api.usecase.UsecaseBuilder;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.assembly.DerbySQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
+import org.apache.polygene.library.sql.dbcp.DBCPDataSourceServiceAssembler;
+import org.apache.polygene.test.entity.model.EntityStoreTestSuite;
+
+import static org.apache.polygene.entitystore.sql.assembly.DerbySQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
+
+public class DerbySQLEntityStoreTestSuite extends EntityStoreTestSuite
+{
+    @Override
+    protected void defineStorageModule( ModuleAssembly module )
+    {
+        module.defaultServices();
+        // DataSourceService
+        new DBCPDataSourceServiceAssembler()
+            .identifiedBy( "derby-datasource-service" )
+            .visibleIn( Visibility.module )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+
+        // DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "derby-datasource-service" )
+            .identifiedBy( "derby-datasource" )
+            .visibleIn( Visibility.module )
+            .withCircuitBreaker()
+            .assemble( module );
+
+        // SQL EntityStore
+        new DerbySQLEntityStoreAssembler()
+            .visibleIn( Visibility.application )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+    }
+
+    @Override
+    public void tearDown()
+        throws Exception
+    {
+        Module storageModule = application.findModule( "Infrastructure Layer","Storage Module" );
+        UnitOfWorkFactory uowf = storageModule.unitOfWorkFactory();
+        UnitOfWork uow = uowf.newUnitOfWork( UsecaseBuilder.newUsecase(
+            "Delete " + getClass().getSimpleName() + " test data" ) );
+        try
+        {
+            SQLEntityStoreConfiguration config = uow.get( SQLEntityStoreConfiguration.class,
+                                                          DEFAULT_ENTITYSTORE_IDENTITY );
+            Connection connection = storageModule.serviceFinder().findService( DataSource.class ).get().getConnection();
+            connection.setAutoCommit( false );
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DELETE FROM %s.%s",
+                                             config.schemaName().get(),
+                                             config.entityTableName().get() ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
new file mode 100644
index 0000000..4b4b759
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
@@ -0,0 +1,67 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql;
+
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.assembly.H2SQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
+import org.apache.polygene.library.sql.dbcp.DBCPDataSourceServiceAssembler;
+import org.apache.polygene.test.EntityTestAssembler;
+import org.apache.polygene.test.entity.AbstractEntityStoreTest;
+
+public class H2SQLEntityStoreTest
+    extends AbstractEntityStoreTest
+{
+    @Override
+    // START SNIPPET: assembly
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        // END SNIPPET: assembly
+        super.assemble( module );
+        ModuleAssembly config = module.layer().module( "config" );
+        new EntityTestAssembler().defaultServicesVisibleIn( Visibility.layer ).assemble( config );
+
+        // START SNIPPET: assembly
+        // DataSourceService
+        new DBCPDataSourceServiceAssembler()
+            .identifiedBy( "h2-datasource-service" )
+            .visibleIn( Visibility.module )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+
+        // DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "h2-datasource-service" )
+            .identifiedBy( "h2-datasource" )
+            .visibleIn( Visibility.module )
+            .withCircuitBreaker()
+            .assemble( module );
+
+        // SQL EntityStore
+        new H2SQLEntityStoreAssembler()
+            .visibleIn( Visibility.application )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+    }
+    // END SNIPPET: assembly
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..f763238
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql;
+
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.assembly.H2SQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
+import org.apache.polygene.library.sql.dbcp.DBCPDataSourceServiceAssembler;
+import org.apache.polygene.test.entity.model.EntityStoreTestSuite;
+
+public class H2SQLEntityStoreTestSuite extends EntityStoreTestSuite
+{
+    @Override
+    protected void defineStorageModule( ModuleAssembly module )
+    {
+        module.defaultServices();
+        // DataSourceService
+        new DBCPDataSourceServiceAssembler()
+            .identifiedBy( "h2-datasource-service" )
+            .visibleIn( Visibility.module )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+
+        // DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "h2-datasource-service" )
+            .identifiedBy( "h2-datasource" )
+            .visibleIn( Visibility.module )
+            .withCircuitBreaker()
+            .assemble( module );
+
+        // SQL EntityStore
+        new H2SQLEntityStoreAssembler()
+            .visibleIn( Visibility.application )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
new file mode 100644
index 0000000..a940e95
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
@@ -0,0 +1,127 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql;
+
+import java.sql.Connection;
+import java.sql.Statement;
+import java.util.HashMap;
+import javax.sql.DataSource;
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.unitofwork.UnitOfWork;
+import org.apache.polygene.api.usecase.UsecaseBuilder;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.assembly.MySQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
+import org.apache.polygene.library.sql.datasource.DataSourceConfiguration;
+import org.apache.polygene.library.sql.dbcp.DBCPDataSourceServiceAssembler;
+import org.apache.polygene.test.EntityTestAssembler;
+import org.apache.polygene.test.docker.DockerRule;
+import org.apache.polygene.test.entity.AbstractEntityStoreTest;
+import org.junit.ClassRule;
+
+import static org.apache.polygene.entitystore.sql.assembly.MySQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
+
+public class MySQLEntityStoreTest
+    extends AbstractEntityStoreTest
+{
+    @ClassRule
+    public static final DockerRule DOCKER = new DockerRule(
+        "mysql",
+        new HashMap<String, String>()
+        {{
+            put( "MYSQL_ROOT_PASSWORD", "" );
+            put( "MYSQL_ALLOW_EMPTY_PASSWORD", "yes" );
+            put( "MYSQL_DATABASE", "jdbc_test_db" );
+            put( "MYSQL_ROOT_HOST", "172.17.0.1" );
+        }},
+        30000L
+//        , "mysqld: ready for connections"   TODO: add this after next release of tdomzal/junit-docker-rule
+    );
+
+    @Override
+    // START SNIPPET: assembly
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        // END SNIPPET: assembly
+        super.assemble( module );
+        ModuleAssembly config = module.layer().module( "config" );
+        new EntityTestAssembler().defaultServicesVisibleIn( Visibility.layer ).assemble( config );
+
+        // START SNIPPET: assembly
+        // DataSourceService
+        new DBCPDataSourceServiceAssembler()
+            .identifiedBy( "mysql-datasource-service" )
+            .visibleIn( Visibility.module )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+
+        // DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "mysql-datasource-service" )
+            .identifiedBy( "mysql-datasource" )
+            .visibleIn( Visibility.module )
+            .withCircuitBreaker()
+            .assemble( module );
+
+        // SQL EntityStore
+        new MySQLEntityStoreAssembler()
+            .visibleIn( Visibility.application )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+        // END SNIPPET: assembly
+        String mysqlHost = DOCKER.getDockerHost();
+        int mysqlPort = DOCKER.getExposedContainerPort( "3306/tcp" );
+        config.forMixin( DataSourceConfiguration.class ).declareDefaults()
+              .url().set( "jdbc:mysql://" + mysqlHost + ":" + mysqlPort
+                          + "/jdbc_test_db?profileSQL=false&useLegacyDatetimeCode=false&serverTimezone=UTC"
+                          + "&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true" );
+        // START SNIPPET: assembly
+    }
+    // END SNIPPET: assembly
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        UnitOfWork uow = this.unitOfWorkFactory.newUnitOfWork(
+            UsecaseBuilder.newUsecase( "Delete " + getClass().getSimpleName() + " test data" )
+        );
+        try
+        {
+            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
+            SQLEntityStoreConfiguration configuration = uow.get( SQLEntityStoreConfiguration.class,
+                                                                 DEFAULT_ENTITYSTORE_IDENTITY );
+            connection.setAutoCommit( false );
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "TRUNCATE %s.%s",
+                                             configuration.schemaName().get(),
+                                             configuration.entityTableName().get() ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3168fdb4/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..e2b0564
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
@@ -0,0 +1,122 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.entitystore.sql;
+
+import java.sql.Connection;
+import java.sql.Statement;
+import java.util.HashMap;
+import javax.sql.DataSource;
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.service.ServiceFinder;
+import org.apache.polygene.api.structure.Module;
+import org.apache.polygene.api.unitofwork.UnitOfWork;
+import org.apache.polygene.api.unitofwork.UnitOfWorkFactory;
+import org.apache.polygene.api.usecase.UsecaseBuilder;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.assembly.MySQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
+import org.apache.polygene.library.sql.datasource.DataSourceConfiguration;
+import org.apache.polygene.library.sql.dbcp.DBCPDataSourceServiceAssembler;
+import org.apache.polygene.test.docker.DockerRule;
+import org.apache.polygene.test.entity.model.EntityStoreTestSuite;
+import org.junit.ClassRule;
+
+import static org.apache.polygene.entitystore.sql.assembly.MySQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
+
+public class MySQLEntityStoreTestSuite extends EntityStoreTestSuite
+{
+    @ClassRule
+    public static final DockerRule DOCKER = new DockerRule(
+        "mysql",
+        new HashMap<String, String>()
+        {{
+            put( "MYSQL_ROOT_PASSWORD", "" );
+            put( "MYSQL_ALLOW_EMPTY_PASSWORD", "yes" );
+            put( "MYSQL_DATABASE", "jdbc_test_db" );
+            put( "MYSQL_ROOT_HOST", "172.17.0.1" );
+        }},
+        30000L
+//        , "mysqld: ready for connections"   TODO: add this after next release of tdomzal/junit-docker-rule
+    );
+
+    @Override
+    protected void defineStorageModule( ModuleAssembly module )
+    {
+        module.defaultServices();
+        // DataSourceService
+        new DBCPDataSourceServiceAssembler()
+            .identifiedBy( "mysql-datasource-service" )
+            .visibleIn( Visibility.module )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+
+        // DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "mysql-datasource-service" )
+            .identifiedBy( "mysql-datasource" )
+            .visibleIn( Visibility.module )
+            .withCircuitBreaker()
+            .assemble( module );
+
+        // SQL EntityStore
+        new MySQLEntityStoreAssembler()
+            .visibleIn( Visibility.application )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+
+        String mysqlHost = DOCKER.getDockerHost();
+        int mysqlPort = DOCKER.getExposedContainerPort( "3306/tcp" );
+        configModule.forMixin( DataSourceConfiguration.class ).declareDefaults()
+                    .url().set( "jdbc:mysql://" + mysqlHost + ":" + mysqlPort
+                                + "/jdbc_test_db?profileSQL=false&useLegacyDatetimeCode=false&serverTimezone=UTC"
+                                + "&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true" );
+    }
+
+    @Override
+    public void tearDown()
+        throws Exception
+    {
+        Module storageModule = application.findModule( "Infrastructure Layer", "Storage Module" );
+        UnitOfWorkFactory uowf = storageModule.unitOfWorkFactory();
+        ServiceFinder serviceFinder = storageModule.serviceFinder();
+        UnitOfWork uow = uowf.newUnitOfWork(
+            UsecaseBuilder.newUsecase( "Delete " + getClass().getSimpleName() + " test data" )
+                                                             );
+        try
+        {
+            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
+            SQLEntityStoreConfiguration configuration = uow.get( SQLEntityStoreConfiguration.class,
+                                                                 DEFAULT_ENTITYSTORE_IDENTITY );
+            connection.setAutoCommit( false );
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "TRUNCATE %s.%s",
+                                             configuration.schemaName().get(),
+                                             configuration.entityTableName().get() ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}