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/10/26 07:34:41 UTC
[11/33] polygene-java git commit: A lot of things fixed to get closer
to a working implementation.
A lot of things fixed to get closer to a working implementation.
Signed-off-by: niclas <ni...@hedhman.org>
Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/59a08629
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/59a08629
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/59a08629
Branch: refs/heads/develop
Commit: 59a08629239a38bdf93cf02fb1a3722e36abbdd8
Parents: ffd7207
Author: niclas <ni...@hedhman.org>
Authored: Sun Jun 11 11:43:12 2017 +0800
Committer: niclas <ni...@hedhman.org>
Committed: Sun Jun 11 11:43:12 2017 +0800
----------------------------------------------------------------------
.../test/entity/AbstractEntityStoreTest.java | 3 -
extensions/entitystore-jooq/dev-status.xml | 20 +-
.../entitystore-jooq/src/docs/es-jooq.txt | 58 +++++
extensions/entitystore-jooq/src/docs/es-orm.txt | 58 -----
.../entitystore/jooq/AssociationValue.java | 7 +-
.../polygene/entitystore/jooq/BaseEntity.java | 3 +-
.../entitystore/jooq/EntitiesTable.java | 210 ++++++++++++++-----
.../entitystore/jooq/JooqEntityStoreMixin.java | 128 ++++++-----
.../polygene/entitystore/jooq/MixinTable.java | 197 +++++++++++------
.../polygene/entitystore/jooq/SqlTable.java | 37 +++-
.../polygene/entitystore/jooq/TableFields.java | 22 +-
.../polygene/entitystore/jooq/TypesTable.java | 10 +-
.../entitystore/jooq/JooqEntityStoreTest.java | 21 +-
manual/src/docs/userguide/extensions.txt | 4 +
14 files changed, 506 insertions(+), 272 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/59a08629/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 2bb6abb..0eee83a 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
@@ -359,7 +359,6 @@ public abstract class AbstractEntityStoreTest
try( UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork() )
{
EntityBuilder<TestEntity> builder = unitOfWork.newEntityBuilder( TestEntity.class );
-
testEntity = builder.newInstance();
unitOfWork.complete();
}
@@ -368,7 +367,6 @@ public abstract class AbstractEntityStoreTest
testEntity = unitOfWork.get( testEntity );
testEntity.name().set( "Rickard" );
version = spi.entityStateOf( testEntity ).version();
-
unitOfWork.complete();
}
try( UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork() )
@@ -376,7 +374,6 @@ public abstract class AbstractEntityStoreTest
testEntity = unitOfWork.get( testEntity );
String newVersion = spi.entityStateOf( testEntity ).version();
assertThat( "version has not changed", newVersion, not( equalTo( version ) ) );
-
unitOfWork.complete();
}
}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/59a08629/extensions/entitystore-jooq/dev-status.xml
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/dev-status.xml b/extensions/entitystore-jooq/dev-status.xml
index 0914c52..6710bdd 100644
--- a/extensions/entitystore-jooq/dev-status.xml
+++ b/extensions/entitystore-jooq/dev-status.xml
@@ -23,16 +23,16 @@
xsi:schemaLocation="http://polygene.apache.org/schemas/2008/dev-status/1
http://polygene.apache.org/schemas/2008/dev-status/1/dev-status.xsd">
<status>
- <!--none,early,beta,stable,mature-->
- <codebase>stable</codebase>
+ <!--none,early,beta,stable,mature-->
+ <codebase>early</codebase>
- <!-- none, brief, good, complete -->
- <documentation>good</documentation>
+ <!-- none, brief, good, complete -->
+ <documentation>none</documentation>
- <!-- none, some, good, complete -->
- <unittests>good</unittests>
- </status>
- <licenses>
- <license>ALv2</license>
- </licenses>
+ <!-- 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/59a08629/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
new file mode 100644
index 0000000..a36d463
--- /dev/null
+++ b/extensions/entitystore-jooq/src/docs/es-jooq.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/59a08629/extensions/entitystore-jooq/src/docs/es-orm.txt
----------------------------------------------------------------------
diff --git a/extensions/entitystore-jooq/src/docs/es-orm.txt b/extensions/entitystore-jooq/src/docs/es-orm.txt
deleted file mode 100644
index 413eb7b..0000000
--- a/extensions/entitystore-jooq/src/docs/es-orm.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-orm,ORM EntityStore]]
-= ORM EntityStore =
-
-[devstatus]
---------------
-source=extensions/entitystore-orm/dev-status.xml
---------------
-
-This entitystore is backed by a SQL server, and maps each 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-riak/src/test/java/org/apache/polygene/entitystore/orm/OrmEntityStoreTest.java
-tag=assembly
-----
-
-== Configuration ==
-
-Here are the available configuration properties:
-
-[snippet,java]
-----
-source=extensions/entitystore-riak/src/main/java/org/apache/polygene/entitystore/orm/OrmEntityStoreConfiguration.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/59a08629/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
index 81331cf..528ab8b 100644
--- 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
@@ -17,9 +17,12 @@
*/
package org.apache.polygene.entitystore.jooq;
-class AssociationValue
+import org.apache.polygene.api.common.QualifiedName;
+
+@SuppressWarnings( "WeakerAccess" )
+public class AssociationValue
{
- String name;
+ QualifiedName name;
String position;
String reference;
}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/59a08629/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
index e4eaa40..3c16f16 100644
--- 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
@@ -21,7 +21,8 @@ import java.time.Instant;
import org.apache.polygene.api.entity.EntityDescriptor;
import org.apache.polygene.api.identity.Identity;
-class BaseEntity
+@SuppressWarnings( "WeakerAccess" )
+public class BaseEntity
{
EntityDescriptor type;
Identity identity;
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/59a08629/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
index dc765a9..001b590 100644
--- 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
@@ -26,12 +26,18 @@ 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;
@@ -48,10 +54,14 @@ 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<>();
@@ -60,6 +70,7 @@ public class EntitiesTable
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 )
{
@@ -72,7 +83,6 @@ public class EntitiesTable
public BaseEntity fetchEntity( EntityReference reference, ModuleDescriptor module )
{
- BaseEntity result = new BaseEntity();
Result<Record> baseEntityResult = dsl
.selectFrom( entitiesTable )
@@ -83,18 +93,32 @@ public class EntitiesTable
{
throw new EntityNotFoundException( reference );
}
- Record baseEntity = baseEntityResult.get( 0 );
- String typeName = baseEntity.field( typeNameColumn ).get( baseEntity );
+ 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 = baseEntity.field( versionColumn ).get( baseEntity );
- result.applicationVersion = baseEntity.field( applicationVersionColumn ).get( baseEntity );
- result.identity = EntityReference.parseEntityReference( baseEntity.field( identityColumn ).get( baseEntity ) ).identity();
- result.currentValueIdentity = EntityReference.parseEntityReference( baseEntity.field( valueIdentityColumn ).get( baseEntity ) ).identity();
- result.modifedAt = Instant.ofEpochMilli( baseEntity.field( modifiedColumn ).get( baseEntity ).getTime() );
- result.createdAt = Instant.ofEpochMilli( baseEntity.field( createdColumn ).get( baseEntity ).getTime() );
+ 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
@@ -108,34 +132,36 @@ public class EntitiesTable
}
}
- void insertEntity( DefaultEntityState state )
+ void insertEntity( DefaultEntityState state, BaseEntity baseEntity )
{
EntityCompositeType compositeType = state.entityDescriptor().valueType();
- Set<Class<?>> mixinTypes = mixinTypeCache.computeIfAbsent( compositeType, type ->
- {
- Set<Class<?>> mixins = compositeType
- .properties()
- .map( PropertyDescriptor::accessor )
- .filter( Classes.instanceOf( Method.class ) )
- .map( accessor -> (Method) accessor )
- .map( Method::getDeclaringClass )
- .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;
- } );
- String valueIdentity = UUID.randomUUID().toString();
+ Set<Class<?>> mixinTypes = mixinTypeCache.computeIfAbsent( compositeType, createMixinTypesSet( compositeType ) );
mixinTypes.forEach( type ->
{
MixinTable table = findMixinTable( type, state.entityDescriptor() );
- table.insertMixinState( state, valueIdentity );
+ 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 ) );
@@ -148,17 +174,32 @@ public class EntitiesTable
.filter( Classes.instanceOf( Method.class ) )
.map( accessor -> (Method) accessor )
.map( Method::getDeclaringClass )
+ .filter( NOT_HASIDENTITY )
+ .filter( NOT_COMPOSITE )
.collect( Collectors.toSet() );
}
- private String columnNameOf( QualifiedName propertyName )
- {
- return null;
- }
-
- void modifyEntity( Class<?> mixinType, DefaultEntityState state )
+ 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 )
@@ -175,6 +216,27 @@ public class EntitiesTable
.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>
@@ -217,31 +279,85 @@ public class EntitiesTable
*/
public SelectQuery<Record> createGetEntityQuery( EntityDescriptor entityDescriptor, EntityReference reference )
{
+ List<Table<Record>> joins = getMixinTables( entityDescriptor );
SelectJoinStep<Record> from = dsl.select().from( entitiesTable );
- List<Table<Record>> joins = getTableJoins( entityDescriptor );
for( Table<Record> joinedTable : joins )
{
- Field<String> joinedField = joinedTable.field( identityColumn );
- Condition joinCondition = joinedField.eq( entitiesTable.field( valueIdentityColumn ) );
+ 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 );
}
- return from.where( identityColumn.eq( reference.identity().toString() ) ).getQuery();
+ 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 );
+ } );
}
- public void fetchAssociations( Record record, Consumer<AssociationValue> consume )
+ private Field<String> identityColumnOf( Table<Record> joinedTable )
{
- AssociationValue value = new AssociationValue();
- value.name = record.getValue( nameColumn );
- value.position = record.getValue( indexColumn );
- value.reference = record.getValue( referenceColumn );
- consume.accept( value );
+ return DSL.field( DSL.name( joinedTable.getName(), identityColumn.getName() ), String.class );
}
- public List<Table<Record>> getTableJoins( EntityDescriptor entityDescriptor )
+ 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/59a08629/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
index a22354b..5a062d8 100644
--- 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
@@ -28,9 +28,11 @@ 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;
@@ -57,6 +59,9 @@ public class JooqEntityStoreMixin
@Service
private IdentityGenerator identityGenerator;
+ @Service
+ private Serialization serialization;
+
@Override
public EntityState newEntityState( EntityStoreUnitOfWork unitOfWork, EntityReference reference, EntityDescriptor entityDescriptor )
{
@@ -73,36 +78,45 @@ public class JooqEntityStoreMixin
{
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<>();
- stateDescriptor.properties().forEach( prop ->
- {
- QualifiedName qualifiedName = prop.qualifiedName();
- Object value = result.getValue( 0, qualifiedName.name() );
- properties.put( qualifiedName, value );
- } );
+ 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() );
- assocations.put( qualifiedName, parseEntityReference( value ) );
- } );
+ 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<>();
- result.forEach( record ->
- sqlTable.fetchAssociations( record, associationValue ->
- {
- // TODO: Perhaps introduce "preserveManyAssociationOrder" option which would have an additional column, separating 'ordinal position' and 'name position'
- if( associationValue.position == null )
- {
- addManyAssociation( stateDescriptor, manyAssocs, associationValue );
- }
- else
- {
- addNamedAssociation( stateDescriptor, namedAssocs, associationValue );
- }
- } ) );
+ 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,
@@ -117,7 +131,7 @@ public class JooqEntityStoreMixin
private void addNamedAssociation( AssociationStateDescriptor stateDescriptor, Map<QualifiedName, Map<String, EntityReference>> namedAssocs, AssociationValue associationValue )
{
- AssociationDescriptor descriptor = stateDescriptor.getNamedAssociationByName( associationValue.name );
+ 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 ) );
@@ -125,10 +139,11 @@ public class JooqEntityStoreMixin
private void addManyAssociation( AssociationStateDescriptor stateDescriptor, Map<QualifiedName, List<EntityReference>> manyAssocs, AssociationValue associationValue )
{
- AssociationDescriptor descriptor = stateDescriptor.getManyAssociationByName( associationValue.name );
+ AssociationDescriptor descriptor = stateDescriptor.getManyAssociationByName( associationValue.name.name() );
QualifiedName qualifiedName = descriptor.qualifiedName();
List<EntityReference> list = manyAssocs.computeIfAbsent( qualifiedName, k -> new ArrayList<>() );
- list.add( parseEntityReference( associationValue.reference ) );
+ String reference = associationValue.reference;
+ list.add( reference == null ? null : parseEntityReference( reference ) );
}
@Override
@@ -158,7 +173,16 @@ public class JooqEntityStoreMixin
@Override
public Stream<EntityState> entityStates( ModuleDescriptor module )
{
- return null;
+ 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
@@ -167,12 +191,36 @@ public class JooqEntityStoreMixin
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
@@ -185,11 +233,11 @@ public class JooqEntityStoreMixin
DefaultEntityState state = (DefaultEntityState) es;
if( state.status() == EntityStatus.NEW )
{
- newState( state );
+ newState( state, unitOfWork );
}
if( state.status() == EntityStatus.UPDATED )
{
- updateState( state );
+ updateState( state, unitOfWork );
}
if( state.status() == EntityStatus.REMOVED )
{
@@ -199,24 +247,6 @@ public class JooqEntityStoreMixin
} );
}
- private void newState( DefaultEntityState state )
- {
- EntityReference ref = state.entityReference();
- EntityDescriptor descriptor = state.entityDescriptor();
- sqlTable.createNewBaseEntity( ref, descriptor, unitOfWork );
- sqlTable.insertEntity( state );
- }
-
- private void updateState( DefaultEntityState state )
- {
-
- }
-
- private void removeState( DefaultEntityState state )
- {
- EntityReference reference = state.entityReference();
- }
-
@Override
public void cancel()
{
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/59a08629/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
index fee95ef..257134e 100644
--- 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
@@ -20,7 +20,11 @@ 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 java.util.function.Consumer;
import org.apache.polygene.api.association.AssociationDescriptor;
import org.apache.polygene.api.common.QualifiedName;
@@ -32,10 +36,12 @@ 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
@@ -46,6 +52,11 @@ class 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;
@@ -57,6 +68,34 @@ class MixinTable
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 -> manyAssociations.add( assocDescriptor.qualifiedName() ) );
}
void insertMixinState( DefaultEntityState state, String valueIdentity )
@@ -64,93 +103,99 @@ class MixinTable
InsertSetMoreStep<Record> primaryTable =
dsl.insertInto( mixinTable )
.set( identityColumn, valueIdentity )
- .set( createdColumn, new Timestamp( System.currentTimeMillis() ) )
- .set( modifiedColumn, new Timestamp( System.currentTimeMillis() ) );
+ .set( createdColumn, new Timestamp( System.currentTimeMillis() ) );
- EntityDescriptor entityDescriptor = state.entityDescriptor();
- entityDescriptor.valueType().properties()
- .filter( this::isThisMixin )
- .forEach( propDescriptor ->
+ 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 )
{
- QualifiedName propertyName = propDescriptor.qualifiedName();
- Field<Object> propertyField = types.fieldOf( propDescriptor );
- primaryTable.set( propertyField, state.propertyValueOf( propertyName ) );
+ identity = reference.identity().toString();
}
- );
- entityDescriptor.valueType().associations()
- .filter( this::isThisMixin )
- .forEach( assocDescriptor ->
- {
- QualifiedName assocName = assocDescriptor.qualifiedName();
- Field<String> assocField = types.fieldOf( assocDescriptor );
- EntityReference reference = state.associationValueOf( assocName );
- String identity = null;
- if( reference != null )
- {
- identity = reference.identity().toString();
- }
- primaryTable.set( assocField, identity );
- }
- );
+ primaryTable.set( assocField, identity );
+ }
+ );
+ int result = primaryTable.execute();
if( mixinAssocsTable != null )
{
- entityDescriptor.valueType().manyAssociations()
- .filter( this::isThisMixin )
- .forEach( setManyAssociations( state, valueIdentity ) );
-
- entityDescriptor.valueType().namedAssociations()
- .filter( this::isThisMixin )
- .forEach( setNamedAssociations( state, valueIdentity ) );
+ insertManyAndNamedAssociations( state, valueIdentity );
}
}
- private Consumer<? super AssociationDescriptor> setManyAssociations( DefaultEntityState state, String valueIdentity )
+ private void insertManyAndNamedAssociations( DefaultEntityState state, String valueIdentity )
{
- return assocDescriptor ->
- {
- QualifiedName assocName = assocDescriptor.qualifiedName();
- ManyAssociationState entityReferences = state.manyAssociationValueOf( assocName );
- entityReferences.stream().forEach( setManyAssociation( state, assocDescriptor, valueIdentity ) );
- };
+ InsertSetStep<Record> assocsTable = dsl.insertInto( mixinAssocsTable );
+ manyAssociations.forEach( assocName ->
+ {
+ ManyAssociationState entityReferences = state.manyAssociationValueOf( assocName );
+ entityReferences.stream().forEach( setManyAssociation( assocName, valueIdentity, assocsTable ) );
+ } );
+
+ namedAssociations.forEach( assocName ->
+ {
+ NamedAssociationState entityReferences = state.namedAssociationValueOf( assocName );
+ entityReferences.stream().forEach( setNamedAssociation( assocName, valueIdentity, assocsTable ) );
+ } );
+
+ InsertSetMoreStep<Record> assocs = assocsTable.set( Collections.emptyMap() );
+ assocs.execute();
}
- private Consumer<? super EntityReference> setManyAssociation( DefaultEntityState state,
- AssociationDescriptor assocDescriptor,
- String valueIdentity )
+ Table<Record> associationsTable()
{
- QualifiedName assocName = assocDescriptor.qualifiedName();
- Field<String> assocField = types.fieldOf( assocDescriptor );
- InsertSetMoreStep<Record> assocsTable = dsl.insertInto( mixinAssocsTable ).set( identityColumn, valueIdentity );
- return ref ->
- {
- assocsTable.newRecord();
- assocsTable.set( assocField, state.associationValueOf( assocName ).identity().toString() );
- };
+ return mixinAssocsTable;
}
- private Consumer<? super AssociationDescriptor> setNamedAssociations( DefaultEntityState state,
- String valueIdentity )
+ /**
+ * Writes one ManyAssoc Reference to the _ASSOCS table.
+ * <ul>
+ * <li>identityColumn - valueIdentity of primaryTable row</li>
+ * <li>nameColumn - index in the of association in state holder</li>
+ * <li>indexColumn - the position within the many association, starting at 0</li>
+ * <li>referenceColumn - referenced entity's identity</li>
+ * </ul>
+ */
+ private Consumer<? super EntityReference> setManyAssociation( QualifiedName assocName,
+ String valueIdentity,
+ InsertSetStep<Record> assocsTable )
{
- return assocDescriptor ->
+ return new Consumer<EntityReference>()
{
- QualifiedName assocName = assocDescriptor.qualifiedName();
- NamedAssociationState entityReferences = state.namedAssociationValueOf( assocName );
- entityReferences.stream().forEach( setNamedAssociation( state, assocDescriptor, valueIdentity ) );
+ private int counter = 0;
+
+ @Override
+ public void accept( EntityReference ref )
+ {
+ InsertSetMoreStep<Record> set = assocsTable.set( identityColumn, valueIdentity )
+ .set( nameColumn, assocName.name() )
+ .set( indexColumn, "" + counter++ )
+ .set( referenceColumn, ref == null ? null : ref.identity().toString() );
+ }
};
}
- private Consumer<? super Map.Entry<String, EntityReference>> setNamedAssociation( DefaultEntityState state,
- AssociationDescriptor assocDescriptor,
- String valueIdentity )
+ /**
+ * Writes one Named Reference to the _ASSOCS table.
+ * <ul>
+ * <li>identityColumn - valueIdentity of primaryTable row</li>
+ * <li>nameColumn - name of association in state holder</li>
+ * <li>indexColumn - the key/lookup name of the reference</li>
+ * <li>referenceColumn - referenced entity's identity</li>
+ * </ul>
+ */
+ private Consumer<? super Map.Entry<String, EntityReference>> setNamedAssociation( QualifiedName assocName,
+ String valueIdentity,
+ InsertSetStep<Record> assocsTable )
{
- QualifiedName assocName = assocDescriptor.qualifiedName();
- Field<String> assocField = types.fieldOf( assocDescriptor );
- InsertSetMoreStep<Record> assocsTable = dsl.insertInto( mixinAssocsTable ).set( identityColumn, valueIdentity );
return ref ->
{
- assocsTable.newRecord();
- assocsTable.set( assocField, state.associationValueOf( assocName ).identity().toString() );
+ InsertSetMoreStep<Record> set = assocsTable.set( identityColumn, valueIdentity )
+ .set( nameColumn, assocName.name() )
+ .set( indexColumn, ref.getKey() )
+ .set( referenceColumn, ref.getValue().identity().toString() );
};
}
@@ -186,9 +231,31 @@ class MixinTable
throw new UnsupportedOperationException( "Property declared as " + accessor.getClass() + " is not supported in this Entity Store yet." );
}
- void modifyMixinState( Class<?> mixinType, DefaultEntityState state )
+ 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 )
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/59a08629/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
index 2801f57..13b6c37 100644
--- 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
@@ -18,6 +18,7 @@
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;
@@ -99,14 +100,20 @@ public interface SqlTable extends ServiceActivation
SelectQuery<Record> createGetEntityQuery( EntityDescriptor descriptor, EntityReference reference );
- void fetchAssociations( Record record, Consumer<AssociationValue> consume );
+ void fetchAssociations( BaseEntity entity, EntityDescriptor descriptor, Consumer<AssociationValue> consume );
void createNewBaseEntity( EntityReference ref, EntityDescriptor descriptor, EntityStoreUnitOfWork unitOfWork );
- void insertEntity( DefaultEntityState state );
+ 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
{
@@ -143,15 +150,21 @@ public interface SqlTable extends ServiceActivation
}
@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( Record record, Consumer<AssociationValue> consume )
+ public void fetchAssociations( BaseEntity entity, EntityDescriptor descriptor, Consumer<AssociationValue> consume )
{
- entitiesTable.fetchAssociations( record, consume );
+ entitiesTable.fetchAssociations( entity, descriptor, consume );
}
@Override
@@ -161,9 +174,15 @@ public interface SqlTable extends ServiceActivation
}
@Override
- public void insertEntity( DefaultEntityState state )
+ public void insertEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork )
{
- entitiesTable.insertEntity( state );
+ entitiesTable.insertEntity( state, baseEntity );
+ }
+
+ @Override
+ public void updateEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreUnitOfWork unitOfWork )
+ {
+ entitiesTable.modifyEntity( state, baseEntity, unitOfWork );
}
@Override
@@ -173,6 +192,12 @@ public interface SqlTable extends ServiceActivation
}
@Override
+ public void removeEntity( EntityReference reference, EntityDescriptor descriptor )
+ {
+ entitiesTable.removeEntity( reference, descriptor );
+ }
+
+ @Override
public void activateService()
throws Exception
{
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/59a08629/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
index 2454ae4..db42413 100644
--- 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
@@ -25,23 +25,23 @@ 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";
+ 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";
+ 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";
+ 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 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";
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/59a08629/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
index 4672d4f..c816c95 100644
--- 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
@@ -110,12 +110,14 @@ public class TypesTable
{
String mixinTypeName = mixinType.getName();
String tableName = createNewTableName( mixinType );
- CreateTableColumnStep primaryTable = dsl.createTable( tableName ).column( identityColumn );
+ CreateTableColumnStep primaryTable = dsl.createTable( DSL.name( schema.getName(), tableName ) )
+ .column( identityColumn )
+ .column( createdColumn );
descriptor.state().properties().forEach(
property ->
{
QualifiedName qualifiedName = property.qualifiedName();
- if( qualifiedName.toNamespace().equals( mixinTypeName ) )
+ if( qualifiedName.type().replace( '-', '$' ).equals( mixinTypeName ) )
{
primaryTable.column( fieldOf( property ) );
}
@@ -124,12 +126,12 @@ public class TypesTable
assoc ->
{
QualifiedName qualifiedName = assoc.qualifiedName();
- if( qualifiedName.toNamespace().equals( mixinTypeName ) )
+ 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 )
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/59a08629/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
index e097662..f36db0e 100644
--- 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
@@ -29,22 +29,13 @@ 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
{
-// @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", "127.0.0.1" );
-// }},
-// 30000L
-//// , "mysqld: ready for connections" TODO: add this after next release of tdomzal/junit-docker-rule
-// );
+ @Rule
+ public final TemporaryFolder tmpDir = new TemporaryFolder();
@Override
// START SNIPPET: assembly
@@ -83,8 +74,6 @@ public class JooqEntityStoreTest extends AbstractEntityStoreTest
.declareDefaults();
jooqDefaults.entitiesTableName().set( "ENTITIES" );
- String path = System.getProperty( "user.dir" ) + "/testdb";
- System.out.println("Niclas: " + path);
DataSourceConfiguration dsDefaults = config.forMixin( DataSourceConfiguration.class ).declareDefaults();
dsDefaults.driver().set( org.h2.Driver.class.getName() );
dsDefaults.enabled().set( true );
@@ -92,7 +81,7 @@ public class JooqEntityStoreTest extends AbstractEntityStoreTest
dsDefaults.minPoolSize().set( 1 );
dsDefaults.username().set( "" );
dsDefaults.password().set( "" );
- dsDefaults.url().set( "jdbc:h2:"+path+";create=true" );
+ 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/59a08629/manual/src/docs/userguide/extensions.txt
----------------------------------------------------------------------
diff --git a/manual/src/docs/userguide/extensions.txt b/manual/src/docs/userguide/extensions.txt
index 44bfd3f..5026259 100644
--- a/manual/src/docs/userguide/extensions.txt
+++ b/manual/src/docs/userguide/extensions.txt
@@ -105,6 +105,10 @@ include::../../../../extensions/entitystore-riak/src/docs/es-riak.txt[]
:leveloffset: 2
+include::../../../../extensions/entitystore-jooq/src/docs/es-jooq.txt[]
+
+:leveloffset: 2
+
include::../../../../extensions/entitystore-sql/src/docs/es-sql.txt[]
:leveloffset: 2