Refactored the SQL ES to not depend on JOOQ doing the right thing in regards to java.lang.String type for MariaDb and MySQL.
diff --git a/core/api/src/main/java/org/apache/polygene/api/common/QualifiedName.java b/core/api/src/main/java/org/apache/polygene/api/common/QualifiedName.java
index 657b6de..badbd3b 100644
--- a/core/api/src/main/java/org/apache/polygene/api/common/QualifiedName.java
+++ b/core/api/src/main/java/org/apache/polygene/api/common/QualifiedName.java
@@ -258,4 +258,9 @@
}
return name.compareTo( other.name );
}
+
+ public boolean isOriginatingFrom( Class<?> mixinType )
+ {
+ return typeName.isClass( mixinType );
+ }
}
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 49623cb..0b67ded 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
@@ -185,11 +185,11 @@
assertThat( "property 'doubleValue' has incorrect value",
instance.doubleValue().get(),
- equalTo( 42D ) );
+ equalTo( 42.0 ) );
assertThat( "property 'floatValue' has incorrect value",
instance.floatValue().get(),
- equalTo( 42F ) );
+ equalTo( 42f ) );
assertThat( "property 'booleanValue' has incorrect value",
instance.booleanValue().get(),
diff --git a/extensions/entitystore-sql/build.gradle b/extensions/entitystore-sql/build.gradle
index e3388ac..5437409 100644
--- a/extensions/entitystore-sql/build.gradle
+++ b/extensions/entitystore-sql/build.gradle
@@ -27,6 +27,7 @@
dependencies {
api polygene.core.bootstrap
api polygene.library( 'sql' )
+ api polygene.library( 'constraints' )
api libraries.jooq
runtimeOnly polygene.core.runtime
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 acd4532..e18f1b5 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
@@ -53,48 +53,75 @@
import org.jooq.Record;
import org.jooq.RecordType;
import org.jooq.Result;
+import org.jooq.SQLDialect;
import org.jooq.SelectJoinStep;
import org.jooq.SelectQuery;
import org.jooq.Table;
import org.jooq.impl.DSL;
+import static org.apache.polygene.entitystore.sql.MixinTable.INDEX_COLUMN_NAME;
+import static org.apache.polygene.entitystore.sql.MixinTable.NAME_COLUMN_NAME;
+import static org.apache.polygene.entitystore.sql.MixinTable.REFERENCE_COLUMN_NAME;
+import static org.apache.polygene.entitystore.sql.SqlType.makeField;
+
/**
* This class handles all the dealing with the main table, called the Entities Table.
* <p>
- * This is the table that holds the {@link BaseEntity} rows, and joins with the different so called
- * {@link MixinTable}, which handles one table per Mixin type.
+ * This is the table that holds the {@link BaseEntity} rows, and joins with the different so called
+ * {@link MixinTable}, which handles one table per Mixin type.
* </p>
*/
@SuppressWarnings( "WeakerAccess" )
public class EntitiesTable
- implements TableFields
{
+ private static final String VALUEID_COLUMN_NAME = "_value_id";
+ private static final String TYPE_COLUMN_NAME = "_type";
+ private static final String VERSION_COLUMN_NAME = "_version";
+ private static final String APPLICATIONVERSION_COLUMN_NAME = "_app_version";
+
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 final SQLDialect dialect;
private Map<EntityCompositeType, Set<Class<?>>> mixinTypeCache = new ConcurrentHashMap<>();
private Map<Class<?>, MixinTable> mixinTablesCache = new ConcurrentHashMap<>();
private final Table<Record> entitiesTable;
- private JooqDslContext dsl;
+
+ private Field<String> valueIdentityColumn;
+ private Field<String> typeNameColumn;
+ private Field<String> versionColumn;
+ private Field<String> applicationVersionColumn;
+
+ private final JooqDslContext dsl;
private final TypesTable types;
- private String applicationVersion;
- private Serialization serialization;
+ private final String applicationVersion;
+ private final Serialization serialization;
private boolean replacementStrategy = false; // Figure out later if we should support both and if so, how.
- EntitiesTable( JooqDslContext dsl, TypesTable types, String applicationVersion, String entitiesTableName, Serialization serialization )
+ EntitiesTable( JooqDslContext dsl,
+ SQLDialect dialect,
+ TypesTable types,
+ String applicationVersion,
+ String entitiesTableName,
+ Serialization serialization )
{
this.dsl = dsl;
+ this.dialect = dialect;
this.types = types;
this.applicationVersion = applicationVersion;
this.serialization = serialization;
entitiesTable = dsl.tableOf( entitiesTableName );
+ valueIdentityColumn = makeField( VALUEID_COLUMN_NAME, String.class, dialect );
+ typeNameColumn = makeField( TYPE_COLUMN_NAME, String.class, dialect );
+ versionColumn = makeField( VERSION_COLUMN_NAME, String.class, dialect );
+ applicationVersionColumn = makeField( APPLICATIONVERSION_COLUMN_NAME, String.class, dialect );
}
public BaseEntity fetchEntity( EntityReference reference, ModuleDescriptor module )
{
Result<Record> baseEntityResult = dsl
.selectFrom( entitiesTable )
- .where( identityColumn.eq( reference.identity().toString() ) )
+ .where( types.identityColumn().eq( reference.identity().toString() ) )
.fetch();
if( baseEntityResult.isEmpty() )
@@ -112,10 +139,10 @@
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.identity = StringIdentity.identityOf( row.field( types.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() );
+ result.modifedAt = Instant.ofEpochMilli( row.field( types.modifiedColumn() ).get( row ).getTime() );
+ result.createdAt = Instant.ofEpochMilli( row.field( types.createdColumn() ).get( row ).getTime() );
return result;
}
@@ -172,7 +199,7 @@
private MixinTable findMixinTable( Class<?> type, EntityDescriptor entityDescriptor )
{
- return mixinTablesCache.computeIfAbsent( type, t -> new MixinTable( dsl, types, type, entityDescriptor, serialization ) );
+ return mixinTablesCache.computeIfAbsent( type, t -> new MixinTable( dsl, dialect, types, type, entityDescriptor, serialization ) );
}
private Set<Class<?>> mixinsOf( Stream<? extends AssociationDescriptor> stream )
@@ -216,9 +243,9 @@
String typeName = descriptor.primaryType().getName();
Instant currentTime = uow.currentTime();
dsl.insertInto( entitiesTable )
- .set( identityColumn, reference.identity().toString() )
- .set( createdColumn, new Timestamp( currentTime.toEpochMilli() ))
- .set( modifiedColumn, new Timestamp( currentTime.toEpochMilli()) )
+ .set( types.identityColumn(), reference.identity().toString() )
+ .set( types.createdColumn(), new Timestamp( currentTime.toEpochMilli() ) )
+ .set( types.modifiedColumn(), new Timestamp( currentTime.toEpochMilli() ) )
.set( valueIdentityColumn, valueIdentity )
.set( typeNameColumn, typeName )
.set( versionColumn, "1" )
@@ -243,11 +270,11 @@
entity.currentValueIdentity = StringIdentity.identityOf( UUID.randomUUID().toString() );
}
dsl.update( entitiesTable )
- .set( modifiedColumn, new Timestamp( uow.currentTime().toEpochMilli() ) )
+ .set( types.modifiedColumn(), new Timestamp( uow.currentTime().toEpochMilli() ) )
.set( valueIdentityColumn, entity.currentValueIdentity.toString() )
.set( versionColumn, entity.version )
.set( applicationVersionColumn, applicationVersion )
- .where( identityColumn.eq( entity.identity.toString() ) )
+ .where( types.identityColumn().eq( entity.identity.toString() ) )
.execute();
}
@@ -321,32 +348,32 @@
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();
- 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 );
- } );
+ result.forEach( record -> {
+ AssociationValue value = new AssociationValue();
+ if( recordType.indexOf( MixinTable.REFERENCE_COLUMN_NAME ) >= 0 )
+ {
+ // some many-to-many association found.
+ if( recordType.indexOf( NAME_COLUMN_NAME ) >= 0 )
+ {
+ // NamedAssociations found.
+ value.name = QualifiedName.fromClass( entityDescriptor.primaryType(), (String) record.get( NAME_COLUMN_NAME ) );
+ EntityCompositeType valueType = entityDescriptor.valueType();
+ }
+ if( recordType.indexOf( INDEX_COLUMN_NAME ) >= 0 )
+ {
+ // ManyAssociations found.
+ value.position = (String) record.get( INDEX_COLUMN_NAME );
+ }
+ value.reference = (String) record.get( REFERENCE_COLUMN_NAME );
+ consume.accept( value );
+ }
+ } );
}
private Field<String> identityColumnOf( Table<Record> joinedTable )
{
String name = joinedTable.getName();
- String identity = identityColumn.getName();
+ String identity = types.identityColumn().getName();
return DSL.field( DSL.name( name, identity ), String.class );
}
@@ -395,4 +422,18 @@
assocTables.forEach( table -> dsl.delete( table ).where( identityColumnOf( table ).eq( valueId ) ).execute() );
}
}
+
+ void create()
+ {
+ dsl.createTableIfNotExists( entitiesTable )
+ .column( types.identityColumn() )
+ .column( types.createdColumn() )
+ .column( typeNameColumn )
+ .column( applicationVersionColumn )
+ .column( versionColumn )
+ .column( types.modifiedColumn() )
+ .column( valueIdentityColumn )
+ .constraint( DSL.primaryKey( types.identityColumn() ) )
+ .execute();
+ }
}
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 cf0968c..cb548b3 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
@@ -32,7 +32,6 @@
import org.apache.polygene.api.property.PropertyDescriptor;
import org.apache.polygene.api.serialization.Serialization;
import org.apache.polygene.api.type.ValueType;
-import org.apache.polygene.spi.PolygeneSPI;
import org.apache.polygene.spi.entity.ManyAssociationState;
import org.apache.polygene.spi.entity.NamedAssociationState;
import org.apache.polygene.spi.entitystore.helpers.DefaultEntityState;
@@ -40,6 +39,7 @@
import org.jooq.InsertSetMoreStep;
import org.jooq.InsertSetStep;
import org.jooq.Record;
+import org.jooq.SQLDialect;
import org.jooq.Table;
import org.jooq.UpdateSetMoreStep;
import org.jooq.impl.DSL;
@@ -48,19 +48,26 @@
* MixinTable is a class that handles the creation of the queries into the Mixin tables, both for insertions/updates
* as well as retrieval.
* <p>
- * Note that these tables are only queried as part of a SQL {@code JOIN} statement and never directly.
+ * Note that these tables are only queried as part of a SQL {@code JOIN} statement and never directly.
* </p>
* <p>
- * Creation of the actual Mixin tables happens in {@link TypesTable}.
+ * Creation of the actual Mixin tables happens in {@link TypesTable}.
* </p>
*/
class MixinTable
- implements TableFields
{
+ static final String NAME_COLUMN_NAME = "_name";
+ static final String INDEX_COLUMN_NAME = "_index"; // either index in ManyAssociation or name in NamedAssociation
+ static final String REFERENCE_COLUMN_NAME = "_reference";
+ private static final String ASSOCS_TABLE_POSTFIX = "_ASSOCS";
private final Table<Record> mixinTable;
private final Table<Record> mixinAssocsTable;
+ private Field<String> nameColumn;
+ private Field<String> referenceColumn;
+ private Field<String> indexColumn;
+
private final JooqDslContext dsl;
private final Map<QualifiedName, Field<Object>> properties = new ConcurrentHashMap<>();
private final Map<QualifiedName, Field<String>> associations = new ConcurrentHashMap<>();
@@ -68,16 +75,20 @@
private final List<QualifiedName> namedAssociations = new CopyOnWriteArrayList<>();
private final Class<?> mixinType;
+ private final TypesTable types;
private Serialization serialization;
- PolygeneSPI spi;
-
- MixinTable( JooqDslContext dsl, TypesTable types, Class<?> mixinType,
+ MixinTable( JooqDslContext dsl, SQLDialect dialect, TypesTable types, Class<?> mixinType,
EntityDescriptor descriptor, Serialization serialization )
{
+ this.types = types;
this.dsl = dsl;
this.mixinType = mixinType;
this.serialization = serialization;
+ nameColumn = SqlType.makeField( NAME_COLUMN_NAME, String.class, dialect);
+ referenceColumn = SqlType.makeField( REFERENCE_COLUMN_NAME, String.class, dialect );
+ indexColumn = SqlType.makeField( INDEX_COLUMN_NAME, String.class, dialect );
+
mixinTable = types.tableFor( mixinType, descriptor );
mixinAssocsTable = getAssocsTable( descriptor );
@@ -114,8 +125,8 @@
{
InsertSetMoreStep<Record> primaryTable =
dsl.insertInto( mixinTable )
- .set( identityColumn, valueIdentity )
- .set( createdColumn, new Timestamp( System.currentTimeMillis() ) );
+ .set( types.identityColumn(), valueIdentity )
+ .set( types.createdColumn(), new Timestamp( System.currentTimeMillis() ) );
properties
.entrySet()
@@ -142,8 +153,8 @@
int counter = 0;
for( EntityReference ref : entityReferences )
{
- InsertSetMoreStep<Record> set = assocsTable.set( identityColumn, valueIdentity )
- .set( createdColumn, new Timestamp( System.currentTimeMillis() ) )
+ InsertSetMoreStep<Record> set = assocsTable.set( types.identityColumn(), valueIdentity )
+ .set( types.createdColumn(), new Timestamp( System.currentTimeMillis() ) )
.set( nameColumn, assocName.name() )
.set( indexColumn, "" + counter++ )
.set( referenceColumn, ref == null ? null : ref.identity().toString() );
@@ -169,8 +180,8 @@
for( String name : entityReferences )
{
EntityReference ref = entityReferences.get( name );
- InsertSetMoreStep<Record> set = assocsTable.set( identityColumn, valueIdentity )
- .set( createdColumn, new Timestamp( System.currentTimeMillis() ) )
+ InsertSetMoreStep<Record> set = assocsTable.set( types.identityColumn(), valueIdentity )
+ .set( types.createdColumn(), new Timestamp( System.currentTimeMillis() ) )
.set( nameColumn, assocName.name() )
.set( indexColumn, name )
.set( referenceColumn, ref.identity().toString() );
@@ -243,7 +254,7 @@
{
// Need to remove existing records.
dsl.delete( mixinAssocsTable )
- .where( identityColumn.eq( valueId ) )
+ .where( types.identityColumn().eq( valueId ) )
.execute();
insertManyAndNamedAssociations( state, valueId );
}
@@ -255,15 +266,15 @@
|| descriptor.state().namedAssociations().count() > 0 )
{
Table<Record> table = dsl.tableOf( mixinTable.getName() + ASSOCS_TABLE_POSTFIX );
- int result2 = dsl.createTableIfNotExists( table )
- .column( identityColumn )
- .column( createdColumn )
- .column( nameColumn )
- .column( indexColumn )
- .column( referenceColumn )
- .execute();
+ int result = dsl.createTableIfNotExists( table )
+ .column( types.identityColumn() )
+ .column( types.createdColumn() )
+ .column( nameColumn )
+ .column( indexColumn )
+ .column( referenceColumn )
+ .execute();
dsl.createIndex( DSL.name( "IDX_" + table.getName() ) )
- .on( table, identityColumn )
+ .on( table, types.identityColumn() )
.execute();
return table;
}
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
index f5a6929..87e481e 100644
--- 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
@@ -17,8 +17,10 @@
*/
package org.apache.polygene.entitystore.sql;
+import org.apache.polygene.api.common.Optional;
import org.apache.polygene.api.common.UseDefaults;
import org.apache.polygene.api.property.Property;
+import org.apache.polygene.library.constraints.annotation.MaxLength;
import org.apache.polygene.library.sql.common.SQLConfiguration;
/**
@@ -64,5 +66,25 @@
*/
@UseDefaults( "" )
Property<String> dialect();
+
+ /** Length of Identity strings.
+ *
+ * MariaDb and MySQL dialects will not allow unspecified VARCHAR lengths for storing Strings.
+ * <p/>
+ * Default: 100
+ */
+ @Optional
+ Property<Integer> identityLength();
+
+ /** Length of Identity strings.
+ *
+ * MariaDb and MySQL dialects will not allow unspecified VARCHAR lengths for storing Strings. This configuration
+ * value defines what value x in VARCHAR(x) should be used for each String property, unless otherwise specified
+ * as a {@link MaxLength} annotation on the property.
+ * <p/>
+ * Default: 1000
+ */
+ @Optional
+ Property<Integer> stringLength();
}
// END SNIPPET: config
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 c1e7985..213c7c5 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
@@ -142,13 +142,20 @@
{
return value;
}
+ if( type.equals( ValueType.FLOAT ) )
+ {
+ if( value instanceof Double ) // MariaDB/MySQL returns a Double
+ {
+ return new Float( (Double) value );
+ }
+ 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.SHORT )
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 0600d06..f34d920 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
@@ -39,7 +39,6 @@
import org.jooq.SQLDialect;
import org.jooq.SelectQuery;
import org.jooq.conf.Settings;
-import org.jooq.impl.DSL;
/**
* This class handles all the Jooq interactions.
@@ -189,7 +188,6 @@
@Override
public void activateService()
- throws Exception
{
SqlEntityStoreConfiguration config = this.configuration.get();
SQLDialect dialect = getSqlDialect( config );
@@ -201,37 +199,19 @@
dsl = tbf.newTransient( JooqDslContext.class, settings, dialect );
types = new TypesTable( dsl, dialect, typesTableName, config );
- entitiesTable = new EntitiesTable( dsl, types, application.version(), entitiesTableName, serialization );
+ entitiesTable = new EntitiesTable( dsl, dialect, types, application.version(), entitiesTableName, serialization );
if( config.createIfMissing().get() )
{
dsl.transaction( t -> {
-
- dsl.createTableIfNotExists( dsl.tableNameOf( typesTableName ) )
- .column( identityColumn )
- .column( tableNameColumn )
- .column( createdColumn )
- .column( modifiedColumn )
- .constraint( DSL.primaryKey( identityColumn ) )
- .execute();
-
- dsl.createTableIfNotExists( dsl.tableNameOf( entitiesTableName ) )
- .column( identityColumn )
- .column( createdColumn )
- .column( typeNameColumn )
- .column( applicationVersionColumn )
- .column( versionColumn )
- .column( modifiedColumn )
- .column( valueIdentityColumn )
- .constraint( DSL.primaryKey( identityColumn ) )
- .execute();
+ types.create();
+ entitiesTable.create();
} );
}
}
@Override
public void passivateService()
- throws Exception
{
}
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
index be98bdb..d072afd 100644
--- 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
@@ -19,6 +19,7 @@
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -27,6 +28,10 @@
import java.time.Period;
import java.time.ZonedDateTime;
import org.jooq.DataType;
+import org.jooq.Field;
+import org.jooq.SQLDialect;
+import org.jooq.impl.DSL;
+import org.jooq.impl.DefaultDataType;
import org.jooq.impl.SQLDataType;
import org.jooq.types.Interval;
@@ -35,17 +40,31 @@
*/
class SqlType
{
+ static <T> Field<T> makeField( String columnName, Class<T> type, SQLDialect dialect, boolean reference )
+ {
+ return DSL.field( DSL.name( columnName ), getSqlDataTypeFor( dialect, type, reference ) );
+ }
+
+ public static <T> Field<T> makeField( String columnName, Class<T> type, SQLDialect dialect )
+ {
+ return makeField( columnName, type, dialect, true );
+ }
+
@SuppressWarnings( "unchecked" )
- static <T> DataType<T> getSqlDataTypeFor( Class<?> propertyType )
+ static <T> DataType<T> getSqlDataTypeFor( SQLDialect dialect, Class<T> propertyType, boolean reference )
{
if( String.class.isAssignableFrom( propertyType ) )
{
- return (DataType<T>) SQLDataType.VARCHAR;
+ return (DataType<T>) varCharType( dialect, reference );
}
if( Integer.class.isAssignableFrom( propertyType ) )
{
return (DataType<T>) SQLDataType.INTEGER;
}
+ if( Timestamp.class.isAssignableFrom( propertyType ) )
+ {
+ return (DataType<T>) SQLDataType.TIMESTAMP;
+ }
if( Long.class.isAssignableFrom( propertyType ) )
{
return (DataType<T>) SQLDataType.BIGINT;
@@ -64,35 +83,35 @@
}
if( Instant.class.isAssignableFrom( propertyType ) )
{
- return (DataType<T>) SQLDataType.VARCHAR;
+ return (DataType<T>) varCharType( dialect, reference );
}
if( Interval.class.isAssignableFrom( propertyType ) )
{
- return (DataType<T>) SQLDataType.VARCHAR;
+ return (DataType<T>) varCharType( dialect, reference );
}
if( Period.class.isAssignableFrom( propertyType ) )
{
- return (DataType<T>) SQLDataType.VARCHAR;
+ return (DataType<T>) varCharType( dialect, reference );
}
if( LocalDate.class.isAssignableFrom( propertyType ) )
{
- return (DataType<T>) SQLDataType.VARCHAR;
+ return (DataType<T>) varCharType( dialect, reference );
}
if( LocalTime.class.isAssignableFrom( propertyType ) )
{
- return (DataType<T>) SQLDataType.VARCHAR;
+ return (DataType<T>) varCharType( dialect, reference );
}
if( LocalDateTime.class.isAssignableFrom( propertyType ) )
{
- return (DataType<T>) SQLDataType.VARCHAR;
+ return (DataType<T>) varCharType( dialect, reference );
}
if( ZonedDateTime.class.isAssignableFrom( propertyType ) )
{
- return (DataType<T>) SQLDataType.VARCHAR;
+ return (DataType<T>) varCharType( dialect, reference );
}
if( OffsetDateTime.class.isAssignableFrom( propertyType ) )
{
- return (DataType<T>) SQLDataType.VARCHAR;
+ return (DataType<T>) varCharType( dialect, reference );
}
if( Character.class.isAssignableFrom( propertyType ) )
{
@@ -153,6 +172,22 @@
return (DataType<T>) SQLDataType.INTEGER;
}
}
- return (DataType<T>) SQLDataType.VARCHAR;
+ return (DataType<T>) varCharType( dialect, reference );
+ }
+
+ private static DataType<String> varCharType( SQLDialect dialect, boolean reference )
+ {
+ if( dialect == SQLDialect.MYSQL || dialect == SQLDialect.MARIADB )
+ {
+ if( reference )
+ {
+ return SQLDataType.VARCHAR.length(1000).nullable(false);
+ }
+ else
+ {
+ return new DefaultDataType<>( null, String.class, "MEDIUMTEXT" );
+ }
+ }
+ return SQLDataType.VARCHAR;
}
}
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
index 11f0acf..ed24905 100644
--- 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
@@ -17,11 +17,6 @@
*/
package org.apache.polygene.entitystore.sql;
-import java.sql.Timestamp;
-import org.jooq.Field;
-
-import static org.apache.polygene.entitystore.sql.TypesTable.makeField;
-
/**
* SQL field names and definitions.
* <p>
@@ -31,46 +26,6 @@
*/
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 );
}
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 0513768..c75ae57 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
@@ -17,7 +17,6 @@
*/
package org.apache.polygene.entitystore.sql;
-import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.Map;
@@ -25,9 +24,9 @@
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.Constraint;
import org.jooq.CreateTableColumnStep;
import org.jooq.DataType;
import org.jooq.Field;
@@ -40,11 +39,25 @@
/**
* This class is effectively the manager of the {@link MixinTable} instances.
*/
-public class TypesTable
- implements TableFields
+class TypesTable
{
+ // Common in all tables
+ private static final String IDENTITY_COLUMN_NAME = "_identity";
+ private static final String CREATED_COLUMN_NAME = "_created_at";
+ private static final String LASTMODIFIED_COLUMN_NAME = "_modified_at";
+
+ // Types Table
+ private static final String TABLENAME_COLUMN_NAME = "_table_name";
+
+ // Common Fields
+ private Field<String> identityColumn;
+ private Field<Timestamp> createdColumn;
+ private Field<Timestamp> modifiedColumn;
+
+ // Types Table
+ private Field<String> tableNameColumn;
+
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;
@@ -62,14 +75,14 @@
this.config = config;
typesTable = dsl.tableOf( typesTablesName );
this.dsl = dsl;
+ Integer idMaxLength = config.identityLength().get();
+ identityColumn = SqlType.makeField( IDENTITY_COLUMN_NAME, String.class, dialect );
+ createdColumn = SqlType.makeField( CREATED_COLUMN_NAME, Timestamp.class, dialect );
+ modifiedColumn = SqlType.makeField( LASTMODIFIED_COLUMN_NAME, Timestamp.class, dialect );
+ tableNameColumn = SqlType.makeField( TABLENAME_COLUMN_NAME, String.class, dialect );
}
- static <T> Field<T> makeField( String columnName, Class<T> type )
- {
- return DSL.field( DSL.name( columnName ), type );
- }
-
- String tableNameOf( Class<?> mixinType )
+ private String tableNameOf( Class<?> mixinType )
{
Result<Record> typeInfo = fetchTypeInfoFromTable( mixinType );
if( typeInfo.isEmpty() )
@@ -143,7 +156,7 @@
String typeName = mixinType.getSimpleName();
String postFix = "";
int counter = 1;
- boolean found = false;
+ boolean found;
do
{
found = checkForTableNamed( typeName + postFix );
@@ -154,7 +167,7 @@
private boolean checkForTableNamed( String tableName )
{
- if( tableName.equalsIgnoreCase( config.entitiesTableName().get() ) || tableName.equalsIgnoreCase( config.typesTableName().get() ))
+ if( tableName.equalsIgnoreCase( config.entitiesTableName().get() ) || tableName.equalsIgnoreCase( config.typesTableName().get() ) )
{
return true;
}
@@ -164,11 +177,6 @@
.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();
@@ -178,13 +186,52 @@
Field<String> fieldOf( AssociationDescriptor descriptor )
{
String propertyName = descriptor.qualifiedName().name();
- return DSL.field( DSL.name( propertyName ), DSL.getDataType( String.class ) );
+ return DSL.field( DSL.name( propertyName ), dataTypeOf( descriptor ) );
}
private <T> DataType<T> dataTypeOf( PropertyDescriptor property )
{
Type type = property.type();
- Class<?> rawType = Classes.RAW_CLASS.apply( type );
- return SqlType.getSqlDataTypeFor( rawType );
+
+ @SuppressWarnings( "unchecked" )
+ Class<T> rawType = (Class<T>) Classes.RAW_CLASS.apply( type );
+
+ return SqlType.getSqlDataTypeFor( dialect, rawType, false );
+ }
+
+ private <T> DataType<T> dataTypeOf( AssociationDescriptor property )
+ {
+ Type type = property.type();
+
+ @SuppressWarnings( "unchecked" )
+ Class<T> rawType = (Class<T>) Classes.RAW_CLASS.apply( type );
+
+ return SqlType.getSqlDataTypeFor( dialect, rawType, false );
+ }
+
+ Field<String> identityColumn()
+ {
+ return identityColumn;
+ }
+
+ Field<Timestamp> modifiedColumn()
+ {
+ return modifiedColumn;
+ }
+
+ Field<Timestamp> createdColumn()
+ {
+ return createdColumn;
+ }
+
+ void create()
+ {
+ dsl.createTableIfNotExists( typesTable )
+ .column( identityColumn )
+ .column( tableNameColumn )
+ .column( createdColumn )
+ .column( modifiedColumn )
+ .constraint( DSL.primaryKey( identityColumn ) )
+ .execute();
}
}
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MariaDbEntityStoreTest.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MariaDbEntityStoreTest.java
index 259bdf9..663aeec 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MariaDbEntityStoreTest.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MariaDbEntityStoreTest.java
@@ -23,6 +23,7 @@
import com.github.junit5docker.Environment;
import com.github.junit5docker.Port;
import com.github.junit5docker.WaitFor;
+import java.lang.reflect.UndeclaredThrowableException;
import org.apache.polygene.api.common.Visibility;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.ModuleAssembly;
@@ -34,9 +35,8 @@
import org.apache.polygene.test.entity.AbstractEntityStoreTest;
import org.jooq.SQLDialect;
import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.BeforeAll;
-@Disabled( "Waiting response from JOOQ to fix SQL generation. VARCHAR instead of CHAR")
@Docker( image = "mariadb",
ports = @Port( exposed = 8801, inner = 3306 ),
environments = {
@@ -44,20 +44,31 @@
@Environment( key = "MYSQL_ALLOW_EMPTY_PASSWORD", value = "yes" ),
@Environment( key = "MYSQL_DATABASE", value = "jdbc_test_db" )
},
- waitFor = @WaitFor( value = "mysqld: ready for connections", timeoutInMillis = 30000 ),
+ waitFor = @WaitFor( value = "mariadb.org binary distribution", timeoutInMillis = 30000 ),
newForEachCase = false
)
-public class MariaDbEntityStoreTest
- extends AbstractEntityStoreTest
+public class MariaDbEntityStoreTest extends AbstractEntityStoreTest
{
+ @BeforeAll
+ public static void waitForDockerToSettle()
+ {
+ try
+ {
+ Thread.sleep( 5000 );
+ }
+ catch( InterruptedException e )
+ {
+ throw new UndeclaredThrowableException( e );
+ }
+ }
+
@Override
// START SNIPPET: assembly
public void assemble( ModuleAssembly module )
throws AssemblyException
{
// END SNIPPET: assembly
- sleep();
super.assemble( module );
ModuleAssembly config = module.layer().module( "config" );
new EntityTestAssembler().defaultServicesVisibleIn( Visibility.layer ).assemble( config );
@@ -92,24 +103,12 @@
+ "&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true" );
defaults.driver().set( "com.mysql.jdbc.Driver" );
defaults.enabled().set( true );
- defaults.username().set("root");
+ defaults.username().set( "root" );
defaults.password().set( "" );
// START SNIPPET: assembly
}
// END SNIPPET: assembly
- static void sleep()
- {
- try
- {
- Thread.sleep( 11500 );
- }
- catch( InterruptedException e )
- {
- e.printStackTrace();
- }
- }
-
@AfterEach
public void cleanUpData()
{
diff --git a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MariaDbEntityStoreTestSuite.java b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MariaDbEntityStoreTestSuite.java
index e180fa4..44eeafa 100644
--- a/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MariaDbEntityStoreTestSuite.java
+++ b/extensions/entitystore-sql/src/test/java/org/apache/polygene/entitystore/sql/MariaDbEntityStoreTestSuite.java
@@ -23,6 +23,7 @@
import com.github.junit5docker.Environment;
import com.github.junit5docker.Port;
import com.github.junit5docker.WaitFor;
+import java.lang.reflect.UndeclaredThrowableException;
import org.apache.polygene.api.common.Visibility;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.entitystore.sql.assembly.MySQLEntityStoreAssembler;
@@ -32,27 +33,36 @@
import org.apache.polygene.test.entity.model.EntityStoreTestSuite;
import org.jooq.SQLDialect;
import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.BeforeAll;
-@Disabled( "Waiting response from JOOQ to fix SQL generation. VARCHAR instead of CHAR")
-@Docker( image = "org.apache.polygene:org.apache.polygene.internal.docker-mariadb",
- ports = @Port( exposed = 8801, inner = 3306),
+@Docker( image = "mariadb",
+ ports = @Port( exposed = 8801, inner = 3306 ),
environments = {
- @Environment( key = "MYSQL_ROOT_PASSWORD", value = ""),
- @Environment(key = "MYSQL_ALLOW_EMPTY_PASSWORD", value = "yes"),
- @Environment(key = "MYSQL_DATABASE", value = "jdbc_test_db"),
- @Environment( key = "MYSQL_ROOT_HOST", value = "172.17.0.1"),
+ @Environment( key = "MYSQL_ROOT_PASSWORD", value = "" ),
+ @Environment( key = "MYSQL_ALLOW_EMPTY_PASSWORD", value = "yes" ),
+ @Environment( key = "MYSQL_DATABASE", value = "jdbc_test_db" )
},
- waitFor = @WaitFor( value = "mysqld: ready for connections", timeoutInMillis = 30000),
+ waitFor = @WaitFor( value = "mariadb.org binary distribution", timeoutInMillis = 30000 ),
newForEachCase = false
)
public class MariaDbEntityStoreTestSuite extends EntityStoreTestSuite
{
+ @BeforeAll
+ static void waitForDockerToSettle()
+ {
+ try
+ {
+ Thread.sleep( 5000 );
+ }
+ catch( InterruptedException e )
+ {
+ throw new UndeclaredThrowableException( e );
+ }
+ }
@Override
protected void defineStorageModule( ModuleAssembly module )
{
- MariaDbEntityStoreTest.sleep();
module.defaultServices();
// DataSourceService
new DBCPDataSourceServiceAssembler()
@@ -77,10 +87,15 @@
String mysqlHost = "localhost";
int mysqlPort = 8801;
- configModule.forMixin( DataSourceConfiguration.class ).declareDefaults()
- .url().set( "jdbc:mysql://" + mysqlHost + ":" + mysqlPort
- + "/jdbc_test_db?profileSQL=false&useLegacyDatetimeCode=false&serverTimezone=UTC"
- + "&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true" );
+ DataSourceConfiguration defaults = configModule.forMixin( DataSourceConfiguration.class ).declareDefaults();
+ defaults
+ .url().set( "jdbc:mysql://" + mysqlHost + ":" + mysqlPort
+ + "/jdbc_test_db?profileSQL=false&useLegacyDatetimeCode=false&serverTimezone=UTC"
+ + "&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true" );
+ defaults.driver().set( "com.mysql.jdbc.Driver" );
+ defaults.enabled().set( true );
+ defaults.username().set( "root" );
+ defaults.password().set( "" );
}
@AfterEach
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 73fa5f7..1a76c4b 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
@@ -23,6 +23,7 @@
import com.github.junit5docker.Environment;
import com.github.junit5docker.Port;
import com.github.junit5docker.WaitFor;
+import java.lang.reflect.UndeclaredThrowableException;
import org.apache.polygene.api.common.Visibility;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.ModuleAssembly;
@@ -34,22 +35,33 @@
import org.apache.polygene.test.entity.AbstractEntityStoreTest;
import org.jooq.SQLDialect;
import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.BeforeAll;
-@Disabled( "Waiting response from JOOQ to fix SQL generation. VARCHAR instead of CHAR")
-@Docker( image = "mysql", ports = @Port( exposed = 8801, inner = 3306),
+@Docker( image = "mysql", ports = @Port( exposed = 8801, inner = 3306 ),
environments = {
- @Environment( key = "MYSQL_ROOT_PASSWORD", value = ""),
- @Environment(key = "MYSQL_ALLOW_EMPTY_PASSWORD", value = "yes"),
- @Environment(key = "MYSQL_DATABASE", value = "jdbc_test_db"),
- @Environment( key = "MYSQL_ROOT_HOST", value = "172.17.0.1"),
+ @Environment( key = "MYSQL_ROOT_PASSWORD", value = "" ),
+ @Environment( key = "MYSQL_ALLOW_EMPTY_PASSWORD", value = "yes" ),
+ @Environment( key = "MYSQL_DATABASE", value = "jdbc_test_db" )
},
- waitFor = @WaitFor( value = "mysqld: ready for connections", timeoutInMillis = 30000),
+ waitFor = @WaitFor( value = "mysqld: ready for connections", timeoutInMillis = 40000 ),
newForEachCase = false
)
public class MySQLEntityStoreTest
extends AbstractEntityStoreTest
{
+ @BeforeAll
+ public static void waitForDockerToSettle()
+ {
+ try
+ {
+ Thread.sleep( 10000 );
+ }
+ catch( InterruptedException e )
+ {
+ throw new UndeclaredThrowableException( e );
+ }
+ }
+
@Override
// START SNIPPET: assembly
public void assemble( ModuleAssembly module )
@@ -84,10 +96,14 @@
// END SNIPPET: assembly
String mysqlHost = "localhost";
int mysqlPort = 8801;
- config.forMixin( DataSourceConfiguration.class ).declareDefaults()
- .url().set( "jdbc:mysql://" + mysqlHost + ":" + mysqlPort
- + "/jdbc_test_db?profileSQL=false&useLegacyDatetimeCode=false&serverTimezone=UTC"
- + "&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true" );
+ DataSourceConfiguration defaults = config.forMixin( DataSourceConfiguration.class ).declareDefaults();
+ defaults.url().set( "jdbc:mysql://" + mysqlHost + ":" + mysqlPort
+ + "/jdbc_test_db?profileSQL=false&useLegacyDatetimeCode=false&serverTimezone=UTC"
+ + "&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true" );
+ defaults.driver().set( "com.mysql.jdbc.Driver" );
+ defaults.enabled().set( true );
+ defaults.username().set( "root" );
+ defaults.password().set( "" );
// START SNIPPET: assembly
}
// END SNIPPET: assembly
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 f062eb8..3426126 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
@@ -23,6 +23,7 @@
import com.github.junit5docker.Environment;
import com.github.junit5docker.Port;
import com.github.junit5docker.WaitFor;
+import java.lang.reflect.UndeclaredThrowableException;
import org.apache.polygene.api.common.Visibility;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.entitystore.sql.assembly.MySQLEntityStoreAssembler;
@@ -32,21 +33,32 @@
import org.apache.polygene.test.entity.model.EntityStoreTestSuite;
import org.jooq.SQLDialect;
import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.BeforeAll;
-@Disabled( "Waiting response from JOOQ to fix SQL generation. VARCHAR instead of CHAR")
-@Docker( image = "mysql", ports = @Port( exposed = 8801, inner = 3306),
+@Docker( image = "mysql", ports = @Port( exposed = 8801, inner = 3306 ),
environments = {
- @Environment( key = "MYSQL_ROOT_PASSWORD", value = ""),
- @Environment(key = "MYSQL_ALLOW_EMPTY_PASSWORD", value = "yes"),
- @Environment(key = "MYSQL_DATABASE", value = "jdbc_test_db"),
- @Environment( key = "MYSQL_ROOT_HOST", value = "172.17.0.1"),
+ @Environment( key = "MYSQL_ROOT_PASSWORD", value = "" ),
+ @Environment( key = "MYSQL_ALLOW_EMPTY_PASSWORD", value = "yes" ),
+ @Environment( key = "MYSQL_DATABASE", value = "jdbc_test_db" )
},
- waitFor = @WaitFor( value = "mysqld: ready for connections", timeoutInMillis = 30000),
+ waitFor = @WaitFor( value = "mysqld: ready for connections", timeoutInMillis = 40000 ),
newForEachCase = false
)
public class MySQLEntityStoreTestSuite extends EntityStoreTestSuite
{
+ @BeforeAll
+ public static void waitForDockerToSettle()
+ {
+ try
+ {
+ Thread.sleep( 12000 );
+ }
+ catch( InterruptedException e )
+ {
+ throw new UndeclaredThrowableException( e );
+ }
+ }
+
@Override
protected void defineStorageModule( ModuleAssembly module )
{
@@ -74,10 +86,14 @@
String mysqlHost = "localhost";
int mysqlPort = 8801;
- configModule.forMixin( DataSourceConfiguration.class ).declareDefaults()
- .url().set( "jdbc:mysql://" + mysqlHost + ":" + mysqlPort
- + "/jdbc_test_db?profileSQL=false&useLegacyDatetimeCode=false&serverTimezone=UTC"
- + "&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true" );
+ DataSourceConfiguration defaults = configModule.forMixin( DataSourceConfiguration.class ).declareDefaults();
+ defaults.url().set( "jdbc:mysql://" + mysqlHost + ":" + mysqlPort
+ + "/jdbc_test_db?profileSQL=false&useLegacyDatetimeCode=false&serverTimezone=UTC"
+ + "&nullCatalogMeansCurrent=true&nullNamePatternMatchesAll=true" );
+ defaults.driver().set( "com.mysql.jdbc.Driver" );
+ defaults.enabled().set( true );
+ defaults.username().set( "root" );
+ defaults.password().set( "" );
}
@AfterEach