Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.

Commit 5354d83

Browse files
committed
Refactored the SQL ES to not depend on JOOQ doing the right thing in regards to java.lang.String type for MariaDb and MySQL.
1 parent ee29552 commit 5354d83

15 files changed

Lines changed: 370 additions & 220 deletions

File tree

core/api/src/main/java/org/apache/polygene/api/common/QualifiedName.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,4 +258,9 @@ public int compareTo( QualifiedName other )
258258
}
259259
return name.compareTo( other.name );
260260
}
261+
262+
public boolean isOriginatingFrom( Class<?> mixinType )
263+
{
264+
return typeName.isClass( mixinType );
265+
}
261266
}

core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractEntityStoreTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,11 @@ public void whenNewEntityThenCanFindEntityAndCorrectValues()
185185

186186
assertThat( "property 'doubleValue' has incorrect value",
187187
instance.doubleValue().get(),
188-
equalTo( 42D ) );
188+
equalTo( 42.0 ) );
189189

190190
assertThat( "property 'floatValue' has incorrect value",
191191
instance.floatValue().get(),
192-
equalTo( 42F ) );
192+
equalTo( 42f ) );
193193

194194
assertThat( "property 'booleanValue' has incorrect value",
195195
instance.booleanValue().get(),

extensions/entitystore-sql/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ jar { manifest { name = "Apache Polygene™ Extension - EntityStore - ORM" } }
2727
dependencies {
2828
api polygene.core.bootstrap
2929
api polygene.library( 'sql' )
30+
api polygene.library( 'constraints' )
3031
api libraries.jooq
3132

3233
runtimeOnly polygene.core.runtime

extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/EntitiesTable.java

Lines changed: 79 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -53,48 +53,75 @@
5353
import org.jooq.Record;
5454
import org.jooq.RecordType;
5555
import org.jooq.Result;
56+
import org.jooq.SQLDialect;
5657
import org.jooq.SelectJoinStep;
5758
import org.jooq.SelectQuery;
5859
import org.jooq.Table;
5960
import org.jooq.impl.DSL;
6061

62+
import static org.apache.polygene.entitystore.sql.MixinTable.INDEX_COLUMN_NAME;
63+
import static org.apache.polygene.entitystore.sql.MixinTable.NAME_COLUMN_NAME;
64+
import static org.apache.polygene.entitystore.sql.MixinTable.REFERENCE_COLUMN_NAME;
65+
import static org.apache.polygene.entitystore.sql.SqlType.makeField;
66+
6167
/**
6268
* This class handles all the dealing with the main table, called the Entities Table.
6369
* <p>
64-
* This is the table that holds the {@link BaseEntity} rows, and joins with the different so called
65-
* {@link MixinTable}, which handles one table per Mixin type.
70+
* This is the table that holds the {@link BaseEntity} rows, and joins with the different so called
71+
* {@link MixinTable}, which handles one table per Mixin type.
6672
* </p>
6773
*/
6874
@SuppressWarnings( "WeakerAccess" )
6975
public class EntitiesTable
70-
implements TableFields
7176
{
77+
private static final String VALUEID_COLUMN_NAME = "_value_id";
78+
private static final String TYPE_COLUMN_NAME = "_type";
79+
private static final String VERSION_COLUMN_NAME = "_version";
80+
private static final String APPLICATIONVERSION_COLUMN_NAME = "_app_version";
81+
7282
private static final Predicate<? super Class<?>> NOT_COMPOSITE = type -> !( type.equals( Composite.class ) || type.equals( EntityComposite.class ) );
7383
private static final Predicate<? super Class<?>> NOT_HASIDENTITY = type -> !( type.equals( HasIdentity.class ) );
84+
private final SQLDialect dialect;
7485
private Map<EntityCompositeType, Set<Class<?>>> mixinTypeCache = new ConcurrentHashMap<>();
7586
private Map<Class<?>, MixinTable> mixinTablesCache = new ConcurrentHashMap<>();
7687

7788
private final Table<Record> entitiesTable;
78-
private JooqDslContext dsl;
89+
90+
private Field<String> valueIdentityColumn;
91+
private Field<String> typeNameColumn;
92+
private Field<String> versionColumn;
93+
private Field<String> applicationVersionColumn;
94+
95+
private final JooqDslContext dsl;
7996
private final TypesTable types;
80-
private String applicationVersion;
81-
private Serialization serialization;
97+
private final String applicationVersion;
98+
private final Serialization serialization;
8299
private boolean replacementStrategy = false; // Figure out later if we should support both and if so, how.
83100

84-
EntitiesTable( JooqDslContext dsl, TypesTable types, String applicationVersion, String entitiesTableName, Serialization serialization )
101+
EntitiesTable( JooqDslContext dsl,
102+
SQLDialect dialect,
103+
TypesTable types,
104+
String applicationVersion,
105+
String entitiesTableName,
106+
Serialization serialization )
85107
{
86108
this.dsl = dsl;
109+
this.dialect = dialect;
87110
this.types = types;
88111
this.applicationVersion = applicationVersion;
89112
this.serialization = serialization;
90113
entitiesTable = dsl.tableOf( entitiesTableName );
114+
valueIdentityColumn = makeField( VALUEID_COLUMN_NAME, String.class, dialect );
115+
typeNameColumn = makeField( TYPE_COLUMN_NAME, String.class, dialect );
116+
versionColumn = makeField( VERSION_COLUMN_NAME, String.class, dialect );
117+
applicationVersionColumn = makeField( APPLICATIONVERSION_COLUMN_NAME, String.class, dialect );
91118
}
92119

93120
public BaseEntity fetchEntity( EntityReference reference, ModuleDescriptor module )
94121
{
95122
Result<Record> baseEntityResult = dsl
96123
.selectFrom( entitiesTable )
97-
.where( identityColumn.eq( reference.identity().toString() ) )
124+
.where( types.identityColumn().eq( reference.identity().toString() ) )
98125
.fetch();
99126

100127
if( baseEntityResult.isEmpty() )
@@ -112,10 +139,10 @@ protected BaseEntity toBaseEntity( Record row, ModuleDescriptor module )
112139
result.type = findEntityDescriptor( typeName, module );
113140
result.version = row.field( versionColumn ).get( row );
114141
result.applicationVersion = row.field( applicationVersionColumn ).get( row );
115-
result.identity = StringIdentity.identityOf( row.field( identityColumn ).get( row ) );
142+
result.identity = StringIdentity.identityOf( row.field( types.identityColumn() ).get( row ) );
116143
result.currentValueIdentity = EntityReference.parseEntityReference( row.field( valueIdentityColumn ).get( row ) ).identity();
117-
result.modifedAt = Instant.ofEpochMilli( row.field( modifiedColumn ).get( row ).getTime() );
118-
result.createdAt = Instant.ofEpochMilli( row.field( createdColumn ).get( row ).getTime() );
144+
result.modifedAt = Instant.ofEpochMilli( row.field( types.modifiedColumn() ).get( row ).getTime() );
145+
result.createdAt = Instant.ofEpochMilli( row.field( types.createdColumn() ).get( row ).getTime() );
119146
return result;
120147
}
121148

@@ -172,7 +199,7 @@ void modifyEntity( DefaultEntityState state, BaseEntity baseEntity, EntityStoreU
172199

173200
private MixinTable findMixinTable( Class<?> type, EntityDescriptor entityDescriptor )
174201
{
175-
return mixinTablesCache.computeIfAbsent( type, t -> new MixinTable( dsl, types, type, entityDescriptor, serialization ) );
202+
return mixinTablesCache.computeIfAbsent( type, t -> new MixinTable( dsl, dialect, types, type, entityDescriptor, serialization ) );
176203
}
177204

178205
private Set<Class<?>> mixinsOf( Stream<? extends AssociationDescriptor> stream )
@@ -216,9 +243,9 @@ BaseEntity createNewBaseEntity( EntityReference reference, EntityDescriptor desc
216243
String typeName = descriptor.primaryType().getName();
217244
Instant currentTime = uow.currentTime();
218245
dsl.insertInto( entitiesTable )
219-
.set( identityColumn, reference.identity().toString() )
220-
.set( createdColumn, new Timestamp( currentTime.toEpochMilli() ))
221-
.set( modifiedColumn, new Timestamp( currentTime.toEpochMilli()) )
246+
.set( types.identityColumn(), reference.identity().toString() )
247+
.set( types.createdColumn(), new Timestamp( currentTime.toEpochMilli() ) )
248+
.set( types.modifiedColumn(), new Timestamp( currentTime.toEpochMilli() ) )
222249
.set( valueIdentityColumn, valueIdentity )
223250
.set( typeNameColumn, typeName )
224251
.set( versionColumn, "1" )
@@ -243,11 +270,11 @@ private void updateBaseEntity( BaseEntity entity, EntityStoreUnitOfWork uow )
243270
entity.currentValueIdentity = StringIdentity.identityOf( UUID.randomUUID().toString() );
244271
}
245272
dsl.update( entitiesTable )
246-
.set( modifiedColumn, new Timestamp( uow.currentTime().toEpochMilli() ) )
273+
.set( types.modifiedColumn(), new Timestamp( uow.currentTime().toEpochMilli() ) )
247274
.set( valueIdentityColumn, entity.currentValueIdentity.toString() )
248275
.set( versionColumn, entity.version )
249276
.set( applicationVersionColumn, applicationVersion )
250-
.where( identityColumn.eq( entity.identity.toString() ) )
277+
.where( types.identityColumn().eq( entity.identity.toString() ) )
251278
.execute();
252279
}
253280

@@ -321,32 +348,32 @@ public void fetchAssociations( BaseEntity entity, EntityDescriptor entityDescrip
321348
SelectQuery<Record> query = from.where( identityColumnOf( entitiesTable ).eq( reference ) ).getQuery();
322349
Result<Record> result = query.fetch();
323350
RecordType<Record> recordType = result.recordType();
324-
result.forEach( record ->
325-
{
326-
AssociationValue value = new AssociationValue();
327-
if( recordType.indexOf( referenceColumn ) >= 0 )
328-
{
329-
// some many-to-many association found.
330-
if( recordType.indexOf( nameColumn ) >= 0 )
331-
{
332-
// NamedAssociations found.
333-
value.name = QualifiedName.fromClass( entityDescriptor.primaryType(), record.getValue( nameColumn ) );
334-
}
335-
if( recordType.indexOf( indexColumn ) >= 0 )
336-
{
337-
// ManyAssociations found.
338-
value.position = record.getValue( indexColumn );
339-
}
340-
value.reference = record.getValue( referenceColumn );
341-
}
342-
consume.accept( value );
343-
} );
351+
result.forEach( record -> {
352+
AssociationValue value = new AssociationValue();
353+
if( recordType.indexOf( MixinTable.REFERENCE_COLUMN_NAME ) >= 0 )
354+
{
355+
// some many-to-many association found.
356+
if( recordType.indexOf( NAME_COLUMN_NAME ) >= 0 )
357+
{
358+
// NamedAssociations found.
359+
value.name = QualifiedName.fromClass( entityDescriptor.primaryType(), (String) record.get( NAME_COLUMN_NAME ) );
360+
EntityCompositeType valueType = entityDescriptor.valueType();
361+
}
362+
if( recordType.indexOf( INDEX_COLUMN_NAME ) >= 0 )
363+
{
364+
// ManyAssociations found.
365+
value.position = (String) record.get( INDEX_COLUMN_NAME );
366+
}
367+
value.reference = (String) record.get( REFERENCE_COLUMN_NAME );
368+
consume.accept( value );
369+
}
370+
} );
344371
}
345372

346373
private Field<String> identityColumnOf( Table<Record> joinedTable )
347374
{
348375
String name = joinedTable.getName();
349-
String identity = identityColumn.getName();
376+
String identity = types.identityColumn().getName();
350377
return DSL.field( DSL.name( name, identity ), String.class );
351378
}
352379

@@ -395,4 +422,18 @@ public void removeEntity( EntityReference entityReference, EntityDescriptor desc
395422
assocTables.forEach( table -> dsl.delete( table ).where( identityColumnOf( table ).eq( valueId ) ).execute() );
396423
}
397424
}
425+
426+
void create()
427+
{
428+
dsl.createTableIfNotExists( entitiesTable )
429+
.column( types.identityColumn() )
430+
.column( types.createdColumn() )
431+
.column( typeNameColumn )
432+
.column( applicationVersionColumn )
433+
.column( versionColumn )
434+
.column( types.modifiedColumn() )
435+
.column( valueIdentityColumn )
436+
.constraint( DSL.primaryKey( types.identityColumn() ) )
437+
.execute();
438+
}
398439
}

extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/MixinTable.java

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@
3232
import org.apache.polygene.api.property.PropertyDescriptor;
3333
import org.apache.polygene.api.serialization.Serialization;
3434
import org.apache.polygene.api.type.ValueType;
35-
import org.apache.polygene.spi.PolygeneSPI;
3635
import org.apache.polygene.spi.entity.ManyAssociationState;
3736
import org.apache.polygene.spi.entity.NamedAssociationState;
3837
import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
3938
import org.jooq.Field;
4039
import org.jooq.InsertSetMoreStep;
4140
import org.jooq.InsertSetStep;
4241
import org.jooq.Record;
42+
import org.jooq.SQLDialect;
4343
import org.jooq.Table;
4444
import org.jooq.UpdateSetMoreStep;
4545
import org.jooq.impl.DSL;
@@ -48,36 +48,47 @@
4848
* MixinTable is a class that handles the creation of the queries into the Mixin tables, both for insertions/updates
4949
* as well as retrieval.
5050
* <p>
51-
* Note that these tables are only queried as part of a SQL {@code JOIN} statement and never directly.
51+
* Note that these tables are only queried as part of a SQL {@code JOIN} statement and never directly.
5252
* </p>
5353
* <p>
54-
* Creation of the actual Mixin tables happens in {@link TypesTable}.
54+
* Creation of the actual Mixin tables happens in {@link TypesTable}.
5555
* </p>
5656
*/
5757
class MixinTable
58-
implements TableFields
5958
{
59+
static final String NAME_COLUMN_NAME = "_name";
60+
static final String INDEX_COLUMN_NAME = "_index"; // either index in ManyAssociation or name in NamedAssociation
61+
static final String REFERENCE_COLUMN_NAME = "_reference";
62+
private static final String ASSOCS_TABLE_POSTFIX = "_ASSOCS";
6063

6164
private final Table<Record> mixinTable;
6265
private final Table<Record> mixinAssocsTable;
6366

67+
private Field<String> nameColumn;
68+
private Field<String> referenceColumn;
69+
private Field<String> indexColumn;
70+
6471
private final JooqDslContext dsl;
6572
private final Map<QualifiedName, Field<Object>> properties = new ConcurrentHashMap<>();
6673
private final Map<QualifiedName, Field<String>> associations = new ConcurrentHashMap<>();
6774
private final List<QualifiedName> manyAssociations = new CopyOnWriteArrayList<>();
6875
private final List<QualifiedName> namedAssociations = new CopyOnWriteArrayList<>();
6976

7077
private final Class<?> mixinType;
78+
private final TypesTable types;
7179
private Serialization serialization;
7280

73-
PolygeneSPI spi;
74-
75-
MixinTable( JooqDslContext dsl, TypesTable types, Class<?> mixinType,
81+
MixinTable( JooqDslContext dsl, SQLDialect dialect, TypesTable types, Class<?> mixinType,
7682
EntityDescriptor descriptor, Serialization serialization )
7783
{
84+
this.types = types;
7885
this.dsl = dsl;
7986
this.mixinType = mixinType;
8087
this.serialization = serialization;
88+
nameColumn = SqlType.makeField( NAME_COLUMN_NAME, String.class, dialect);
89+
referenceColumn = SqlType.makeField( REFERENCE_COLUMN_NAME, String.class, dialect );
90+
indexColumn = SqlType.makeField( INDEX_COLUMN_NAME, String.class, dialect );
91+
8192
mixinTable = types.tableFor( mixinType, descriptor );
8293
mixinAssocsTable = getAssocsTable( descriptor );
8394

@@ -114,8 +125,8 @@ void insertMixinState( DefaultEntityState state, String valueIdentity )
114125
{
115126
InsertSetMoreStep<Record> primaryTable =
116127
dsl.insertInto( mixinTable )
117-
.set( identityColumn, valueIdentity )
118-
.set( createdColumn, new Timestamp( System.currentTimeMillis() ) );
128+
.set( types.identityColumn(), valueIdentity )
129+
.set( types.createdColumn(), new Timestamp( System.currentTimeMillis() ) );
119130

120131
properties
121132
.entrySet()
@@ -142,8 +153,8 @@ private void insertManyAndNamedAssociations( DefaultEntityState state, String va
142153
int counter = 0;
143154
for( EntityReference ref : entityReferences )
144155
{
145-
InsertSetMoreStep<Record> set = assocsTable.set( identityColumn, valueIdentity )
146-
.set( createdColumn, new Timestamp( System.currentTimeMillis() ) )
156+
InsertSetMoreStep<Record> set = assocsTable.set( types.identityColumn(), valueIdentity )
157+
.set( types.createdColumn(), new Timestamp( System.currentTimeMillis() ) )
147158
.set( nameColumn, assocName.name() )
148159
.set( indexColumn, "" + counter++ )
149160
.set( referenceColumn, ref == null ? null : ref.identity().toString() );
@@ -169,8 +180,8 @@ private void insertManyAndNamedAssociations( DefaultEntityState state, String va
169180
for( String name : entityReferences )
170181
{
171182
EntityReference ref = entityReferences.get( name );
172-
InsertSetMoreStep<Record> set = assocsTable.set( identityColumn, valueIdentity )
173-
.set( createdColumn, new Timestamp( System.currentTimeMillis() ) )
183+
InsertSetMoreStep<Record> set = assocsTable.set( types.identityColumn(), valueIdentity )
184+
.set( types.createdColumn(), new Timestamp( System.currentTimeMillis() ) )
174185
.set( nameColumn, assocName.name() )
175186
.set( indexColumn, name )
176187
.set( referenceColumn, ref.identity().toString() );
@@ -243,7 +254,7 @@ void modifyMixinState( DefaultEntityState state, String valueId )
243254
{
244255
// Need to remove existing records.
245256
dsl.delete( mixinAssocsTable )
246-
.where( identityColumn.eq( valueId ) )
257+
.where( types.identityColumn().eq( valueId ) )
247258
.execute();
248259
insertManyAndNamedAssociations( state, valueId );
249260
}
@@ -255,15 +266,15 @@ private Table<Record> getAssocsTable( EntityDescriptor descriptor )
255266
|| descriptor.state().namedAssociations().count() > 0 )
256267
{
257268
Table<Record> table = dsl.tableOf( mixinTable.getName() + ASSOCS_TABLE_POSTFIX );
258-
int result2 = dsl.createTableIfNotExists( table )
259-
.column( identityColumn )
260-
.column( createdColumn )
261-
.column( nameColumn )
262-
.column( indexColumn )
263-
.column( referenceColumn )
264-
.execute();
269+
int result = dsl.createTableIfNotExists( table )
270+
.column( types.identityColumn() )
271+
.column( types.createdColumn() )
272+
.column( nameColumn )
273+
.column( indexColumn )
274+
.column( referenceColumn )
275+
.execute();
265276
dsl.createIndex( DSL.name( "IDX_" + table.getName() ) )
266-
.on( table, identityColumn )
277+
.on( table, types.identityColumn() )
267278
.execute();
268279
return table;
269280
}

0 commit comments

Comments
 (0)