You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2017/09/18 15:20:57 UTC

[01/15] polygene-java git commit: Clarification of tests in the distribution.

Repository: polygene-java
Updated Branches:
  refs/heads/es-sql [created] 3cca3c605


Clarification of tests in the distribution.


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/815c77b3
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/815c77b3
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/815c77b3

Branch: refs/heads/es-sql
Commit: 815c77b3210b613fe8fdc8b163c3fe2dc8a97bee
Parents: 42b3d33
Author: niclas <ni...@hedhman.org>
Authored: Sat Jul 22 10:14:57 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Sat Jul 22 10:14:57 2017 +0800

----------------------------------------------------------------------
 distributions/src/src-dist/README.txt | 6 ++++++
 1 file changed, 6 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/815c77b3/distributions/src/src-dist/README.txt
----------------------------------------------------------------------
diff --git a/distributions/src/src-dist/README.txt b/distributions/src/src-dist/README.txt
index 2aa83ed..b76b536 100644
--- a/distributions/src/src-dist/README.txt
+++ b/distributions/src/src-dist/README.txt
@@ -62,6 +62,12 @@ Here is how to run a full build with checks:
 Running gradlew for the first time will download the required Gradle
 distribution. You can run ./gradlew tasks to list available tasks.
 
+Also, if Docker engine is present on your system, a large amount of time
+will be spent in testing the many Entity Store implementations, as it
+will spin up the many external systems for the tests (on at a time). If
+Docker is not running, and those external systems are not available locally,
+then those tests will be skipped automatically.
+
 Read the Polygene™ Build System tutorial for more details:
 https://polygene.apache.org/java/latest/build-system.html
 


[04/15] polygene-java git commit: Working on new Envisage over http.

Posted by ni...@apache.org.
Working on new Envisage over http.


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/2bef7120
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/2bef7120
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/2bef7120

Branch: refs/heads/es-sql
Commit: 2bef7120f17475e547234f35f6aae2a7f9e6a24b
Parents: 96f0713
Author: niclas <ni...@hedhman.org>
Authored: Mon Sep 4 13:06:16 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Mon Sep 4 13:06:16 2017 +0800

----------------------------------------------------------------------
 .../runtime/activation/ActivationDelegate.java  |   4 +-
 .../serialization/JsonRepresentation.java       |   5 +
 .../HttpServerModule/bootstrap.tmpl             |   7 +-
 .../RestAPIApplication/Launcher.java.tmpl       |  24 +++-
 .../RestAPIApplication/bootstrap-test.tmpl      |  22 +---
 tools/model-detail/build.gradle                 |   1 +
 .../polygene/tools/model/EnvisageServlet.java   | 113 +++++++++++++++++++
 .../descriptor/ApplicationDetailDescriptor.java |  52 ++++++++-
 .../model/descriptor/LayerDetailDescriptor.java |  23 ++++
 .../model-detail/src/main/resources/index.html  |  11 ++
 10 files changed, 233 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/2bef7120/core/runtime/src/main/java/org/apache/polygene/runtime/activation/ActivationDelegate.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/activation/ActivationDelegate.java b/core/runtime/src/main/java/org/apache/polygene/runtime/activation/ActivationDelegate.java
index af3a812..662b1c2 100644
--- a/core/runtime/src/main/java/org/apache/polygene/runtime/activation/ActivationDelegate.java
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/activation/ActivationDelegate.java
@@ -157,7 +157,7 @@ public final class ActivationDelegate
             {
                 throw ( (ActivationException) e );
             }
-            throw new ActivationException( "Unable to Activate application.", e );
+            throw new ActivationException( "Unable to Activate application: " + target, e );
         }
     }
 
@@ -308,7 +308,7 @@ public final class ActivationDelegate
         public Object get()
         {
             throw new IllegalStateException( "Service is passive, either activating and"
-                                             + " cannot be used yet or passivating and cannot be used anymore." );
+                                             + " cannot be used yet or passivating and cannot be used anymore: " + reference );
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/2bef7120/libraries/restlet/src/main/java/org/apache/polygene/library/restlet/serialization/JsonRepresentation.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/polygene/library/restlet/serialization/JsonRepresentation.java b/libraries/restlet/src/main/java/org/apache/polygene/library/restlet/serialization/JsonRepresentation.java
index fafabe4..01947cf 100644
--- a/libraries/restlet/src/main/java/org/apache/polygene/library/restlet/serialization/JsonRepresentation.java
+++ b/libraries/restlet/src/main/java/org/apache/polygene/library/restlet/serialization/JsonRepresentation.java
@@ -32,6 +32,7 @@ import org.apache.polygene.api.serialization.Serializer;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.spi.PolygeneSPI;
 import org.restlet.data.MediaType;
+import org.restlet.engine.application.StatusInfo;
 import org.restlet.representation.OutputRepresentation;
 import org.restlet.representation.Representation;
 
@@ -121,6 +122,10 @@ public class JsonRepresentation<T> extends OutputRepresentation
         {
             representation.write( outputStream );
         }
+        else if( object instanceof StatusInfo )
+        {
+            outputStream.write(((StatusInfo) object).getReasonPhrase().getBytes());
+        }
         else if( object != null )
         {
             stateSerialization.serialize( Serializer.Options.NO_TYPE_INFO, outputStream, object );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/2bef7120/tools/generator-polygene/app/templates/ConnectivityLayer/HttpServerModule/bootstrap.tmpl
----------------------------------------------------------------------
diff --git a/tools/generator-polygene/app/templates/ConnectivityLayer/HttpServerModule/bootstrap.tmpl b/tools/generator-polygene/app/templates/ConnectivityLayer/HttpServerModule/bootstrap.tmpl
index addab42..2018bfa 100644
--- a/tools/generator-polygene/app/templates/ConnectivityLayer/HttpServerModule/bootstrap.tmpl
+++ b/tools/generator-polygene/app/templates/ConnectivityLayer/HttpServerModule/bootstrap.tmpl
@@ -37,7 +37,9 @@ import org.apache.polygene.bootstrap.LayerAssembly;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.bootstrap.layered.ModuleAssembler;
 import org.apache.polygene.library.restlet.PolygeneServerServlet;
-
+<% if( hasFeature( 'envisage' ) ) {
+%>import org.apache.polygene.tools.model.EnvisageServlet;
+<% } %>
 import <%= polygene.packageName %>.rest.<%= polygene.name %>RestApplication;
 
 import static org.apache.polygene.library.http.Servlets.addServlets;
@@ -97,6 +99,9 @@ public class HttpServerModule
         defaults.port().set( DEFAULT_PORT );
         HashMap<String, String> initParams = new HashMap<>();
         initParams.put("org.restlet.application", <%= polygene.name %>RestApplication.class.getName() );
+<% if( hasFeature( 'envisage' ) ) {
+%>        addServlets( serve( "/envisage/*" ).with( EnvisageServlet.class ) ).to( module );
+<% } %>
         addServlets( serve( "/*" ).with(PolygeneServerServlet.class ).withInitParams( initParams ) ).to( module );
         return module;
     }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/2bef7120/tools/generator-polygene/app/templates/RestAPIApplication/Launcher.java.tmpl
----------------------------------------------------------------------
diff --git a/tools/generator-polygene/app/templates/RestAPIApplication/Launcher.java.tmpl b/tools/generator-polygene/app/templates/RestAPIApplication/Launcher.java.tmpl
index ad03b15..ad1909f 100644
--- a/tools/generator-polygene/app/templates/RestAPIApplication/Launcher.java.tmpl
+++ b/tools/generator-polygene/app/templates/RestAPIApplication/Launcher.java.tmpl
@@ -23,29 +23,45 @@ import <%= polygene.packageName %>.bootstrap.<%= polygene.name %>ApplicationAsse
 import <%= polygene.packageName %>.bootstrap.connectivity.ConnectivityLayer;
 import <%= polygene.packageName %>.bootstrap.connectivity.RestApiModule;
 
+import java.util.function.Consumer;
+
 import org.apache.polygene.api.structure.Application;
+import org.apache.polygene.bootstrap.ApplicationAssembly;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.layered.LayeredApplicationAssembler;
 import org.apache.polygene.library.restlet.PolygeneRestApplicationLauncher;
+<% if( hasFeature( 'envisage' ) ) {
+%>import org.apache.polygene.tools.model.descriptor.ApplicationDetailDescriptor;
+<% } %>
 
 public class <%= polygene.name %>Launcher extends PolygeneRestApplicationLauncher
 {
     private static final String name = "<%= polygene.name %>";
     private static final String version = "0.1";
-    private Application.Mode mode = getApplicationMode();
+    private Application.Mode mode;
+    private Consumer<ApplicationAssembly> customize;
+<% if( hasFeature( 'envisage' ) ) {
+%>    private ApplicationDetailDescriptor detailedModel;
+<% } %>
 
     public static void main( String[] args )
         throws Exception
     {
-        <%= polygene.name %>Launcher app = new <%= polygene.name %>Launcher();
+        <%= polygene.name %>Launcher app = new <%= polygene.name %>Launcher(getApplicationMode(), none -> {} );
         app.installShutdownHook();
         app.initialize();
     }
 
+    public <%= polygene.name %>Launcher(Application.Mode mode, Consumer<ApplicationAssembly> customize)
+    {
+        this.mode = mode;
+        this.customize = customize;
+    }
+
     protected LayeredApplicationAssembler createApplicationAssembler()
         throws AssemblyException
     {
-        return new <%= polygene.name %>ApplicationAssembler( name, version, mode, none -> {} );
+        return new <%= polygene.name %>ApplicationAssembler( name, version, mode, customize );
     }
 
     @Override
@@ -64,7 +80,7 @@ public class <%= polygene.name %>Launcher extends PolygeneRestApplicationLaunche
         return RestApiModule.NAME;
     }
 
-    private Application.Mode getApplicationMode()
+    private static Application.Mode getApplicationMode()
     {
         String mode = System.getenv( "APP_MODE" );
         if( mode == null )

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/2bef7120/tools/generator-polygene/app/templates/RestAPIApplication/bootstrap-test.tmpl
----------------------------------------------------------------------
diff --git a/tools/generator-polygene/app/templates/RestAPIApplication/bootstrap-test.tmpl b/tools/generator-polygene/app/templates/RestAPIApplication/bootstrap-test.tmpl
index a0cad7a..1e50b00 100644
--- a/tools/generator-polygene/app/templates/RestAPIApplication/bootstrap-test.tmpl
+++ b/tools/generator-polygene/app/templates/RestAPIApplication/bootstrap-test.tmpl
@@ -85,27 +85,7 @@ public class BootstrapTest
     public void applicationBootstrapSucceeds()
         throws Exception
     {
-        <%= polygene.name %>Launcher launcher = new <%= polygene.name %>Launcher()
-        {
-            @Override
-            protected LayeredApplicationAssembler createApplicationAssembler()
-                throws AssemblyException
-            {
-                return new <%= polygene.name %>ApplicationAssembler( "LaunchTest", "0", Application.Mode.development, BootstrapTest.this::setupTest )
-                {
-                    @Override
-                    protected void onModelCreated( ApplicationDescriptor model )
-                    {
-                        ApplicationDetailDescriptor modelDescription = ApplicationDetailDescriptorBuilder.createApplicationDetailDescriptor( model );
-                        System.out.println( "Application Model" );
-                        JsonWriter writer = Json.createWriter( System.out );
-                        System.out.println();
-                        writer.writeObject( modelDescription.toJson() );
-                        super.onModelCreated( model );
-                    }
-                };
-            }
-        };
+        <%= polygene.name %>Launcher launcher = new <%= polygene.name %>Launcher(Application.Mode.development, this::setupTest);
         launcher.initialize();
         System.out.println("Application Launched...");
         // Thread.sleep( 3600000L );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/2bef7120/tools/model-detail/build.gradle
----------------------------------------------------------------------
diff --git a/tools/model-detail/build.gradle b/tools/model-detail/build.gradle
index c6cd684..20dbc15 100644
--- a/tools/model-detail/build.gradle
+++ b/tools/model-detail/build.gradle
@@ -26,6 +26,7 @@ jar { manifest { name = "Apache Polygene™ Model Detail" }}
 
 dependencies {
   api polygene.core.bootstrap
+  implementation libraries.servlet_api
 
   runtimeOnly polygene.core.runtime
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/2bef7120/tools/model-detail/src/main/java/org/apache/polygene/tools/model/EnvisageServlet.java
----------------------------------------------------------------------
diff --git a/tools/model-detail/src/main/java/org/apache/polygene/tools/model/EnvisageServlet.java b/tools/model-detail/src/main/java/org/apache/polygene/tools/model/EnvisageServlet.java
new file mode 100644
index 0000000..a72d2b2
--- /dev/null
+++ b/tools/model-detail/src/main/java/org/apache/polygene/tools/model/EnvisageServlet.java
@@ -0,0 +1,113 @@
+package org.apache.polygene.tools.model;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonWriter;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.polygene.api.activation.Activation;
+import org.apache.polygene.api.activation.ActivationException;
+import org.apache.polygene.api.activation.PassivationException;
+import org.apache.polygene.api.injection.scope.Structure;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.structure.ApplicationDescriptor;
+
+import static org.apache.polygene.tools.model.descriptor.ApplicationDetailDescriptorBuilder.createApplicationDetailDescriptor;
+
+@Mixins( EnvisageServlet.Mixin.class )
+public interface EnvisageServlet extends Servlet
+{
+    class Mixin extends HttpServlet
+        implements EnvisageServlet
+    {
+        private JsonObject model;
+
+        public Mixin( @Structure ApplicationDescriptor descriptor )
+        {
+            model = createApplicationDetailDescriptor( descriptor ).toJson();
+        }
+
+        @Override
+        protected void doGet( HttpServletRequest req, HttpServletResponse resp )
+            throws ServletException, IOException
+        {
+            String pathInfo = req.getPathInfo();
+            log( "Fetch " + pathInfo );
+            if( isStatic( pathInfo ) )
+            {
+                serviceStatic( pathInfo, resp );
+            }
+            if( isJson( pathInfo ) )
+            {
+                serviceJson( resp );
+            }
+        }
+
+        private boolean isStatic( String pathInfo )
+        {
+            return (pathInfo.equals( "/index.html" )
+                   || pathInfo.startsWith( "/js/" )
+                   || pathInfo.startsWith( "/css/" )
+                   || pathInfo.startsWith( "/images/" ) )
+                   && !pathInfo.contains( ".." )
+                ;
+        }
+
+        private boolean isJson( String pathInfo )
+        {
+            return pathInfo.equals( "/model/" );
+        }
+
+        private void serviceStatic( String pathInfo, HttpServletResponse resp )
+            throws IOException
+        {
+            ServletOutputStream out = resp.getOutputStream();
+            try( InputStream resource = getClass().getClassLoader().getResourceAsStream( pathInfo ) )
+            {
+                if( resource == null )
+                {
+                    resp.setStatus( HttpServletResponse.SC_NOT_FOUND );
+                }
+                else
+                {
+                    copy( resource, out );
+                }
+            }
+        }
+
+        private void serviceJson( HttpServletResponse resp )
+            throws IOException
+        {
+            if( model == null )
+            {
+                resp.setStatus( HttpServletResponse.SC_NO_CONTENT );
+            }
+            else
+            {
+                PrintWriter out = resp.getWriter();
+                JsonWriter writer = Json.createWriter( out );
+                writer.writeObject( model );
+                writer.close();
+                out.flush();
+            }
+        }
+
+        private void copy( InputStream resource, ServletOutputStream out )
+            throws IOException
+        {
+            int b;
+            while( ( b = resource.read() ) >= 0 )
+            {
+                out.write( b );
+            }
+            out.flush();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/2bef7120/tools/model-detail/src/main/java/org/apache/polygene/tools/model/descriptor/ApplicationDetailDescriptor.java
----------------------------------------------------------------------
diff --git a/tools/model-detail/src/main/java/org/apache/polygene/tools/model/descriptor/ApplicationDetailDescriptor.java b/tools/model-detail/src/main/java/org/apache/polygene/tools/model/descriptor/ApplicationDetailDescriptor.java
index e23247f..d6c18fd 100644
--- a/tools/model-detail/src/main/java/org/apache/polygene/tools/model/descriptor/ApplicationDetailDescriptor.java
+++ b/tools/model-detail/src/main/java/org/apache/polygene/tools/model/descriptor/ApplicationDetailDescriptor.java
@@ -19,9 +19,12 @@
  */
 package org.apache.polygene.tools.model.descriptor;
 
+import java.util.Comparator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Objects;
+import java.util.SortedSet;
+import java.util.TreeSet;
 import javax.json.Json;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonObject;
@@ -41,13 +44,14 @@ public final class ApplicationDetailDescriptor
 {
     private final ApplicationDescriptor descriptor;
     private final List<ActivatorDetailDescriptor> activators = new LinkedList<>();
-    private final List<LayerDetailDescriptor> layers = new LinkedList<>();
+    private final SortedSet<LayerDetailDescriptor> layers;
 
     ApplicationDetailDescriptor( ApplicationDescriptor descriptor )
         throws IllegalArgumentException
     {
         Objects.requireNonNull( descriptor, "ApplicationDescriptor" );
         this.descriptor = descriptor;
+        layers = new TreeSet<>( new UsedLayerComparator() );
     }
 
     /**
@@ -81,6 +85,7 @@ public final class ApplicationDetailDescriptor
 
     final void addLayer( LayerDetailDescriptor descriptor )
     {
+        System.out.println("NICLAS!!!! Layer:" + descriptor.toString());
         Objects.requireNonNull( descriptor, "LayerDetailDescriptor" );
         descriptor.setApplication( this );
         layers.add( descriptor );
@@ -136,4 +141,49 @@ public final class ApplicationDetailDescriptor
 
         return appBuilder.build();
     }
+
+    private static class UsedLayerComparator
+        implements Comparator<LayerDetailDescriptor>
+    {
+
+        @Override
+        public int compare( LayerDetailDescriptor d1, LayerDetailDescriptor d2 )
+        {
+            if( d1.equals( d2 ))
+            {
+                return 0;
+            }
+            if( uses( d1, d2 ) )
+            {
+                return -1;
+            }
+            if( uses(d2, d1) )
+            {
+                return 1;
+            }
+            return 0;
+        }
+
+        // 0 = same layer
+        // 1 = user uses used
+        // 2 = not determination
+        private boolean uses( LayerDetailDescriptor user, LayerDetailDescriptor used )
+        {
+            System.out.println("Compare " + user.usedLayers() + " : " + used.usedLayers());
+            System.out.println("Compare " + user.usedBy() + " : " + used.usedBy());
+            System.out.println("---");
+            if( user.equals( used ))
+            {
+                return true;
+            }
+            for( LayerDetailDescriptor usedLayer : user.usedLayers() )
+            {
+                if( uses( usedLayer, used ) )
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/2bef7120/tools/model-detail/src/main/java/org/apache/polygene/tools/model/descriptor/LayerDetailDescriptor.java
----------------------------------------------------------------------
diff --git a/tools/model-detail/src/main/java/org/apache/polygene/tools/model/descriptor/LayerDetailDescriptor.java b/tools/model-detail/src/main/java/org/apache/polygene/tools/model/descriptor/LayerDetailDescriptor.java
index d96f12d..ac4d4b5 100644
--- a/tools/model-detail/src/main/java/org/apache/polygene/tools/model/descriptor/LayerDetailDescriptor.java
+++ b/tools/model-detail/src/main/java/org/apache/polygene/tools/model/descriptor/LayerDetailDescriptor.java
@@ -160,6 +160,29 @@ public final class LayerDetailDescriptor
     }
 
     @Override
+    public boolean equals( Object o )
+    {
+        if( this == o )
+        {
+            return true;
+        }
+        if( o == null || getClass() != o.getClass() )
+        {
+            return false;
+        }
+
+        LayerDetailDescriptor that = (LayerDetailDescriptor) o;
+
+        return descriptor.equals( that.descriptor );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return descriptor.hashCode();
+    }
+
+    @Override
     public final String toString()
     {
         return descriptor.name();

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/2bef7120/tools/model-detail/src/main/resources/index.html
----------------------------------------------------------------------
diff --git a/tools/model-detail/src/main/resources/index.html b/tools/model-detail/src/main/resources/index.html
new file mode 100644
index 0000000..486feab
--- /dev/null
+++ b/tools/model-detail/src/main/resources/index.html
@@ -0,0 +1,11 @@
+<html>
+<body>
+<h1>Envisage</h1>
+<div class="header"></div>
+<div class="menu"></div>
+<div class="type-tree"></div>
+<div class="app-structure"></div>
+<div class="details"></div>
+<div class="footer"></div>
+</body>
+</html>
\ No newline at end of file


[07/15] polygene-java git commit: entitystore-sql is brought in from the es-jooq branch, and fixed it up so that it compiles and passes the standard unit tests using H2. More testing needed for other SQL systems, since there seems to not be consensus on

Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/SqlType.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/SqlType.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/SqlType.java
deleted file mode 100644
index 6b6dfdd..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/SqlType.java
+++ /dev/null
@@ -1,141 +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.jooq;
-
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.OffsetDateTime;
-import java.time.Period;
-import java.time.ZonedDateTime;
-import org.jooq.DataType;
-import org.jooq.impl.SQLDataType;
-import org.jooq.types.Interval;
-
-class SqlType
-{
-    @SuppressWarnings( "unchecked" )
-    static <T> DataType<T> getSqlDataTypeFor( Class<?> propertyType )
-    {
-        if( String.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.VARCHAR;
-        }
-        if( Integer.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.INTEGER;
-        }
-        if( Long.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.BIGINT;
-        }
-        if( Boolean.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.BOOLEAN;
-        }
-        if( Float.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.FLOAT;
-        }
-        if( Double.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.DOUBLE;
-        }
-        if( Instant.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.TIMESTAMPWITHTIMEZONE;
-        }
-        if( Interval.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.VARCHAR;
-        }
-        if( Period.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.VARCHAR;
-        }
-        if( LocalDate.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.LOCALDATE;
-        }
-        if( LocalTime.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.LOCALTIME;
-        }
-        if( LocalDateTime.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.LOCALDATETIME;
-        }
-        if( ZonedDateTime.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.OFFSETDATETIME;
-        }
-        if( OffsetDateTime.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.OFFSETDATETIME;
-        }
-        if( Character.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.CHAR( 1 );
-        }
-        if( Short.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.INTEGER;
-        }
-        if( Byte.class.isAssignableFrom( propertyType ) )
-        {
-            return (DataType<T>) SQLDataType.INTEGER;
-        }
-        if( propertyType.isPrimitive() )
-        {
-            if( propertyType.equals( Integer.TYPE ) )
-            {
-                return (DataType<T>) SQLDataType.INTEGER;
-            }
-            if( propertyType.equals( Long.TYPE ) )
-            {
-                return (DataType<T>) SQLDataType.BIGINT;
-            }
-            if( propertyType.equals( Boolean.TYPE ) )
-            {
-                return (DataType<T>) SQLDataType.BOOLEAN;
-            }
-            if( propertyType.equals( Float.TYPE ) )
-            {
-                return (DataType<T>) SQLDataType.FLOAT;
-            }
-            if( propertyType.equals( Double.TYPE ) )
-            {
-                return (DataType<T>) SQLDataType.DOUBLE;
-            }
-            if( propertyType.equals( Character.TYPE ) )
-            {
-                return (DataType<T>) SQLDataType.CHAR( 1 );
-            }
-            if( propertyType.equals( Short.TYPE ) )
-            {
-                return (DataType<T>) SQLDataType.INTEGER;
-            }
-            if( propertyType.equals( Byte.TYPE ) )
-            {
-                return (DataType<T>) SQLDataType.INTEGER;
-            }
-        }
-        return (DataType<T>) SQLDataType.VARCHAR;
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/TableFields.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/TableFields.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/TableFields.java
deleted file mode 100644
index db42413..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/TableFields.java
+++ /dev/null
@@ -1,69 +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.jooq;
-
-import java.sql.Timestamp;
-import org.jooq.Field;
-
-import static org.apache.polygene.entitystore.jooq.TypesTable.makeField;
-
-public interface TableFields
-{
-    // Common in all tables
-    String IDENTITY_COLUMN_NAME = "_identity";
-    String CREATED_COLUMN_NAME = "_created_at";
-    String LASTMODIFIED_COLUMN_NAME = "_modified_at";
-
-    // Types Table
-    String TABLENAME_COLUMN_NAME = "_table_name";
-
-    // Entities Table
-    String VALUEID_COLUMN_NAME = "_value_id";
-    String TYPE_COLUMN_NAME = "_type";
-    String VERSION_COLUMN_NAME = "_version";
-    String APPLICATIONVERSION_COLUMN_NAME = "_app_version";
-
-    // Mixin Tables
-    String NAME_COLUMN_NAME = "_name";
-    String INDEX_COLUMN_NAME = "_index";    // either index in ManyAssociation or name in NamedAssociation
-    String REFERENCE_COLUMN_NAME = "_reference";
-    String ASSOCS_TABLE_POSTFIX = "_ASSOCS";
-
-
-    // Common Fields
-    Field<String> identityColumn = makeField( IDENTITY_COLUMN_NAME, String.class );
-    Field<Timestamp> createdColumn = makeField( CREATED_COLUMN_NAME, Timestamp.class );
-    Field<Timestamp> modifiedColumn = makeField( LASTMODIFIED_COLUMN_NAME, Timestamp.class );
-
-    // Types Table
-    Field<String> tableNameColumn = makeField( TABLENAME_COLUMN_NAME, String.class );
-
-    // Entities Table
-    Field<String> valueIdentityColumn = makeField( VALUEID_COLUMN_NAME, String.class );
-    Field<String> typeNameColumn = makeField( TYPE_COLUMN_NAME, String.class );
-    Field<String> versionColumn = makeField( VERSION_COLUMN_NAME, String.class );
-    Field<String> applicationVersionColumn = makeField( APPLICATIONVERSION_COLUMN_NAME, String.class );
-
-    // Mixin Tables
-
-    // The _ASSOCS table
-    Field<String> nameColumn = makeField( NAME_COLUMN_NAME, String.class );
-    Field<String> referenceColumn = makeField( REFERENCE_COLUMN_NAME, String.class );
-    Field<String> indexColumn = makeField( INDEX_COLUMN_NAME, String.class );
-
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/TypesTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/TypesTable.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/TypesTable.java
deleted file mode 100644
index c816c95..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/TypesTable.java
+++ /dev/null
@@ -1,189 +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.jooq;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.sql.Timestamp;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import org.apache.polygene.api.association.AssociationDescriptor;
-import org.apache.polygene.api.common.QualifiedName;
-import org.apache.polygene.api.entity.EntityDescriptor;
-import org.apache.polygene.api.property.Property;
-import org.apache.polygene.api.property.PropertyDescriptor;
-import org.apache.polygene.api.util.Classes;
-import org.jooq.CreateTableColumnStep;
-import org.jooq.DataType;
-import org.jooq.Field;
-import org.jooq.Record;
-import org.jooq.Result;
-import org.jooq.SQLDialect;
-import org.jooq.Schema;
-import org.jooq.Table;
-import org.jooq.impl.DSL;
-
-public class TypesTable
-    implements TableFields
-{
-    private final Map<Class<?>, Table<Record>> mixinTablesCache = new ConcurrentHashMap<>();
-    private final Map<Class<?>, Table<Record>> mixinAssocsTablesCache = new ConcurrentHashMap<>();
-
-    private final Table<Record> typesTable;
-    private final SQLDialect dialect;
-    private final Schema schema;
-
-    private final JooqDslContext dsl;
-
-    TypesTable( JooqDslContext dsl, Schema schema,
-                SQLDialect dialect,
-                String typesTablesName
-              )
-    {
-        this.schema = schema;
-        this.dialect = dialect;
-        typesTable = tableOf( typesTablesName );
-        this.dsl = dsl;
-    }
-
-    static <T> Field<T> makeField( String columnName, Class<T> type )
-    {
-        return DSL.field( DSL.name( columnName ), type );
-    }
-
-    Table<Record> tableOf( String tableName )
-    {
-        return DSL.table(
-            dialect.equals( SQLDialect.SQLITE )
-            ? DSL.name( tableName )
-            : DSL.name( schema.getName(), tableName ) );
-    }
-
-    String tableNameOf( Class<?> mixinType )
-    {
-        Result<Record> typeInfo = fetchTypeInfoFromTable( mixinType );
-        if( typeInfo.isEmpty() )
-        {
-            return null;
-        }
-        return typeInfo.getValue( 0, tableNameColumn );
-    }
-
-    Table<Record> tableFor( Class<?> type, EntityDescriptor descriptor )
-    {
-        return mixinTablesCache.computeIfAbsent( type, t ->
-        {
-            String tableName = tableNameOf( t );
-            if( tableName == null )
-            {
-                Result<Record> newMixinTable = createNewMixinTable( type, descriptor );
-                return tableOf( newMixinTable.getValue( 0, tableNameColumn ) );
-            }
-            return tableOf( tableName );
-        } );
-    }
-
-    private Result<Record> fetchTypeInfoFromTable( Class<?> mixinTableName )
-    {
-        return dsl.select()
-                  .from( typesTable )
-                  .where( identityColumn.eq( mixinTableName.getName() ) )
-                  .fetch();
-    }
-
-    private Result<Record> createNewMixinTable( Class<?> mixinType, EntityDescriptor descriptor )
-    {
-        String mixinTypeName = mixinType.getName();
-        String tableName = createNewTableName( mixinType );
-        CreateTableColumnStep primaryTable = dsl.createTable( DSL.name( schema.getName(), tableName ) )
-                                                .column( identityColumn )
-                                                .column( createdColumn );
-        descriptor.state().properties().forEach(
-            property ->
-            {
-                QualifiedName qualifiedName = property.qualifiedName();
-                if( qualifiedName.type().replace( '-', '$' ).equals( mixinTypeName ) )
-                {
-                    primaryTable.column( fieldOf( property ) );
-                }
-            } );
-        descriptor.state().associations().forEach(
-            assoc ->
-            {
-                QualifiedName qualifiedName = assoc.qualifiedName();
-                if( qualifiedName.type().replace( '-', '$' ).equals( mixinTypeName ) )
-                {
-                    primaryTable.column( fieldOf( assoc ) );
-                }
-            } );
-        int result1 = primaryTable.execute();
-        int result3 = dsl.insertInto( typesTable )
-                         .set( identityColumn, mixinTypeName )
-                         .set( tableNameColumn, tableName )
-                         .set( createdColumn, new Timestamp( System.currentTimeMillis() ) )
-                         .set( modifiedColumn, new Timestamp( System.currentTimeMillis() ) )
-                         .execute();
-        return fetchTypeInfoFromTable( mixinType );
-    }
-
-    private String createNewTableName( Class<?> mixinType )
-    {
-        String typeName = mixinType.getSimpleName();
-        String postFix = "";
-        int counter = 0;
-        boolean found = false;
-        do
-        {
-            found = checkForTableNamed( typeName + postFix );
-            postFix = "_" + counter++;
-        } while( found );
-        return typeName;
-    }
-
-    private boolean checkForTableNamed( String tableName )
-    {
-        return dsl.select()
-                  .from( typesTable )
-                  .where( tableNameColumn.eq( tableName ) )
-                  .fetch().size() > 0;
-    }
-
-    private boolean isProperty( Method method )
-    {
-        return Property.class.isAssignableFrom( method.getReturnType() ) && method.getParameterCount() == 0;
-    }
-
-    Field<Object> fieldOf( PropertyDescriptor descriptor )
-    {
-        String propertyName = descriptor.qualifiedName().name();
-        return DSL.field( DSL.name( propertyName ), dataTypeOf( descriptor ) );
-    }
-
-    Field<String> fieldOf( AssociationDescriptor descriptor )
-    {
-        String propertyName = descriptor.qualifiedName().name();
-        return DSL.field( DSL.name( propertyName ), DSL.getDataType( String.class ) );
-    }
-
-    private <T> DataType<T> dataTypeOf( PropertyDescriptor property )
-    {
-        Type type = property.type();
-        Class<?> rawType = Classes.RAW_CLASS.apply( type );
-        return SqlType.getSqlDataTypeFor( rawType );
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/assembly/JooqEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/assembly/JooqEntityStoreAssembler.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/assembly/JooqEntityStoreAssembler.java
deleted file mode 100644
index c251efe..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/assembly/JooqEntityStoreAssembler.java
+++ /dev/null
@@ -1,77 +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.jooq.assembly;
-
-import org.apache.polygene.api.identity.Identity;
-import org.apache.polygene.api.identity.StringIdentity;
-import org.apache.polygene.bootstrap.Assembler;
-import org.apache.polygene.bootstrap.Assemblers;
-import org.apache.polygene.bootstrap.AssemblyException;
-import org.apache.polygene.bootstrap.ModuleAssembly;
-import org.apache.polygene.entitystore.jooq.JooqDslContext;
-import org.apache.polygene.entitystore.jooq.JooqEntityStoreConfiguration;
-import org.apache.polygene.entitystore.jooq.JooqEntityStoreService;
-import org.jooq.SQLDialect;
-import org.jooq.conf.RenderNameStyle;
-import org.jooq.conf.Settings;
-
-/**
- * JOOQ EntityStore assembly.
- */
-@SuppressWarnings( "WeakerAccess" )
-public class JooqEntityStoreAssembler extends Assemblers.VisibilityIdentityConfig<JooqEntityStoreAssembler>
-    implements Assembler
-{
-    public static final Identity DEFAULT_ENTITYSTORE_IDENTITY = new StringIdentity( "entitystore-jooq" );
-
-    @Override
-    public void assemble( ModuleAssembly module )
-    {
-        Settings settings = getSettings();
-        if( settings == null )
-        {
-            throw new AssemblyException( "Settings must not be null" );
-        }
-
-        String identity = ( hasIdentity() ? identity() : DEFAULT_ENTITYSTORE_IDENTITY ).toString();
-        module.transients( JooqDslContext.class );
-
-        module.services( JooqEntityStoreService.class )
-              .identifiedBy( identity )
-              .visibleIn( visibility() )
-              .instantiateOnStartup()
-              .setMetaInfo( settings );
-
-        if( hasConfig() )
-        {
-            configModule().entities( JooqEntityStoreConfiguration.class ).visibleIn( configVisibility() );
-        }
-    }
-
-    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/6055b8f7/extensions/entitystore-jooq/src/test/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/test/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreTest.java b/extensions/entitystore-jooq/src/test/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreTest.java
deleted file mode 100644
index f36db0e..0000000
--- a/extensions/entitystore-jooq/src/test/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreTest.java
+++ /dev/null
@@ -1,88 +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.jooq;
-
-import org.apache.polygene.api.common.Visibility;
-import org.apache.polygene.bootstrap.AssemblyException;
-import org.apache.polygene.bootstrap.ModuleAssembly;
-import org.apache.polygene.entitystore.jooq.assembly.JooqEntityStoreAssembler;
-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.entity.AbstractEntityStoreTest;
-import org.jooq.SQLDialect;
-import org.junit.Rule;
-import org.junit.rules.TemporaryFolder;
-
-public class JooqEntityStoreTest extends AbstractEntityStoreTest
-{
-    @Rule
-    public final TemporaryFolder tmpDir = new TemporaryFolder();
-
-    @Override
-    // START SNIPPET: assembly
-    public void assemble( ModuleAssembly module )
-        throws AssemblyException
-    {
-        // END SNIPPET: assembly
-        super.assemble( module );
-        module.defaultServices();
-        ModuleAssembly config = module.layer().module( "config" );
-        new EntityTestAssembler().visibleIn( Visibility.module ).assemble( config );
-
-        // START SNIPPET: assembly
-        // Assemble a DataSource
-        new DataSourceAssembler()
-            .withDataSourceServiceIdentity( "datasource" )
-            .identifiedBy( "ds-mysql" )
-            .visibleIn( Visibility.module )
-            .assemble( module );
-
-        // Assemble the Apache DBCP based Service Importer
-        new DBCPDataSourceServiceAssembler()
-            .identifiedBy( "datasource" )
-            .visibleIn( Visibility.module )
-            .withConfig( config, Visibility.layer )
-            .assemble( module );
-
-        new JooqEntityStoreAssembler()
-            .withConfig( config, Visibility.layer )
-            .identifiedBy( "jooq-entitystore" )
-            .assemble( module );
-        // END SNIPPET: assembly
-
-        JooqEntityStoreConfiguration jooqDefaults = config.forMixin( JooqEntityStoreConfiguration.class )
-                                                          .setMetaInfo( SQLDialect.H2 )
-                                                          .declareDefaults();
-        jooqDefaults.entitiesTableName().set( "ENTITIES" );
-
-        DataSourceConfiguration dsDefaults = config.forMixin( DataSourceConfiguration.class ).declareDefaults();
-        dsDefaults.driver().set( org.h2.Driver.class.getName() );
-        dsDefaults.enabled().set( true );
-        dsDefaults.maxPoolSize().set( 3 );
-        dsDefaults.minPoolSize().set( 1 );
-        dsDefaults.username().set( "" );
-        dsDefaults.password().set( "" );
-        dsDefaults.url().set( "jdbc:h2:" + tmpDir.getRoot().getAbsolutePath() + "/testdb;create=true" );
-        // START SNIPPET: assembly
-    }
-    // END SNIPPET: assembly
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/build.gradle
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/build.gradle b/extensions/entitystore-sql/build.gradle
new file mode 100644
index 0000000..32ceb70
--- /dev/null
+++ b/extensions/entitystore-sql/build.gradle
@@ -0,0 +1,44 @@
+/*
+ *  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™ ORM EntityStore Extension"
+
+jar { manifest { name = "Apache Polygene™ Extension - EntityStore - ORM" } }
+
+dependencies {
+  api polygene.core.bootstrap
+  api polygene.library( 'sql' )
+  api libraries.jooq
+
+  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/6055b8f7/extensions/entitystore-sql/dev-status.xml
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/dev-status.xml b/extensions/entitystore-sql/dev-status.xml
new file mode 100644
index 0000000..b6d4c31
--- /dev/null
+++ b/extensions/entitystore-sql/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>early</codebase>
+
+        <!-- none, brief, good, complete -->
+        <documentation>brief</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/6055b8f7/extensions/entitystore-sql/src/docs/es-sql.txt
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/docs/es-sql.txt b/extensions/entitystore-sql/src/docs/es-sql.txt
new file mode 100644
index 0000000..a36d463
--- /dev/null
+++ b/extensions/entitystore-sql/src/docs/es-sql.txt
@@ -0,0 +1,58 @@
+///////////////////////////////////////////////////////////////
+ * 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-jooq,SQL EntityStore]]
+= ORM EntityStore =
+
+[devstatus]
+--------------
+source=extensions/entitystore-jooq/dev-status.xml
+--------------
+
+This entitystore is backed by a SQL server, and maps each mixin type of the Composite into separate tables. This is more
+enterprise-friendly, but comes at the cost of less performance compared to the <<extension-es-sql>>.
+
+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.
+
+include::../../build/docs/buildinfo/artifact.txt[]
+
+== Assembly ==
+
+Assembly is done using the provided Assembler:
+
+[snippet,java]
+----
+source=extensions/entitystore-jooq/src/test/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreTest.java
+tag=assembly
+----
+
+== Configuration ==
+
+Here are the available configuration properties:
+
+[snippet,java]
+----
+source=extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreConfiguration.java
+tag=config
+----
+
+All authentication related properties are optional.
+By default no authentication is used.
+As soon as you provide a `username`, authentication is set up.

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/AssociationValue.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/AssociationValue.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/AssociationValue.java
new file mode 100644
index 0000000..9fb6771
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/AssociationValue.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;
+
+import org.apache.polygene.api.common.QualifiedName;
+
+@SuppressWarnings( "WeakerAccess" )
+public class AssociationValue
+{
+    QualifiedName name;
+    String position;
+    String reference;
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/BaseEntity.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/BaseEntity.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/BaseEntity.java
new file mode 100644
index 0000000..982366d
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/BaseEntity.java
@@ -0,0 +1,34 @@
+/*
+ *  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.time.Instant;
+import org.apache.polygene.api.entity.EntityDescriptor;
+import org.apache.polygene.api.identity.Identity;
+
+@SuppressWarnings( "WeakerAccess" )
+public class BaseEntity
+{
+    EntityDescriptor type;
+    Identity identity;
+    String version;
+    String applicationVersion;
+    Instant modifedAt;
+    Instant createdAt;
+    Identity currentValueIdentity;
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
new file mode 100644
index 0000000..d25e7fc
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
@@ -0,0 +1,363 @@
+/*
+ *  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.lang.reflect.Method;
+import java.sql.Timestamp;
+import java.time.Instant;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.polygene.api.association.AssociationDescriptor;
+import org.apache.polygene.api.common.QualifiedName;
+import org.apache.polygene.api.composite.Composite;
+import org.apache.polygene.api.entity.EntityComposite;
+import org.apache.polygene.api.entity.EntityDescriptor;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.identity.HasIdentity;
+import org.apache.polygene.api.identity.StringIdentity;
+import org.apache.polygene.api.property.PropertyDescriptor;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.EntityCompositeType;
+import org.apache.polygene.api.unitofwork.NoSuchEntityTypeException;
+import org.apache.polygene.api.util.Classes;
+import org.apache.polygene.spi.entitystore.EntityNotFoundException;
+import org.apache.polygene.spi.entitystore.EntityStoreUnitOfWork;
+import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
+import org.jooq.Condition;
+import org.jooq.Field;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.jooq.Schema;
+import org.jooq.SelectJoinStep;
+import org.jooq.SelectQuery;
+import org.jooq.Table;
+import org.jooq.impl.DSL;
+
+@SuppressWarnings( "WeakerAccess" )
+public class EntitiesTable
+    implements TableFields
+{
+    private static final Predicate<? super Class<?>> NOT_COMPOSITE = type -> !( type.equals( Composite.class ) || type.equals( EntityComposite.class ) );
+    private static final Predicate<? super Class<?>> NOT_HASIDENTITY = type -> !( type.equals( HasIdentity.class ) );
+    private Map<EntityCompositeType, Set<Class<?>>> mixinTypeCache = new ConcurrentHashMap<>();
+    private Map<Class<?>, MixinTable> mixinTablesCache = new ConcurrentHashMap<>();
+
+    private final Table<Record> entitiesTable;
+    private JooqDslContext dsl;
+    private final TypesTable types;
+    private final Schema schema;
+    private String applicationVersion;
+    private boolean replacementStrategy = false;  // Figure out later if we should support both and if so, how.
+
+    EntitiesTable( JooqDslContext dsl, Schema schema, TypesTable types, String applicationVersion, String entitiesTableName )
+    {
+        this.dsl = dsl;
+        this.types = types;
+        this.schema = schema;
+        this.applicationVersion = applicationVersion;
+        entitiesTable = types.tableOf( entitiesTableName );
+    }
+
+    public BaseEntity fetchEntity( EntityReference reference, ModuleDescriptor module )
+    {
+
+        Result<Record> baseEntityResult = dsl
+            .selectFrom( entitiesTable )
+            .where( identityColumn.eq( reference.identity().toString() ) )
+            .fetch();
+
+        if( baseEntityResult.isEmpty() )
+        {
+            throw new EntityNotFoundException( reference );
+        }
+        Record row = baseEntityResult.get( 0 );
+        return toBaseEntity( row, module );
+    }
+
+    protected BaseEntity toBaseEntity( Record row, ModuleDescriptor module )
+    {
+        BaseEntity result = new BaseEntity();
+        String typeName = row.field( typeNameColumn ).get( row );
+        result.type = findEntityDescriptor( typeName, module );
+        result.version = row.field( versionColumn ).get( row );
+        result.applicationVersion = row.field( applicationVersionColumn ).get( row );
+        result.identity = StringIdentity.identityOf( row.field( identityColumn ).get( row ) );
+        result.currentValueIdentity = EntityReference.parseEntityReference( row.field( valueIdentityColumn ).get( row ) ).identity();
+        result.modifedAt = Instant.ofEpochMilli( row.field( modifiedColumn ).get( row ).getTime() );
+        result.createdAt = Instant.ofEpochMilli( row.field( createdColumn ).get( row ).getTime() );
+        return result;
+    }
+
+    public Stream<BaseEntity> fetchAll( EntityDescriptor type, ModuleDescriptor module )
+    {
+        Result<Record> baseEntityResult = dsl
+            .selectFrom( entitiesTable )
+            .fetch();
+        return baseEntityResult.stream().map( record -> toBaseEntity( record, module ) );
+    }
+
+    private EntityDescriptor findEntityDescriptor( String typeName, ModuleDescriptor module )
+    {
+        try
+        {
+            Class<?> type = getClass().getClassLoader().loadClass( typeName );
+            return module.typeLookup().lookupEntityModel( type );
+        }
+        catch( ClassNotFoundException e )
+        {
+            throw new NoSuchEntityTypeException( typeName, module);
+        }
+    }
+
+    void insertEntity( DefaultEntityState state, BaseEntity baseEntity )
+    {
+        EntityCompositeType compositeType = state.entityDescriptor().valueType();
+        Set<Class<?>> mixinTypes = mixinTypeCache.computeIfAbsent( compositeType, createMixinTypesSet( compositeType ) );
+        mixinTypes.forEach( type ->
+                            {
+                                MixinTable table = findMixinTable( type, state.entityDescriptor() );
+                                table.insertMixinState( state, baseEntity.currentValueIdentity.toString() );
+                            } );
+    }
+
+    void modifyEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork uow )
+    {
+        updateBaseEntity( baseEntity, uow );
+        if( replacementStrategy )
+        {
+            insertEntity( state, baseEntity );      // replacement strategy (more safe)
+        }
+        else
+        {
+            EntityCompositeType compositeType = state.entityDescriptor().valueType();
+            Set<Class<?>> mixinTypes = mixinTypeCache.computeIfAbsent( compositeType, createMixinTypesSet( compositeType ) );
+            mixinTypes.forEach( type ->
+                                {
+                                    MixinTable table = findMixinTable( type, state.entityDescriptor() );
+                                    table.modifyMixinState( state, baseEntity.currentValueIdentity.toString() );
+                                } );
+        }
+    }
+
+    private MixinTable findMixinTable( Class<?> type, EntityDescriptor entityDescriptor )
+    {
+        return mixinTablesCache.computeIfAbsent( type, t -> new MixinTable( dsl, schema, types, type, entityDescriptor ) );
+    }
+
+    private Set<Class<?>> mixinsOf( Stream<? extends AssociationDescriptor> stream )
+    {
+        return stream
+            .map( AssociationDescriptor::accessor )
+            .filter( Classes.instanceOf( Method.class ) )
+            .map( accessor -> (Method) accessor )
+            .map( Method::getDeclaringClass )
+            .filter( NOT_HASIDENTITY )
+            .filter( NOT_COMPOSITE )
+            .collect( Collectors.toSet() );
+    }
+
+    private Function<EntityCompositeType, Set<Class<?>>> createMixinTypesSet( EntityCompositeType compositeType )
+    {
+        return type ->
+        {
+            Set<Class<?>> mixins = compositeType
+                .properties()
+                .map( PropertyDescriptor::accessor )
+                .filter( Classes.instanceOf( Method.class ) )
+                .map( accessor -> (Method) accessor )
+                .map( Method::getDeclaringClass )
+                .filter( NOT_HASIDENTITY )
+                .filter( NOT_COMPOSITE )
+                .collect( Collectors.toSet() );
+            Set<Class<?>> mixinsWithAssociations = mixinsOf( compositeType.associations() );
+            Set<Class<?>> mixinsWithManyAssociations = mixinsOf( compositeType.manyAssociations() );
+            Set<Class<?>> mixinsWithNamedAssociations = mixinsOf( compositeType.namedAssociations() );
+            mixins.addAll( mixinsWithAssociations );
+            mixins.addAll( mixinsWithManyAssociations );
+            mixins.addAll( mixinsWithNamedAssociations );
+            return mixins;
+        };
+    }
+
+    void createNewBaseEntity( EntityReference reference, EntityDescriptor descriptor, EntityStoreUnitOfWork uow )
+    {
+        String valueIdentity = UUID.randomUUID().toString();
+        dsl.insertInto( entitiesTable )
+           .set( identityColumn, reference.identity().toString() )
+           .set( createdColumn, new Timestamp( uow.currentTime().toEpochMilli() ) )
+           .set( modifiedColumn, new Timestamp( uow.currentTime().toEpochMilli() ) )
+           .set( valueIdentityColumn, valueIdentity )
+           .set( typeNameColumn, descriptor.primaryType().getName() )
+           .set( versionColumn, "1" )
+           .set( applicationVersionColumn, applicationVersion )
+           .execute();
+    }
+
+    private void updateBaseEntity( BaseEntity entity, EntityStoreUnitOfWork uow )
+    {
+        entity.version = increment( entity.version );
+        if( replacementStrategy )
+        {
+            entity.currentValueIdentity = StringIdentity.identityOf( UUID.randomUUID().toString() );
+        }
+        dsl.update( entitiesTable )
+           .set( modifiedColumn, new Timestamp( uow.currentTime().toEpochMilli() ) )
+           .set( valueIdentityColumn, entity.currentValueIdentity.toString() )
+           .set( versionColumn, entity.version )
+           .set( applicationVersionColumn, applicationVersion )
+           .execute();
+    }
+
+    private String increment( String version )
+    {
+        long ver = Long.parseLong( version );
+        return Long.toString( ver + 1 );
+    }
+
+    /**
+     * Builds the SELECT statement for a given entity.
+     * <p>
+     * Example; If we have the following entity
+     * </p>
+     * <code><pre>
+     *     public interface LegalEntity
+     *     {
+     *         Property&lt;String&gt; registration();
+     *     }
+     * <p>
+     *     public interface Person extends LegalEntity
+     *     {
+     *         Property&lt;String&gt; name();
+     * <p>
+     *         &#64;Optional
+     *         Association&lt;Person&gt; spouse();
+     * <p>
+     *         ManyAssocation&lt;Person&gt; children();
+     *     }
+     * </pre></code>
+     * <p>
+     * and we do a simple;
+     * <code><pre>
+     *     Person p = uow.get( Person.class, "niclas" );
+     * </pre></code>
+     * <p>
+     * then the generated query will be
+     * </p>
+     * <code><pre>
+     *     SELECT * FROM ENTITIES
+     *     JOIN Person ON identity = ENTITIES.value_id
+     *     JOIN LegalEntity ON identity = ENTITIES.value_id
+     *     JOIN Person_Assoc ON identity = ENTITIES.value_id
+     *     WHERE ENTITIES.identity = '123'
+     * </pre></code>
+     *
+     * @param entityDescriptor The descriptor of the entity type to be built.
+     * @return The SELECT query that can be executed to retrieve the entity.
+     */
+    public SelectQuery<Record> createGetEntityQuery( EntityDescriptor entityDescriptor, EntityReference reference )
+    {
+        List<Table<Record>> joins = getMixinTables( entityDescriptor );
+        SelectJoinStep<Record> from = dsl.select().from( entitiesTable );
+        for( Table<Record> joinedTable : joins )
+        {
+            Condition joinCondition = valueIdentityColumn.eq( identityColumnOf( joinedTable ) );
+            from = from.leftJoin( joinedTable ).on( joinCondition );
+        }
+        return from.where( identityColumnOf( entitiesTable ).eq( reference.identity().toString() ) ).getQuery();
+    }
+
+    public void fetchAssociations( BaseEntity entity, EntityDescriptor entityDescriptor, Consumer<AssociationValue> consume )
+    {
+        List<Table<Record>> joins = getAssocationsTables( entityDescriptor );
+        SelectJoinStep<Record> from = dsl.select().from( entitiesTable );
+        for( Table<Record> joinedTable : joins )
+        {
+            Condition joinCondition = valueIdentityColumn.eq( identityColumnOf( joinedTable ) );
+            from = from.join( joinedTable ).on( joinCondition );
+        }
+        String reference = entity.identity.toString();
+        SelectQuery<Record> query = from.where( identityColumnOf( entitiesTable ).eq( reference ) ).getQuery();
+        Result<Record> result = query.fetch();
+        result.forEach( record ->
+                        {
+                            AssociationValue value = new AssociationValue();
+                            value.name = QualifiedName.fromClass( entityDescriptor.primaryType(), record.getValue( nameColumn ) );
+                            value.position = record.getValue( indexColumn );
+                            value.reference = record.getValue( referenceColumn );
+                            consume.accept( value );
+                        } );
+    }
+
+    private Field<String> identityColumnOf( Table<Record> joinedTable )
+    {
+        return DSL.field( DSL.name( joinedTable.getName(), identityColumn.getName() ), String.class );
+    }
+
+    public List<Table<Record>> getMixinTables( EntityDescriptor entityDescriptor )
+    {
+        return entityDescriptor
+            .mixinTypes()
+            .filter( NOT_COMPOSITE )
+            .filter( NOT_HASIDENTITY )
+            .map( ( Class<?> type ) -> types.tableFor( type, entityDescriptor ) )
+            .collect( Collectors.toList() );
+    }
+
+    public List<Table<Record>> getAssocationsTables( EntityDescriptor entityDescriptor )
+    {
+        return entityDescriptor
+            .mixinTypes()
+            .filter( NOT_COMPOSITE )
+            .filter( NOT_HASIDENTITY )
+            .map( type -> findMixinTable( type, entityDescriptor ) )
+            .map( MixinTable::associationsTable )
+            .collect( Collectors.toList() );
+    }
+
+    public void removeEntity( EntityReference entityReference, EntityDescriptor descriptor )
+    {
+        ModuleDescriptor module = descriptor.module();
+        BaseEntity baseEntity = fetchEntity( entityReference, module );
+        if( replacementStrategy )
+        {
+            // TODO;  Mark deleted, I guess... not implemented
+        }
+        else
+        {
+            dsl.delete( entitiesTable )
+               .where(
+                   identityColumnOf( entitiesTable ).eq( entityReference.identity().toString() )
+                     )
+               .execute()
+            ;
+            String valueId = baseEntity.currentValueIdentity.toString();
+            List<Table<Record>> mixinTables = getMixinTables( descriptor );
+            List<Table<Record>> assocTables = getAssocationsTables( descriptor );
+            mixinTables.forEach( table -> dsl.delete( table ).where( identityColumnOf( table ).eq( valueId ) ).execute() );
+            assocTables.forEach( table -> dsl.delete( table ).where( identityColumnOf( table ).eq( valueId ) ).execute() );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/JooqDslContext.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/JooqDslContext.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/JooqDslContext.java
new file mode 100644
index 0000000..d89c058
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/JooqDslContext.java
@@ -0,0 +1,58 @@
+/*
+ *  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.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import javax.sql.DataSource;
+import org.apache.polygene.api.injection.scope.Service;
+import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.mixin.Mixins;
+import org.jooq.Configuration;
+import org.jooq.DSLContext;
+import org.jooq.SQLDialect;
+import org.jooq.conf.Settings;
+import org.jooq.impl.DSL;
+import org.jooq.impl.DefaultConfiguration;
+
+@Mixins( JooqDslContext.Mixin.class )
+public interface JooqDslContext extends DSLContext
+{
+
+    class Mixin
+        implements InvocationHandler
+    {
+        private DSLContext dsl;
+
+        public Mixin( @Service DataSource dataSource, @Uses Settings settings, @Uses SQLDialect dialect )
+        {
+            Configuration configuration = new DefaultConfiguration()
+                .set( dataSource )
+                .set( dialect )
+                .set( settings );
+            dsl = DSL.using( configuration );
+        }
+
+        @Override
+        public Object invoke( Object o, Method method, Object[] objects )
+            throws Throwable
+        {
+            return method.invoke( dsl, objects );       // delegate all
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/MixinTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/MixinTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/MixinTable.java
new file mode 100644
index 0000000..80c26a2
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/MixinTable.java
@@ -0,0 +1,256 @@
+/*
+ *  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.lang.reflect.AccessibleObject;
+import java.lang.reflect.Method;
+import java.sql.Timestamp;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import org.apache.polygene.api.association.AssociationDescriptor;
+import org.apache.polygene.api.common.QualifiedName;
+import org.apache.polygene.api.entity.EntityDescriptor;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.property.PropertyDescriptor;
+import org.apache.polygene.spi.entity.ManyAssociationState;
+import org.apache.polygene.spi.entity.NamedAssociationState;
+import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
+import org.jooq.Field;
+import org.jooq.InsertSetMoreStep;
+import org.jooq.InsertSetStep;
+import org.jooq.Name;
+import org.jooq.Record;
+import org.jooq.Schema;
+import org.jooq.Table;
+import org.jooq.UpdateSetMoreStep;
+import org.jooq.impl.DSL;
+
+class MixinTable
+    implements TableFields
+{
+
+    private final Table<Record> mixinTable;
+    private final Table<Record> mixinAssocsTable;
+
+    private final JooqDslContext dsl;
+    private final Map<QualifiedName, Field<Object>> properties = new ConcurrentHashMap<>();
+    private final Map<QualifiedName, Field<String>> associations = new ConcurrentHashMap<>();
+    private final List<QualifiedName> manyAssociations = new CopyOnWriteArrayList<>();
+    private final List<QualifiedName> namedAssociations = new CopyOnWriteArrayList<>();
+
+    private TypesTable types;
+    private final Class<?> mixinType;
+
+    MixinTable( JooqDslContext dsl, Schema schema, TypesTable types, Class<?> mixinType,
+                EntityDescriptor descriptor )
+    {
+        this.dsl = dsl;
+        this.types = types;
+        this.mixinType = mixinType;
+        mixinTable = types.tableFor( mixinType, descriptor );
+        mixinAssocsTable = getAssocsTable( descriptor, schema );
+
+        descriptor.valueType().properties()
+                  .filter( this::isThisMixin )
+                  .forEach( propDescriptor ->
+                            {
+                                QualifiedName propertyName = propDescriptor.qualifiedName();
+                                Field<Object> propertyField = types.fieldOf( propDescriptor );
+                                properties.put( propertyName, propertyField );
+                            }
+                          );
+
+        descriptor.valueType().associations()
+                  .filter( this::isThisMixin )
+                  .forEach( assocDescriptor ->
+                            {
+                                QualifiedName assocName = assocDescriptor.qualifiedName();
+                                Field<String> assocField = types.fieldOf( assocDescriptor );
+                                associations.put( assocName, assocField );
+                            }
+                          );
+
+        descriptor.valueType().manyAssociations()
+                  .filter( this::isThisMixin )
+                  .forEach( assocDescriptor -> manyAssociations.add( assocDescriptor.qualifiedName() ) );
+
+        descriptor.valueType().namedAssociations()
+                  .filter( this::isThisMixin )
+                  .forEach( assocDescriptor -> namedAssociations.add( assocDescriptor.qualifiedName() ) );
+    }
+
+    void insertMixinState( DefaultEntityState state, String valueIdentity )
+    {
+        InsertSetMoreStep<Record> primaryTable =
+            dsl.insertInto( mixinTable )
+               .set( identityColumn, valueIdentity )
+               .set( createdColumn, new Timestamp( System.currentTimeMillis() ) );
+
+        properties.forEach( ( propertyName, propertyField ) -> primaryTable.set( propertyField, state.propertyValueOf( propertyName ) ) );
+        associations.forEach( ( assocName, assocField ) ->
+                              {
+                                  EntityReference reference = state.associationValueOf( assocName );
+                                  String identity = null;
+                                  if( reference != null )
+                                  {
+                                      identity = reference.identity().toString();
+                                  }
+                                  primaryTable.set( assocField, identity );
+                              }
+                            );
+        int result = primaryTable.execute();
+
+        if( mixinAssocsTable != null )
+        {
+            insertManyAndNamedAssociations( state, valueIdentity );
+        }
+    }
+
+    private void insertManyAndNamedAssociations( DefaultEntityState state, String valueIdentity )
+    {
+        manyAssociations.forEach( assocName ->
+                                  {
+                                      InsertSetStep<Record> assocsTable = dsl.insertInto( mixinAssocsTable );
+                                      ManyAssociationState entityReferences = state.manyAssociationValueOf( assocName );
+                                      int endCount = entityReferences.count();
+                                      int counter = 0;
+                                      for( EntityReference ref : entityReferences )
+                                      {
+                                          InsertSetMoreStep<Record> set = assocsTable.set( identityColumn, valueIdentity )
+                                                                                     .set( nameColumn, assocName.name() )
+                                                                                     .set( indexColumn, "" + counter++ )
+                                                                                     .set( referenceColumn, ref == null ? null : ref.identity().toString() );
+                                          if( ++counter < endCount )
+                                          {
+                                              set.newRecord();
+                                          }
+                                      }
+                                      InsertSetMoreStep<Record> assocs = assocsTable.set( Collections.emptyMap() );
+                                      assocs.execute();
+                                  } );
+
+        namedAssociations.forEach( assocName ->
+                                   {
+                                       InsertSetStep<Record> assocsTable = dsl.insertInto( mixinAssocsTable );
+                                       NamedAssociationState entityReferences = state.namedAssociationValueOf( assocName );
+                                       int count = entityReferences.count();
+                                       for( String name : entityReferences )
+                                       {
+                                           EntityReference ref = entityReferences.get( name );
+                                           InsertSetMoreStep<Record> set = assocsTable.set( identityColumn, valueIdentity )
+                                                                                      .set( nameColumn, assocName.name() )
+                                                                                      .set( indexColumn, name )
+                                                                                      .set( referenceColumn, ref.identity().toString() );
+                                           if( --count > 0 )
+                                           {
+                                               set.newRecord();
+                                           }
+                                       }
+                                       InsertSetMoreStep<Record> assocs = assocsTable.set( Collections.emptyMap() );
+                                       assocs.execute();
+                                   } );
+    }
+
+    Table<Record> associationsTable()
+    {
+        return mixinAssocsTable;
+    }
+
+    private boolean isThisMixin( PropertyDescriptor descriptor )
+    {
+        Class<?> declaringClass = declaredIn( descriptor );
+        return mixinType.equals( declaringClass );
+    }
+
+    private boolean isThisMixin( AssociationDescriptor descriptor )
+    {
+        Class<?> declaringClass = declaredIn( descriptor );
+        return mixinType.equals( declaringClass );
+    }
+
+    private Class<?> declaredIn( PropertyDescriptor descriptor )
+    {
+        AccessibleObject accessor = descriptor.accessor();
+        if( accessor instanceof Method )
+        {
+            return ( (Method) accessor ).getDeclaringClass();
+        }
+        throw new UnsupportedOperationException( "Property declared as " + accessor.getClass() + " is not supported in this Entity Store yet." );
+    }
+
+    private Class<?> declaredIn( AssociationDescriptor descriptor )
+    {
+        AccessibleObject accessor = descriptor.accessor();
+        if( accessor instanceof Method )
+        {
+            return ( (Method) accessor ).getDeclaringClass();
+        }
+        throw new UnsupportedOperationException( "Property declared as " + accessor.getClass() + " is not supported in this Entity Store yet." );
+    }
+
+    void modifyMixinState( DefaultEntityState state, String valueId )
+    {
+        UpdateSetMoreStep<Record> primaryTable =
+            dsl.update( mixinTable )
+               .set( Collections.emptyMap() );  // empty map is a hack to get the right type returned from JOOQ.
+
+        properties.forEach( ( propertyName, propertyField ) -> primaryTable.set( propertyField, state.propertyValueOf( propertyName ) ) );
+        associations.forEach( ( assocName, assocField ) ->
+                              {
+                                  EntityReference reference = state.associationValueOf( assocName );
+                                  primaryTable.set( assocField,
+                                                    reference == null ? null : reference.identity().toString()
+                                                  );
+                              }
+                            );
+        int result = primaryTable.execute();
+
+        if( mixinAssocsTable != null )
+        {
+            // Need to remove existing records.
+            dsl.delete( mixinAssocsTable )
+               .where( identityColumn.eq( valueId ) )
+               .execute();
+            insertManyAndNamedAssociations( state, valueId );
+        }
+    }
+
+    private Table<Record> getAssocsTable( EntityDescriptor descriptor, Schema schema )
+    {
+        if( descriptor.state().manyAssociations().count() > 0
+            || descriptor.state().namedAssociations().count() > 0 )
+        {
+            Name tableName = DSL.name( schema.getName(), mixinTable.getName() + ASSOCS_TABLE_POSTFIX );
+            Table<Record> table = DSL.table( tableName );
+            int result2 = dsl.createTableIfNotExists( table )
+                             .column( identityColumn )
+                             .column( nameColumn )
+                             .column( indexColumn )
+                             .column( referenceColumn )
+                             .execute();
+            return table;
+        }
+        else
+        {
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreConfiguration.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreConfiguration.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreConfiguration.java
new file mode 100644
index 0000000..e93d7a3
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreConfiguration.java
@@ -0,0 +1,73 @@
+/*
+ *  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" )
+    @Override
+    Property<String> schemaName();
+
+    /**
+     * Name of the entities table.
+     * <p>
+     * This table contains the Identity and other metadata about each entity instance
+     * </p>
+     */
+    @UseDefaults( "ENTITIES" )
+    Property<String> entitiesTableName();
+
+    /**
+     * Name of the entity types table.
+     * <p>
+     * This table contains the metainfo about each type. Types are versioned according to
+     * application version, to support entity migration over time, and therefor there might
+     * be (but not necessarily) multiple tables for entity types that has evolved beyond
+     * what can be managed within a single table.
+     * </p>
+     */
+    @UseDefaults( "TYPES" )
+    Property<String> typesTableName();
+
+    /**
+     * Defines whether the database schema and table should be created if not already present.
+     */
+    @UseDefaults( "true" )
+    Property<Boolean> createIfMissing();
+
+    /**
+     * The SQL dialect that is being used.
+     * <p>
+     * Typically that is matching a supporting dialect in JOOQ.
+     * See {@link org.jooq.SQLDialect} for supported values.
+     * </p>
+     * @return The property with the dialect value.
+     */
+    @UseDefaults( "" )
+    Property<String> dialect();
+}
+// END SNIPPET: config

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
new file mode 100644
index 0000000..5f17fd4
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
@@ -0,0 +1,367 @@
+/*
+ *  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.Timestamp;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.OffsetDateTime;
+import java.time.Period;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+import org.apache.polygene.api.association.AssociationDescriptor;
+import org.apache.polygene.api.association.AssociationStateDescriptor;
+import org.apache.polygene.api.common.QualifiedName;
+import org.apache.polygene.api.entity.EntityDescriptor;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.identity.HasIdentity;
+import org.apache.polygene.api.identity.IdentityGenerator;
+import org.apache.polygene.api.injection.scope.Service;
+import org.apache.polygene.api.injection.scope.This;
+import org.apache.polygene.api.serialization.Serialization;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.ValueType;
+import org.apache.polygene.api.usecase.Usecase;
+import org.apache.polygene.spi.entity.EntityState;
+import org.apache.polygene.spi.entity.EntityStatus;
+import org.apache.polygene.spi.entitystore.DefaultEntityStoreUnitOfWork;
+import org.apache.polygene.spi.entitystore.EntityNotFoundException;
+import org.apache.polygene.spi.entitystore.EntityStore;
+import org.apache.polygene.spi.entitystore.EntityStoreSPI;
+import org.apache.polygene.spi.entitystore.EntityStoreUnitOfWork;
+import org.apache.polygene.spi.entitystore.StateCommitter;
+import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.jooq.SelectQuery;
+
+import static org.apache.polygene.api.entity.EntityReference.parseEntityReference;
+
+public class SqlEntityStoreMixin
+    implements EntityStore, EntityStoreSPI
+{
+    @This
+    private SqlTable sqlTable;
+
+    @Service
+    private IdentityGenerator identityGenerator;
+
+    @Service
+    private Serialization serialization;
+
+    @Override
+    public EntityState newEntityState( EntityStoreUnitOfWork unitOfWork, EntityReference reference, EntityDescriptor entityDescriptor )
+    {
+        return new DefaultEntityState( unitOfWork.currentTime(), reference, entityDescriptor );
+    }
+
+    @Override
+    public EntityState entityStateOf( EntityStoreUnitOfWork unitOfWork, ModuleDescriptor module, EntityReference reference )
+    {
+        BaseEntity baseEntity = sqlTable.fetchBaseEntity( reference, module );
+        SelectQuery<Record> selectQuery = sqlTable.createGetEntityQuery( baseEntity.type, reference );
+        Result<Record> result = selectQuery.fetch();
+        if( result.isEmpty() )
+        {
+            throw new EntityNotFoundException( reference );
+        }
+        return toEntityState( result, baseEntity, reference, module );
+    }
+
+    protected EntityState toEntityState( Result<Record> result, BaseEntity baseEntity, EntityReference reference, ModuleDescriptor module )
+    {
+        AssociationStateDescriptor stateDescriptor = baseEntity.type.state();
+        Map<QualifiedName, Object> properties = new HashMap<>();
+        properties.put( HasIdentity.IDENTITY_STATE_NAME, baseEntity.identity );
+        stateDescriptor.properties()
+                       .filter( prop -> !HasIdentity.IDENTITY_STATE_NAME.equals( prop.qualifiedName() ) )
+                       .forEach( prop ->
+                                 {
+                                     QualifiedName qualifiedName = prop.qualifiedName();
+                                     Object value = result.getValue( 0, qualifiedName.name() );
+                                     value = amendValue( value, prop.valueType(), module );
+                                     properties.put( qualifiedName, value );
+                                 } );
+        Map<QualifiedName, EntityReference> assocations = new HashMap<>();
+        stateDescriptor.associations()
+                       .forEach( assoc ->
+                                 {
+                                     QualifiedName qualifiedName = assoc.qualifiedName();
+                                     String value = (String) result.getValue( 0, qualifiedName.name() );
+                                     if( value != null )
+                                     {
+                                         assocations.put( qualifiedName, parseEntityReference( value ) );
+                                     }
+                                 } );
+        Map<QualifiedName, List<EntityReference>> manyAssocs = new HashMap<>();
+        Map<QualifiedName, Map<String, EntityReference>> namedAssocs = new HashMap<>();
+        sqlTable.fetchAssociations( baseEntity, baseEntity.type, associationValue ->
+        {
+            if( stateDescriptor.hasManyAssociation( associationValue.name ) )
+            {
+                addManyAssociation( stateDescriptor, manyAssocs, associationValue );
+            }
+            else if( stateDescriptor.hasNamedAssociation( associationValue.name ) )
+            {
+                addNamedAssociation( stateDescriptor, namedAssocs, associationValue );
+            }
+        } );
+
+        return new DefaultEntityState( baseEntity.version,
+                                       baseEntity.modifedAt,
+                                       reference,
+                                       EntityStatus.LOADED,
+                                       baseEntity.type,
+                                       properties,
+                                       assocations,
+                                       manyAssocs,
+                                       namedAssocs );
+    }
+
+    private Object amendValue( Object value, ValueType type, ModuleDescriptor module )
+    {
+        if( value == null )
+        {
+            return null;
+        }
+        if( value.getClass().isPrimitive() )
+        {
+            return value;
+        }
+        if( type.equals( ValueType.STRING )
+            || type.equals( ValueType.INTEGER )
+            || type.equals( ValueType.BOOLEAN )
+            || type.equals( ValueType.DOUBLE )
+            || type.equals( ValueType.IDENTITY )
+            || type.equals( ValueType.LONG )
+            || type.equals( ValueType.FLOAT )
+            || type.equals( ValueType.BYTE )
+            || type.equals( ValueType.CHARACTER )
+            || type.equals( ValueType.ENTITY_REFERENCE )
+            || type.equals( ValueType.SHORT )
+            || type.equals( ValueType.BIG_INTEGER )
+            || type.equals( ValueType.BIG_DECIMAL )
+            )
+        {
+            return value;
+        }
+        if( type.equals( ValueType.INSTANT ) )  // Instant type contains timezone (why?), and we promise to always return in UTC (or is that just bad testcases, and that we actually promise to return original instant timezone?).
+        {
+            if( value instanceof Instant )
+            {
+                return Instant.ofEpochMilli( ( (Instant) value ).toEpochMilli() );
+            }
+            if( value instanceof OffsetDateTime )
+            {
+                return Instant.ofEpochMilli( ( (OffsetDateTime) value ).toInstant().toEpochMilli() );
+            }
+            if( value instanceof ZonedDateTime )
+            {
+                return Instant.ofEpochMilli( ( (ZonedDateTime) value ).toInstant().toEpochMilli() );
+            }
+        }
+        if( type.equals( ValueType.ZONED_DATE_TIME ) )
+        {
+            if( value instanceof ZonedDateTime )
+            {
+                return ( (ZonedDateTime) value ).withZoneSameInstant( ZoneOffset.UTC );
+            }
+            if( value instanceof OffsetDateTime )
+            {
+                return ( (OffsetDateTime) value ).toZonedDateTime().withZoneSameInstant( ZoneOffset.UTC );
+            }
+        }
+        if( type.equals( ValueType.OFFSET_DATE_TIME ) )
+        {
+            if( value instanceof OffsetDateTime )
+            {
+                return ( (OffsetDateTime) value ).withOffsetSameInstant( ZoneOffset.UTC );
+            }
+            if( value instanceof ZonedDateTime )
+            {
+                return ( (ZonedDateTime) value ).toOffsetDateTime().withOffsetSameInstant( ZoneOffset.UTC );
+            }
+        }
+        if( type.equals( ValueType.LOCAL_DATE_TIME ) )
+        {
+            if( value instanceof Timestamp )
+            {
+                return ( (Timestamp) value ).toLocalDateTime();
+            }
+        }
+        if( type.equals( ValueType.PERIOD ) )
+        {
+            if( value instanceof String )
+            {
+                return Period.parse( (String) value );
+            }
+        }
+        if( type.equals( ValueType.DURATION ) )
+        {
+            if( value instanceof String )
+            {
+                return Duration.parse( (String) value );
+            }
+        }
+        if( type.equals( ValueType.LOCAL_DATE ) )
+        {
+            if( value instanceof java.sql.Date )
+            {
+                return ( (java.sql.Date) value ).toLocalDate();
+            }
+        }
+        if( type.equals( ValueType.LOCAL_TIME ) )
+        {
+            if( value instanceof java.sql.Time )
+            {
+                return ( (java.sql.Time) value ).toLocalTime();
+            }
+        }
+        // otherwise, we deal with a serialized value.
+        return serialization.deserialize( module, type, (String) value );
+    }
+
+    private void addNamedAssociation( AssociationStateDescriptor stateDescriptor, Map<QualifiedName, Map<String, EntityReference>> namedAssocs, AssociationValue associationValue )
+    {
+        AssociationDescriptor descriptor = stateDescriptor.getNamedAssociationByName( associationValue.name.name() );
+        QualifiedName qualifiedName = descriptor.qualifiedName();
+        Map<String, EntityReference> map = namedAssocs.computeIfAbsent( qualifiedName, k -> new HashMap<>() );
+        map.put( associationValue.position, parseEntityReference( associationValue.reference ) );
+    }
+
+    private void addManyAssociation( AssociationStateDescriptor stateDescriptor, Map<QualifiedName, List<EntityReference>> manyAssocs, AssociationValue associationValue )
+    {
+        AssociationDescriptor descriptor = stateDescriptor.getManyAssociationByName( associationValue.name.name() );
+        QualifiedName qualifiedName = descriptor.qualifiedName();
+        List<EntityReference> list = manyAssocs.computeIfAbsent( qualifiedName, k -> new ArrayList<>() );
+        String reference = associationValue.reference;
+        list.add( reference == null ? null : parseEntityReference( reference ) );
+    }
+
+    @Override
+    public String versionOf( EntityStoreUnitOfWork unitOfWork, EntityReference reference )
+    {
+        BaseEntity baseEntity = sqlTable.fetchBaseEntity( reference, unitOfWork.module() );
+        return baseEntity.version;
+    }
+
+    @Override
+    public StateCommitter applyChanges( EntityStoreUnitOfWork unitOfWork, Iterable<EntityState> state )
+    {
+        return new JooqStateCommitter( unitOfWork, state, sqlTable.jooqDslContext() );
+    }
+
+    @Override
+    public EntityStoreUnitOfWork newUnitOfWork( ModuleDescriptor module, Usecase usecase, Instant currentTime )
+    {
+        return new DefaultEntityStoreUnitOfWork( module,
+                                                 this,
+                                                 identityGenerator.generate( SqlEntityStoreService.class ),
+                                                 usecase,
+                                                 currentTime
+        );
+    }
+
+    @Override
+    public Stream<EntityState> entityStates( ModuleDescriptor module )
+    {
+        Stream<? extends EntityDescriptor> entityTypes = module.entityComposites();
+        return entityTypes
+            .flatMap( type -> sqlTable.fetchAll( type, module ) )
+            .map( baseEntity ->
+                  {
+                      EntityReference reference = EntityReference.entityReferenceFor( baseEntity.identity );
+                      SelectQuery<Record> selectQuery = sqlTable.createGetEntityQuery( baseEntity.type, reference );
+                      Result<Record> result = selectQuery.fetch();
+                      return toEntityState( result, baseEntity, reference, module );
+                  } );
+    }
+
+    private class JooqStateCommitter
+        implements StateCommitter
+    {
+        private final EntityStoreUnitOfWork unitOfWork;
+        private final Iterable<EntityState> states;
+        private final JooqDslContext dslContext;
+        private final ModuleDescriptor module;
+
+        JooqStateCommitter( EntityStoreUnitOfWork unitOfWork, Iterable<EntityState> states, JooqDslContext dslContext )
+        {
+            this.unitOfWork = unitOfWork;
+            this.states = states;
+            this.dslContext = dslContext;
+            this.module = unitOfWork.module();
+        }
+
+        private void newState( DefaultEntityState state, EntityStoreUnitOfWork unitOfWork )
+        {
+            EntityReference ref = state.entityReference();
+            EntityDescriptor descriptor = state.entityDescriptor();
+            sqlTable.createNewBaseEntity( ref, descriptor, this.unitOfWork );
+            sqlTable.insertEntity( state, sqlTable.fetchBaseEntity( ref, module ), unitOfWork );
+        }
+
+        private void updateState( DefaultEntityState state, EntityStoreUnitOfWork unitOfWork )
+        {
+            EntityDescriptor descriptor = state.entityDescriptor();
+            BaseEntity baseEntity = sqlTable.fetchBaseEntity( state.entityReference(), descriptor.module() );
+            sqlTable.updateEntity( state, baseEntity, unitOfWork );
+        }
+
+        private void removeState( DefaultEntityState state )
+        {
+            EntityReference reference = state.entityReference();
+            EntityDescriptor descriptor = state.entityDescriptor();
+            sqlTable.removeEntity( reference, descriptor );
+        }
+
+        @Override
+        public void commit()
+        {
+            dslContext.transaction( configuration ->
+                                    {
+                                        for( EntityState es : this.states )
+                                        {
+                                            DefaultEntityState state = (DefaultEntityState) es;
+                                            if( state.status() == EntityStatus.NEW )
+                                            {
+                                                newState( state, unitOfWork );
+                                            }
+                                            if( state.status() == EntityStatus.UPDATED )
+                                            {
+                                                updateState( state, unitOfWork );
+                                            }
+                                            if( state.status() == EntityStatus.REMOVED )
+                                            {
+                                                removeState( state );
+                                            }
+                                        }
+                                    } );
+        }
+
+        @Override
+        public void cancel()
+        {
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreService.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreService.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreService.java
new file mode 100644
index 0000000..cf401d6
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreService.java
@@ -0,0 +1,36 @@
+/*
+ *  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.spi.entitystore.ConcurrentModificationCheckConcern;
+import org.apache.polygene.spi.entitystore.EntityStateVersions;
+import org.apache.polygene.spi.entitystore.EntityStore;
+import org.apache.polygene.spi.entitystore.StateChangeNotificationConcern;
+
+/**
+ * SQL EntityStore service.
+ */
+@Concerns( { StateChangeNotificationConcern.class, ConcurrentModificationCheckConcern.class } )
+@Mixins( { SqlEntityStoreMixin.class } )
+public interface SqlEntityStoreService
+    extends EntityStore, EntityStateVersions, Configuration, SqlTable
+{
+}


[09/15] polygene-java git commit: Missing call to super.assemble() which removes a warning of assemble() not being called.

Posted by ni...@apache.org.
Missing call to super.assemble() which removes a warning of assemble() not being called.


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/ff9c272c
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/ff9c272c
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/ff9c272c

Branch: refs/heads/es-sql
Commit: ff9c272c41e131e07e9fd017e2ecb6b32a60b6f5
Parents: 6055b8f
Author: niclas <ni...@hedhman.org>
Authored: Sun Sep 10 10:40:43 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Sun Sep 10 10:40:43 2017 +0800

----------------------------------------------------------------------
 .../polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java  | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/ff9c272c/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java
index b1f660f..847c07b 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java
@@ -63,6 +63,7 @@ public class SqlEntityStoreAssembler extends Assemblers.VisibilityIdentityConfig
         {
             configModule().entities( SqlEntityStoreConfiguration.class ).visibleIn( configVisibility() );
         }
+        super.assemble( module );
     }
 
     protected Settings getSettings()


[08/15] polygene-java git commit: entitystore-sql is brought in from the es-jooq branch, and fixed it up so that it compiles and passes the standard unit tests using H2. More testing needed for other SQL systems, since there seems to not be consensus on

Posted by ni...@apache.org.
entitystore-sql is brought in from the es-jooq branch, and fixed it up so that it compiles and passes the standard unit tests using H2. More testing needed for other SQL systems, since there seems to not be consensus on how TIME is handled and Jooq is unable to smooth it out completely. Also, the BigDecimal, BigInteger and Float are possibly issues across SQL systems.


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/6055b8f7
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/6055b8f7
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/6055b8f7

Branch: refs/heads/es-sql
Commit: 6055b8f7deccec5f6a7f154b060f08be2f383439
Parents: ad658f6
Author: niclas <ni...@hedhman.org>
Authored: Sun Sep 10 10:35:52 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Sun Sep 10 10:35:52 2017 +0800

----------------------------------------------------------------------
 .../test/entity/AbstractEntityStoreTest.java    |  72 ++--
 dependencies.gradle                             |   8 +-
 extensions/entitystore-jooq/build.gradle        |  44 ---
 extensions/entitystore-jooq/dev-status.xml      |  38 --
 .../entitystore-jooq/src/docs/es-jooq.txt       |  58 ---
 .../entitystore/jooq/AssociationValue.java      |  28 --
 .../polygene/entitystore/jooq/BaseEntity.java   |  34 --
 .../entitystore/jooq/EntitiesTable.java         | 363 ------------------
 .../entitystore/jooq/JooqDslContext.java        |  58 ---
 .../jooq/JooqEntityStoreConfiguration.java      |  73 ----
 .../entitystore/jooq/JooqEntityStoreMixin.java  | 256 -------------
 .../jooq/JooqEntityStoreService.java            |  36 --
 .../polygene/entitystore/jooq/MixinTable.java   | 256 -------------
 .../polygene/entitystore/jooq/SqlTable.java     | 277 --------------
 .../polygene/entitystore/jooq/SqlType.java      | 141 -------
 .../polygene/entitystore/jooq/TableFields.java  |  69 ----
 .../polygene/entitystore/jooq/TypesTable.java   | 189 ----------
 .../jooq/assembly/JooqEntityStoreAssembler.java |  77 ----
 .../entitystore/jooq/JooqEntityStoreTest.java   |  88 -----
 extensions/entitystore-sql/build.gradle         |  44 +++
 extensions/entitystore-sql/dev-status.xml       |  38 ++
 extensions/entitystore-sql/src/docs/es-sql.txt  |  58 +++
 .../entitystore/sql/AssociationValue.java       |  28 ++
 .../polygene/entitystore/sql/BaseEntity.java    |  34 ++
 .../polygene/entitystore/sql/EntitiesTable.java | 363 ++++++++++++++++++
 .../entitystore/sql/JooqDslContext.java         |  58 +++
 .../polygene/entitystore/sql/MixinTable.java    | 256 +++++++++++++
 .../sql/SqlEntityStoreConfiguration.java        |  73 ++++
 .../entitystore/sql/SqlEntityStoreMixin.java    | 367 +++++++++++++++++++
 .../entitystore/sql/SqlEntityStoreService.java  |  36 ++
 .../polygene/entitystore/sql/SqlTable.java      | 271 ++++++++++++++
 .../polygene/entitystore/sql/SqlType.java       | 156 ++++++++
 .../polygene/entitystore/sql/TableFields.java   |  69 ++++
 .../polygene/entitystore/sql/TypesTable.java    | 189 ++++++++++
 .../sql/assembly/SqlEntityStoreAssembler.java   |  77 ++++
 .../entitystore/sql/SqlEntityStoreTest.java     |  88 +++++
 settings.gradle                                 |   2 +-
 37 files changed, 2249 insertions(+), 2123 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java b/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java
index 749bf2e..2812c4e 100644
--- a/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java
@@ -175,113 +175,119 @@ public abstract class AbstractEntityStoreTest
             instance = unitOfWork.get( instance );
 
             // Check state
-            assertThat( "property 'intValue' has correct value",
+            assertThat( "property 'intValue' has incorrect value",
                         instance.intValue().get(),
                         equalTo( 42 ) );
 
-            assertThat( "property 'longValue' has correct value",
+            assertThat( "property 'longValue' has incorrect value",
                         instance.longValue().get(),
                         equalTo( 42L ) );
 
-            assertThat( "property 'doubleValue' has correct value",
+            assertThat( "property 'doubleValue' has incorrect value",
                         instance.doubleValue().get(),
                         equalTo( 42D ) );
 
-            assertThat( "property 'floatValue' has correct value",
+            assertThat( "property 'floatValue' has incorrect value",
                         instance.floatValue().get(),
                         equalTo( 42F ) );
 
-            assertThat( "property 'booleanValue' has correct value",
+            assertThat( "property 'booleanValue' has incorrect value",
                         instance.booleanValue().get(),
                         equalTo( Boolean.TRUE ) );
 
-            assertThat( "property 'bigInteger' has correct value",
-                        instance.bigIntegerValue().get(),
-                        equalTo( new BigInteger( "42" ) ) );
-
-            assertThat( "property 'bigDecimal' has correct value",
+            assertThat( "property 'bigDecimal' has incorrect value",
                         instance.bigDecimalValue().get(),
                         equalTo( new BigDecimal( "42" ) ) );
 
-            assertThat( "property 'instantValue' has correct value",
-                        instance.instantValue().get(),
-                        equalTo( refDate.toInstant() ) );
+            assertThat( "property 'bigInteger' has incorrect value",
+                        instance.bigIntegerValue().get(),
+                        equalTo( new BigInteger( "42" ) ) );
 
-            assertThat( "property 'dateTimeValue' has correct value",
+            assertThat( "property 'dateTimeValue' has incorrect value",
                         instance.dateTimeValue().get(),
                         equalTo( refDate ) );
 
-            assertThat( "property 'localDateTimeValue' has correct value",
+            assertThat( "property 'instantValue' has incorrect value",
+                        instance.instantValue().get(),
+                        equalTo( refDate.toInstant() ) );
+
+            assertThat( "property 'localDateTimeValue' has incorrect value",
                         instance.localDateTimeValue().get(),
                         equalTo( LocalDateTime.of( 2020, 3, 4, 13, 23, 0 ) ) );
 
-            assertThat( "property 'localDateValue' has correct value",
+            assertThat( "property 'localDateValue' has incorrect value",
                         instance.localDateValue().get(),
                         equalTo( LocalDate.of( 2020, 3, 4 ) ) );
 
-            assertThat( "property 'localTimeValue' has correct value",
+            assertThat( "property 'localTimeValue' has incorrect value",
                         instance.localTimeValue().get(),
                         equalTo( LocalTime.of( 19, 20, 21 ) ) );
 
-            assertThat( "property 'periodValue' has correct value",
+            assertThat( "property 'periodValue' has incorrect value",
                         instance.periodValue().get(),
                         equalTo( Period.of( 1, 1, 2 ) ) );
 
-            assertThat( "property 'durationValue' has correct value",
+            assertThat( "property 'durationValue' has incorrect value",
                         instance.duractionValue().get(),
                         equalTo( Duration.ofSeconds( 3661 ) ) );
 
-            assertThat( "property 'name' has correct value",
+            assertThat( "property 'name' has incorrect value",
                         instance.name().get(),
                         equalTo( "Test" ) );
 
-            assertThat( "property 'unsetName' has correct value",
+            assertThat( "property 'unsetName' has incorrect value",
                         instance.unsetName().get(),
                         equalTo( null ) );
 
-            assertThat( "property 'emptyName' has correct value",
+            assertThat( "property 'emptyName' has incorrect value",
                         instance.emptyName().get(),
                         equalTo( "" ) );
 
-            assertThat( "property 'valueProperty.stringValue' has correct value",
-                        instance.valueProperty().get().valueProperty().get().stringValue().get(),
+            Property<TestValue> testValueProperty = instance.valueProperty();
+            TestValue testValue = testValueProperty.get();
+            Property<TestValue2> testValue2Property = testValue.valueProperty();
+            TestValue2 testValue2 = testValue2Property.get();
+            Property<String> stringProperty = testValue2.stringValue();
+            String actual = stringProperty.get();
+            assertThat( "property 'valueProperty.stringValue' has incorrect value",
+                        actual,
                         equalTo( "Bar" ) );
 
-            assertThat( "property 'valueProperty.listProperty' has correct value",
+            assertThat( "property 'valueProperty.listProperty' has incorrect value",
                         instance.valueProperty().get().listProperty().get().get( 0 ),
                         equalTo( "Foo" ) );
 
-            assertThat( "property 'valueProperty.enumProperty' has correct value",
+            assertThat( "property 'valueProperty.enumProperty' has incorrect value",
                         instance.valueProperty().get().enumProperty().get(),
                         equalTo( TestEnum.VALUE3 ) );
 
-            assertThat( "property 'valueProperty.anotherValue.bling' has correct value",
+            assertThat( "property 'valueProperty.anotherValue.bling' has incorrect value",
                         instance.valueProperty().get().valueProperty().get().anotherValue().get().bling().get(),
                         equalTo( "BlinkLjus" ) );
 
-            assertThat( "property 'valueProperty.tjabbaProperty.bling' has correct value",
+            assertThat( "property 'valueProperty.tjabbaProperty.bling' has incorrect value",
                         instance.valueProperty().get().tjabbaProperty().get().bling().get(),
                         equalTo( "Brakfis" ) );
 
             Map<String, String> mapValue = new HashMap<>();
             mapValue.put( "foo", "bar" );
-            assertThat( "property 'valueProperty.mapStringStringProperty' has correct value",
+            assertThat( "property 'valueProperty.mapStringStringProperty' has incorrect value",
                         instance.valueProperty().get().mapStringStringProperty().get(),
                         equalTo( mapValue ) );
 
-            assertThat( "association has correct value",
+            assertThat( "association has incorrect value",
                         instance.association().get(),
                         equalTo( instance ) );
 
-            assertThat( "manyAssociation has correct value",
+            assertThat( "manyAssociation has incorrect value",
                         instance.manyAssociation().iterator().next(),
                         equalTo( instance ) );
 
-            assertThat( "namedAssociation has correct 'foo' value",
+            assertThat( "namedAssociation has incorrect 'foo' value",
                         instance.namedAssociation().get( "foo" ),
                         equalTo( instance ) );
 
-            assertThat( "namedAssociation has correct 'bar' value",
+            assertThat( "namedAssociation has incorrect 'bar' value",
                         instance.namedAssociation().get( "bar" ),
                         equalTo( instance ) );
         }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/dependencies.gradle
----------------------------------------------------------------------
diff --git a/dependencies.gradle b/dependencies.gradle
index f803793..ff4dd48 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -50,12 +50,12 @@ def commonsDbcpVersion = '2.1.1'
 def commonsLangVersion = '3.6'
 def commonsValidatorVersion = '1.6'
 def derbyVersion = '10.13.1.1'
-def ehcacheVersion = '3.3.1'
-def elasticsearchVersion = '5.5.0'
+def ehcacheVersion = '3.4.0'
+def elasticsearchVersion = '5.5.2'
 def freemarkerVersion = '2.3.26-incubating'
 def geodeVersion = '1.2.0'
 def groovyVersion = '2.4.12'
-def hazelcastVersion = '3.8.3'
+def hazelcastVersion = '3.8.5'
 def httpClientVersion = '4.5.3'
 def jacksonVersion = '2.8.9'
 def jaxbApiVersion = '2.2.12'
@@ -64,7 +64,7 @@ def jdbmVersion = '2.4'
 def jedisVersion = '2.9.0'
 def jettyVersion = '9.2.17.v20160517' // 9.3.x Tests fail!
 def johnzonVersion = '1.1.1'
-def jooqVersion = '3.9.3'
+def jooqVersion = '3.9.5'
 def leveldbVersion = '0.9'
 def leveldbJniVersion = '1.8'
 def liquibaseVersion = '3.5.3'

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/build.gradle
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/build.gradle b/extensions/entitystore-jooq/build.gradle
deleted file mode 100644
index 32ceb70..0000000
--- a/extensions/entitystore-jooq/build.gradle
+++ /dev/null
@@ -1,44 +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.
- *
- *
- */
-
-apply plugin: 'polygene-extension'
-
-description = "Apache Polygene™ ORM EntityStore Extension"
-
-jar { manifest { name = "Apache Polygene™ Extension - EntityStore - ORM" } }
-
-dependencies {
-  api polygene.core.bootstrap
-  api polygene.library( 'sql' )
-  api libraries.jooq
-
-  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/6055b8f7/extensions/entitystore-jooq/dev-status.xml
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/dev-status.xml b/extensions/entitystore-jooq/dev-status.xml
deleted file mode 100644
index b6d4c31..0000000
--- a/extensions/entitystore-jooq/dev-status.xml
+++ /dev/null
@@ -1,38 +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.
-  ~
-  ~
-  -->
-<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>early</codebase>
-
-        <!-- none, brief, good, complete -->
-        <documentation>brief</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/6055b8f7/extensions/entitystore-jooq/src/docs/es-jooq.txt
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/docs/es-jooq.txt b/extensions/entitystore-jooq/src/docs/es-jooq.txt
deleted file mode 100644
index a36d463..0000000
--- a/extensions/entitystore-jooq/src/docs/es-jooq.txt
+++ /dev/null
@@ -1,58 +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.
-///////////////////////////////////////////////////////////////
-
-[[extension-es-jooq,SQL EntityStore]]
-= ORM EntityStore =
-
-[devstatus]
---------------
-source=extensions/entitystore-jooq/dev-status.xml
---------------
-
-This entitystore is backed by a SQL server, and maps each mixin type of the Composite into separate tables. This is more
-enterprise-friendly, but comes at the cost of less performance compared to the <<extension-es-sql>>.
-
-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.
-
-include::../../build/docs/buildinfo/artifact.txt[]
-
-== Assembly ==
-
-Assembly is done using the provided Assembler:
-
-[snippet,java]
-----
-source=extensions/entitystore-jooq/src/test/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreTest.java
-tag=assembly
-----
-
-== Configuration ==
-
-Here are the available configuration properties:
-
-[snippet,java]
-----
-source=extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreConfiguration.java
-tag=config
-----
-
-All authentication related properties are optional.
-By default no authentication is used.
-As soon as you provide a `username`, authentication is set up.

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/AssociationValue.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/AssociationValue.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/AssociationValue.java
deleted file mode 100644
index 528ab8b..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/AssociationValue.java
+++ /dev/null
@@ -1,28 +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.jooq;
-
-import org.apache.polygene.api.common.QualifiedName;
-
-@SuppressWarnings( "WeakerAccess" )
-public class AssociationValue
-{
-    QualifiedName name;
-    String position;
-    String reference;
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/BaseEntity.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/BaseEntity.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/BaseEntity.java
deleted file mode 100644
index 3c16f16..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/BaseEntity.java
+++ /dev/null
@@ -1,34 +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.jooq;
-
-import java.time.Instant;
-import org.apache.polygene.api.entity.EntityDescriptor;
-import org.apache.polygene.api.identity.Identity;
-
-@SuppressWarnings( "WeakerAccess" )
-public class BaseEntity
-{
-    EntityDescriptor type;
-    Identity identity;
-    String version;
-    String applicationVersion;
-    Instant modifedAt;
-    Instant createdAt;
-    Identity currentValueIdentity;
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/EntitiesTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/EntitiesTable.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/EntitiesTable.java
deleted file mode 100644
index 001b590..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/EntitiesTable.java
+++ /dev/null
@@ -1,363 +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.jooq;
-
-import java.lang.reflect.Method;
-import java.sql.Timestamp;
-import java.time.Instant;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.apache.polygene.api.association.AssociationDescriptor;
-import org.apache.polygene.api.common.QualifiedName;
-import org.apache.polygene.api.composite.Composite;
-import org.apache.polygene.api.entity.EntityComposite;
-import org.apache.polygene.api.entity.EntityDescriptor;
-import org.apache.polygene.api.entity.EntityReference;
-import org.apache.polygene.api.identity.HasIdentity;
-import org.apache.polygene.api.identity.StringIdentity;
-import org.apache.polygene.api.property.PropertyDescriptor;
-import org.apache.polygene.api.structure.ModuleDescriptor;
-import org.apache.polygene.api.type.EntityCompositeType;
-import org.apache.polygene.api.unitofwork.NoSuchEntityTypeException;
-import org.apache.polygene.api.util.Classes;
-import org.apache.polygene.spi.entitystore.EntityNotFoundException;
-import org.apache.polygene.spi.entitystore.EntityStoreUnitOfWork;
-import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
-import org.jooq.Condition;
-import org.jooq.Field;
-import org.jooq.Record;
-import org.jooq.Result;
-import org.jooq.Schema;
-import org.jooq.SelectJoinStep;
-import org.jooq.SelectQuery;
-import org.jooq.Table;
-import org.jooq.impl.DSL;
-
-@SuppressWarnings( "WeakerAccess" )
-public class EntitiesTable
-    implements TableFields
-{
-    private static final Predicate<? super Class<?>> NOT_COMPOSITE = type -> !( type.equals( Composite.class ) || type.equals( EntityComposite.class ) );
-    private static final Predicate<? super Class<?>> NOT_HASIDENTITY = type -> !( type.equals( HasIdentity.class ) );
-    private Map<EntityCompositeType, Set<Class<?>>> mixinTypeCache = new ConcurrentHashMap<>();
-    private Map<Class<?>, MixinTable> mixinTablesCache = new ConcurrentHashMap<>();
-
-    private final Table<Record> entitiesTable;
-    private JooqDslContext dsl;
-    private final TypesTable types;
-    private final Schema schema;
-    private String applicationVersion;
-    private boolean replacementStrategy = false;  // Figure out later if we should support both and if so, how.
-
-    EntitiesTable( JooqDslContext dsl, Schema schema, TypesTable types, String applicationVersion, String entitiesTableName )
-    {
-        this.dsl = dsl;
-        this.types = types;
-        this.schema = schema;
-        this.applicationVersion = applicationVersion;
-        entitiesTable = types.tableOf( entitiesTableName );
-    }
-
-    public BaseEntity fetchEntity( EntityReference reference, ModuleDescriptor module )
-    {
-
-        Result<Record> baseEntityResult = dsl
-            .selectFrom( entitiesTable )
-            .where( identityColumn.eq( reference.identity().toString() ) )
-            .fetch();
-
-        if( baseEntityResult.isEmpty() )
-        {
-            throw new EntityNotFoundException( reference );
-        }
-        Record row = baseEntityResult.get( 0 );
-        return toBaseEntity( row, module );
-    }
-
-    protected BaseEntity toBaseEntity( Record row, ModuleDescriptor module )
-    {
-        BaseEntity result = new BaseEntity();
-        String typeName = row.field( typeNameColumn ).get( row );
-        result.type = findEntityDescriptor( typeName, module );
-        result.version = row.field( versionColumn ).get( row );
-        result.applicationVersion = row.field( applicationVersionColumn ).get( row );
-        result.identity = new StringIdentity( row.field( identityColumn ).get( row ) );
-        result.currentValueIdentity = EntityReference.parseEntityReference( row.field( valueIdentityColumn ).get( row ) ).identity();
-        result.modifedAt = Instant.ofEpochMilli( row.field( modifiedColumn ).get( row ).getTime() );
-        result.createdAt = Instant.ofEpochMilli( row.field( createdColumn ).get( row ).getTime() );
-        return result;
-    }
-
-    public Stream<BaseEntity> fetchAll( EntityDescriptor type, ModuleDescriptor module )
-    {
-        Result<Record> baseEntityResult = dsl
-            .selectFrom( entitiesTable )
-            .fetch();
-        return baseEntityResult.stream().map( record -> toBaseEntity( record, module ) );
-    }
-
-    private EntityDescriptor findEntityDescriptor( String typeName, ModuleDescriptor module )
-    {
-        try
-        {
-            Class<?> type = getClass().getClassLoader().loadClass( typeName );
-            return module.typeLookup().lookupEntityModel( type );
-        }
-        catch( ClassNotFoundException e )
-        {
-            throw new NoSuchEntityTypeException( typeName, module.name(), module.typeLookup() );
-        }
-    }
-
-    void insertEntity( DefaultEntityState state, BaseEntity baseEntity )
-    {
-        EntityCompositeType compositeType = state.entityDescriptor().valueType();
-        Set<Class<?>> mixinTypes = mixinTypeCache.computeIfAbsent( compositeType, createMixinTypesSet( compositeType ) );
-        mixinTypes.forEach( type ->
-                            {
-                                MixinTable table = findMixinTable( type, state.entityDescriptor() );
-                                table.insertMixinState( state, baseEntity.currentValueIdentity.toString() );
-                            } );
-    }
-
-    void modifyEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork uow )
-    {
-        updateBaseEntity( baseEntity, uow );
-        if( replacementStrategy )
-        {
-            insertEntity( state, baseEntity );      // replacement strategy (more safe)
-        }
-        else
-        {
-            EntityCompositeType compositeType = state.entityDescriptor().valueType();
-            Set<Class<?>> mixinTypes = mixinTypeCache.computeIfAbsent( compositeType, createMixinTypesSet( compositeType ) );
-            mixinTypes.forEach( type ->
-                                {
-                                    MixinTable table = findMixinTable( type, state.entityDescriptor() );
-                                    table.modifyMixinState( state, baseEntity.currentValueIdentity.toString() );
-                                } );
-        }
-    }
-
-    private MixinTable findMixinTable( Class<?> type, EntityDescriptor entityDescriptor )
-    {
-        return mixinTablesCache.computeIfAbsent( type, t -> new MixinTable( dsl, schema, types, type, entityDescriptor ) );
-    }
-
-    private Set<Class<?>> mixinsOf( Stream<? extends AssociationDescriptor> stream )
-    {
-        return stream
-            .map( AssociationDescriptor::accessor )
-            .filter( Classes.instanceOf( Method.class ) )
-            .map( accessor -> (Method) accessor )
-            .map( Method::getDeclaringClass )
-            .filter( NOT_HASIDENTITY )
-            .filter( NOT_COMPOSITE )
-            .collect( Collectors.toSet() );
-    }
-
-    private Function<EntityCompositeType, Set<Class<?>>> createMixinTypesSet( EntityCompositeType compositeType )
-    {
-        return type ->
-        {
-            Set<Class<?>> mixins = compositeType
-                .properties()
-                .map( PropertyDescriptor::accessor )
-                .filter( Classes.instanceOf( Method.class ) )
-                .map( accessor -> (Method) accessor )
-                .map( Method::getDeclaringClass )
-                .filter( NOT_HASIDENTITY )
-                .filter( NOT_COMPOSITE )
-                .collect( Collectors.toSet() );
-            Set<Class<?>> mixinsWithAssociations = mixinsOf( compositeType.associations() );
-            Set<Class<?>> mixinsWithManyAssociations = mixinsOf( compositeType.manyAssociations() );
-            Set<Class<?>> mixinsWithNamedAssociations = mixinsOf( compositeType.namedAssociations() );
-            mixins.addAll( mixinsWithAssociations );
-            mixins.addAll( mixinsWithManyAssociations );
-            mixins.addAll( mixinsWithNamedAssociations );
-            return mixins;
-        };
-    }
-
-    void createNewBaseEntity( EntityReference reference, EntityDescriptor descriptor, EntityStoreUnitOfWork uow )
-    {
-        String valueIdentity = UUID.randomUUID().toString();
-        dsl.insertInto( entitiesTable )
-           .set( identityColumn, reference.identity().toString() )
-           .set( createdColumn, new Timestamp( uow.currentTime().toEpochMilli() ) )
-           .set( modifiedColumn, new Timestamp( uow.currentTime().toEpochMilli() ) )
-           .set( valueIdentityColumn, valueIdentity )
-           .set( typeNameColumn, descriptor.primaryType().getName() )
-           .set( versionColumn, "1" )
-           .set( applicationVersionColumn, applicationVersion )
-           .execute();
-    }
-
-    private void updateBaseEntity( BaseEntity entity, EntityStoreUnitOfWork uow )
-    {
-        entity.version = increment( entity.version );
-        if( replacementStrategy )
-        {
-            entity.currentValueIdentity = new StringIdentity( UUID.randomUUID().toString() );
-        }
-        dsl.update( entitiesTable )
-           .set( modifiedColumn, new Timestamp( uow.currentTime().toEpochMilli() ) )
-           .set( valueIdentityColumn, entity.currentValueIdentity.toString() )
-           .set( versionColumn, entity.version )
-           .set( applicationVersionColumn, applicationVersion )
-           .execute();
-    }
-
-    private String increment( String version )
-    {
-        long ver = Long.parseLong( version );
-        return Long.toString( ver + 1 );
-    }
-
-    /**
-     * Builds the SELECT statement for a given entity.
-     * <p>
-     * Example; If we have the following entity
-     * </p>
-     * <code><pre>
-     *     public interface LegalEntity
-     *     {
-     *         Property&lt;String&gt; registration();
-     *     }
-     * <p>
-     *     public interface Person extends LegalEntity
-     *     {
-     *         Property&lt;String&gt; name();
-     * <p>
-     *         &#64;Optional
-     *         Association&lt;Person&gt; spouse();
-     * <p>
-     *         ManyAssocation&lt;Person&gt; children();
-     *     }
-     * </pre></code>
-     * <p>
-     * and we do a simple;
-     * <code><pre>
-     *     Person p = uow.get( Person.class, "niclas" );
-     * </pre></code>
-     * <p>
-     * then the generated query will be
-     * </p>
-     * <code><pre>
-     *     SELECT * FROM ENTITIES
-     *     JOIN Person ON identity = ENTITIES.value_id
-     *     JOIN LegalEntity ON identity = ENTITIES.value_id
-     *     JOIN Person_Assoc ON identity = ENTITIES.value_id
-     *     WHERE ENTITIES.identity = '123'
-     * </pre></code>
-     *
-     * @param entityDescriptor The descriptor of the entity type to be built.
-     * @return The SELECT query that can be executed to retrieve the entity.
-     */
-    public SelectQuery<Record> createGetEntityQuery( EntityDescriptor entityDescriptor, EntityReference reference )
-    {
-        List<Table<Record>> joins = getMixinTables( entityDescriptor );
-        SelectJoinStep<Record> from = dsl.select().from( entitiesTable );
-        for( Table<Record> joinedTable : joins )
-        {
-            Condition joinCondition = valueIdentityColumn.eq( identityColumnOf( joinedTable ) );
-            from = from.leftJoin( joinedTable ).on( joinCondition );
-        }
-        return from.where( identityColumnOf( entitiesTable ).eq( reference.identity().toString() ) ).getQuery();
-    }
-
-    public void fetchAssociations( BaseEntity entity, EntityDescriptor entityDescriptor, Consumer<AssociationValue> consume )
-    {
-        List<Table<Record>> joins = getAssocationsTables( entityDescriptor );
-        SelectJoinStep<Record> from = dsl.select().from( entitiesTable );
-        for( Table<Record> joinedTable : joins )
-        {
-            Condition joinCondition = valueIdentityColumn.eq( identityColumnOf( joinedTable ) );
-            from = from.join( joinedTable ).on( joinCondition );
-        }
-        String reference = entity.identity.toString();
-        SelectQuery<Record> query = from.where( identityColumnOf( entitiesTable ).eq( reference ) ).getQuery();
-        Result<Record> result = query.fetch();
-        result.forEach( record ->
-                        {
-                            AssociationValue value = new AssociationValue();
-                            value.name = QualifiedName.fromClass( entityDescriptor.primaryType(), record.getValue( nameColumn ) );
-                            value.position = record.getValue( indexColumn );
-                            value.reference = record.getValue( referenceColumn );
-                            consume.accept( value );
-                        } );
-    }
-
-    private Field<String> identityColumnOf( Table<Record> joinedTable )
-    {
-        return DSL.field( DSL.name( joinedTable.getName(), identityColumn.getName() ), String.class );
-    }
-
-    public List<Table<Record>> getMixinTables( EntityDescriptor entityDescriptor )
-    {
-        return entityDescriptor
-            .mixinTypes()
-            .filter( NOT_COMPOSITE )
-            .filter( NOT_HASIDENTITY )
-            .map( ( Class<?> type ) -> types.tableFor( type, entityDescriptor ) )
-            .collect( Collectors.toList() );
-    }
-
-    public List<Table<Record>> getAssocationsTables( EntityDescriptor entityDescriptor )
-    {
-        return entityDescriptor
-            .mixinTypes()
-            .filter( NOT_COMPOSITE )
-            .filter( NOT_HASIDENTITY )
-            .map( type -> findMixinTable( type, entityDescriptor ) )
-            .map( MixinTable::associationsTable )
-            .collect( Collectors.toList() );
-    }
-
-    public void removeEntity( EntityReference entityReference, EntityDescriptor descriptor )
-    {
-        ModuleDescriptor module = descriptor.module();
-        BaseEntity baseEntity = fetchEntity( entityReference, module );
-        if( replacementStrategy )
-        {
-            // TODO;  Mark deleted, I guess... not implemented
-        }
-        else
-        {
-            dsl.delete( entitiesTable )
-               .where(
-                   identityColumnOf( entitiesTable ).eq( entityReference.identity().toString() )
-                     )
-               .execute()
-            ;
-            String valueId = baseEntity.currentValueIdentity.toString();
-            List<Table<Record>> mixinTables = getMixinTables( descriptor );
-            List<Table<Record>> assocTables = getAssocationsTables( descriptor );
-            mixinTables.forEach( table -> dsl.delete( table ).where( identityColumnOf( table ).eq( valueId ) ).execute() );
-            assocTables.forEach( table -> dsl.delete( table ).where( identityColumnOf( table ).eq( valueId ) ).execute() );
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqDslContext.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqDslContext.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqDslContext.java
deleted file mode 100644
index 95a0fd5..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqDslContext.java
+++ /dev/null
@@ -1,58 +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.jooq;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import javax.sql.DataSource;
-import org.apache.polygene.api.injection.scope.Service;
-import org.apache.polygene.api.injection.scope.Uses;
-import org.apache.polygene.api.mixin.Mixins;
-import org.jooq.Configuration;
-import org.jooq.DSLContext;
-import org.jooq.SQLDialect;
-import org.jooq.conf.Settings;
-import org.jooq.impl.DSL;
-import org.jooq.impl.DefaultConfiguration;
-
-@Mixins( JooqDslContext.Mixin.class )
-public interface JooqDslContext extends DSLContext
-{
-
-    class Mixin
-        implements InvocationHandler
-    {
-        private DSLContext dsl;
-
-        public Mixin( @Service DataSource dataSource, @Uses Settings settings, @Uses SQLDialect dialect )
-        {
-            Configuration configuration = new DefaultConfiguration()
-                .set( dataSource )
-                .set( dialect )
-                .set( settings );
-            dsl = DSL.using( configuration );
-        }
-
-        @Override
-        public Object invoke( Object o, Method method, Object[] objects )
-            throws Throwable
-        {
-            return method.invoke( dsl, objects );       // delegate all
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreConfiguration.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreConfiguration.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreConfiguration.java
deleted file mode 100644
index 7d27cdf..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreConfiguration.java
+++ /dev/null
@@ -1,73 +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.jooq;
-
-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 JooqEntityStoreConfiguration extends SQLConfiguration
-{
-    /**
-     * Name of the database schema to use.
-     * Ignored on SQL databases that don't support schemas.
-     */
-    @UseDefaults( "POLYGENE" )
-    @Override
-    Property<String> schemaName();
-
-    /**
-     * Name of the entities table.
-     * <p>
-     * This table contains the Identity and other metadata about each entity instance
-     * </p>
-     */
-    @UseDefaults( "ENTITIES" )
-    Property<String> entitiesTableName();
-
-    /**
-     * Name of the entity types table.
-     * <p>
-     * This table contains the metainfo about each type. Types are versioned according to
-     * application version, to support entity migration over time, and therefor there might
-     * be (but not necessarily) multiple tables for entity types that has evolved beyond
-     * what can be managed within a single table.
-     * </p>
-     */
-    @UseDefaults( "TYPES" )
-    Property<String> typesTableName();
-
-    /**
-     * Defines whether the database schema and table should be created if not already present.
-     */
-    @UseDefaults( "true" )
-    Property<Boolean> createIfMissing();
-
-    /**
-     * The SQL dialect that is being used.
-     * <p>
-     * Typically that is matching a supporting dialect in JOOQ.
-     * See {@link org.jooq.SQLDialect} for supported values.
-     * </p>
-     * @return The property with the dialect value.
-     */
-    @UseDefaults( "" )
-    Property<String> dialect();
-}
-// END SNIPPET: config

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreMixin.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreMixin.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreMixin.java
deleted file mode 100644
index 1daa78b..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreMixin.java
+++ /dev/null
@@ -1,256 +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.jooq;
-
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-import org.apache.polygene.api.association.AssociationDescriptor;
-import org.apache.polygene.api.association.AssociationStateDescriptor;
-import org.apache.polygene.api.common.QualifiedName;
-import org.apache.polygene.api.entity.EntityDescriptor;
-import org.apache.polygene.api.entity.EntityReference;
-import org.apache.polygene.api.identity.HasIdentity;
-import org.apache.polygene.api.identity.IdentityGenerator;
-import org.apache.polygene.api.injection.scope.Service;
-import org.apache.polygene.api.injection.scope.This;
-import org.apache.polygene.api.serialization.Serialization;
-import org.apache.polygene.api.structure.ModuleDescriptor;
-import org.apache.polygene.api.usecase.Usecase;
-import org.apache.polygene.spi.entity.EntityState;
-import org.apache.polygene.spi.entity.EntityStatus;
-import org.apache.polygene.spi.entitystore.DefaultEntityStoreUnitOfWork;
-import org.apache.polygene.spi.entitystore.EntityNotFoundException;
-import org.apache.polygene.spi.entitystore.EntityStore;
-import org.apache.polygene.spi.entitystore.EntityStoreSPI;
-import org.apache.polygene.spi.entitystore.EntityStoreUnitOfWork;
-import org.apache.polygene.spi.entitystore.StateCommitter;
-import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
-import org.jooq.Record;
-import org.jooq.Result;
-import org.jooq.SelectQuery;
-
-import static org.apache.polygene.api.entity.EntityReference.parseEntityReference;
-
-public class JooqEntityStoreMixin
-    implements EntityStore, EntityStoreSPI
-{
-    @This
-    private SqlTable sqlTable;
-
-    @Service
-    private IdentityGenerator identityGenerator;
-
-    @Service
-    private Serialization serialization;
-
-    @Override
-    public EntityState newEntityState( EntityStoreUnitOfWork unitOfWork, EntityReference reference, EntityDescriptor entityDescriptor )
-    {
-        return new DefaultEntityState( unitOfWork.currentTime(), reference, entityDescriptor );
-    }
-
-    @Override
-    public EntityState entityStateOf( EntityStoreUnitOfWork unitOfWork, ModuleDescriptor module, EntityReference reference )
-    {
-        BaseEntity baseEntity = sqlTable.fetchBaseEntity( reference, module );
-        SelectQuery<Record> selectQuery = sqlTable.createGetEntityQuery( baseEntity.type, reference );
-        Result<Record> result = selectQuery.fetch();
-        if( result.isEmpty() )
-        {
-            throw new EntityNotFoundException( reference );
-        }
-        return toEntityState( result, baseEntity, reference );
-    }
-
-    protected EntityState toEntityState( Result<Record> result, BaseEntity baseEntity, EntityReference reference )
-    {
-        AssociationStateDescriptor stateDescriptor = baseEntity.type.state();
-        Map<QualifiedName, Object> properties = new HashMap<>();
-        properties.put( HasIdentity.IDENTITY_STATE_NAME, baseEntity.identity );
-        stateDescriptor.properties()
-                       .filter( prop -> !HasIdentity.IDENTITY_STATE_NAME.equals( prop.qualifiedName() ) )
-                       .forEach( prop ->
-                                 {
-                                     QualifiedName qualifiedName = prop.qualifiedName();
-                                     Object value = result.getValue( 0, qualifiedName.name() );
-                                     properties.put( qualifiedName, value );
-                                 } );
-        Map<QualifiedName, EntityReference> assocations = new HashMap<>();
-        stateDescriptor.associations()
-                       .forEach( assoc ->
-                                 {
-                                     QualifiedName qualifiedName = assoc.qualifiedName();
-                                     String value = (String) result.getValue( 0, qualifiedName.name() );
-                                     if( value != null )
-                                     {
-                                         assocations.put( qualifiedName, parseEntityReference( value ) );
-                                     }
-                                 } );
-        Map<QualifiedName, List<EntityReference>> manyAssocs = new HashMap<>();
-        Map<QualifiedName, Map<String, EntityReference>> namedAssocs = new HashMap<>();
-        sqlTable.fetchAssociations( baseEntity, baseEntity.type, associationValue ->
-        {
-            if( stateDescriptor.hasManyAssociation( associationValue.name ) )
-            {
-                addManyAssociation( stateDescriptor, manyAssocs, associationValue );
-            }
-            else if( stateDescriptor.hasNamedAssociation( associationValue.name ) )
-            {
-                addNamedAssociation( stateDescriptor, namedAssocs, associationValue );
-            }
-        } );
-
-        return new DefaultEntityState( baseEntity.version,
-                                       baseEntity.modifedAt,
-                                       reference,
-                                       EntityStatus.LOADED,
-                                       baseEntity.type,
-                                       properties,
-                                       assocations,
-                                       manyAssocs,
-                                       namedAssocs );
-    }
-
-    private void addNamedAssociation( AssociationStateDescriptor stateDescriptor, Map<QualifiedName, Map<String, EntityReference>> namedAssocs, AssociationValue associationValue )
-    {
-        AssociationDescriptor descriptor = stateDescriptor.getNamedAssociationByName( associationValue.name.name() );
-        QualifiedName qualifiedName = descriptor.qualifiedName();
-        Map<String, EntityReference> map = namedAssocs.computeIfAbsent( qualifiedName, k -> new HashMap<>() );
-        map.put( associationValue.position, parseEntityReference( associationValue.reference ) );
-    }
-
-    private void addManyAssociation( AssociationStateDescriptor stateDescriptor, Map<QualifiedName, List<EntityReference>> manyAssocs, AssociationValue associationValue )
-    {
-        AssociationDescriptor descriptor = stateDescriptor.getManyAssociationByName( associationValue.name.name() );
-        QualifiedName qualifiedName = descriptor.qualifiedName();
-        List<EntityReference> list = manyAssocs.computeIfAbsent( qualifiedName, k -> new ArrayList<>() );
-        String reference = associationValue.reference;
-        list.add( reference == null ? null : parseEntityReference( reference ) );
-    }
-
-    @Override
-    public String versionOf( EntityStoreUnitOfWork unitOfWork, EntityReference reference )
-    {
-        BaseEntity baseEntity = sqlTable.fetchBaseEntity( reference, unitOfWork.module() );
-        return baseEntity.version;
-    }
-
-    @Override
-    public StateCommitter applyChanges( EntityStoreUnitOfWork unitOfWork, Iterable<EntityState> state )
-    {
-        return new JooqStateCommitter( unitOfWork, state, sqlTable.jooqDslContext() );
-    }
-
-    @Override
-    public EntityStoreUnitOfWork newUnitOfWork( ModuleDescriptor module, Usecase usecase, Instant currentTime )
-    {
-        return new DefaultEntityStoreUnitOfWork( module,
-                                                 this,
-                                                 identityGenerator.generate( JooqEntityStoreService.class ),
-                                                 usecase,
-                                                 currentTime
-        );
-    }
-
-    @Override
-    public Stream<EntityState> entityStates( ModuleDescriptor module )
-    {
-        Stream<? extends EntityDescriptor> entityTypes = module.entityComposites();
-        return entityTypes
-            .flatMap( type -> sqlTable.fetchAll( type, module ) )
-            .map( baseEntity ->
-                  {
-                      EntityReference reference = EntityReference.entityReferenceFor( baseEntity.identity );
-                      SelectQuery<Record> selectQuery = sqlTable.createGetEntityQuery( baseEntity.type, reference );
-                      Result<Record> result = selectQuery.fetch();
-                      return toEntityState( result, baseEntity, reference );
-                  } );
-    }
-
-    private class JooqStateCommitter
-        implements StateCommitter
-    {
-        private final EntityStoreUnitOfWork unitOfWork;
-        private final Iterable<EntityState> states;
-        private final JooqDslContext dslContext;
-        private final ModuleDescriptor module;
-
-        JooqStateCommitter( EntityStoreUnitOfWork unitOfWork, Iterable<EntityState> states, JooqDslContext dslContext )
-        {
-            this.unitOfWork = unitOfWork;
-            this.states = states;
-            this.dslContext = dslContext;
-            this.module = unitOfWork.module();
-        }
-
-        private void newState( DefaultEntityState state, EntityStoreUnitOfWork unitOfWork )
-        {
-            EntityReference ref = state.entityReference();
-            EntityDescriptor descriptor = state.entityDescriptor();
-            sqlTable.createNewBaseEntity( ref, descriptor, this.unitOfWork );
-            sqlTable.insertEntity( state, sqlTable.fetchBaseEntity( ref, module ), unitOfWork );
-        }
-
-        private void updateState( DefaultEntityState state, EntityStoreUnitOfWork unitOfWork )
-        {
-            EntityDescriptor descriptor = state.entityDescriptor();
-            BaseEntity baseEntity = sqlTable.fetchBaseEntity( state.entityReference(), descriptor.module() );
-            sqlTable.updateEntity( state, baseEntity, unitOfWork );
-        }
-
-        private void removeState( DefaultEntityState state )
-        {
-            EntityReference reference = state.entityReference();
-            EntityDescriptor descriptor = state.entityDescriptor();
-            sqlTable.removeEntity( reference, descriptor );
-        }
-
-        @Override
-        public void commit()
-        {
-            dslContext.transaction( configuration ->
-                                    {
-                                        for( EntityState es : this.states )
-                                        {
-                                            DefaultEntityState state = (DefaultEntityState) es;
-                                            if( state.status() == EntityStatus.NEW )
-                                            {
-                                                newState( state, unitOfWork );
-                                            }
-                                            if( state.status() == EntityStatus.UPDATED )
-                                            {
-                                                updateState( state, unitOfWork );
-                                            }
-                                            if( state.status() == EntityStatus.REMOVED )
-                                            {
-                                                removeState( state );
-                                            }
-                                        }
-                                    } );
-        }
-
-        @Override
-        public void cancel()
-        {
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreService.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreService.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreService.java
deleted file mode 100644
index 511f2f0..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/JooqEntityStoreService.java
+++ /dev/null
@@ -1,36 +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.jooq;
-
-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.spi.entitystore.ConcurrentModificationCheckConcern;
-import org.apache.polygene.spi.entitystore.EntityStateVersions;
-import org.apache.polygene.spi.entitystore.EntityStore;
-import org.apache.polygene.spi.entitystore.StateChangeNotificationConcern;
-
-/**
- * SQL EntityStore service.
- */
-@Concerns( { StateChangeNotificationConcern.class, ConcurrentModificationCheckConcern.class } )
-@Mixins( { JooqEntityStoreMixin.class } )
-public interface JooqEntityStoreService
-    extends EntityStore, EntityStateVersions, Configuration, SqlTable
-{
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/MixinTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/MixinTable.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/MixinTable.java
deleted file mode 100644
index c7b219b..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/MixinTable.java
+++ /dev/null
@@ -1,256 +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.jooq;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Method;
-import java.sql.Timestamp;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import org.apache.polygene.api.association.AssociationDescriptor;
-import org.apache.polygene.api.common.QualifiedName;
-import org.apache.polygene.api.entity.EntityDescriptor;
-import org.apache.polygene.api.entity.EntityReference;
-import org.apache.polygene.api.property.PropertyDescriptor;
-import org.apache.polygene.spi.entity.ManyAssociationState;
-import org.apache.polygene.spi.entity.NamedAssociationState;
-import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
-import org.jooq.Field;
-import org.jooq.InsertSetMoreStep;
-import org.jooq.InsertSetStep;
-import org.jooq.Name;
-import org.jooq.Record;
-import org.jooq.Schema;
-import org.jooq.Table;
-import org.jooq.UpdateSetMoreStep;
-import org.jooq.impl.DSL;
-
-class MixinTable
-    implements TableFields
-{
-
-    private final Table<Record> mixinTable;
-    private final Table<Record> mixinAssocsTable;
-
-    private final JooqDslContext dsl;
-    private final Map<QualifiedName, Field<Object>> properties = new ConcurrentHashMap<>();
-    private final Map<QualifiedName, Field<String>> associations = new ConcurrentHashMap<>();
-    private final List<QualifiedName> manyAssociations = new CopyOnWriteArrayList<>();
-    private final List<QualifiedName> namedAssociations = new CopyOnWriteArrayList<>();
-
-    private TypesTable types;
-    private final Class<?> mixinType;
-
-    MixinTable( JooqDslContext dsl, Schema schema, TypesTable types, Class<?> mixinType,
-                EntityDescriptor descriptor )
-    {
-        this.dsl = dsl;
-        this.types = types;
-        this.mixinType = mixinType;
-        mixinTable = types.tableFor( mixinType, descriptor );
-        mixinAssocsTable = getAssocsTable( descriptor, schema );
-
-        descriptor.valueType().properties()
-                  .filter( this::isThisMixin )
-                  .forEach( propDescriptor ->
-                            {
-                                QualifiedName propertyName = propDescriptor.qualifiedName();
-                                Field<Object> propertyField = types.fieldOf( propDescriptor );
-                                properties.put( propertyName, propertyField );
-                            }
-                          );
-
-        descriptor.valueType().associations()
-                  .filter( this::isThisMixin )
-                  .forEach( assocDescriptor ->
-                            {
-                                QualifiedName assocName = assocDescriptor.qualifiedName();
-                                Field<String> assocField = types.fieldOf( assocDescriptor );
-                                associations.put( assocName, assocField );
-                            }
-                          );
-
-        descriptor.valueType().manyAssociations()
-                  .filter( this::isThisMixin )
-                  .forEach( assocDescriptor -> manyAssociations.add( assocDescriptor.qualifiedName() ) );
-
-        descriptor.valueType().namedAssociations()
-                  .filter( this::isThisMixin )
-                  .forEach( assocDescriptor -> namedAssociations.add( assocDescriptor.qualifiedName() ) );
-    }
-
-    void insertMixinState( DefaultEntityState state, String valueIdentity )
-    {
-        InsertSetMoreStep<Record> primaryTable =
-            dsl.insertInto( mixinTable )
-               .set( identityColumn, valueIdentity )
-               .set( createdColumn, new Timestamp( System.currentTimeMillis() ) );
-
-        properties.forEach( ( propertyName, propertyField ) -> primaryTable.set( propertyField, state.propertyValueOf( propertyName ) ) );
-        associations.forEach( ( assocName, assocField ) ->
-                              {
-                                  EntityReference reference = state.associationValueOf( assocName );
-                                  String identity = null;
-                                  if( reference != null )
-                                  {
-                                      identity = reference.identity().toString();
-                                  }
-                                  primaryTable.set( assocField, identity );
-                              }
-                            );
-        int result = primaryTable.execute();
-
-        if( mixinAssocsTable != null )
-        {
-            insertManyAndNamedAssociations( state, valueIdentity );
-        }
-    }
-
-    private void insertManyAndNamedAssociations( DefaultEntityState state, String valueIdentity )
-    {
-        manyAssociations.forEach( assocName ->
-                                  {
-                                      InsertSetStep<Record> assocsTable = dsl.insertInto( mixinAssocsTable );
-                                      ManyAssociationState entityReferences = state.manyAssociationValueOf( assocName );
-                                      int endCount = entityReferences.count();
-                                      int counter = 0;
-                                      for( EntityReference ref : entityReferences )
-                                      {
-                                          InsertSetMoreStep<Record> set = assocsTable.set( identityColumn, valueIdentity )
-                                                                                     .set( nameColumn, assocName.name() )
-                                                                                     .set( indexColumn, "" + counter++ )
-                                                                                     .set( referenceColumn, ref == null ? null : ref.identity().toString() );
-                                          if( ++counter < endCount )
-                                          {
-                                              set.newRecord();
-                                          }
-                                      }
-                                      InsertSetMoreStep<Record> assocs = assocsTable.set( Collections.emptyMap() );
-                                      assocs.execute();
-                                  } );
-
-        namedAssociations.forEach( assocName ->
-                                   {
-                                       InsertSetStep<Record> assocsTable = dsl.insertInto( mixinAssocsTable );
-                                       NamedAssociationState entityReferences = state.namedAssociationValueOf( assocName );
-                                       int count = entityReferences.count();
-                                       for( String name : entityReferences )
-                                       {
-                                           EntityReference ref = entityReferences.get( name );
-                                           InsertSetMoreStep<Record> set = assocsTable.set( identityColumn, valueIdentity )
-                                                                                      .set( nameColumn, assocName.name() )
-                                                                                      .set( indexColumn, name )
-                                                                                      .set( referenceColumn, ref.identity().toString() );
-                                           if( --count > 0 )
-                                           {
-                                               set.newRecord();
-                                           }
-                                       }
-                                       InsertSetMoreStep<Record> assocs = assocsTable.set( Collections.emptyMap() );
-                                       assocs.execute();
-                                   } );
-    }
-
-    Table<Record> associationsTable()
-    {
-        return mixinAssocsTable;
-    }
-
-    private boolean isThisMixin( PropertyDescriptor descriptor )
-    {
-        Class<?> declaringClass = declaredIn( descriptor );
-        return mixinType.equals( declaringClass );
-    }
-
-    private boolean isThisMixin( AssociationDescriptor descriptor )
-    {
-        Class<?> declaringClass = declaredIn( descriptor );
-        return mixinType.equals( declaringClass );
-    }
-
-    private Class<?> declaredIn( PropertyDescriptor descriptor )
-    {
-        AccessibleObject accessor = descriptor.accessor();
-        if( accessor instanceof Method )
-        {
-            return ( (Method) accessor ).getDeclaringClass();
-        }
-        throw new UnsupportedOperationException( "Property declared as " + accessor.getClass() + " is not supported in this Entity Store yet." );
-    }
-
-    private Class<?> declaredIn( AssociationDescriptor descriptor )
-    {
-        AccessibleObject accessor = descriptor.accessor();
-        if( accessor instanceof Method )
-        {
-            return ( (Method) accessor ).getDeclaringClass();
-        }
-        throw new UnsupportedOperationException( "Property declared as " + accessor.getClass() + " is not supported in this Entity Store yet." );
-    }
-
-    void modifyMixinState( DefaultEntityState state, String valueId )
-    {
-        UpdateSetMoreStep<Record> primaryTable =
-            dsl.update( mixinTable )
-               .set( Collections.emptyMap() );  // empty map is a hack to get the right type returned from JOOQ.
-
-        properties.forEach( ( propertyName, propertyField ) -> primaryTable.set( propertyField, state.propertyValueOf( propertyName ) ) );
-        associations.forEach( ( assocName, assocField ) ->
-                              {
-                                  EntityReference reference = state.associationValueOf( assocName );
-                                  primaryTable.set( assocField,
-                                                    reference == null ? null : reference.identity().toString()
-                                                  );
-                              }
-                            );
-        int result = primaryTable.execute();
-
-        if( mixinAssocsTable != null )
-        {
-            // Need to remove existing records.
-            dsl.delete( mixinAssocsTable )
-               .where( identityColumn.eq( valueId ) )
-               .execute();
-            insertManyAndNamedAssociations( state, valueId );
-        }
-    }
-
-    private Table<Record> getAssocsTable( EntityDescriptor descriptor, Schema schema )
-    {
-        if( descriptor.state().manyAssociations().count() > 0
-            || descriptor.state().namedAssociations().count() > 0 )
-        {
-            Name tableName = DSL.name( schema.getName(), mixinTable.getName() + ASSOCS_TABLE_POSTFIX );
-            Table<Record> table = DSL.table( tableName );
-            int result2 = dsl.createTableIfNotExists( table )
-                             .column( identityColumn )
-                             .column( nameColumn )
-                             .column( indexColumn )
-                             .column( referenceColumn )
-                             .execute();
-            return table;
-        }
-        else
-        {
-            return null;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/SqlTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/SqlTable.java b/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/SqlTable.java
deleted file mode 100644
index 13b6c37..0000000
--- a/extensions/entitystore-jooq/src/main/java/org/apache/polygene/entitystore/jooq/SqlTable.java
+++ /dev/null
@@ -1,277 +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.jooq;
-
-import java.util.function.Consumer;
-import java.util.stream.Stream;
-import javax.sql.DataSource;
-import org.apache.polygene.api.PolygeneAPI;
-import org.apache.polygene.api.composite.TransientBuilderFactory;
-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.Structure;
-import org.apache.polygene.api.injection.scope.This;
-import org.apache.polygene.api.injection.scope.Uses;
-import org.apache.polygene.api.mixin.Mixins;
-import org.apache.polygene.api.object.ObjectFactory;
-import org.apache.polygene.api.service.ServiceActivation;
-import org.apache.polygene.api.service.ServiceDescriptor;
-import org.apache.polygene.api.structure.Application;
-import org.apache.polygene.api.structure.ModuleDescriptor;
-import org.apache.polygene.spi.entitystore.EntityStoreUnitOfWork;
-import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
-import org.jooq.Record;
-import org.jooq.SQLDialect;
-import org.jooq.Schema;
-import org.jooq.SelectQuery;
-import org.jooq.conf.RenderNameStyle;
-import org.jooq.conf.Settings;
-import org.jooq.impl.DSL;
-
-/**
- * This class handles all the Jooq interactions.
- * <p>
- * <p>
- * <p>
- * <h1>Tables</h1>
- * <h2>Types Table</h2>
- * <ul>
- * <li>identity</li>
- * <li>table_name</li>
- * <li>created_at</li>
- * <li>modified_at</li>
- * </ul>
- * <h2>Entities Table</h2>
- * <ul>
- * <li>identity</li>
- * <li>app_version</li>
- * <li>value_id</li>
- * <li>version</li>
- * <li>type</li>
- * <li>modified_at</li>
- * <li>created_at</li>
- * </ul>
- * <h2>Mixin Tables</h2>
- * <p>
- * Each Mixin is stored in its own table. Only the following column is always present;
- * <ul>
- * <li>identity - this is not entity identity but the UUID of the value_id in the Entities Table above.</li>
- * </ul>
- * </p>
- * <p>
- * Each Property of the Mixin (as defined by QualifiedName of the Property, will reside in its own column.
- * All values in columns are (for now) serialized using a ValueSerialization service.
- * </p>
- * <p>
- * Associations also has their own columns in the table, with the EntityReference.identity() stored in them.
- * </p>
- * <p>
- * ManyAssociations and NamedAssociations are stored in a separate table, named &lt;mixintable&gt;_ASSOCS, see below.
- * </p>
- * <h2>Mixin_ASSOCS Table</h2>
- * <ul>
- * <li>identity - the value_id of the mixin value</li>
- * <li>name - the name of the ManyAssociation or NamedAssociation</li>
- * <li>position - for NamedAssociation this is the 'name' (i.e key) and for ManyAssociation this is the index into the list.</li>
- * <li>reference - EntityReference.identity of that association</li>
- * </ul>
- */
-@Mixins( SqlTable.Mixin.class )
-public interface SqlTable extends ServiceActivation
-{
-    BaseEntity fetchBaseEntity( EntityReference reference, ModuleDescriptor module );
-
-    SelectQuery<Record> createGetEntityQuery( EntityDescriptor descriptor, EntityReference reference );
-
-    void fetchAssociations( BaseEntity entity, EntityDescriptor descriptor, Consumer<AssociationValue> consume );
-
-    void createNewBaseEntity( EntityReference ref, EntityDescriptor descriptor, EntityStoreUnitOfWork unitOfWork );
-
-    void insertEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork );
-
-    void updateEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork );
-
-    JooqDslContext jooqDslContext();
-
-    void removeEntity( EntityReference entityReference, EntityDescriptor descriptor );
-
-    Stream<BaseEntity> fetchAll( EntityDescriptor type, ModuleDescriptor module );
-
-    class Mixin
-        implements SqlTable, TableFields, ServiceActivation
-    {
-        @Structure
-        private Application application;
-
-        @Structure
-        private PolygeneAPI api;
-
-        @Structure
-        private TransientBuilderFactory tbf;
-
-        @Structure
-        private ObjectFactory objectFactory;
-
-        @This
-        private Configuration<JooqEntityStoreConfiguration> configuration;
-
-        @Service
-        private DataSource datasource;
-
-        @Uses
-        private ServiceDescriptor serviceDescriptor;
-
-        private EntitiesTable entitiesTable;
-
-        private TypesTable types;
-        private JooqDslContext dsl;
-
-        @Override
-        public BaseEntity fetchBaseEntity( EntityReference reference, ModuleDescriptor module )
-        {
-            return entitiesTable.fetchEntity( reference, module );
-        }
-
-        @Override
-        public Stream<BaseEntity> fetchAll( EntityDescriptor type, ModuleDescriptor module )
-        {
-            return entitiesTable.fetchAll( type, module );
-        }
-
-        @Override
-        public SelectQuery<Record> createGetEntityQuery( EntityDescriptor descriptor, EntityReference reference )
-        {
-            return entitiesTable.createGetEntityQuery( descriptor, reference );
-        }
-
-        @Override
-        public void fetchAssociations( BaseEntity entity, EntityDescriptor descriptor, Consumer<AssociationValue> consume )
-        {
-            entitiesTable.fetchAssociations( entity, descriptor, consume );
-        }
-
-        @Override
-        public void createNewBaseEntity( EntityReference ref, EntityDescriptor descriptor, EntityStoreUnitOfWork unitOfWork )
-        {
-            entitiesTable.createNewBaseEntity( ref, descriptor, unitOfWork );
-        }
-
-        @Override
-        public void insertEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork )
-        {
-            entitiesTable.insertEntity( state, baseEntity );
-        }
-
-        @Override
-        public void updateEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork )
-        {
-            entitiesTable.modifyEntity( state, baseEntity, unitOfWork );
-        }
-
-        @Override
-        public JooqDslContext jooqDslContext()
-        {
-            return dsl;
-        }
-
-        @Override
-        public void removeEntity( EntityReference reference, EntityDescriptor descriptor )
-        {
-            entitiesTable.removeEntity( reference, descriptor );
-        }
-
-        @Override
-        public void activateService()
-            throws Exception
-        {
-            JooqEntityStoreConfiguration config = this.configuration.get();
-            SQLDialect dialect = getSqlDialect( config );
-
-            Settings settings = serviceDescriptor
-                .metaInfo( Settings.class )
-                .withRenderNameStyle( RenderNameStyle.QUOTED );
-            dsl = tbf.newTransient( JooqDslContext.class, settings, dialect );
-
-            String schemaName = config.schemaName().get();
-            String typesTableName = config.typesTableName().get();
-            String entitiesTableName = config.entitiesTableName().get();
-            Schema schema = DSL.schema( DSL.name( schemaName ) );
-            types = new TypesTable( dsl, schema, dialect, typesTableName );
-            entitiesTable = new EntitiesTable( dsl, schema, types, application.version(), entitiesTableName );
-
-            // Eventually create schema
-            if( config.createIfMissing().get() )
-            {
-                if( !dialect.equals( SQLDialect.SQLITE )
-                    && dsl.meta().getSchemas().stream().noneMatch( s -> schema.getName().equalsIgnoreCase( s.getName() ) ) )
-                {
-                    dsl.createSchema( schema ).execute();
-                }
-
-                dsl.createTableIfNotExists( DSL.name( schemaName, typesTableName ) )
-                   .column( identityColumn )
-                   .column( tableNameColumn )
-                   .column( createdColumn )
-                   .column( modifiedColumn )
-                   .execute();
-
-                dsl.createTableIfNotExists( DSL.name( schemaName, entitiesTableName ) )
-                   .column( identityColumn )
-                   .column( applicationVersionColumn )
-                   .column( valueIdentityColumn )
-                   .column( versionColumn )
-                   .column( typeNameColumn )
-                   .column( modifiedColumn )
-                   .column( createdColumn )
-                   .execute();
-            }
-            datasource.getConnection().commit();
-        }
-
-        @Override
-        public void passivateService()
-            throws Exception
-        {
-
-        }
-
-        private SQLDialect getSqlDialect( JooqEntityStoreConfiguration config )
-        {
-            SQLDialect dialect = null;
-            String dialectString = config.dialect().get();
-            if( dialectString.length() == 0 )
-            {
-                dialect = SQLDialect.DEFAULT;
-            }
-            else
-            {
-                try
-                {
-                    dialect = SQLDialect.valueOf( dialectString );
-                }
-                catch( IllegalArgumentException e )
-                {
-                    throw new IllegalArgumentException( "Invalid SQLDialect: '" + dialectString + "'" );
-                }
-            }
-            return dialect;
-        }
-    }
-}


[10/15] polygene-java git commit: Introducing the whole test suite from entitystore-sqlkv and starting to solidify the implementation against all these SQL systems.

Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/tools/generator-polygene/app/index.js
----------------------------------------------------------------------
diff --git a/tools/generator-polygene/app/index.js b/tools/generator-polygene/app/index.js
index 9d220a7..565f455 100644
--- a/tools/generator-polygene/app/index.js
+++ b/tools/generator-polygene/app/index.js
@@ -112,6 +112,7 @@ module.exports = generators.Base.extend(
                                 'JClouds',
                                 'Jdbm',
                                 'LevelDB',
+                                'MariaDbSQL',
                                 'Memory',
                                 'MongoDB',
                                 'MySQL',

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/bootstrap.tmpl
----------------------------------------------------------------------
diff --git a/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/bootstrap.tmpl b/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/bootstrap.tmpl
index 8a990c8..95f1e1e 100644
--- a/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/bootstrap.tmpl
+++ b/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/bootstrap.tmpl
@@ -34,7 +34,7 @@ import org.apache.polygene.entitystore.<%- polygene.entitystoremodule %>.<%- pol
 }
 if( polygene.entitystore.indexOf('SQL') >= 0 ) {
 %>
-import org.apache.polygene.entitystore.sql.SQLEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sql.SqlEntityStoreConfiguration;
 <%
 }
 %>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/storage/ds-es-mariadb.properties
----------------------------------------------------------------------
diff --git a/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/storage/ds-es-mariadb.properties b/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/storage/ds-es-mariadb.properties
new file mode 100644
index 0000000..c1fd527
--- /dev/null
+++ b/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/storage/ds-es-mariadb.properties
@@ -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.
+#
+#
+#
+enabled=true
+url=jdbc:mysql://127.0.0.1:3306/<%= polygene.name %>?profileSQL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true
+driver=com.mysql.cj.jdbc.Driver
+username=polygene
+password=ThisIsGreat!

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/storage/ds-es-sqlite.properties
----------------------------------------------------------------------
diff --git a/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/storage/ds-es-sqlite.properties b/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/storage/ds-es-sqlite.properties
index 5c49ece..bebe32b 100644
--- a/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/storage/ds-es-sqlite.properties
+++ b/tools/generator-polygene/app/templates/InfrastructureLayer/StorageModule/storage/ds-es-sqlite.properties
@@ -18,7 +18,7 @@
 #
 #
 enabled=true
-url=jdbc:sqlite:sqlite-entities/
+url=jdbc:sqlite:sqlite-entities.db
 driver=org.sqlite.JDBC
 username=polygene
 password=ThisIsGreat

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/tools/generator-polygene/app/templates/RestAPIApplication/bootstrap-test.tmpl
----------------------------------------------------------------------
diff --git a/tools/generator-polygene/app/templates/RestAPIApplication/bootstrap-test.tmpl b/tools/generator-polygene/app/templates/RestAPIApplication/bootstrap-test.tmpl
index 1e50b00..7a0174e 100644
--- a/tools/generator-polygene/app/templates/RestAPIApplication/bootstrap-test.tmpl
+++ b/tools/generator-polygene/app/templates/RestAPIApplication/bootstrap-test.tmpl
@@ -43,7 +43,7 @@ if( polygene.entitystore !== 'Memory' && polygene.entitystore !== 'Preferences'
     if( polygene.entitystore.indexOf('SQL') < 0 ) {
 %>import org.apache.polygene.entitystore.<%= polygene.entitystore.toLowerCase() %>.<%= polygene.entitystore %>EntityStoreConfiguration;
 <% } else {
-%>import org.apache.polygene.entitystore.sql.SQLEntityStoreConfiguration;
+%>import org.apache.polygene.entitystore.sql.SqlEntityStoreConfiguration;
 <%
     }
 }


[12/15] polygene-java git commit: Introducing the whole test suite from entitystore-sqlkv and starting to solidify the implementation against all these SQL systems.

Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/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
deleted file mode 100644
index 19658ea..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreConfiguration.java
+++ /dev/null
@@ -1,47 +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.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/0f8f0b8d/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
deleted file mode 100644
index 293ce58..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreMixin.java
+++ /dev/null
@@ -1,244 +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 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/0f8f0b8d/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
deleted file mode 100644
index 9e4e0e7..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/SQLEntityStoreService.java
+++ /dev/null
@@ -1,43 +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.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/0f8f0b8d/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
deleted file mode 100644
index 24e8ec5..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
+++ /dev/null
@@ -1,98 +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.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/0f8f0b8d/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
deleted file mode 100644
index 4e88d01..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/DerbySQLEntityStoreAssembler.java
+++ /dev/null
@@ -1,35 +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.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/0f8f0b8d/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
deleted file mode 100644
index 928e660..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/H2SQLEntityStoreAssembler.java
+++ /dev/null
@@ -1,35 +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.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/0f8f0b8d/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
deleted file mode 100644
index dec7be5..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/MySQLEntityStoreAssembler.java
+++ /dev/null
@@ -1,35 +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.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/0f8f0b8d/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
deleted file mode 100644
index 8e3e31f..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/PostgreSQLEntityStoreAssembler.java
+++ /dev/null
@@ -1,35 +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.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/0f8f0b8d/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
deleted file mode 100644
index 1477c6b..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLEntityStoreAssembler.java
+++ /dev/null
@@ -1,28 +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.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/0f8f0b8d/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
deleted file mode 100644
index 2615316..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLiteEntityStoreAssembler.java
+++ /dev/null
@@ -1,35 +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.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/0f8f0b8d/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
deleted file mode 100644
index a93cf6f..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/assembly/package.html
+++ /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.
-  ~
-  ~
-  -->
-<html>
-    <body>
-        <h2>SQL EntityStore Assembly.</h2>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/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
deleted file mode 100644
index a90af3e..0000000
--- a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sql/package.html
+++ /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.
-  ~
-  ~
-  -->
-<html>
-    <body>
-        <h2>SQL EntityStore.</h2>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/SQLEntityStoreConfiguration.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/SQLEntityStoreConfiguration.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/SQLEntityStoreConfiguration.java
new file mode 100644
index 0000000..e5e3510
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv;
+
+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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/SQLEntityStoreMixin.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/SQLEntityStoreMixin.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/SQLEntityStoreMixin.java
new file mode 100644
index 0000000..f3c4b93
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv;
+
+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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/SQLEntityStoreService.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/SQLEntityStoreService.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/SQLEntityStoreService.java
new file mode 100644
index 0000000..e31f01f
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv;
+
+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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/AbstractSQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/AbstractSQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/AbstractSQLEntityStoreAssembler.java
new file mode 100644
index 0000000..c2f7eb2
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv.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.sqlkv.SQLEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/DerbySQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/DerbySQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/DerbySQLEntityStoreAssembler.java
new file mode 100644
index 0000000..9110b80
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/H2SQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/H2SQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/H2SQLEntityStoreAssembler.java
new file mode 100644
index 0000000..b046de6
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/MySQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/MySQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/MySQLEntityStoreAssembler.java
new file mode 100644
index 0000000..2e48adb
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/PostgreSQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/PostgreSQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/PostgreSQLEntityStoreAssembler.java
new file mode 100644
index 0000000..cadd0e1
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/SQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/SQLEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/SQLEntityStoreAssembler.java
new file mode 100644
index 0000000..04f8465
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/SQLiteEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/SQLiteEntityStoreAssembler.java b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/SQLiteEntityStoreAssembler.java
new file mode 100644
index 0000000..5bc71bf
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/package.html
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/package.html b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/assembly/package.html
new file mode 100644
index 0000000..a93cf6f
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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/0f8f0b8d/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/package.html
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/package.html b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/package.html
new file mode 100644
index 0000000..a90af3e
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/main/java/org/apache/polygene/entitystore/sqlkv/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/0f8f0b8d/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
deleted file mode 100644
index 4bd1578..0000000
--- a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
+++ /dev/null
@@ -1,101 +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 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/0f8f0b8d/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
deleted file mode 100644
index 7fbfb2a..0000000
--- a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java
+++ /dev/null
@@ -1,94 +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 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/0f8f0b8d/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
deleted file mode 100644
index 4b4b759..0000000
--- a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
+++ /dev/null
@@ -1,67 +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.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/0f8f0b8d/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
deleted file mode 100644
index f763238..0000000
--- a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java
+++ /dev/null
@@ -1,56 +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.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 );
-    }
-}


[14/15] polygene-java git commit: There seems to be permission problems.

Posted by ni...@apache.org.
There seems to be permission problems.


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/58d19ab4
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/58d19ab4
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/58d19ab4

Branch: refs/heads/es-sql
Commit: 58d19ab46fff7d710ac12ade0a17da97f3af5d2b
Parents: 0f8f0b8
Author: niclas <ni...@hedhman.org>
Authored: Sun Sep 10 21:00:43 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Sun Sep 10 21:00:43 2017 +0800

----------------------------------------------------------------------
 .../polygene/entitystore/sql/SqlTable.java      | 52 ++++++++++----------
 .../sql/PostgreSQLEntityStoreTest.java          | 24 +++++++--
 .../resources/postgresql-datasource.properties  |  2 -
 3 files changed, 46 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/58d19ab4/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
index a2fc658..c553532 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
@@ -211,31 +211,33 @@ public interface SqlTable extends ServiceActivation
             // Eventually create schema
             if( config.createIfMissing().get() )
             {
-                if( !dialect.equals( SQLDialect.SQLITE )
-                    && dsl.meta().getSchemas().stream().noneMatch( s -> schema.getName().equalsIgnoreCase( s.getName() ) ) )
-                {
-                    dsl.createSchema( schemaName ).execute();
-                    datasource.getConnection().commit();
-                }
-
-                dsl.createTableIfNotExists( DSL.name( schemaName, typesTableName ) )
-                   .column( identityColumn )
-                   .column( tableNameColumn )
-                   .column( createdColumn )
-                   .column( modifiedColumn )
-                   .execute();
-                datasource.getConnection().commit();
-
-                dsl.createTableIfNotExists( DSL.name( schemaName, entitiesTableName ) )
-                   .column( identityColumn )
-                   .column( applicationVersionColumn )
-                   .column( valueIdentityColumn )
-                   .column( versionColumn )
-                   .column( typeNameColumn )
-                   .column( modifiedColumn )
-                   .column( createdColumn )
-                   .execute();
-                datasource.getConnection().commit();
+                dsl.transaction( t -> {
+                    if( !dialect.equals( SQLDialect.SQLITE )
+                        && dsl.meta().getSchemas().stream().noneMatch( s -> schema.getName().equalsIgnoreCase( s.getName() ) ) )
+                    {
+                        dsl.createSchema( schemaName ).execute();
+                    }
+                } );
+
+                dsl.transaction( t -> {
+
+                    dsl.createTableIfNotExists( DSL.name( schemaName, typesTableName ) )
+                       .column( identityColumn )
+                       .column( tableNameColumn )
+                       .column( createdColumn )
+                       .column( modifiedColumn )
+                       .execute();
+
+                    dsl.createTableIfNotExists( DSL.name( schemaName, entitiesTableName ) )
+                       .column( identityColumn )
+                       .column( applicationVersionColumn )
+                       .column( valueIdentityColumn )
+                       .column( versionColumn )
+                       .column( typeNameColumn )
+                       .column( modifiedColumn )
+                       .column( createdColumn )
+                       .execute();
+                } );
             }
         }
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/58d19ab4/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
index d193728..1122c71 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
@@ -21,6 +21,8 @@ package org.apache.polygene.entitystore.sql;
 
 import java.sql.Connection;
 import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
 import javax.sql.DataSource;
 import org.apache.polygene.api.common.Visibility;
 import org.apache.polygene.api.unitofwork.UnitOfWork;
@@ -43,9 +45,19 @@ public class PostgreSQLEntityStoreTest
     extends AbstractEntityStoreTest
 {
     @ClassRule
-    public static final DockerRule DOCKER = new DockerRule( "postgres",
-                                                            3000L,
-                                                            "PostgreSQL init process complete; ready for start up." );
+    public static final DockerRule DOCKER;
+
+    static
+    {
+        Map<String,String> environment = new HashMap<>();
+        environment.put( "POSTGRES_USER", System.getProperty( "user.name" ));
+        environment.put( "POSTGRES_PASSWORD", "ThisIsGreat!");
+
+        DOCKER = new DockerRule( "postgres",
+                                 environment,
+                                 3000L,
+                                 "PostgreSQL init process complete; ready for start up." );
+    }
 
     @Override
     // START SNIPPET: assembly
@@ -81,8 +93,10 @@ public class PostgreSQLEntityStoreTest
         // END SNIPPET: assembly
         String host = DOCKER.getDockerHost();
         int port = DOCKER.getExposedContainerPort( "5432/tcp" );
-        config.forMixin( DataSourceConfiguration.class ).declareDefaults()
-              .url().set( "jdbc:postgresql://" + host + ":" + port + "/jdbc_test_db" );
+        DataSourceConfiguration defaults = config.forMixin( DataSourceConfiguration.class ).declareDefaults();
+        defaults.url().set( "jdbc:postgresql://" + host + ":" + port + "/jdbc_test_db" );
+        defaults.username().set( System.getProperty( "user.name" ) );
+        defaults.password().set( "ThisIsGreat!" );
         // START SNIPPET: assembly
     }
     // END SNIPPET: assembly

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/58d19ab4/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
index bdda284..f47d5d3 100644
--- a/extensions/entitystore-sql/src/test/resources/postgresql-datasource.properties
+++ b/extensions/entitystore-sql/src/test/resources/postgresql-datasource.properties
@@ -20,5 +20,3 @@
 
 enabled=true
 driver=org.postgresql.Driver
-username=jdbc_test_login
-password=password


[03/15] polygene-java git commit: Found a weird case that cause NPE incorrectly.

Posted by ni...@apache.org.
Found a weird case that cause NPE incorrectly.


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/96f07132
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/96f07132
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/96f07132

Branch: refs/heads/es-sql
Commit: 96f0713214da32fb7d7c7299c6d983a2e5b73fb6
Parents: 4da1885
Author: niclas <ni...@hedhman.org>
Authored: Mon Sep 4 10:24:42 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Mon Sep 4 10:24:42 2017 +0800

----------------------------------------------------------------------
 .../org/apache/polygene/runtime/composite/MixinsModel.java     | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/96f07132/core/runtime/src/main/java/org/apache/polygene/runtime/composite/MixinsModel.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/composite/MixinsModel.java b/core/runtime/src/main/java/org/apache/polygene/runtime/composite/MixinsModel.java
index 35efb9d..a998b9e 100644
--- a/core/runtime/src/main/java/org/apache/polygene/runtime/composite/MixinsModel.java
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/composite/MixinsModel.java
@@ -228,7 +228,11 @@ public class MixinsModel
                     if( !Modifier.isStatic( method.getModifiers() ) )
                     {
                         MixinModel used = methodImplementation.get( method );
-                        usedMixinClasses.add( used );
+                        if( used != null )
+                        {
+                            // TODO: Should we actually throw an Exception, since this means that a method implementation is missing??
+                            usedMixinClasses.add( used );
+                        }
                     }
                 }
             }


[15/15] polygene-java git commit: Pushing for Tibor to assist.

Posted by ni...@apache.org.
Pushing for Tibor to assist.


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/3cca3c60
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/3cca3c60
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/3cca3c60

Branch: refs/heads/es-sql
Commit: 3cca3c6054cd2b3749f3a5830c9b8f58b5a42741
Parents: 58d19ab
Author: niclas <ni...@hedhman.org>
Authored: Mon Sep 18 23:19:02 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Mon Sep 18 23:19:02 2017 +0800

----------------------------------------------------------------------
 .../test/entity/AbstractEntityStoreTest.java    |  1 +
 .../polygene/entitystore/sql/EntitiesTable.java | 11 ++---
 .../entitystore/sql/JooqDslContext.java         | 38 +++++++++++++++--
 .../polygene/entitystore/sql/MixinTable.java    | 12 ++----
 .../entitystore/sql/SqlEntityStoreMixin.java    |  1 +
 .../polygene/entitystore/sql/SqlTable.java      | 16 +++----
 .../polygene/entitystore/sql/TypesTable.java    | 22 +++-------
 .../AbstractSQLEntityStoreAssembler.java        |  9 +++-
 .../sql/DerbySQLEntityStoreTest.java            | 23 +++-------
 .../sql/DerbySQLEntityStoreTestSuite.java       | 25 ++---------
 .../entitystore/sql/H2SQLEntityStoreTest.java   | 12 ++++++
 .../sql/H2SQLEntityStoreTestSuite.java          | 13 ++++++
 .../entitystore/sql/MySQLEntityStoreTest.java   | 25 +++--------
 .../sql/MySQLEntityStoreTestSuite.java          | 23 ++--------
 .../sql/PostgreSQLEntityStoreTest.java          | 27 ++++--------
 .../sql/PostgreSQLEntityStoreTestSuite.java     | 27 ++----------
 .../entitystore/sql/SQLiteEntityStoreTest.java  | 11 +++++
 .../sql/SQLiteEntityStoreTestSuite.java         | 12 ++++++
 .../polygene/entitystore/sql/TearDownUtil.java  | 44 ++++++++++++++++++++
 .../src/test/resources/logback.xml              |  1 +
 20 files changed, 186 insertions(+), 167 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java b/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java
index 2812c4e..a349309 100644
--- a/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java
@@ -55,6 +55,7 @@ import org.apache.polygene.spi.entity.EntityState;
 import org.apache.polygene.spi.entitystore.EntityStore;
 import org.apache.polygene.test.AbstractPolygeneTest;
 import org.junit.After;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import static java.time.ZoneOffset.UTC;

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
index 257ca02..0bd9227 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
@@ -52,7 +52,6 @@ import org.jooq.Field;
 import org.jooq.Record;
 import org.jooq.RecordType;
 import org.jooq.Result;
-import org.jooq.Schema;
 import org.jooq.SelectJoinStep;
 import org.jooq.SelectQuery;
 import org.jooq.Table;
@@ -70,17 +69,15 @@ public class EntitiesTable
     private final Table<Record> entitiesTable;
     private JooqDslContext dsl;
     private final TypesTable types;
-    private final Schema schema;
     private String applicationVersion;
     private boolean replacementStrategy = false;  // Figure out later if we should support both and if so, how.
 
-    EntitiesTable( JooqDslContext dsl, Schema schema, TypesTable types, String applicationVersion, String entitiesTableName )
+    EntitiesTable( JooqDslContext dsl, TypesTable types, String applicationVersion, String entitiesTableName )
     {
         this.dsl = dsl;
         this.types = types;
-        this.schema = schema;
         this.applicationVersion = applicationVersion;
-        entitiesTable = types.tableOf( entitiesTableName );
+        entitiesTable = dsl.tableOf( entitiesTableName );
     }
 
     public BaseEntity fetchEntity( EntityReference reference, ModuleDescriptor module )
@@ -165,7 +162,7 @@ public class EntitiesTable
 
     private MixinTable findMixinTable( Class<?> type, EntityDescriptor entityDescriptor )
     {
-        return mixinTablesCache.computeIfAbsent( type, t -> new MixinTable( dsl, schema, types, type, entityDescriptor ) );
+        return mixinTablesCache.computeIfAbsent( type, t -> new MixinTable( dsl, types, type, entityDescriptor ) );
     }
 
     private Set<Class<?>> mixinsOf( Stream<? extends AssociationDescriptor> stream )
@@ -222,7 +219,7 @@ public class EntitiesTable
         baseEntity.version = "1";
         baseEntity.applicationVersion = applicationVersion;
         baseEntity.identity = reference.identity();
-        baseEntity.currentValueIdentity = null;
+        baseEntity.currentValueIdentity = StringIdentity.identityOf( UUID.randomUUID().toString() );
         baseEntity.modifedAt = currentTime;
         baseEntity.createdAt = currentTime;
         return baseEntity;

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/JooqDslContext.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/JooqDslContext.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/JooqDslContext.java
index d89c058..be2f66b 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/JooqDslContext.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/JooqDslContext.java
@@ -25,7 +25,11 @@ import org.apache.polygene.api.injection.scope.Uses;
 import org.apache.polygene.api.mixin.Mixins;
 import org.jooq.Configuration;
 import org.jooq.DSLContext;
+import org.jooq.Name;
+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;
 import org.jooq.impl.DefaultConfiguration;
@@ -33,14 +37,19 @@ import org.jooq.impl.DefaultConfiguration;
 @Mixins( JooqDslContext.Mixin.class )
 public interface JooqDslContext extends DSLContext
 {
+    boolean isSchemaCapable();
+    Name tableNameOf( String tableName );
+    Table<Record> tableOf( String tableName );
 
     class Mixin
         implements InvocationHandler
     {
-        private DSLContext dsl;
+        private final Schema schema;
+        private final DSLContext dsl;
 
-        public Mixin( @Service DataSource dataSource, @Uses Settings settings, @Uses SQLDialect dialect )
+        public Mixin( @Service DataSource dataSource, @Uses Settings settings, @Uses SQLDialect dialect, @Uses Schema schema )
         {
+            this.schema = schema;
             Configuration configuration = new DefaultConfiguration()
                 .set( dataSource )
                 .set( dialect )
@@ -49,10 +58,31 @@ public interface JooqDslContext extends DSLContext
         }
 
         @Override
-        public Object invoke( Object o, Method method, Object[] objects )
+        public Object invoke( Object o, Method method, Object[] args )
             throws Throwable
         {
-            return method.invoke( dsl, objects );       // delegate all
+            if(method.getName().equals( "tableOf" )){
+                return DSL.table(tableNameOf( (String) args[0] ) );
+            }
+            if(method.getName().equals( "tableNameOf" )){
+                return tableNameOf( (String) args[ 0 ] );
+            }
+
+            if(method.getName().equals( "isSchemaCapable" ))
+            {
+                return isSchemaCapable();
+            }
+            return method.invoke( dsl, args );       // delegate all
+        }
+
+        private Name tableNameOf( String name )
+        {
+            return this.isSchemaCapable() ? DSL.name( schema.getName(), name ) : DSL.name( name );
+        }
+
+        private boolean isSchemaCapable()
+        {
+            return !dsl.dialect().equals( SQLDialect.SQLITE ) && !dsl.dialect().equals( SQLDialect.MYSQL );
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/MixinTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/MixinTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/MixinTable.java
index 80c26a2..9ddfe0e 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/MixinTable.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/MixinTable.java
@@ -36,12 +36,9 @@ import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
 import org.jooq.Field;
 import org.jooq.InsertSetMoreStep;
 import org.jooq.InsertSetStep;
-import org.jooq.Name;
 import org.jooq.Record;
-import org.jooq.Schema;
 import org.jooq.Table;
 import org.jooq.UpdateSetMoreStep;
-import org.jooq.impl.DSL;
 
 class MixinTable
     implements TableFields
@@ -59,14 +56,14 @@ class MixinTable
     private TypesTable types;
     private final Class<?> mixinType;
 
-    MixinTable( JooqDslContext dsl, Schema schema, TypesTable types, Class<?> mixinType,
+    MixinTable( JooqDslContext dsl, TypesTable types, Class<?> mixinType,
                 EntityDescriptor descriptor )
     {
         this.dsl = dsl;
         this.types = types;
         this.mixinType = mixinType;
         mixinTable = types.tableFor( mixinType, descriptor );
-        mixinAssocsTable = getAssocsTable( descriptor, schema );
+        mixinAssocsTable = getAssocsTable( descriptor );
 
         descriptor.valueType().properties()
                   .filter( this::isThisMixin )
@@ -233,13 +230,12 @@ class MixinTable
         }
     }
 
-    private Table<Record> getAssocsTable( EntityDescriptor descriptor, Schema schema )
+    private Table<Record> getAssocsTable( EntityDescriptor descriptor )
     {
         if( descriptor.state().manyAssociations().count() > 0
             || descriptor.state().namedAssociations().count() > 0 )
         {
-            Name tableName = DSL.name( schema.getName(), mixinTable.getName() + ASSOCS_TABLE_POSTFIX );
-            Table<Record> table = DSL.table( tableName );
+            Table<Record> table = dsl.tableOf( mixinTable.getName() + ASSOCS_TABLE_POSTFIX );
             int result2 = dsl.createTableIfNotExists( table )
                              .column( identityColumn )
                              .column( nameColumn )

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
index 4fd7d3c..e881636 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
@@ -356,6 +356,7 @@ public class SqlEntityStoreMixin
                                                 removeState( state );
                                             }
                                         }
+
                                     } );
         }
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
index c553532..9b2f7c6 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
@@ -195,24 +195,24 @@ public interface SqlTable extends ServiceActivation
         {
             SqlEntityStoreConfiguration config = this.configuration.get();
             SQLDialect dialect = getSqlDialect( config );
-
             Settings settings = serviceDescriptor
                 .metaInfo( Settings.class )
                 .withRenderNameStyle( RenderNameStyle.QUOTED );
-            dsl = tbf.newTransient( JooqDslContext.class, settings, dialect );
 
             String schemaName = config.schemaName().get();
             String typesTableName = config.typesTableName().get();
             String entitiesTableName = config.entitiesTableName().get();
             Schema schema = DSL.schema( DSL.name( schemaName ) );
-            types = new TypesTable( dsl, schema, dialect, typesTableName );
-            entitiesTable = new EntitiesTable( dsl, schema, types, application.version(), entitiesTableName );
 
-            // Eventually create schema
+            dsl = tbf.newTransient( JooqDslContext.class, settings, dialect, schema );
+
+            types = new TypesTable( dsl, dialect, typesTableName );
+            entitiesTable = new EntitiesTable( dsl, types, application.version(), entitiesTableName );
+
             if( config.createIfMissing().get() )
             {
                 dsl.transaction( t -> {
-                    if( !dialect.equals( SQLDialect.SQLITE )
+                    if( dsl.isSchemaCapable()
                         && dsl.meta().getSchemas().stream().noneMatch( s -> schema.getName().equalsIgnoreCase( s.getName() ) ) )
                     {
                         dsl.createSchema( schemaName ).execute();
@@ -221,14 +221,14 @@ public interface SqlTable extends ServiceActivation
 
                 dsl.transaction( t -> {
 
-                    dsl.createTableIfNotExists( DSL.name( schemaName, typesTableName ) )
+                    dsl.createTableIfNotExists( dsl.tableNameOf( typesTableName ) )
                        .column( identityColumn )
                        .column( tableNameColumn )
                        .column( createdColumn )
                        .column( modifiedColumn )
                        .execute();
 
-                    dsl.createTableIfNotExists( DSL.name( schemaName, entitiesTableName ) )
+                    dsl.createTableIfNotExists( dsl.tableNameOf( entitiesTableName ) )
                        .column( identityColumn )
                        .column( applicationVersionColumn )
                        .column( valueIdentityColumn )

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TypesTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TypesTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TypesTable.java
index d04bc95..4c4b6ea 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TypesTable.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TypesTable.java
@@ -34,9 +34,9 @@ import org.jooq.Field;
 import org.jooq.Record;
 import org.jooq.Result;
 import org.jooq.SQLDialect;
-import org.jooq.Schema;
 import org.jooq.Table;
 import org.jooq.impl.DSL;
+import org.jooq.impl.DefaultDataType;
 
 public class TypesTable
     implements TableFields
@@ -46,18 +46,16 @@ public class TypesTable
 
     private final Table<Record> typesTable;
     private final SQLDialect dialect;
-    private final Schema schema;
 
     private final JooqDslContext dsl;
 
-    TypesTable( JooqDslContext dsl, Schema schema,
+    TypesTable( JooqDslContext dsl,
                 SQLDialect dialect,
                 String typesTablesName
               )
     {
-        this.schema = schema;
         this.dialect = dialect;
-        typesTable = tableOf( typesTablesName );
+        typesTable = dsl.tableOf( typesTablesName );
         this.dsl = dsl;
     }
 
@@ -66,14 +64,6 @@ public class TypesTable
         return DSL.field( DSL.name( columnName ), type );
     }
 
-    Table<Record> tableOf( String tableName )
-    {
-        return DSL.table(
-            dialect.equals( SQLDialect.SQLITE )
-            ? DSL.name( tableName )
-            : DSL.name( schema.getName(), tableName ) );
-    }
-
     String tableNameOf( Class<?> mixinType )
     {
         Result<Record> typeInfo = fetchTypeInfoFromTable( mixinType );
@@ -92,9 +82,9 @@ public class TypesTable
             if( tableName == null )
             {
                 Result<Record> newMixinTable = createNewMixinTable( type, descriptor );
-                return tableOf( newMixinTable.getValue( 0, tableNameColumn ) );
+                return dsl.tableOf( newMixinTable.getValue( 0, tableNameColumn ) );
             }
-            return tableOf( tableName );
+            return dsl.tableOf( tableName );
         } );
     }
 
@@ -110,7 +100,7 @@ public class TypesTable
     {
         String mixinTypeName = mixinType.getName();
         String tableName = createNewTableName( mixinType );
-        CreateTableColumnStep primaryTable = dsl.createTable( DSL.name( schema.getName(), tableName ) )
+        CreateTableColumnStep primaryTable = dsl.createTable( dsl.tableOf( tableName ) )
                                                 .column( identityColumn )
                                                 .column( createdColumn );
         descriptor.state().properties().forEach(

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
index c9258ec..8e9273a 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
@@ -28,6 +28,7 @@ import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.entitystore.sql.JooqDslContext;
 import org.apache.polygene.entitystore.sql.SqlEntityStoreConfiguration;
 import org.apache.polygene.entitystore.sql.SqlEntityStoreService;
+import org.jooq.SQLDialect;
 import org.jooq.conf.RenderNameStyle;
 import org.jooq.conf.Settings;
 
@@ -60,14 +61,18 @@ public abstract class AbstractSQLEntityStoreAssembler<T extends AbstractSQLEntit
 
         if( hasConfig() )
         {
-            configModule().entities( SqlEntityStoreConfiguration.class ).visibleIn( configVisibility() );
+            configModule().configurations( SqlEntityStoreConfiguration.class ).visibleIn( configVisibility() );
+            SqlEntityStoreConfiguration defaults = configModule().forMixin( SqlEntityStoreConfiguration.class )
+                                                                 .declareDefaults();
+            defaults.dialect().set( getSQLDialect().toString() );
         }
         super.assemble( module );
     }
 
+    protected abstract SQLDialect getSQLDialect();
+
     protected Settings getSettings()
     {
         return new Settings().withRenderNameStyle( RenderNameStyle.QUOTED );
     }
-
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
index 512c43e..5d7fc3d 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
@@ -23,6 +23,7 @@ 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.usecase.UsecaseBuilder;
 import org.apache.polygene.bootstrap.AssemblyException;
@@ -33,6 +34,7 @@ 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.Ignore;
 
 import static org.apache.polygene.api.usecase.UsecaseBuilder.newUsecase;
 
@@ -77,23 +79,8 @@ public class DerbySQLEntityStoreTest
     public void tearDown()
         throws Exception
     {
-        UnitOfWork uow = this.unitOfWorkFactory.newUnitOfWork( newUsecase("Delete " + getClass().getSimpleName() + " test data" ) );
-        try
-        {
-            SqlEntityStoreConfiguration config = uow.get( SqlEntityStoreConfiguration.class,
-                                                          AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
-            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
-            connection.setAutoCommit( false );
-            try( Statement stmt = connection.createStatement() )
-            {
-                stmt.execute( String.format( "DROP DATABASE FROM %s", config.schemaName().get() ) );
-                connection.commit();
-            }
-        }
-        finally
-        {
-            uow.discard();
-            super.tearDown();
-        }
+        Module storageModule = application.findModule( "Infrastructure Layer", "Storage Module" );
+        TearDownUtil.cleanupSQL( storageModule, getClass().getSimpleName() );
+        super.tearDown();
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java
index cdfcd54..a6fa218 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java
@@ -34,6 +34,7 @@ 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 org.junit.Ignore;
 
 import static org.apache.polygene.entitystore.sql.assembly.DerbySQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
 
@@ -69,26 +70,8 @@ public class DerbySQLEntityStoreTestSuite extends EntityStoreTestSuite
     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,
-                                                          AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
-            Connection connection = storageModule.serviceFinder().findService( DataSource.class ).get().getConnection();
-            connection.setAutoCommit( false );
-            try( Statement stmt = connection.createStatement() )
-            {
-                stmt.execute( String.format( "DROP DATABASE FROM %s", config.schemaName().get() ) );
-                connection.commit();
-            }
-        }
-        finally
-        {
-            uow.discard();
-            super.tearDown();
-        }
+        Module storageModule = application.findModule( "Infrastructure Layer", "Storage Module" );
+        TearDownUtil.cleanupSQL( storageModule, getClass().getSimpleName() );
+        super.tearDown();
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
index 4b4b759..2b997c8 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
@@ -20,6 +20,7 @@
 package org.apache.polygene.entitystore.sql;
 
 import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.structure.Module;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.entitystore.sql.assembly.H2SQLEntityStoreAssembler;
@@ -27,6 +28,8 @@ 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.After;
+import org.junit.Ignore;
 
 public class H2SQLEntityStoreTest
     extends AbstractEntityStoreTest
@@ -64,4 +67,13 @@ public class H2SQLEntityStoreTest
             .assemble( module );
     }
     // END SNIPPET: assembly
+
+    @After
+    public void tearDown()
+        throws Exception
+    {
+        Module storageModule = application.findModule( "Infrastructure Layer", "Storage Module" );
+        TearDownUtil.cleanupSQL( storageModule, getClass().getSimpleName() );
+        super.tearDown();
+    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java
index f763238..32dfcb2 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java
@@ -20,11 +20,14 @@
 package org.apache.polygene.entitystore.sql;
 
 import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.structure.Module;
 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;
+import org.junit.After;
+import org.junit.Ignore;
 
 public class H2SQLEntityStoreTestSuite extends EntityStoreTestSuite
 {
@@ -53,4 +56,14 @@ public class H2SQLEntityStoreTestSuite extends EntityStoreTestSuite
             .withConfig( configModule, Visibility.application )
             .assemble( module );
     }
+
+    @After
+    public void tearDown()
+        throws Exception
+    {
+        Module storageModule = application.findModule( "Infrastructure Layer", "Storage Module" );
+        TearDownUtil.cleanupSQL( storageModule, getClass().getSimpleName() );
+        super.tearDown();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
index fe8da9c..dd9759b 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
@@ -24,6 +24,7 @@ import java.sql.Statement;
 import java.util.HashMap;
 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.usecase.UsecaseBuilder;
 import org.apache.polygene.bootstrap.AssemblyException;
@@ -37,6 +38,7 @@ 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 org.junit.Ignore;
 
 public class MySQLEntityStoreTest
     extends AbstractEntityStoreTest
@@ -101,25 +103,8 @@ public class MySQLEntityStoreTest
     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 config = uow.get( SqlEntityStoreConfiguration.class,
-                                                          AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
-            connection.setAutoCommit( false );
-            try( Statement stmt = connection.createStatement() )
-            {
-                stmt.execute( String.format( "DROP DATABASE FROM %s", config.schemaName().get() ) );
-                connection.commit();
-            }
-        }
-        finally
-        {
-            uow.discard();
-            super.tearDown();
-        }
+        Module storageModule = application.findModule( "Infrastructure Layer", "Storage Module" );
+        TearDownUtil.cleanupSQL( storageModule, getClass().getSimpleName() );
+        super.tearDown();
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
index f625317..c3d2919 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
@@ -37,6 +37,7 @@ 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 org.junit.Ignore;
 
 import static org.apache.polygene.api.usecase.UsecaseBuilder.newUsecase;
 
@@ -94,25 +95,7 @@ public class MySQLEntityStoreTestSuite extends EntityStoreTestSuite
         throws Exception
     {
         Module storageModule = application.findModule( "Infrastructure Layer", "Storage Module" );
-        UnitOfWorkFactory uowf = storageModule.unitOfWorkFactory();
-        ServiceFinder serviceFinder = storageModule.serviceFinder();
-        UnitOfWork uow = uowf.newUnitOfWork( newUsecase( "Delete " + getClass().getSimpleName() + " test data" ) );
-        try
-        {
-            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
-            SqlEntityStoreConfiguration config = uow.get( SqlEntityStoreConfiguration.class,
-                                                          AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
-            connection.setAutoCommit( false );
-            try( Statement stmt = connection.createStatement() )
-            {
-                stmt.execute( String.format( "DROP DATABASE FROM %s", config.schemaName().get() ) );
-                connection.commit();
-            }
-        }
-        finally
-        {
-            uow.discard();
-            super.tearDown();
-        }
+        TearDownUtil.cleanupSQL( storageModule, getClass().getSimpleName() );
+        super.tearDown();
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
index 1122c71..d7ef07c 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
@@ -25,6 +25,7 @@ import java.util.HashMap;
 import java.util.Map;
 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.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
@@ -91,12 +92,16 @@ public class PostgreSQLEntityStoreTest
             .withConfig( config, Visibility.layer )
             .assemble( module );
         // END SNIPPET: assembly
+
+
         String host = DOCKER.getDockerHost();
         int port = DOCKER.getExposedContainerPort( "5432/tcp" );
+
         DataSourceConfiguration defaults = config.forMixin( DataSourceConfiguration.class ).declareDefaults();
         defaults.url().set( "jdbc:postgresql://" + host + ":" + port + "/jdbc_test_db" );
         defaults.username().set( System.getProperty( "user.name" ) );
         defaults.password().set( "ThisIsGreat!" );
+
         // START SNIPPET: assembly
     }
     // END SNIPPET: assembly
@@ -105,24 +110,8 @@ public class PostgreSQLEntityStoreTest
     public void tearDown()
         throws Exception
     {
-        String usecaseName = "Delete " + getClass().getSimpleName() + " test data";
-        UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( newUsecase( usecaseName ) );
-        try
-        {
-            SQLConfiguration config = uow.get( SQLConfiguration.class, AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
-            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
-            connection.setAutoCommit( false );
-            String schemaName = config.schemaName().get();
-            try( Statement stmt = connection.createStatement() )
-            {
-                stmt.execute( String.format( "DROP SCHEMA \"%s\" CASCADE", schemaName ) );
-                connection.commit();
-            }
-        }
-        finally
-        {
-            uow.discard();
-            super.tearDown();
-        }
+        Module storageModule = application.findModule( "Infrastructure Layer", "Storage Module" );
+        TearDownUtil.cleanupSQL( storageModule, getClass().getSimpleName() );
+        super.tearDown();
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java
index d53c7d1..d35fce0 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java
@@ -27,7 +27,6 @@ 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.AbstractSQLEntityStoreAssembler;
 import org.apache.polygene.entitystore.sql.assembly.PostgreSQLEntityStoreAssembler;
@@ -39,7 +38,7 @@ 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.PostgreSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
+import static org.apache.polygene.api.usecase.UsecaseBuilder.newUsecase;
 
 public class PostgreSQLEntityStoreTestSuite extends EntityStoreTestSuite
 {
@@ -86,27 +85,7 @@ public class PostgreSQLEntityStoreTestSuite extends EntityStoreTestSuite
         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
-        {
-            SQLConfiguration config = uow.get( SQLConfiguration.class, AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
-            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
-            connection.setAutoCommit( false );
-            String schemaName = config.schemaName().get();
-            try( Statement stmt = connection.createStatement() )
-            {
-                stmt.execute( String.format( "DROP SCHEMA \"%s\" CASCADE", schemaName ) );
-                connection.commit();
-            }
-        }
-        finally
-        {
-            uow.discard();
-            super.tearDown();
-        }
+        TearDownUtil.cleanupSQL(storageModule, getClass().getSimpleName());
+        super.tearDown();
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/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
index 83e8a21..14a52a0 100644
--- 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
@@ -20,6 +20,7 @@
 package org.apache.polygene.entitystore.sql;
 
 import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.structure.Module;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.entitystore.sql.assembly.SQLiteEntityStoreAssembler;
@@ -27,6 +28,7 @@ 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.After;
 import org.junit.BeforeClass;
 
 import static org.apache.polygene.test.util.Assume.assumeNoIbmJdk;
@@ -72,4 +74,13 @@ public class SQLiteEntityStoreTest extends AbstractEntityStoreTest
             .assemble( module );
     }
     // END SNIPPET: assembly
+
+    @After
+    public void tearDown()
+        throws Exception
+    {
+        Module storageModule = application.findModule( "Infrastructure Layer", "Storage Module" );
+        TearDownUtil.cleanupSQL( storageModule, getClass().getSimpleName() );
+        super.tearDown();
+    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/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
index 6dc5fbe..678309b 100644
--- 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
@@ -20,11 +20,13 @@
 package org.apache.polygene.entitystore.sql;
 
 import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.structure.Module;
 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.After;
 import org.junit.BeforeClass;
 
 import static org.apache.polygene.test.util.Assume.assumeNoIbmJdk;
@@ -62,4 +64,14 @@ public class SQLiteEntityStoreTestSuite extends EntityStoreTestSuite
             .withConfig( configModule, Visibility.application )
             .assemble( module );
     }
+
+    @After
+    public void tearDown()
+        throws Exception
+    {
+        Module storageModule = application.findModule( "Infrastructure Layer", "Storage Module" );
+        TearDownUtil.cleanupSQL( storageModule, getClass().getSimpleName() );
+        super.tearDown();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/TearDownUtil.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/TearDownUtil.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/TearDownUtil.java
new file mode 100644
index 0000000..31a15d5
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/TearDownUtil.java
@@ -0,0 +1,44 @@
+package org.apache.polygene.entitystore.sql;
+
+import java.sql.Connection;
+import java.sql.Statement;
+import javax.sql.DataSource;
+import org.apache.polygene.api.service.ServiceFinder;
+import org.apache.polygene.api.structure.Application;
+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.entitystore.sql.assembly.AbstractSQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.common.SQLConfiguration;
+
+import static org.apache.polygene.api.usecase.UsecaseBuilder.newUsecase;
+
+public class TearDownUtil
+{
+
+    public static void cleanupSQL( Module storageModule, String testName )
+        throws Exception
+    {
+        String usecaseName = "Delete " + testName + " test data";
+        UnitOfWorkFactory uowf = storageModule.unitOfWorkFactory();
+        ServiceFinder serviceFinder = storageModule.serviceFinder();
+        UnitOfWork uow = uowf.newUnitOfWork( newUsecase( usecaseName ) );
+        try
+        {
+            SQLConfiguration config = uow.get( SQLConfiguration.class, AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
+            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
+            connection.setAutoCommit( false );
+            String schemaName = config.schemaName().get();
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DROP SCHEMA \"%s\" CASCADE", schemaName ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/3cca3c60/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
index 03fb4dd..0ca004d 100644
--- a/extensions/entitystore-sql/src/test/resources/logback.xml
+++ b/extensions/entitystore-sql/src/test/resources/logback.xml
@@ -30,6 +30,7 @@
         <appender-ref ref="stdout" />
     </root>
 
+    <logger name="org.jooq" level="debug"/>
     <logger name="org.apache.polygene.entitystore.sql" level="debug"/>
 
 </configuration>
\ No newline at end of file


[02/15] polygene-java git commit: Merge remote-tracking branch 'origin/develop' into develop

Posted by ni...@apache.org.
Merge remote-tracking branch 'origin/develop' into develop


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/4da18850
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/4da18850
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/4da18850

Branch: refs/heads/es-sql
Commit: 4da1885063915c33c9ea571fcf44991eca475bc2
Parents: 815c77b 824c37c
Author: niclas <ni...@hedhman.org>
Authored: Sat Jul 29 16:01:57 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Sat Jul 29 16:01:57 2017 +0800

----------------------------------------------------------------------
 dependencies.gradle                             |   2 +-
 .../entitystore-sqlkv/src/docs/es-sqlkv.txt     |   3 +
 extensions/indexing-sql/src/docs/index-sql.txt  |   3 +
 gradle/wrapper/gradle-wrapper.jar               | Bin 54712 -> 54712 bytes
 gradle/wrapper/gradle-wrapper.properties        |   2 +-
 libraries/sql/src/docs/sql.txt                  |   3 +
 .../docs/tutorials/howto-releasing-apache.txt   |   7 +-
 manual/src/docs/website/samples.txt             |  31 ++++
 samples/sql-support/build.gradle                |  46 ++++++
 .../sample/sqlsupport/AppAssembler.java         | 111 +++++++++++++
 .../apache/polygene/sample/sqlsupport/Main.java | 160 +++++++++++++++++++
 .../sample/sqlsupport/PretextEntity.java        |  29 ++++
 .../resources/entitystore-postgresql.properties |  22 +++
 .../src/main/resources/indexing-sql.properties  |  22 +++
 .../postgresql-es-datasource.properties         |  25 +++
 .../postgresql-index-datasource.properties      |  25 +++
 settings.gradle                                 |   1 +
 17 files changed, 488 insertions(+), 4 deletions(-)
----------------------------------------------------------------------



[13/15] polygene-java git commit: Introducing the whole test suite from entitystore-sqlkv and starting to solidify the implementation against all these SQL systems.

Posted by ni...@apache.org.
Introducing the whole test suite from entitystore-sqlkv and starting to solidify the implementation against all these SQL systems.


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/0f8f0b8d
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/0f8f0b8d
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/0f8f0b8d

Branch: refs/heads/es-sql
Commit: 0f8f0b8d9677c37a136cd4b3e050107d09e4c483
Parents: ff9c272
Author: niclas <ni...@hedhman.org>
Authored: Sun Sep 10 20:22:00 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Sun Sep 10 20:22:00 2017 +0800

----------------------------------------------------------------------
 extensions/entitystore-sql/build.gradle         |   2 +-
 .../polygene/entitystore/sql/EntitiesTable.java |  48 +++-
 .../entitystore/sql/SqlEntityStoreMixin.java    |   4 +-
 .../polygene/entitystore/sql/SqlTable.java      |  14 +-
 .../AbstractSQLEntityStoreAssembler.java        |  73 ++++++
 .../assembly/DerbySQLEntityStoreAssembler.java  |  12 +
 .../sql/assembly/H2SQLEntityStoreAssembler.java |  12 +
 .../MariaDbSQLEntityStoreAssembler.java         |  12 +
 .../sql/assembly/MySQLEntityStoreAssembler.java |  12 +
 .../PostgreSQLEntityStoreAssembler.java         |  12 +
 .../sql/assembly/SQLEntityStoreAssembler.java   |   9 +
 .../assembly/SQLiteEntityStoreAssembler.java    |  12 +
 .../sql/assembly/SqlEntityStoreAssembler.java   |  78 ------
 .../sql/DerbySQLEntityStoreTest.java            |  99 ++++++++
 .../sql/DerbySQLEntityStoreTestSuite.java       |  94 +++++++
 .../entitystore/sql/H2SQLEntityStoreTest.java   |  67 +++++
 .../sql/H2SQLEntityStoreTestSuite.java          |  56 +++++
 .../entitystore/sql/MySQLEntityStoreTest.java   | 125 ++++++++++
 .../sql/MySQLEntityStoreTestSuite.java          | 118 +++++++++
 .../sql/PostgreSQLEntityStoreTest.java          | 114 +++++++++
 .../sql/PostgreSQLEntityStoreTestSuite.java     | 112 +++++++++
 .../entitystore/sql/SQLiteEntityStoreTest.java  |  75 ++++++
 .../sql/SQLiteEntityStoreTestSuite.java         |  65 +++++
 .../entitystore/sql/SqlEntityStoreTest.java     |   7 +-
 .../test/resources/derby-datasource.properties  |  25 ++
 .../src/test/resources/h2-datasource.properties |  25 ++
 .../src/test/resources/logback.xml              |  35 +++
 .../test/resources/mysql-datasource.properties  |  25 ++
 .../resources/postgresql-datasource.properties  |  24 ++
 .../test/resources/sqlite-datasource.properties |  25 ++
 .../sql/SQLEntityStoreConfiguration.java        |  47 ----
 .../entitystore/sql/SQLEntityStoreMixin.java    | 244 -------------------
 .../entitystore/sql/SQLEntityStoreService.java  |  43 ----
 .../AbstractSQLEntityStoreAssembler.java        |  98 --------
 .../assembly/DerbySQLEntityStoreAssembler.java  |  35 ---
 .../sql/assembly/H2SQLEntityStoreAssembler.java |  35 ---
 .../sql/assembly/MySQLEntityStoreAssembler.java |  35 ---
 .../PostgreSQLEntityStoreAssembler.java         |  35 ---
 .../sql/assembly/SQLEntityStoreAssembler.java   |  28 ---
 .../assembly/SQLiteEntityStoreAssembler.java    |  35 ---
 .../entitystore/sql/assembly/package.html       |  24 --
 .../polygene/entitystore/sql/package.html       |  24 --
 .../sqlkv/SQLEntityStoreConfiguration.java      |  47 ++++
 .../entitystore/sqlkv/SQLEntityStoreMixin.java  | 244 +++++++++++++++++++
 .../sqlkv/SQLEntityStoreService.java            |  43 ++++
 .../AbstractSQLEntityStoreAssembler.java        |  98 ++++++++
 .../assembly/DerbySQLEntityStoreAssembler.java  |  35 +++
 .../assembly/H2SQLEntityStoreAssembler.java     |  35 +++
 .../assembly/MySQLEntityStoreAssembler.java     |  35 +++
 .../PostgreSQLEntityStoreAssembler.java         |  35 +++
 .../sqlkv/assembly/SQLEntityStoreAssembler.java |  28 +++
 .../assembly/SQLiteEntityStoreAssembler.java    |  35 +++
 .../entitystore/sqlkv/assembly/package.html     |  24 ++
 .../polygene/entitystore/sqlkv/package.html     |  24 ++
 .../sql/DerbySQLEntityStoreTest.java            | 101 --------
 .../sql/DerbySQLEntityStoreTestSuite.java       |  94 -------
 .../entitystore/sql/H2SQLEntityStoreTest.java   |  67 -----
 .../sql/H2SQLEntityStoreTestSuite.java          |  56 -----
 .../entitystore/sql/MySQLEntityStoreTest.java   | 127 ----------
 .../sql/MySQLEntityStoreTestSuite.java          | 122 ----------
 .../sql/PostgreSQLEntityStoreTest.java          | 115 ---------
 .../sql/PostgreSQLEntityStoreTestSuite.java     | 111 ---------
 .../entitystore/sql/SQLiteEntityStoreTest.java  |  75 ------
 .../sql/SQLiteEntityStoreTestSuite.java         |  65 -----
 .../sqlkv/DerbySQLEntityStoreTest.java          | 102 ++++++++
 .../sqlkv/DerbySQLEntityStoreTestSuite.java     |  95 ++++++++
 .../entitystore/sqlkv/H2SQLEntityStoreTest.java |  67 +++++
 .../sqlkv/H2SQLEntityStoreTestSuite.java        |  56 +++++
 .../entitystore/sqlkv/MySQLEntityStoreTest.java | 128 ++++++++++
 .../sqlkv/MySQLEntityStoreTestSuite.java        | 123 ++++++++++
 .../sqlkv/PostgreSQLEntityStoreTest.java        | 115 +++++++++
 .../sqlkv/PostgreSQLEntityStoreTestSuite.java   | 111 +++++++++
 .../sqlkv/SQLiteEntityStoreTest.java            |  75 ++++++
 .../sqlkv/SQLiteEntityStoreTestSuite.java       |  65 +++++
 .../sql/dbcp/DBCPDataSourceServiceImporter.java |  51 ++--
 .../DataSourceConfigurationState.java           |   2 +
 .../DataSourceServiceImporterActivation.java    |   3 -
 .../sample/sqlsupport/AppAssembler.java         |   2 +-
 .../apache/polygene/sample/sqlsupport/Main.java |   2 +-
 .../sql/DerbySQLEntityStorePerformanceTest.java |   6 +-
 .../PostgreSQLEntityStorePerformanceTest.java   |   4 +-
 tools/generator-polygene/app/index.js           |   1 +
 .../StorageModule/bootstrap.tmpl                |   2 +-
 .../storage/ds-es-mariadb.properties            |  24 ++
 .../storage/ds-es-sqlite.properties             |   2 +-
 .../RestAPIApplication/bootstrap-test.tmpl      |   2 +-
 86 files changed, 2976 insertions(+), 1752 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/build.gradle
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/build.gradle b/extensions/entitystore-sql/build.gradle
index 32ceb70..8eb353f 100644
--- a/extensions/entitystore-sql/build.gradle
+++ b/extensions/entitystore-sql/build.gradle
@@ -34,10 +34,10 @@ dependencies {
   testImplementation polygene.internals.testsupport
   testImplementation polygene.library( 'sql-dbcp' )
   testImplementation libraries.docker_junit
+  testImplementation libraries.h2
 
   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/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
index d25e7fc..257ca02 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java
@@ -22,6 +22,7 @@ import java.sql.Timestamp;
 import java.time.Instant;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
@@ -49,6 +50,7 @@ import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
 import org.jooq.Condition;
 import org.jooq.Field;
 import org.jooq.Record;
+import org.jooq.RecordType;
 import org.jooq.Result;
 import org.jooq.Schema;
 import org.jooq.SelectJoinStep;
@@ -83,7 +85,6 @@ public class EntitiesTable
 
     public BaseEntity fetchEntity( EntityReference reference, ModuleDescriptor module )
     {
-
         Result<Record> baseEntityResult = dsl
             .selectFrom( entitiesTable )
             .where( identityColumn.eq( reference.identity().toString() ) )
@@ -128,7 +129,7 @@ public class EntitiesTable
         }
         catch( ClassNotFoundException e )
         {
-            throw new NoSuchEntityTypeException( typeName, module);
+            throw new NoSuchEntityTypeException( typeName, module );
         }
     }
 
@@ -202,18 +203,29 @@ public class EntitiesTable
         };
     }
 
-    void createNewBaseEntity( EntityReference reference, EntityDescriptor descriptor, EntityStoreUnitOfWork uow )
+    BaseEntity createNewBaseEntity( EntityReference reference, EntityDescriptor descriptor, EntityStoreUnitOfWork uow )
     {
         String valueIdentity = UUID.randomUUID().toString();
+        String typeName = descriptor.primaryType().getName();
+        Instant currentTime = uow.currentTime();
         dsl.insertInto( entitiesTable )
            .set( identityColumn, reference.identity().toString() )
-           .set( createdColumn, new Timestamp( uow.currentTime().toEpochMilli() ) )
-           .set( modifiedColumn, new Timestamp( uow.currentTime().toEpochMilli() ) )
+           .set( createdColumn, new Timestamp( currentTime.toEpochMilli() ))
+           .set( modifiedColumn, new Timestamp( currentTime.toEpochMilli()) )
            .set( valueIdentityColumn, valueIdentity )
-           .set( typeNameColumn, descriptor.primaryType().getName() )
+           .set( typeNameColumn, typeName )
            .set( versionColumn, "1" )
            .set( applicationVersionColumn, applicationVersion )
            .execute();
+        BaseEntity baseEntity = new BaseEntity();
+        baseEntity.type = descriptor;
+        baseEntity.version = "1";
+        baseEntity.applicationVersion = applicationVersion;
+        baseEntity.identity = reference.identity();
+        baseEntity.currentValueIdentity = null;
+        baseEntity.modifedAt = currentTime;
+        baseEntity.createdAt = currentTime;
+        return baseEntity;
     }
 
     private void updateBaseEntity( BaseEntity entity, EntityStoreUnitOfWork uow )
@@ -301,19 +313,34 @@ public class EntitiesTable
         String reference = entity.identity.toString();
         SelectQuery<Record> query = from.where( identityColumnOf( entitiesTable ).eq( reference ) ).getQuery();
         Result<Record> result = query.fetch();
+        RecordType<Record> recordType = result.recordType();
         result.forEach( record ->
                         {
                             AssociationValue value = new AssociationValue();
-                            value.name = QualifiedName.fromClass( entityDescriptor.primaryType(), record.getValue( nameColumn ) );
-                            value.position = record.getValue( indexColumn );
-                            value.reference = record.getValue( referenceColumn );
+                            if( recordType.indexOf( referenceColumn ) >= 0 )
+                            {
+                                // some many-to-many association found.
+                                if( recordType.indexOf( nameColumn ) >= 0 )
+                                {
+                                    // NamedAssociations found.
+                                    value.name = QualifiedName.fromClass( entityDescriptor.primaryType(), record.getValue( nameColumn ) );
+                                }
+                                if( recordType.indexOf( indexColumn ) >= 0 )
+                                {
+                                    // ManyAssociations found.
+                                    value.position = record.getValue( indexColumn );
+                                }
+                                value.reference = record.getValue( referenceColumn );
+                            }
                             consume.accept( value );
                         } );
     }
 
     private Field<String> identityColumnOf( Table<Record> joinedTable )
     {
-        return DSL.field( DSL.name( joinedTable.getName(), identityColumn.getName() ), String.class );
+        String name = joinedTable.getName();
+        String identity = identityColumn.getName();
+        return DSL.field( DSL.name( name, identity ), String.class );
     }
 
     public List<Table<Record>> getMixinTables( EntityDescriptor entityDescriptor )
@@ -334,6 +361,7 @@ public class EntitiesTable
             .filter( NOT_HASIDENTITY )
             .map( type -> findMixinTable( type, entityDescriptor ) )
             .map( MixinTable::associationsTable )
+            .filter( Objects::nonNull )
             .collect( Collectors.toList() );
     }
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
index 5f17fd4..4fd7d3c 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlEntityStoreMixin.java
@@ -317,8 +317,8 @@ public class SqlEntityStoreMixin
         {
             EntityReference ref = state.entityReference();
             EntityDescriptor descriptor = state.entityDescriptor();
-            sqlTable.createNewBaseEntity( ref, descriptor, this.unitOfWork );
-            sqlTable.insertEntity( state, sqlTable.fetchBaseEntity( ref, module ), unitOfWork );
+            BaseEntity baseEntity = sqlTable.createNewBaseEntity( ref, descriptor, this.unitOfWork );
+            sqlTable.insertEntity( state, baseEntity, unitOfWork );
         }
 
         private void updateState( DefaultEntityState state, EntityStoreUnitOfWork unitOfWork )

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
index 6537782..a2fc658 100644
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
@@ -20,7 +20,6 @@ package org.apache.polygene.entitystore.sql;
 import java.util.function.Consumer;
 import java.util.stream.Stream;
 import javax.sql.DataSource;
-import org.apache.polygene.api.PolygeneAPI;
 import org.apache.polygene.api.composite.TransientBuilderFactory;
 import org.apache.polygene.api.configuration.Configuration;
 import org.apache.polygene.api.entity.EntityDescriptor;
@@ -30,7 +29,6 @@ import org.apache.polygene.api.injection.scope.Structure;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
 import org.apache.polygene.api.mixin.Mixins;
-import org.apache.polygene.api.object.ObjectFactory;
 import org.apache.polygene.api.service.ServiceActivation;
 import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.api.structure.Application;
@@ -102,7 +100,7 @@ public interface SqlTable extends ServiceActivation
 
     void fetchAssociations( BaseEntity entity, EntityDescriptor descriptor, Consumer<AssociationValue> consume );
 
-    void createNewBaseEntity( EntityReference ref, EntityDescriptor descriptor, EntityStoreUnitOfWork unitOfWork );
+    BaseEntity createNewBaseEntity( EntityReference ref, EntityDescriptor descriptor, EntityStoreUnitOfWork unitOfWork );
 
     void insertEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork );
 
@@ -162,9 +160,9 @@ public interface SqlTable extends ServiceActivation
         }
 
         @Override
-        public void createNewBaseEntity( EntityReference ref, EntityDescriptor descriptor, EntityStoreUnitOfWork unitOfWork )
+        public BaseEntity createNewBaseEntity( EntityReference ref, EntityDescriptor descriptor, EntityStoreUnitOfWork unitOfWork )
         {
-            entitiesTable.createNewBaseEntity( ref, descriptor, unitOfWork );
+            return entitiesTable.createNewBaseEntity( ref, descriptor, unitOfWork );
         }
 
         @Override
@@ -216,7 +214,8 @@ public interface SqlTable extends ServiceActivation
                 if( !dialect.equals( SQLDialect.SQLITE )
                     && dsl.meta().getSchemas().stream().noneMatch( s -> schema.getName().equalsIgnoreCase( s.getName() ) ) )
                 {
-                    dsl.createSchema( schema ).execute();
+                    dsl.createSchema( schemaName ).execute();
+                    datasource.getConnection().commit();
                 }
 
                 dsl.createTableIfNotExists( DSL.name( schemaName, typesTableName ) )
@@ -225,6 +224,7 @@ public interface SqlTable extends ServiceActivation
                    .column( createdColumn )
                    .column( modifiedColumn )
                    .execute();
+                datasource.getConnection().commit();
 
                 dsl.createTableIfNotExists( DSL.name( schemaName, entitiesTableName ) )
                    .column( identityColumn )
@@ -235,8 +235,8 @@ public interface SqlTable extends ServiceActivation
                    .column( modifiedColumn )
                    .column( createdColumn )
                    .execute();
+                datasource.getConnection().commit();
             }
-            datasource.getConnection().commit();
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
new file mode 100644
index 0000000..c9258ec
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/AbstractSQLEntityStoreAssembler.java
@@ -0,0 +1,73 @@
+/*
+ *  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.Assembler;
+import org.apache.polygene.bootstrap.Assemblers;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.JooqDslContext;
+import org.apache.polygene.entitystore.sql.SqlEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sql.SqlEntityStoreService;
+import org.jooq.conf.RenderNameStyle;
+import org.jooq.conf.Settings;
+
+/**
+ * JOOQ EntityStore assembly.
+ */
+@SuppressWarnings( "WeakerAccess" )
+public abstract class AbstractSQLEntityStoreAssembler<T extends AbstractSQLEntityStoreAssembler> extends Assemblers.VisibilityIdentityConfig<T>
+    implements Assembler
+{
+    public static final Identity DEFAULT_ENTITYSTORE_IDENTITY = StringIdentity.identityOf( "entitystore-sql" );
+
+    @Override
+    public void assemble( ModuleAssembly module )
+    {
+        Settings settings = getSettings();
+        if( settings == null )
+        {
+            throw new AssemblyException( "Settings must not be null" );
+        }
+
+        String identity = ( hasIdentity() ? identity() : DEFAULT_ENTITYSTORE_IDENTITY ).toString();
+        module.transients( JooqDslContext.class );
+
+        module.services( SqlEntityStoreService.class )
+              .identifiedBy( identity )
+              .visibleIn( visibility() )
+              .instantiateOnStartup()
+              .setMetaInfo( settings );
+
+        if( hasConfig() )
+        {
+            configModule().entities( SqlEntityStoreConfiguration.class ).visibleIn( configVisibility() );
+        }
+        super.assemble( module );
+    }
+
+    protected Settings getSettings()
+    {
+        return new Settings().withRenderNameStyle( RenderNameStyle.QUOTED );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/DerbySQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/DerbySQLEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/DerbySQLEntityStoreAssembler.java
new file mode 100644
index 0000000..f150ede
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/DerbySQLEntityStoreAssembler.java
@@ -0,0 +1,12 @@
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+public class DerbySQLEntityStoreAssembler extends AbstractSQLEntityStoreAssembler<DerbySQLEntityStoreAssembler>
+{
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.DERBY;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/H2SQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/H2SQLEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/H2SQLEntityStoreAssembler.java
new file mode 100644
index 0000000..4bc40e2
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/H2SQLEntityStoreAssembler.java
@@ -0,0 +1,12 @@
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+public class H2SQLEntityStoreAssembler extends AbstractSQLEntityStoreAssembler<H2SQLEntityStoreAssembler>
+{
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.H2;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/MariaDbSQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/MariaDbSQLEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/MariaDbSQLEntityStoreAssembler.java
new file mode 100644
index 0000000..a9b6d6b
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/MariaDbSQLEntityStoreAssembler.java
@@ -0,0 +1,12 @@
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+public class MariaDbSQLEntityStoreAssembler extends AbstractSQLEntityStoreAssembler<MariaDbSQLEntityStoreAssembler>
+{
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.MARIADB;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/MySQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/MySQLEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/MySQLEntityStoreAssembler.java
new file mode 100644
index 0000000..4cc3bda
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/MySQLEntityStoreAssembler.java
@@ -0,0 +1,12 @@
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+public class MySQLEntityStoreAssembler extends AbstractSQLEntityStoreAssembler<MySQLEntityStoreAssembler>
+{
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.MYSQL;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/PostgreSQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/PostgreSQLEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/PostgreSQLEntityStoreAssembler.java
new file mode 100644
index 0000000..34901f4
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/PostgreSQLEntityStoreAssembler.java
@@ -0,0 +1,12 @@
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+public class PostgreSQLEntityStoreAssembler extends AbstractSQLEntityStoreAssembler<PostgreSQLEntityStoreAssembler>
+{
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.POSTGRES;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLEntityStoreAssembler.java
new file mode 100644
index 0000000..53a5d58
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLEntityStoreAssembler.java
@@ -0,0 +1,9 @@
+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/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLiteEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLiteEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLiteEntityStoreAssembler.java
new file mode 100644
index 0000000..6f132fd
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SQLiteEntityStoreAssembler.java
@@ -0,0 +1,12 @@
+package org.apache.polygene.entitystore.sql.assembly;
+
+import org.jooq.SQLDialect;
+
+public class SQLiteEntityStoreAssembler extends AbstractSQLEntityStoreAssembler<SQLiteEntityStoreAssembler>
+{
+    protected SQLDialect getSQLDialect()
+    {
+        return SQLDialect.SQLITE;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java
deleted file mode 100644
index 847c07b..0000000
--- a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java
+++ /dev/null
@@ -1,78 +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.assembly;
-
-import org.apache.polygene.api.identity.Identity;
-import org.apache.polygene.api.identity.StringIdentity;
-import org.apache.polygene.bootstrap.Assembler;
-import org.apache.polygene.bootstrap.Assemblers;
-import org.apache.polygene.bootstrap.AssemblyException;
-import org.apache.polygene.bootstrap.ModuleAssembly;
-import org.apache.polygene.entitystore.sql.JooqDslContext;
-import org.apache.polygene.entitystore.sql.SqlEntityStoreConfiguration;
-import org.apache.polygene.entitystore.sql.SqlEntityStoreService;
-import org.jooq.SQLDialect;
-import org.jooq.conf.RenderNameStyle;
-import org.jooq.conf.Settings;
-
-/**
- * JOOQ EntityStore assembly.
- */
-@SuppressWarnings( "WeakerAccess" )
-public class SqlEntityStoreAssembler extends Assemblers.VisibilityIdentityConfig<SqlEntityStoreAssembler>
-    implements Assembler
-{
-    public static final Identity DEFAULT_ENTITYSTORE_IDENTITY = StringIdentity.identityOf( "entitystore-sql" );
-
-    @Override
-    public void assemble( ModuleAssembly module )
-    {
-        Settings settings = getSettings();
-        if( settings == null )
-        {
-            throw new AssemblyException( "Settings must not be null" );
-        }
-
-        String identity = ( hasIdentity() ? identity() : DEFAULT_ENTITYSTORE_IDENTITY ).toString();
-        module.transients( JooqDslContext.class );
-
-        module.services( SqlEntityStoreService.class )
-              .identifiedBy( identity )
-              .visibleIn( visibility() )
-              .instantiateOnStartup()
-              .setMetaInfo( settings );
-
-        if( hasConfig() )
-        {
-            configModule().entities( SqlEntityStoreConfiguration.class ).visibleIn( configVisibility() );
-        }
-        super.assemble( module );
-    }
-
-    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/0f8f0b8d/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
new file mode 100644
index 0000000..512c43e
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTest.java
@@ -0,0 +1,99 @@
+/*
+ *  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.AbstractSQLEntityStoreAssembler;
+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.api.usecase.UsecaseBuilder.newUsecase;
+
+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( newUsecase("Delete " + getClass().getSimpleName() + " test data" ) );
+        try
+        {
+            SqlEntityStoreConfiguration config = uow.get( SqlEntityStoreConfiguration.class,
+                                                          AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
+            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
+            connection.setAutoCommit( false );
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DROP DATABASE FROM %s", config.schemaName().get() ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/DerbySQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..cdfcd54
--- /dev/null
+++ b/extensions/entitystore-sql/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.SqlEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sql.assembly.AbstractSQLEntityStoreAssembler;
+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,
+                                                          AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
+            Connection connection = storageModule.serviceFinder().findService( DataSource.class ).get().getConnection();
+            connection.setAutoCommit( false );
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DROP DATABASE FROM %s", config.schemaName().get() ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTest.java
new file mode 100644
index 0000000..4b4b759
--- /dev/null
+++ b/extensions/entitystore-sql/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/0f8f0b8d/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/H2SQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..f763238
--- /dev/null
+++ b/extensions/entitystore-sql/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/0f8f0b8d/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
new file mode 100644
index 0000000..fe8da9c
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
@@ -0,0 +1,125 @@
+/*
+ *  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.AbstractSQLEntityStoreAssembler;
+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;
+
+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 config = uow.get( SqlEntityStoreConfiguration.class,
+                                                          AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
+            connection.setAutoCommit( false );
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DROP DATABASE FROM %s", config.schemaName().get() ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..f625317
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
@@ -0,0 +1,118 @@
+/*
+ *  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.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.assembly.AbstractSQLEntityStoreAssembler;
+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.api.usecase.UsecaseBuilder.newUsecase;
+
+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( newUsecase( "Delete " + getClass().getSimpleName() + " test data" ) );
+        try
+        {
+            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
+            SqlEntityStoreConfiguration config = uow.get( SqlEntityStoreConfiguration.class,
+                                                          AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
+            connection.setAutoCommit( false );
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DROP DATABASE FROM %s", config.schemaName().get() ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
new file mode 100644
index 0000000..d193728
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
@@ -0,0 +1,114 @@
+/*
+ *  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.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.assembly.AbstractSQLEntityStoreAssembler;
+import org.apache.polygene.entitystore.sql.assembly.PostgreSQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
+import org.apache.polygene.library.sql.common.SQLConfiguration;
+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.api.usecase.UsecaseBuilder.newUsecase;
+
+public class PostgreSQLEntityStoreTest
+    extends AbstractEntityStoreTest
+{
+    @ClassRule
+    public static final DockerRule DOCKER = new DockerRule( "postgres",
+                                                            3000L,
+                                                            "PostgreSQL init process complete; ready for start up." );
+
+    @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( "postgresql-datasource-service" )
+            .visibleIn( Visibility.module )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+
+        // DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "postgresql-datasource-service" )
+            .identifiedBy( "postgresql-datasource" )
+            .visibleIn( Visibility.module )
+            .withCircuitBreaker()
+            .assemble( module );
+
+        // SQL EntityStore
+        new PostgreSQLEntityStoreAssembler()
+            .visibleIn( Visibility.application )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+        // END SNIPPET: assembly
+        String host = DOCKER.getDockerHost();
+        int port = DOCKER.getExposedContainerPort( "5432/tcp" );
+        config.forMixin( DataSourceConfiguration.class ).declareDefaults()
+              .url().set( "jdbc:postgresql://" + host + ":" + port + "/jdbc_test_db" );
+        // START SNIPPET: assembly
+    }
+    // END SNIPPET: assembly
+
+    @Override
+    public void tearDown()
+        throws Exception
+    {
+        String usecaseName = "Delete " + getClass().getSimpleName() + " test data";
+        UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( newUsecase( usecaseName ) );
+        try
+        {
+            SQLConfiguration config = uow.get( SQLConfiguration.class, AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
+            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
+            connection.setAutoCommit( false );
+            String schemaName = config.schemaName().get();
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DROP SCHEMA \"%s\" CASCADE", schemaName ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..d53c7d1
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java
@@ -0,0 +1,112 @@
+/*
+ *  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.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.AbstractSQLEntityStoreAssembler;
+import org.apache.polygene.entitystore.sql.assembly.PostgreSQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
+import org.apache.polygene.library.sql.common.SQLConfiguration;
+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.PostgreSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
+
+public class PostgreSQLEntityStoreTestSuite extends EntityStoreTestSuite
+{
+    @ClassRule
+    public static final DockerRule DOCKER = new DockerRule( "postgres",
+                                                            3000L,
+                                                            "PostgreSQL init process complete; ready for start up." );
+
+    @Override
+    protected void defineStorageModule( ModuleAssembly module )
+    {
+        module.defaultServices();
+        // DataSourceService
+        new DBCPDataSourceServiceAssembler()
+            .identifiedBy( "postgresql-datasource-service" )
+            .visibleIn( Visibility.module )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+
+        // DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "postgresql-datasource-service" )
+            .identifiedBy( "postgresql-datasource" )
+            .visibleIn( Visibility.module )
+            .withCircuitBreaker()
+            .assemble( module );
+
+        // SQL EntityStore
+        new PostgreSQLEntityStoreAssembler()
+            .visibleIn( Visibility.application )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+
+        String host = DOCKER.getDockerHost();
+        int port = DOCKER.getExposedContainerPort( "5432/tcp" );
+        configModule.forMixin( DataSourceConfiguration.class ).declareDefaults()
+                    .url().set( "jdbc:postgresql://" + host + ":" + port + "/jdbc_test_db" );
+        // START SNIPPET: assembly
+    }
+    // END SNIPPET: assembly
+
+    @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
+        {
+            SQLConfiguration config = uow.get( SQLConfiguration.class, AbstractSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY );
+            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
+            connection.setAutoCommit( false );
+            String schemaName = config.schemaName().get();
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DROP SCHEMA \"%s\" CASCADE", schemaName ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/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
new file mode 100644
index 0000000..83e8a21
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTest.java
@@ -0,0 +1,75 @@
+/*
+ *  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/0f8f0b8d/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
new file mode 100644
index 0000000..6dc5fbe
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTestSuite.java
@@ -0,0 +1,65 @@
+/*
+ *  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/0f8f0b8d/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SqlEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SqlEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SqlEntityStoreTest.java
index d8f0d59..2a4ce95 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SqlEntityStoreTest.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SqlEntityStoreTest.java
@@ -22,7 +22,8 @@ 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.SqlEntityStoreAssembler;
+import org.apache.polygene.entitystore.sql.assembly.AbstractSQLEntityStoreAssembler;
+import org.apache.polygene.entitystore.sql.assembly.H2SQLEntityStoreAssembler;
 import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
 import org.apache.polygene.library.sql.datasource.DataSourceConfiguration;
 import org.apache.polygene.library.sql.dbcp.DBCPDataSourceServiceAssembler;
@@ -52,7 +53,7 @@ public class SqlEntityStoreTest extends AbstractEntityStoreTest
         // Assemble a DataSource
         new DataSourceAssembler()
             .withDataSourceServiceIdentity( "datasource" )
-            .identifiedBy( "ds-mysql" )
+            .identifiedBy( "ds-h2" )
             .visibleIn( Visibility.module )
             .assemble( module );
 
@@ -63,7 +64,7 @@ public class SqlEntityStoreTest extends AbstractEntityStoreTest
             .withConfig( config, Visibility.layer )
             .assemble( module );
 
-        new SqlEntityStoreAssembler()
+        new H2SQLEntityStoreAssembler()
             .withConfig( config, Visibility.layer )
             .identifiedBy( "sql-entitystore" )
             .assemble( module );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/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
new file mode 100644
index 0000000..35261ab
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/resources/derby-datasource.properties
@@ -0,0 +1,25 @@
+#
+#  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/0f8f0b8d/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
new file mode 100644
index 0000000..74abf51
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/resources/h2-datasource.properties
@@ -0,0 +1,25 @@
+#
+#  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/0f8f0b8d/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
new file mode 100644
index 0000000..03fb4dd
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/resources/logback.xml
@@ -0,0 +1,35 @@
+<?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/0f8f0b8d/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
new file mode 100644
index 0000000..a2f4175
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/resources/mysql-datasource.properties
@@ -0,0 +1,25 @@
+#
+#  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/0f8f0b8d/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
new file mode 100644
index 0000000..bdda284
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/resources/postgresql-datasource.properties
@@ -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.
+#
+#
+#
+
+enabled=true
+driver=org.postgresql.Driver
+username=jdbc_test_login
+password=password

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/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
new file mode 100644
index 0000000..17e52b5
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/resources/sqlite-datasource.properties
@@ -0,0 +1,25 @@
+#
+#  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=


[11/15] polygene-java git commit: Introducing the whole test suite from entitystore-sqlkv and starting to solidify the implementation against all these SQL systems.

Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/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
deleted file mode 100644
index a940e95..0000000
--- a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTest.java
+++ /dev/null
@@ -1,127 +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 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/0f8f0b8d/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
deleted file mode 100644
index e2b0564..0000000
--- a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/MySQLEntityStoreTestSuite.java
+++ /dev/null
@@ -1,122 +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 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();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
deleted file mode 100644
index daa9949..0000000
--- a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTest.java
+++ /dev/null
@@ -1,115 +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 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.PostgreSQLEntityStoreAssembler;
-import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
-import org.apache.polygene.library.sql.common.SQLConfiguration;
-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.PostgreSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
-
-public class PostgreSQLEntityStoreTest
-    extends AbstractEntityStoreTest
-{
-    @ClassRule
-    public static final DockerRule DOCKER = new DockerRule( "postgres",
-                                                            3000L,
-                                                            "PostgreSQL init process complete; ready for start up." );
-
-    @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( "postgresql-datasource-service" )
-            .visibleIn( Visibility.module )
-            .withConfig( config, Visibility.layer )
-            .assemble( module );
-
-        // DataSource
-        new DataSourceAssembler()
-            .withDataSourceServiceIdentity( "postgresql-datasource-service" )
-            .identifiedBy( "postgresql-datasource" )
-            .visibleIn( Visibility.module )
-            .withCircuitBreaker()
-            .assemble( module );
-
-        // SQL EntityStore
-        new PostgreSQLEntityStoreAssembler()
-            .visibleIn( Visibility.application )
-            .withConfig( config, Visibility.layer )
-            .assemble( module );
-        // END SNIPPET: assembly
-        String host = DOCKER.getDockerHost();
-        int port = DOCKER.getExposedContainerPort( "5432/tcp" );
-        config.forMixin( DataSourceConfiguration.class ).declareDefaults()
-              .url().set( "jdbc:postgresql://" + host + ":" + port + "/jdbc_test_db" );
-        // START SNIPPET: assembly
-    }
-    // END SNIPPET: assembly
-
-    @Override
-    public void tearDown()
-        throws Exception
-    {
-        UnitOfWork uow = unitOfWorkFactory.newUnitOfWork(
-            UsecaseBuilder.newUsecase( "Delete " + getClass().getSimpleName() + " test data" )
-        );
-        try
-        {
-            SQLConfiguration config = uow.get( SQLConfiguration.class, DEFAULT_ENTITYSTORE_IDENTITY );
-            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
-            connection.setAutoCommit( false );
-            String schemaName = config.schemaName().get();
-            try( Statement stmt = connection.createStatement() )
-            {
-                stmt.execute( String.format( "DROP SCHEMA \"%s\" CASCADE", schemaName ) );
-                connection.commit();
-            }
-        }
-        finally
-        {
-            uow.discard();
-            super.tearDown();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java
deleted file mode 100644
index d1dd952..0000000
--- a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/PostgreSQLEntityStoreTestSuite.java
+++ /dev/null
@@ -1,111 +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 java.sql.Connection;
-import java.sql.Statement;
-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.PostgreSQLEntityStoreAssembler;
-import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
-import org.apache.polygene.library.sql.common.SQLConfiguration;
-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.PostgreSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
-
-public class PostgreSQLEntityStoreTestSuite extends EntityStoreTestSuite
-{
-    @ClassRule
-    public static final DockerRule DOCKER = new DockerRule( "postgres",
-                                                            3000L,
-                                                            "PostgreSQL init process complete; ready for start up." );
-
-    @Override
-    protected void defineStorageModule( ModuleAssembly module )
-    {
-        module.defaultServices();
-        // DataSourceService
-        new DBCPDataSourceServiceAssembler()
-            .identifiedBy( "postgresql-datasource-service" )
-            .visibleIn( Visibility.module )
-            .withConfig( configModule, Visibility.application )
-            .assemble( module );
-
-        // DataSource
-        new DataSourceAssembler()
-            .withDataSourceServiceIdentity( "postgresql-datasource-service" )
-            .identifiedBy( "postgresql-datasource" )
-            .visibleIn( Visibility.module )
-            .withCircuitBreaker()
-            .assemble( module );
-
-        // SQL EntityStore
-        new PostgreSQLEntityStoreAssembler()
-            .visibleIn( Visibility.application )
-            .withConfig( configModule, Visibility.application )
-            .assemble( module );
-
-        String host = DOCKER.getDockerHost();
-        int port = DOCKER.getExposedContainerPort( "5432/tcp" );
-        configModule.forMixin( DataSourceConfiguration.class ).declareDefaults()
-                    .url().set( "jdbc:postgresql://" + host + ":" + port + "/jdbc_test_db" );
-        // START SNIPPET: assembly
-    }
-    // END SNIPPET: assembly
-
-    @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
-        {
-            SQLConfiguration config = uow.get( SQLConfiguration.class, DEFAULT_ENTITYSTORE_IDENTITY );
-            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
-            connection.setAutoCommit( false );
-            String schemaName = config.schemaName().get();
-            try( Statement stmt = connection.createStatement() )
-            {
-                stmt.execute( String.format( "DROP SCHEMA \"%s\" CASCADE", schemaName ) );
-                connection.commit();
-            }
-        }
-        finally
-        {
-            uow.discard();
-            super.tearDown();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTest.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTest.java
deleted file mode 100644
index 83e8a21..0000000
--- a/extensions/entitystore-sqlkv/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/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTestSuite.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sql/SQLiteEntityStoreTestSuite.java
deleted file mode 100644
index 6dc5fbe..0000000
--- a/extensions/entitystore-sqlkv/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/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/DerbySQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/DerbySQLEntityStoreTest.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/DerbySQLEntityStoreTest.java
new file mode 100644
index 0000000..627699f
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/DerbySQLEntityStoreTest.java
@@ -0,0 +1,102 @@
+/*
+ *  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.sqlkv;
+
+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.sqlkv.SQLEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sqlkv.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.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/DerbySQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/DerbySQLEntityStoreTestSuite.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/DerbySQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..b5d3949
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/DerbySQLEntityStoreTestSuite.java
@@ -0,0 +1,95 @@
+/*
+ *  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.sqlkv;
+
+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.sqlkv.SQLEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sqlkv.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.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/H2SQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/H2SQLEntityStoreTest.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/H2SQLEntityStoreTest.java
new file mode 100644
index 0000000..1303106
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv;
+
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/H2SQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/H2SQLEntityStoreTestSuite.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/H2SQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..daa3030
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/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.sqlkv;
+
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/MySQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/MySQLEntityStoreTest.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/MySQLEntityStoreTest.java
new file mode 100644
index 0000000..3c9f689
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/MySQLEntityStoreTest.java
@@ -0,0 +1,128 @@
+/*
+ *  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.sqlkv;
+
+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.sqlkv.SQLEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sqlkv.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.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/MySQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/MySQLEntityStoreTestSuite.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/MySQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..65f6b72
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/MySQLEntityStoreTestSuite.java
@@ -0,0 +1,123 @@
+/*
+ *  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.sqlkv;
+
+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.sqlkv.SQLEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sqlkv.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.sqlkv.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();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/PostgreSQLEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/PostgreSQLEntityStoreTest.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/PostgreSQLEntityStoreTest.java
new file mode 100644
index 0000000..2525265
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/PostgreSQLEntityStoreTest.java
@@ -0,0 +1,115 @@
+/*
+ *  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.sqlkv;
+
+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.sqlkv.assembly.PostgreSQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
+import org.apache.polygene.library.sql.common.SQLConfiguration;
+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.sqlkv.assembly.PostgreSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
+
+public class PostgreSQLEntityStoreTest
+    extends AbstractEntityStoreTest
+{
+    @ClassRule
+    public static final DockerRule DOCKER = new DockerRule( "postgres",
+                                                            3000L,
+                                                            "PostgreSQL init process complete; ready for start up." );
+
+    @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( "postgresql-datasource-service" )
+            .visibleIn( Visibility.module )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+
+        // DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "postgresql-datasource-service" )
+            .identifiedBy( "postgresql-datasource" )
+            .visibleIn( Visibility.module )
+            .withCircuitBreaker()
+            .assemble( module );
+
+        // SQL EntityStore
+        new PostgreSQLEntityStoreAssembler()
+            .visibleIn( Visibility.application )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+        // END SNIPPET: assembly
+        String host = DOCKER.getDockerHost();
+        int port = DOCKER.getExposedContainerPort( "5432/tcp" );
+        DataSourceConfiguration defaults = config.forMixin( DataSourceConfiguration.class ).declareDefaults();
+        defaults.url().set( "jdbc:postgresql://" + host + ":" + port + "/jdbc_test_db" );
+        // START SNIPPET: assembly
+    }
+    // END SNIPPET: assembly
+
+    @Override
+    public void tearDown()
+        throws Exception
+    {
+        UnitOfWork uow = unitOfWorkFactory.newUnitOfWork(
+            UsecaseBuilder.newUsecase( "Delete " + getClass().getSimpleName() + " test data" )
+        );
+        try
+        {
+            SQLConfiguration config = uow.get( SQLConfiguration.class, DEFAULT_ENTITYSTORE_IDENTITY );
+            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
+            connection.setAutoCommit( false );
+            String schemaName = config.schemaName().get();
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DROP SCHEMA \"%s\" CASCADE", schemaName ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/PostgreSQLEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/PostgreSQLEntityStoreTestSuite.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/PostgreSQLEntityStoreTestSuite.java
new file mode 100644
index 0000000..93e73e8
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/PostgreSQLEntityStoreTestSuite.java
@@ -0,0 +1,111 @@
+/*
+ *  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.sqlkv;
+
+import java.sql.Connection;
+import java.sql.Statement;
+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.sqlkv.assembly.PostgreSQLEntityStoreAssembler;
+import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
+import org.apache.polygene.library.sql.common.SQLConfiguration;
+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.sqlkv.assembly.PostgreSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
+
+public class PostgreSQLEntityStoreTestSuite extends EntityStoreTestSuite
+{
+    @ClassRule
+    public static final DockerRule DOCKER = new DockerRule( "postgres",
+                                                            3000L,
+                                                            "PostgreSQL init process complete; ready for start up." );
+
+    @Override
+    protected void defineStorageModule( ModuleAssembly module )
+    {
+        module.defaultServices();
+        // DataSourceService
+        new DBCPDataSourceServiceAssembler()
+            .identifiedBy( "postgresql-datasource-service" )
+            .visibleIn( Visibility.module )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+
+        // DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "postgresql-datasource-service" )
+            .identifiedBy( "postgresql-datasource" )
+            .visibleIn( Visibility.module )
+            .withCircuitBreaker()
+            .assemble( module );
+
+        // SQL EntityStore
+        new PostgreSQLEntityStoreAssembler()
+            .visibleIn( Visibility.application )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+
+        String host = DOCKER.getDockerHost();
+        int port = DOCKER.getExposedContainerPort( "5432/tcp" );
+        configModule.forMixin( DataSourceConfiguration.class ).declareDefaults()
+                    .url().set( "jdbc:postgresql://" + host + ":" + port + "/jdbc_test_db" );
+        // START SNIPPET: assembly
+    }
+    // END SNIPPET: assembly
+
+    @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
+        {
+            SQLConfiguration config = uow.get( SQLConfiguration.class, DEFAULT_ENTITYSTORE_IDENTITY );
+            Connection connection = serviceFinder.findService( DataSource.class ).get().getConnection();
+            connection.setAutoCommit( false );
+            String schemaName = config.schemaName().get();
+            try( Statement stmt = connection.createStatement() )
+            {
+                stmt.execute( String.format( "DROP SCHEMA \"%s\" CASCADE", schemaName ) );
+                connection.commit();
+            }
+        }
+        finally
+        {
+            uow.discard();
+            super.tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/SQLiteEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/SQLiteEntityStoreTest.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/SQLiteEntityStoreTest.java
new file mode 100644
index 0000000..d554cd6
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/SQLiteEntityStoreTest.java
@@ -0,0 +1,75 @@
+/*
+ *  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.sqlkv;
+
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sqlkv.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/0f8f0b8d/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/SQLiteEntityStoreTestSuite.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/SQLiteEntityStoreTestSuite.java b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/SQLiteEntityStoreTestSuite.java
new file mode 100644
index 0000000..5ae254f
--- /dev/null
+++ b/extensions/entitystore-sqlkv/src/test/java/org/apache/polygene/entitystore/sqlkv/SQLiteEntityStoreTestSuite.java
@@ -0,0 +1,65 @@
+/*
+ *  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.sqlkv;
+
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sqlkv.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/0f8f0b8d/libraries/sql-dbcp/src/main/java/org/apache/polygene/library/sql/dbcp/DBCPDataSourceServiceImporter.java
----------------------------------------------------------------------
diff --git a/libraries/sql-dbcp/src/main/java/org/apache/polygene/library/sql/dbcp/DBCPDataSourceServiceImporter.java b/libraries/sql-dbcp/src/main/java/org/apache/polygene/library/sql/dbcp/DBCPDataSourceServiceImporter.java
index 6e89f1f..31be482 100644
--- a/libraries/sql-dbcp/src/main/java/org/apache/polygene/library/sql/dbcp/DBCPDataSourceServiceImporter.java
+++ b/libraries/sql-dbcp/src/main/java/org/apache/polygene/library/sql/dbcp/DBCPDataSourceServiceImporter.java
@@ -19,10 +19,13 @@
  */
 package org.apache.polygene.library.sql.dbcp;
 
+import java.sql.Connection;
+import java.util.function.Consumer;
 import javax.sql.DataSource;
 import org.apache.commons.dbcp2.BasicDataSource;
 import org.apache.polygene.api.activation.Activators;
 import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.property.Property;
 import org.apache.polygene.api.service.ServiceComposite;
 import org.apache.polygene.api.service.ServiceImporter;
 import org.apache.polygene.library.sql.datasource.AbstractDataSourceServiceImporterMixin;
@@ -32,7 +35,7 @@ import org.apache.polygene.library.sql.datasource.DataSourceServiceImporterActiv
 @Mixins( DBCPDataSourceServiceImporter.Mixin.class )
 @Activators( DataSourceServiceImporterActivation.Activator.class )
 public interface DBCPDataSourceServiceImporter
-        extends ServiceImporter<DataSource>, DataSourceServiceImporterActivation, ServiceComposite
+    extends ServiceImporter<DataSource>, DataSourceServiceImporterActivation, ServiceComposite
 {
 
     class Mixin extends AbstractDataSourceServiceImporterMixin<BasicDataSource>
@@ -40,7 +43,7 @@ public interface DBCPDataSourceServiceImporter
 
         @Override
         protected BasicDataSource setupDataSourcePool( DataSourceConfiguration config )
-                throws Exception
+            throws Exception
         {
             BasicDataSource pool = new BasicDataSource();
 
@@ -48,37 +51,41 @@ public interface DBCPDataSourceServiceImporter
             pool.setDriverClassName( config.driver().get() );
             pool.setUrl( config.url().get() );
 
-            if ( !config.username().get().equals( "" ) ) {
-                pool.setUsername( config.username().get() );
-                pool.setPassword( config.password().get() );
-            }
+            setConfig( config.username(), pool::setUsername, null );
+            setConfig( config.password(), pool::setPassword, null );
+            setConfig( config.minPoolSize(), pool::setMinIdle, null );
+            setConfig( config.maxPoolSize(), pool::setMaxTotal, null );
+            setConfig( config.maxConnectionAgeSeconds(), v -> pool.setMinEvictableIdleTimeMillis( v * 1000 ), null );
+            setConfig( config.validationQuery(), pool::setValidationQuery, null );
+            setConfig( config.autoCommit(), pool::setDefaultAutoCommit, null );
+            setConfig( config.isolationLevel(), pool::setDefaultTransactionIsolation, Connection.TRANSACTION_SERIALIZABLE );
 
-            if ( config.minPoolSize().get() != null ) {
-                pool.setMinIdle( config.minPoolSize().get() );
-            }
-            if ( config.maxPoolSize().get() != null ) {
-                pool.setMaxTotal( config.maxPoolSize().get() );
-            }
-            if ( config.loginTimeoutSeconds().get() != null ) {
+            // Throws checked exception and can't be neatly handled
+            if( config.loginTimeoutSeconds().get() != null )
+            {
                 pool.setLoginTimeout( config.loginTimeoutSeconds().get() );
             }
-            if ( config.maxConnectionAgeSeconds().get() != null ) {
-                pool.setMinEvictableIdleTimeMillis( config.maxConnectionAgeSeconds().get() * 1000 );
+            return pool;
+        }
+
+        private <T> void setConfig( Property<T> property, Consumer<T> setter, T defaultValue )
+        {
+            T value = property.get();
+            if( value != null )
+            {
+                setter.accept( value );
             }
-            if ( config.validationQuery().get() != null ) {
-                pool.setValidationQuery( config.validationQuery().get() );
+            else if( defaultValue != null )
+            {
+                setter.accept( defaultValue );
             }
-
-            return pool;
         }
 
         @Override
         protected void passivateDataSourcePool( BasicDataSource dataSourcePool )
-                throws Exception
+            throws Exception
         {
             dataSourcePool.close();
         }
-
     }
-
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/libraries/sql/src/main/java/org/apache/polygene/library/sql/datasource/DataSourceConfigurationState.java
----------------------------------------------------------------------
diff --git a/libraries/sql/src/main/java/org/apache/polygene/library/sql/datasource/DataSourceConfigurationState.java b/libraries/sql/src/main/java/org/apache/polygene/library/sql/datasource/DataSourceConfigurationState.java
index 9243fa5..bf5aaa2 100644
--- a/libraries/sql/src/main/java/org/apache/polygene/library/sql/datasource/DataSourceConfigurationState.java
+++ b/libraries/sql/src/main/java/org/apache/polygene/library/sql/datasource/DataSourceConfigurationState.java
@@ -40,5 +40,7 @@ public interface DataSourceConfigurationState extends Enabled
     @Optional Property<Integer> maxConnectionAgeSeconds();
     @Optional Property<String> validationQuery();
     @UseDefaults Property<String> properties();
+    @UseDefaults Property<Boolean> autoCommit();
+    @Optional Property<Integer> isolationLevel();
 }
 // END SNIPPET: config

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/libraries/sql/src/main/java/org/apache/polygene/library/sql/datasource/DataSourceServiceImporterActivation.java
----------------------------------------------------------------------
diff --git a/libraries/sql/src/main/java/org/apache/polygene/library/sql/datasource/DataSourceServiceImporterActivation.java b/libraries/sql/src/main/java/org/apache/polygene/library/sql/datasource/DataSourceServiceImporterActivation.java
index c28c357..82cbb32 100644
--- a/libraries/sql/src/main/java/org/apache/polygene/library/sql/datasource/DataSourceServiceImporterActivation.java
+++ b/libraries/sql/src/main/java/org/apache/polygene/library/sql/datasource/DataSourceServiceImporterActivation.java
@@ -31,14 +31,11 @@ public interface DataSourceServiceImporterActivation
     class Activator
             extends ActivatorAdapter<ServiceReference<DataSourceServiceImporterActivation>>
     {
-
         @Override
         public void beforePassivation( ServiceReference<DataSourceServiceImporterActivation> passivating )
                 throws Exception
         {
             passivating.get().passivateDataSourceService();
         }
-
     }
-
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/samples/sql-support/src/main/java/org/apache/polygene/sample/sqlsupport/AppAssembler.java
----------------------------------------------------------------------
diff --git a/samples/sql-support/src/main/java/org/apache/polygene/sample/sqlsupport/AppAssembler.java b/samples/sql-support/src/main/java/org/apache/polygene/sample/sqlsupport/AppAssembler.java
index 716c954..e748106 100644
--- a/samples/sql-support/src/main/java/org/apache/polygene/sample/sqlsupport/AppAssembler.java
+++ b/samples/sql-support/src/main/java/org/apache/polygene/sample/sqlsupport/AppAssembler.java
@@ -26,7 +26,7 @@ import org.apache.polygene.bootstrap.ApplicationAssemblyFactory;
 import org.apache.polygene.bootstrap.LayerAssembly;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
-import org.apache.polygene.entitystore.sql.assembly.PostgreSQLEntityStoreAssembler;
+import org.apache.polygene.entitystore.sqlkv.assembly.PostgreSQLEntityStoreAssembler;
 import org.apache.polygene.index.sql.assembly.PostgreSQLIndexQueryAssembler;
 import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
 import org.apache.polygene.library.sql.datasource.DataSources;

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/samples/sql-support/src/main/java/org/apache/polygene/sample/sqlsupport/Main.java
----------------------------------------------------------------------
diff --git a/samples/sql-support/src/main/java/org/apache/polygene/sample/sqlsupport/Main.java b/samples/sql-support/src/main/java/org/apache/polygene/sample/sqlsupport/Main.java
index 5a96f31..66a0918 100644
--- a/samples/sql-support/src/main/java/org/apache/polygene/sample/sqlsupport/Main.java
+++ b/samples/sql-support/src/main/java/org/apache/polygene/sample/sqlsupport/Main.java
@@ -30,7 +30,7 @@ import org.apache.polygene.api.structure.Application;
 import org.apache.polygene.api.structure.Module;
 import org.apache.polygene.api.unitofwork.UnitOfWork;
 import org.apache.polygene.bootstrap.Energy4Java;
-import org.apache.polygene.entitystore.sql.assembly.PostgreSQLEntityStoreAssembler;
+import org.apache.polygene.entitystore.sqlkv.assembly.PostgreSQLEntityStoreAssembler;
 import org.apache.polygene.index.sql.assembly.PostgreSQLIndexQueryAssembler;
 import org.apache.polygene.library.sql.common.SQLConfiguration;
 import org.apache.polygene.library.sql.common.SQLUtil;

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/tests/performance/src/perf/java/org/apache/polygene/test/performance/entitystore/sql/DerbySQLEntityStorePerformanceTest.java
----------------------------------------------------------------------
diff --git a/tests/performance/src/perf/java/org/apache/polygene/test/performance/entitystore/sql/DerbySQLEntityStorePerformanceTest.java b/tests/performance/src/perf/java/org/apache/polygene/test/performance/entitystore/sql/DerbySQLEntityStorePerformanceTest.java
index 42305a2..e034c38 100644
--- a/tests/performance/src/perf/java/org/apache/polygene/test/performance/entitystore/sql/DerbySQLEntityStorePerformanceTest.java
+++ b/tests/performance/src/perf/java/org/apache/polygene/test/performance/entitystore/sql/DerbySQLEntityStorePerformanceTest.java
@@ -25,14 +25,14 @@ import org.apache.polygene.api.unitofwork.UnitOfWork;
 import org.apache.polygene.api.usecase.UsecaseBuilder;
 import org.apache.polygene.bootstrap.Assembler;
 import org.apache.polygene.bootstrap.ModuleAssembly;
-import org.apache.polygene.entitystore.sql.SQLEntityStoreConfiguration;
-import org.apache.polygene.entitystore.sql.assembly.DerbySQLEntityStoreAssembler;
+import org.apache.polygene.entitystore.sqlkv.SQLEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sqlkv.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.performance.entitystore.AbstractEntityStorePerformanceTest;
 
-import static org.apache.polygene.entitystore.sql.assembly.DerbySQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
+import static org.apache.polygene.entitystore.sqlkv.assembly.DerbySQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
 
 /**
  * Performance test for DerbySQLEntityStore.

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/0f8f0b8d/tests/performance/src/perf/java/org/apache/polygene/test/performance/entitystore/sql/PostgreSQLEntityStorePerformanceTest.java
----------------------------------------------------------------------
diff --git a/tests/performance/src/perf/java/org/apache/polygene/test/performance/entitystore/sql/PostgreSQLEntityStorePerformanceTest.java b/tests/performance/src/perf/java/org/apache/polygene/test/performance/entitystore/sql/PostgreSQLEntityStorePerformanceTest.java
index eac294b..6f91b12 100644
--- a/tests/performance/src/perf/java/org/apache/polygene/test/performance/entitystore/sql/PostgreSQLEntityStorePerformanceTest.java
+++ b/tests/performance/src/perf/java/org/apache/polygene/test/performance/entitystore/sql/PostgreSQLEntityStorePerformanceTest.java
@@ -30,7 +30,7 @@ import org.apache.polygene.bootstrap.ApplicationAssemblerAdapter;
 import org.apache.polygene.bootstrap.Assembler;
 import org.apache.polygene.bootstrap.Energy4Java;
 import org.apache.polygene.bootstrap.ModuleAssembly;
-import org.apache.polygene.entitystore.sql.assembly.PostgreSQLEntityStoreAssembler;
+import org.apache.polygene.entitystore.sqlkv.assembly.PostgreSQLEntityStoreAssembler;
 import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
 import org.apache.polygene.library.sql.common.SQLConfiguration;
 import org.apache.polygene.library.sql.dbcp.DBCPDataSourceServiceAssembler;
@@ -38,7 +38,7 @@ import org.apache.polygene.test.EntityTestAssembler;
 import org.apache.polygene.test.performance.entitystore.AbstractEntityStorePerformanceTest;
 import org.junit.Ignore;
 
-import static org.apache.polygene.entitystore.sql.assembly.PostgreSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
+import static org.apache.polygene.entitystore.sqlkv.assembly.PostgreSQLEntityStoreAssembler.DEFAULT_ENTITYSTORE_IDENTITY;
 
 /**
  * Performance test for PostgreSQLEntityStore.


[06/15] polygene-java git commit: entitystore-sql is brought in from the es-jooq branch, and fixed it up so that it compiles and passes the standard unit tests using H2. More testing needed for other SQL systems, since there seems to not be consensus on

Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
new file mode 100644
index 0000000..6537782
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlTable.java
@@ -0,0 +1,271 @@
+/*
+ *  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.util.function.Consumer;
+import java.util.stream.Stream;
+import javax.sql.DataSource;
+import org.apache.polygene.api.PolygeneAPI;
+import org.apache.polygene.api.composite.TransientBuilderFactory;
+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.Structure;
+import org.apache.polygene.api.injection.scope.This;
+import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.object.ObjectFactory;
+import org.apache.polygene.api.service.ServiceActivation;
+import org.apache.polygene.api.service.ServiceDescriptor;
+import org.apache.polygene.api.structure.Application;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.spi.entitystore.EntityStoreUnitOfWork;
+import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
+import org.jooq.Record;
+import org.jooq.SQLDialect;
+import org.jooq.Schema;
+import org.jooq.SelectQuery;
+import org.jooq.conf.RenderNameStyle;
+import org.jooq.conf.Settings;
+import org.jooq.impl.DSL;
+
+/**
+ * This class handles all the Jooq interactions.
+ * <p>
+ * <p>
+ * <p>
+ * <h1>Tables</h1>
+ * <h2>Types Table</h2>
+ * <ul>
+ * <li>identity</li>
+ * <li>table_name</li>
+ * <li>created_at</li>
+ * <li>modified_at</li>
+ * </ul>
+ * <h2>Entities Table</h2>
+ * <ul>
+ * <li>identity</li>
+ * <li>app_version</li>
+ * <li>value_id</li>
+ * <li>version</li>
+ * <li>type</li>
+ * <li>modified_at</li>
+ * <li>created_at</li>
+ * </ul>
+ * <h2>Mixin Tables</h2>
+ * <p>
+ * Each Mixin is stored in its own table. Only the following column is always present;
+ * <ul>
+ * <li>identity - this is not entity identity but the UUID of the value_id in the Entities Table above.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Each Property of the Mixin (as defined by QualifiedName of the Property, will reside in its own column.
+ * All values in columns are (for now) serialized using a ValueSerialization service.
+ * </p>
+ * <p>
+ * Associations also has their own columns in the table, with the EntityReference.identity() stored in them.
+ * </p>
+ * <p>
+ * ManyAssociations and NamedAssociations are stored in a separate table, named &lt;mixintable&gt;_ASSOCS, see below.
+ * </p>
+ * <h2>Mixin_ASSOCS Table</h2>
+ * <ul>
+ * <li>identity - the value_id of the mixin value</li>
+ * <li>name - the name of the ManyAssociation or NamedAssociation</li>
+ * <li>position - for NamedAssociation this is the 'name' (i.e key) and for ManyAssociation this is the index into the list.</li>
+ * <li>reference - EntityReference.identity of that association</li>
+ * </ul>
+ */
+@Mixins( SqlTable.Mixin.class )
+public interface SqlTable extends ServiceActivation
+{
+    BaseEntity fetchBaseEntity( EntityReference reference, ModuleDescriptor module );
+
+    SelectQuery<Record> createGetEntityQuery( EntityDescriptor descriptor, EntityReference reference );
+
+    void fetchAssociations( BaseEntity entity, EntityDescriptor descriptor, Consumer<AssociationValue> consume );
+
+    void createNewBaseEntity( EntityReference ref, EntityDescriptor descriptor, EntityStoreUnitOfWork unitOfWork );
+
+    void insertEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork );
+
+    void updateEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork );
+
+    JooqDslContext jooqDslContext();
+
+    void removeEntity( EntityReference entityReference, EntityDescriptor descriptor );
+
+    Stream<BaseEntity> fetchAll( EntityDescriptor type, ModuleDescriptor module );
+
+    class Mixin
+        implements SqlTable, TableFields, ServiceActivation
+    {
+        @Structure
+        private Application application;
+
+        @Structure
+        private TransientBuilderFactory tbf;
+
+        @This
+        private Configuration<SqlEntityStoreConfiguration> configuration;
+
+        @Service
+        private DataSource datasource;
+
+        @Uses
+        private ServiceDescriptor serviceDescriptor;
+
+        private EntitiesTable entitiesTable;
+
+        private TypesTable types;
+        private JooqDslContext dsl;
+
+        @Override
+        public BaseEntity fetchBaseEntity( EntityReference reference, ModuleDescriptor module )
+        {
+            return entitiesTable.fetchEntity( reference, module );
+        }
+
+        @Override
+        public Stream<BaseEntity> fetchAll( EntityDescriptor type, ModuleDescriptor module )
+        {
+            return entitiesTable.fetchAll( type, module );
+        }
+
+        @Override
+        public SelectQuery<Record> createGetEntityQuery( EntityDescriptor descriptor, EntityReference reference )
+        {
+            return entitiesTable.createGetEntityQuery( descriptor, reference );
+        }
+
+        @Override
+        public void fetchAssociations( BaseEntity entity, EntityDescriptor descriptor, Consumer<AssociationValue> consume )
+        {
+            entitiesTable.fetchAssociations( entity, descriptor, consume );
+        }
+
+        @Override
+        public void createNewBaseEntity( EntityReference ref, EntityDescriptor descriptor, EntityStoreUnitOfWork unitOfWork )
+        {
+            entitiesTable.createNewBaseEntity( ref, descriptor, unitOfWork );
+        }
+
+        @Override
+        public void insertEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork )
+        {
+            entitiesTable.insertEntity( state, baseEntity );
+        }
+
+        @Override
+        public void updateEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork )
+        {
+            entitiesTable.modifyEntity( state, baseEntity, unitOfWork );
+        }
+
+        @Override
+        public JooqDslContext jooqDslContext()
+        {
+            return dsl;
+        }
+
+        @Override
+        public void removeEntity( EntityReference reference, EntityDescriptor descriptor )
+        {
+            entitiesTable.removeEntity( reference, descriptor );
+        }
+
+        @Override
+        public void activateService()
+            throws Exception
+        {
+            SqlEntityStoreConfiguration config = this.configuration.get();
+            SQLDialect dialect = getSqlDialect( config );
+
+            Settings settings = serviceDescriptor
+                .metaInfo( Settings.class )
+                .withRenderNameStyle( RenderNameStyle.QUOTED );
+            dsl = tbf.newTransient( JooqDslContext.class, settings, dialect );
+
+            String schemaName = config.schemaName().get();
+            String typesTableName = config.typesTableName().get();
+            String entitiesTableName = config.entitiesTableName().get();
+            Schema schema = DSL.schema( DSL.name( schemaName ) );
+            types = new TypesTable( dsl, schema, dialect, typesTableName );
+            entitiesTable = new EntitiesTable( dsl, schema, types, application.version(), entitiesTableName );
+
+            // Eventually create schema
+            if( config.createIfMissing().get() )
+            {
+                if( !dialect.equals( SQLDialect.SQLITE )
+                    && dsl.meta().getSchemas().stream().noneMatch( s -> schema.getName().equalsIgnoreCase( s.getName() ) ) )
+                {
+                    dsl.createSchema( schema ).execute();
+                }
+
+                dsl.createTableIfNotExists( DSL.name( schemaName, typesTableName ) )
+                   .column( identityColumn )
+                   .column( tableNameColumn )
+                   .column( createdColumn )
+                   .column( modifiedColumn )
+                   .execute();
+
+                dsl.createTableIfNotExists( DSL.name( schemaName, entitiesTableName ) )
+                   .column( identityColumn )
+                   .column( applicationVersionColumn )
+                   .column( valueIdentityColumn )
+                   .column( versionColumn )
+                   .column( typeNameColumn )
+                   .column( modifiedColumn )
+                   .column( createdColumn )
+                   .execute();
+            }
+            datasource.getConnection().commit();
+        }
+
+        @Override
+        public void passivateService()
+            throws Exception
+        {
+
+        }
+
+        private SQLDialect getSqlDialect( SqlEntityStoreConfiguration config )
+        {
+            SQLDialect dialect = null;
+            String dialectString = config.dialect().get();
+            if( dialectString.length() == 0 )
+            {
+                dialect = SQLDialect.DEFAULT;
+            }
+            else
+            {
+                try
+                {
+                    dialect = SQLDialect.valueOf( dialectString );
+                }
+                catch( IllegalArgumentException e )
+                {
+                    throw new IllegalArgumentException( "Invalid SQLDialect: '" + dialectString + "'" );
+                }
+            }
+            return dialect;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlType.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlType.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlType.java
new file mode 100644
index 0000000..21de44d
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SqlType.java
@@ -0,0 +1,156 @@
+/*
+ *  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.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.Period;
+import java.time.ZonedDateTime;
+import org.jooq.DataType;
+import org.jooq.impl.DefaultDataType;
+import org.jooq.impl.SQLDataType;
+import org.jooq.types.Interval;
+
+class SqlType
+{
+    @SuppressWarnings( "unchecked" )
+    static <T> DataType<T> getSqlDataTypeFor( Class<?> propertyType )
+    {
+        if( String.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.VARCHAR;
+        }
+        if( Integer.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.INTEGER;
+        }
+        if( Long.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.BIGINT;
+        }
+        if( Boolean.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.BOOLEAN;
+        }
+        if( Float.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.REAL;
+        }
+        if( Double.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.DOUBLE;
+        }
+        if( Instant.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.TIMESTAMPWITHTIMEZONE;
+        }
+        if( Interval.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.VARCHAR;
+        }
+        if( Period.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.VARCHAR;
+        }
+        if( LocalDate.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.LOCALDATE;
+        }
+        if( LocalTime.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.LOCALTIME;
+        }
+        if( LocalDateTime.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.LOCALDATETIME;
+        }
+        if( ZonedDateTime.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.OFFSETDATETIME;
+        }
+        if( OffsetDateTime.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.OFFSETDATETIME;
+        }
+        if( Character.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.CHAR( 1 );
+        }
+        if( Short.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.INTEGER;
+        }
+        if( Byte.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.INTEGER;
+        }
+        if( Byte.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.INTEGER;
+        }
+        if( BigDecimal.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.DECIMAL;
+        }
+        if( BigInteger.class.isAssignableFrom( propertyType ) )
+        {
+            return (DataType<T>) SQLDataType.DECIMAL(50, 0);
+        }
+        if( propertyType.isPrimitive() )
+        {
+            if( propertyType.equals( Integer.TYPE ) )
+            {
+                return (DataType<T>) SQLDataType.INTEGER;
+            }
+            if( propertyType.equals( Long.TYPE ) )
+            {
+                return (DataType<T>) SQLDataType.BIGINT;
+            }
+            if( propertyType.equals( Boolean.TYPE ) )
+            {
+                return (DataType<T>) SQLDataType.BOOLEAN;
+            }
+            if( propertyType.equals( Float.TYPE ) )
+            {
+                return (DataType<T>) SQLDataType.REAL;
+            }
+            if( propertyType.equals( Double.TYPE ) )
+            {
+                return (DataType<T>) SQLDataType.DOUBLE;
+            }
+            if( propertyType.equals( Character.TYPE ) )
+            {
+                return (DataType<T>) SQLDataType.CHAR( 1 );
+            }
+            if( propertyType.equals( Short.TYPE ) )
+            {
+                return (DataType<T>) SQLDataType.INTEGER;
+            }
+            if( propertyType.equals( Byte.TYPE ) )
+            {
+                return (DataType<T>) SQLDataType.INTEGER;
+            }
+        }
+        return (DataType<T>) SQLDataType.VARCHAR;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TableFields.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TableFields.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TableFields.java
new file mode 100644
index 0000000..cfa9d99
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TableFields.java
@@ -0,0 +1,69 @@
+/*
+ *  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.Timestamp;
+import org.jooq.Field;
+
+import static org.apache.polygene.entitystore.sql.TypesTable.makeField;
+
+public interface TableFields
+{
+    // Common in all tables
+    String IDENTITY_COLUMN_NAME = "_identity";
+    String CREATED_COLUMN_NAME = "_created_at";
+    String LASTMODIFIED_COLUMN_NAME = "_modified_at";
+
+    // Types Table
+    String TABLENAME_COLUMN_NAME = "_table_name";
+
+    // Entities Table
+    String VALUEID_COLUMN_NAME = "_value_id";
+    String TYPE_COLUMN_NAME = "_type";
+    String VERSION_COLUMN_NAME = "_version";
+    String APPLICATIONVERSION_COLUMN_NAME = "_app_version";
+
+    // Mixin Tables
+    String NAME_COLUMN_NAME = "_name";
+    String INDEX_COLUMN_NAME = "_index";    // either index in ManyAssociation or name in NamedAssociation
+    String REFERENCE_COLUMN_NAME = "_reference";
+    String ASSOCS_TABLE_POSTFIX = "_ASSOCS";
+
+
+    // Common Fields
+    Field<String> identityColumn = makeField( IDENTITY_COLUMN_NAME, String.class );
+    Field<Timestamp> createdColumn = makeField( CREATED_COLUMN_NAME, Timestamp.class );
+    Field<Timestamp> modifiedColumn = makeField( LASTMODIFIED_COLUMN_NAME, Timestamp.class );
+
+    // Types Table
+    Field<String> tableNameColumn = makeField( TABLENAME_COLUMN_NAME, String.class );
+
+    // Entities Table
+    Field<String> valueIdentityColumn = makeField( VALUEID_COLUMN_NAME, String.class );
+    Field<String> typeNameColumn = makeField( TYPE_COLUMN_NAME, String.class );
+    Field<String> versionColumn = makeField( VERSION_COLUMN_NAME, String.class );
+    Field<String> applicationVersionColumn = makeField( APPLICATIONVERSION_COLUMN_NAME, String.class );
+
+    // Mixin Tables
+
+    // The _ASSOCS table
+    Field<String> nameColumn = makeField( NAME_COLUMN_NAME, String.class );
+    Field<String> referenceColumn = makeField( REFERENCE_COLUMN_NAME, String.class );
+    Field<String> indexColumn = makeField( INDEX_COLUMN_NAME, String.class );
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TypesTable.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TypesTable.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TypesTable.java
new file mode 100644
index 0000000..d04bc95
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/TypesTable.java
@@ -0,0 +1,189 @@
+/*
+ *  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.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.sql.Timestamp;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.polygene.api.association.AssociationDescriptor;
+import org.apache.polygene.api.common.QualifiedName;
+import org.apache.polygene.api.entity.EntityDescriptor;
+import org.apache.polygene.api.property.Property;
+import org.apache.polygene.api.property.PropertyDescriptor;
+import org.apache.polygene.api.util.Classes;
+import org.jooq.CreateTableColumnStep;
+import org.jooq.DataType;
+import org.jooq.Field;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.jooq.SQLDialect;
+import org.jooq.Schema;
+import org.jooq.Table;
+import org.jooq.impl.DSL;
+
+public class TypesTable
+    implements TableFields
+{
+    private final Map<Class<?>, Table<Record>> mixinTablesCache = new ConcurrentHashMap<>();
+    private final Map<Class<?>, Table<Record>> mixinAssocsTablesCache = new ConcurrentHashMap<>();
+
+    private final Table<Record> typesTable;
+    private final SQLDialect dialect;
+    private final Schema schema;
+
+    private final JooqDslContext dsl;
+
+    TypesTable( JooqDslContext dsl, Schema schema,
+                SQLDialect dialect,
+                String typesTablesName
+              )
+    {
+        this.schema = schema;
+        this.dialect = dialect;
+        typesTable = tableOf( typesTablesName );
+        this.dsl = dsl;
+    }
+
+    static <T> Field<T> makeField( String columnName, Class<T> type )
+    {
+        return DSL.field( DSL.name( columnName ), type );
+    }
+
+    Table<Record> tableOf( String tableName )
+    {
+        return DSL.table(
+            dialect.equals( SQLDialect.SQLITE )
+            ? DSL.name( tableName )
+            : DSL.name( schema.getName(), tableName ) );
+    }
+
+    String tableNameOf( Class<?> mixinType )
+    {
+        Result<Record> typeInfo = fetchTypeInfoFromTable( mixinType );
+        if( typeInfo.isEmpty() )
+        {
+            return null;
+        }
+        return typeInfo.getValue( 0, tableNameColumn );
+    }
+
+    Table<Record> tableFor( Class<?> type, EntityDescriptor descriptor )
+    {
+        return mixinTablesCache.computeIfAbsent( type, t ->
+        {
+            String tableName = tableNameOf( t );
+            if( tableName == null )
+            {
+                Result<Record> newMixinTable = createNewMixinTable( type, descriptor );
+                return tableOf( newMixinTable.getValue( 0, tableNameColumn ) );
+            }
+            return tableOf( tableName );
+        } );
+    }
+
+    private Result<Record> fetchTypeInfoFromTable( Class<?> mixinTableName )
+    {
+        return dsl.select()
+                  .from( typesTable )
+                  .where( identityColumn.eq( mixinTableName.getName() ) )
+                  .fetch();
+    }
+
+    private Result<Record> createNewMixinTable( Class<?> mixinType, EntityDescriptor descriptor )
+    {
+        String mixinTypeName = mixinType.getName();
+        String tableName = createNewTableName( mixinType );
+        CreateTableColumnStep primaryTable = dsl.createTable( DSL.name( schema.getName(), tableName ) )
+                                                .column( identityColumn )
+                                                .column( createdColumn );
+        descriptor.state().properties().forEach(
+            property ->
+            {
+                QualifiedName qualifiedName = property.qualifiedName();
+                if( qualifiedName.type().replace( '-', '$' ).equals( mixinTypeName ) )
+                {
+                    primaryTable.column( fieldOf( property ) );
+                }
+            } );
+        descriptor.state().associations().forEach(
+            assoc ->
+            {
+                QualifiedName qualifiedName = assoc.qualifiedName();
+                if( qualifiedName.type().replace( '-', '$' ).equals( mixinTypeName ) )
+                {
+                    primaryTable.column( fieldOf( assoc ) );
+                }
+            } );
+        int result1 = primaryTable.execute();
+        int result3 = dsl.insertInto( typesTable )
+                         .set( identityColumn, mixinTypeName )
+                         .set( tableNameColumn, tableName )
+                         .set( createdColumn, new Timestamp( System.currentTimeMillis() ) )
+                         .set( modifiedColumn, new Timestamp( System.currentTimeMillis() ) )
+                         .execute();
+        return fetchTypeInfoFromTable( mixinType );
+    }
+
+    private String createNewTableName( Class<?> mixinType )
+    {
+        String typeName = mixinType.getSimpleName();
+        String postFix = "";
+        int counter = 0;
+        boolean found = false;
+        do
+        {
+            found = checkForTableNamed( typeName + postFix );
+            postFix = "_" + counter++;
+        } while( found );
+        return typeName;
+    }
+
+    private boolean checkForTableNamed( String tableName )
+    {
+        return dsl.select()
+                  .from( typesTable )
+                  .where( tableNameColumn.eq( tableName ) )
+                  .fetch().size() > 0;
+    }
+
+    private boolean isProperty( Method method )
+    {
+        return Property.class.isAssignableFrom( method.getReturnType() ) && method.getParameterCount() == 0;
+    }
+
+    Field<Object> fieldOf( PropertyDescriptor descriptor )
+    {
+        String propertyName = descriptor.qualifiedName().name();
+        return DSL.field( DSL.name( propertyName ), dataTypeOf( descriptor ) );
+    }
+
+    Field<String> fieldOf( AssociationDescriptor descriptor )
+    {
+        String propertyName = descriptor.qualifiedName().name();
+        return DSL.field( DSL.name( propertyName ), DSL.getDataType( String.class ) );
+    }
+
+    private <T> DataType<T> dataTypeOf( PropertyDescriptor property )
+    {
+        Type type = property.type();
+        Class<?> rawType = Classes.RAW_CLASS.apply( type );
+        return SqlType.getSqlDataTypeFor( rawType );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java
new file mode 100644
index 0000000..b1f660f
--- /dev/null
+++ b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/assembly/SqlEntityStoreAssembler.java
@@ -0,0 +1,77 @@
+/*
+ *  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.Assembler;
+import org.apache.polygene.bootstrap.Assemblers;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.entitystore.sql.JooqDslContext;
+import org.apache.polygene.entitystore.sql.SqlEntityStoreConfiguration;
+import org.apache.polygene.entitystore.sql.SqlEntityStoreService;
+import org.jooq.SQLDialect;
+import org.jooq.conf.RenderNameStyle;
+import org.jooq.conf.Settings;
+
+/**
+ * JOOQ EntityStore assembly.
+ */
+@SuppressWarnings( "WeakerAccess" )
+public class SqlEntityStoreAssembler extends Assemblers.VisibilityIdentityConfig<SqlEntityStoreAssembler>
+    implements Assembler
+{
+    public static final Identity DEFAULT_ENTITYSTORE_IDENTITY = StringIdentity.identityOf( "entitystore-sql" );
+
+    @Override
+    public void assemble( ModuleAssembly module )
+    {
+        Settings settings = getSettings();
+        if( settings == null )
+        {
+            throw new AssemblyException( "Settings must not be null" );
+        }
+
+        String identity = ( hasIdentity() ? identity() : DEFAULT_ENTITYSTORE_IDENTITY ).toString();
+        module.transients( JooqDslContext.class );
+
+        module.services( SqlEntityStoreService.class )
+              .identifiedBy( identity )
+              .visibleIn( visibility() )
+              .instantiateOnStartup()
+              .setMetaInfo( settings );
+
+        if( hasConfig() )
+        {
+            configModule().entities( SqlEntityStoreConfiguration.class ).visibleIn( configVisibility() );
+        }
+    }
+
+    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/6055b8f7/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SqlEntityStoreTest.java
----------------------------------------------------------------------
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SqlEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SqlEntityStoreTest.java
new file mode 100644
index 0000000..d8f0d59
--- /dev/null
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/SqlEntityStoreTest.java
@@ -0,0 +1,88 @@
+/*
+ *  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.SqlEntityStoreAssembler;
+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.entity.AbstractEntityStoreTest;
+import org.jooq.SQLDialect;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+public class SqlEntityStoreTest extends AbstractEntityStoreTest
+{
+    @Rule
+    public final TemporaryFolder tmpDir = new TemporaryFolder();
+
+    @Override
+    // START SNIPPET: assembly
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        // END SNIPPET: assembly
+        super.assemble( module );
+        module.defaultServices();
+        ModuleAssembly config = module.layer().module( "config" );
+        new EntityTestAssembler().visibleIn( Visibility.module ).assemble( config );
+
+        // START SNIPPET: assembly
+        // Assemble a DataSource
+        new DataSourceAssembler()
+            .withDataSourceServiceIdentity( "datasource" )
+            .identifiedBy( "ds-mysql" )
+            .visibleIn( Visibility.module )
+            .assemble( module );
+
+        // Assemble the Apache DBCP based Service Importer
+        new DBCPDataSourceServiceAssembler()
+            .identifiedBy( "datasource" )
+            .visibleIn( Visibility.module )
+            .withConfig( config, Visibility.layer )
+            .assemble( module );
+
+        new SqlEntityStoreAssembler()
+            .withConfig( config, Visibility.layer )
+            .identifiedBy( "sql-entitystore" )
+            .assemble( module );
+        // END SNIPPET: assembly
+
+        SqlEntityStoreConfiguration jooqDefaults = config.forMixin( SqlEntityStoreConfiguration.class )
+                                                         .setMetaInfo( SQLDialect.H2 )
+                                                         .declareDefaults();
+        jooqDefaults.entitiesTableName().set( "ENTITIES" );
+
+        DataSourceConfiguration dsDefaults = config.forMixin( DataSourceConfiguration.class ).declareDefaults();
+        dsDefaults.driver().set( org.h2.Driver.class.getName() );
+        dsDefaults.enabled().set( true );
+        dsDefaults.maxPoolSize().set( 3 );
+        dsDefaults.minPoolSize().set( 1 );
+        dsDefaults.username().set( "" );
+        dsDefaults.password().set( "" );
+        dsDefaults.url().set( "jdbc:h2:" + tmpDir.getRoot().getAbsolutePath() + "/testdb;create=true" );
+        // START SNIPPET: assembly
+    }
+    // END SNIPPET: assembly
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/6055b8f7/settings.gradle
----------------------------------------------------------------------
diff --git a/settings.gradle b/settings.gradle
index 78570dc..3a4067c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -61,13 +61,13 @@ include 'core:api',
         'extensions:entitystore-hazelcast',
         'extensions:entitystore-jclouds',
         'extensions:entitystore-jdbm',
-        'extensions:entitystore-jooq',
         'extensions:entitystore-leveldb',
         'extensions:entitystore-memory',
         'extensions:entitystore-mongodb',
         'extensions:entitystore-preferences',
         'extensions:entitystore-redis',
         'extensions:entitystore-riak',
+        'extensions:entitystore-sql',
         'extensions:entitystore-sqlkv',
         'extensions:indexing-elasticsearch',
         'extensions:indexing-rdf',


[05/15] polygene-java git commit: Merge branch 'es-jooq' into develop

Posted by ni...@apache.org.
Merge branch 'es-jooq' into develop

# Conflicts:
#	manual/src/docs/userguide/extensions.txt


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/ad658f64
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/ad658f64
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/ad658f64

Branch: refs/heads/es-sql
Commit: ad658f6483fb31507eaffcb5b8de5dffaeed2b9a
Parents: 2bef712 9e12cd7
Author: niclas <ni...@hedhman.org>
Authored: Sat Sep 9 10:07:56 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Sat Sep 9 10:07:56 2017 +0800

----------------------------------------------------------------------
 .../org/apache/polygene/api/PolygeneAPI.java    |   1 +
 .../api/association/AssociationDescriptor.java  |   8 +-
 .../api/property/PropertyDescriptor.java        |   8 +-
 .../composite/FragmentInvocationHandler.java    |   2 +-
 .../runtime/methods/AccessibleTest.java         | 120 ++++++
 .../test/entity/AbstractEntityStoreTest.java    |   3 -
 extensions/entitystore-jooq/build.gradle        |  44 +++
 extensions/entitystore-jooq/dev-status.xml      |  38 ++
 .../entitystore-jooq/src/docs/es-jooq.txt       |  58 +++
 .../entitystore/jooq/AssociationValue.java      |  28 ++
 .../polygene/entitystore/jooq/BaseEntity.java   |  34 ++
 .../entitystore/jooq/EntitiesTable.java         | 363 +++++++++++++++++++
 .../entitystore/jooq/JooqDslContext.java        |  58 +++
 .../jooq/JooqEntityStoreConfiguration.java      |  73 ++++
 .../entitystore/jooq/JooqEntityStoreMixin.java  | 256 +++++++++++++
 .../jooq/JooqEntityStoreService.java            |  36 ++
 .../polygene/entitystore/jooq/MixinTable.java   | 256 +++++++++++++
 .../polygene/entitystore/jooq/SqlTable.java     | 277 ++++++++++++++
 .../polygene/entitystore/jooq/SqlType.java      | 141 +++++++
 .../polygene/entitystore/jooq/TableFields.java  |  69 ++++
 .../polygene/entitystore/jooq/TypesTable.java   | 189 ++++++++++
 .../jooq/assembly/JooqEntityStoreAssembler.java |  77 ++++
 .../entitystore/jooq/JooqEntityStoreTest.java   |  88 +++++
 .../sql/dbcp/DBCPDataSourceServiceImporter.java |   3 +-
 manual/src/docs/userguide/extensions.txt        |   4 +
 settings.gradle                                 |   1 +
 26 files changed, 2221 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/ad658f64/manual/src/docs/userguide/extensions.txt
----------------------------------------------------------------------
diff --cc manual/src/docs/userguide/extensions.txt
index 928b90e,5026259..82c692b
--- a/manual/src/docs/userguide/extensions.txt
+++ b/manual/src/docs/userguide/extensions.txt
@@@ -105,7 -105,11 +105,11 @@@ include::../../../../extensions/entitys
  
  :leveloffset: 2
  
 -include::../../../../extensions/entitystore-jooq/src/docs/es-jooq.txt[]
++include::../../../../extensions/entitystore-sql/src/docs/es-jooq.txt[]
+ 
+ :leveloffset: 2
+ 
 -include::../../../../extensions/entitystore-sql/src/docs/es-sql.txt[]
 +include::../../../../extensions/entitystore-sqlkv/src/docs/es-sqlkv.txt[]
  
  :leveloffset: 2
  

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/ad658f64/settings.gradle
----------------------------------------------------------------------