branch feature/7739 updated (79f8009 -> 394b8fc)
This is an automated email from the git hooks/post-receive script. New change to branch feature/7739 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git from 79f8009 Introduction du moteur de synchronisation (reste plus qu'à générer le code sql à partir de la requète produite (See #7739) new 7b9b5c2 Ajout du nom des tables pour les associations many-to-many new b65e1ad Introduction des générateurs de requètes sql (RAF celui de remplacement) (See #7739) new 394b8fc Mise en place de la génération des requètes sql et de leur application (See #7739) The 3 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 394b8fc137f15becfb56630d7f58dbfedfffa0c8 Author: Tony CHEMIT <chemit@codelutin.com> Date: Wed Jun 29 12:39:49 2016 +0200 Mise en place de la génération des requètes sql et de leur application (See #7739) commit b65e1ad8ee05b2caf7bf78b76a2d7b494abb5a11 Author: Tony CHEMIT <chemit@codelutin.com> Date: Wed Jun 29 12:37:35 2016 +0200 Introduction des générateurs de requètes sql (RAF celui de remplacement) (See #7739) commit 7b9b5c20f068d0ef28b86fe7210d84b261b2ff0d Author: Tony CHEMIT <chemit@codelutin.com> Date: Wed Jun 29 11:58:49 2016 +0200 Ajout du nom des tables pour les associations many-to-many Summary of changes: ...UnidirectionalReferentialSynchronizeEngine.java | 15 +- ...ectionalReferentialSynchronizeLocalService.java | 23 ++ ...nidirectionalReferentialSynchronizeRequest.java | 57 +++-- .../synchro/DeleteSqlStatementGenerator.java | 41 ++++ .../synchro/InsertSqlStatementGenerator.java | 242 ++++++++++++++++++ ...nalReferentialSynchronizeLocalServiceTopia.java | 121 +++++++-- .../synchro/UpdateSqlStatementGenerator.java | 269 +++++++++++++++++++++ .../persistence/metadata/TopiaMetadataEntity.java | 26 +- .../templates/TopiaMetadataModelGenerator.java | 4 +- 9 files changed, 747 insertions(+), 51 deletions(-) create mode 100644 observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/DeleteSqlStatementGenerator.java create mode 100644 observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/InsertSqlStatementGenerator.java create mode 100644 observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UpdateSqlStatementGenerator.java -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/7739 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 7b9b5c20f068d0ef28b86fe7210d84b261b2ff0d Author: Tony CHEMIT <chemit@codelutin.com> Date: Wed Jun 29 11:58:49 2016 +0200 Ajout du nom des tables pour les associations many-to-many --- .../persistence/metadata/TopiaMetadataEntity.java | 26 ++++++++++++++++++---- .../templates/TopiaMetadataModelGenerator.java | 4 +++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/observe-topia-extension/src/main/java/org/nuiton/topia/persistence/metadata/TopiaMetadataEntity.java b/observe-topia-extension/src/main/java/org/nuiton/topia/persistence/metadata/TopiaMetadataEntity.java index 8c16f2c..6f4b8ba 100644 --- a/observe-topia-extension/src/main/java/org/nuiton/topia/persistence/metadata/TopiaMetadataEntity.java +++ b/observe-topia-extension/src/main/java/org/nuiton/topia/persistence/metadata/TopiaMetadataEntity.java @@ -83,9 +83,14 @@ public class TopiaMetadataEntity { * @see #getDbColumnName(String) */ protected final Map<String, String> dbColumnsName = new LinkedHashMap<>(); + /** + * Le nom des tables utilisées pour les associations nm. + */ + protected final Map<String, String> dbNmAssociationsName = new LinkedHashMap<>(); + public TopiaMetadataEntity(String parent, String type, String dbSchemaName, String dbTableName) { - this.parent=parent; + this.parent = parent; this.type = type; this.dbSchemaName = dbSchemaName; this.dbTableName = dbTableName; @@ -116,7 +121,10 @@ public class TopiaMetadataEntity { .toString(); } - public boolean withParent() { return parent!=null;} + public boolean withParent() { + return parent != null; + } + public String getParent() { return parent; } @@ -161,6 +169,14 @@ public class TopiaMetadataEntity { return dbColumnName; } + public Map<String, String> getDbNmAssociationsName() { + return dbNmAssociationsName; + } + + public String getBdNmAssociationName(String propertyName) { + return dbNmAssociationsName.get(propertyName); + } + public void addAssociation(TopiaMetadataEntity associationClazz, String name, String dbColumnName) { log.info(getType() + "/" + name + "(" + dbColumnName + ") →" + associationClazz.getType()); associations.put(name, associationClazz.getType()); @@ -173,10 +189,11 @@ public class TopiaMetadataEntity { addDbColumnName(name, dbColumnName); } - public void addNmAssociation(TopiaMetadataEntity associationClazz, String name, String dbColumnName) { - log.info(getType() + "/" + name + "(" + dbColumnName + ") →" + associationClazz.getType()); + public void addNmAssociation(TopiaMetadataEntity associationClazz, String name, String dbColumnName, String dbNmAssociationName) { + log.info(getType() + "/" + name + "(" + dbNmAssociationName + ") →" + associationClazz.getType()); nmAssociations.put(name, associationClazz.getType()); addDbColumnName(name, dbColumnName); + dbNmAssociationsName.put(name, dbNmAssociationName); } public void addRequired(TopiaMetadataEntity attributeClazz, String name, String dbColumnName) { @@ -199,6 +216,7 @@ public class TopiaMetadataEntity { copy.required.putAll(required); copy.properties.putAll(properties); copy.dbColumnsName.putAll(dbColumnsName); + copy.dbNmAssociationsName.putAll(dbNmAssociationsName); return copy; } diff --git a/observe-topia-templates-extension/src/main/java/org/nuiton/topia/templates/TopiaMetadataModelGenerator.java b/observe-topia-templates-extension/src/main/java/org/nuiton/topia/templates/TopiaMetadataModelGenerator.java index 4d79925..950ae90 100644 --- a/observe-topia-templates-extension/src/main/java/org/nuiton/topia/templates/TopiaMetadataModelGenerator.java +++ b/observe-topia-templates-extension/src/main/java/org/nuiton/topia/templates/TopiaMetadataModelGenerator.java @@ -222,6 +222,7 @@ public class TopiaMetadataModelGenerator extends ObjectModelGenerator { metadataEntity.getRequired().putAll(parentMetadataEntity.getRequired()); metadataEntity.getProperties().putAll(parentMetadataEntity.getProperties()); metadataEntity.getDbColumnsName().putAll(parentMetadataEntity.getDbColumnsName()); + metadataEntity.getDbColumnsName().putAll(parentMetadataEntity.getDbNmAssociationsName()); applyInheritance(metadataEntity, superClass, metadataModel); @@ -321,7 +322,8 @@ public class TopiaMetadataModelGenerator extends ObjectModelGenerator { if (GeneratorUtil.isNMultiplicity(attr.getReverseMaxMultiplicity()) && !attr.hasAssociationClass()) { // many to many - metadataEntity.addNmAssociation(attributeClazz, name, attrColumn); + String tableName = templateHelper.getManyToManyTableName(attr); + metadataEntity.addNmAssociation(attributeClazz, name, attrColumn, tableName); } else { // one to many -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/7739 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit b65e1ad8ee05b2caf7bf78b76a2d7b494abb5a11 Author: Tony CHEMIT <chemit@codelutin.com> Date: Wed Jun 29 12:37:35 2016 +0200 Introduction des générateurs de requètes sql (RAF celui de remplacement) (See #7739) --- .../synchro/DeleteSqlStatementGenerator.java | 41 ++++ .../synchro/InsertSqlStatementGenerator.java | 242 ++++++++++++++++++ .../synchro/UpdateSqlStatementGenerator.java | 269 +++++++++++++++++++++ 3 files changed, 552 insertions(+) diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/DeleteSqlStatementGenerator.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/DeleteSqlStatementGenerator.java new file mode 100644 index 0000000..c4339de --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/DeleteSqlStatementGenerator.java @@ -0,0 +1,41 @@ +package fr.ird.observe.services.service.actions.synchro; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.metadata.TopiaMetadataEntity; + +/** + * Pour générer une requète sql de suppression à partir d'un référentiel donné. + * + * Created on 29/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class DeleteSqlStatementGenerator { + + /** Logger. */ + private static final Log log = LogFactory.getLog(DeleteSqlStatementGenerator.class); + + private static final String DELETE_STATEMENT = "DELETE FROM %s.%s WHERE topiaId = '%s';\n"; + + private final String schemaName; + private final String tableName; + + public DeleteSqlStatementGenerator(TopiaMetadataEntity metadataEntity) { + this.schemaName = metadataEntity.getDbSchemaName(); + this.tableName = metadataEntity.getDbTableName(); + } + + public String generateSql(String id) { + + String result = String.format(DELETE_STATEMENT, schemaName, tableName, id); + + if (log.isDebugEnabled()) { + log.debug("sql: " + result); + } + + return result; + + } + +} diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/InsertSqlStatementGenerator.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/InsertSqlStatementGenerator.java new file mode 100644 index 0000000..65fcac6 --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/InsertSqlStatementGenerator.java @@ -0,0 +1,242 @@ +package fr.ird.observe.services.service.actions.synchro; + +import fr.ird.observe.services.dto.referential.ReferentialDto; +import fr.ird.observe.services.dto.referential.ReferentialReference; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.metadata.TopiaMetadataEntity; +import org.nuiton.util.beans.Binder; +import org.nuiton.util.beans.BinderFactory; + +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +/** + * Pour générer une requète sql d'ajout à partir d'un référentiel donné. + * + * Created on 29/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class InsertSqlStatementGenerator<R extends ReferentialDto> { + + /** Logger. */ + private static final Log log = LogFactory.getLog(InsertSqlStatementGenerator.class); + + private static final String INSERT_STATEMENT = "INSERT INTO %s.%s(%s) VALUES (%s);\n"; + private static final String NM_ASSOCIATION_INSERT_STATEMENT = "INSERT INTO %s.%s(%s, %s) VALUES ('%s', '%s');\n"; + + private final Set<String> columnNames; + private final String schemaName; + private final String tableName; + private final Binder<R, R> binder; + private final String[] simplePropertyNames; + private final String[] compositionPropertyNames; + private final Set<NmAssociation> nmAssociations; + + /** + * Pour décrire une association nm. + */ + private static class NmAssociation { + + /** + * Le nom de la propriété dans l'objet. + */ + private final String propertyName; + /** + * Le nom de la colonne de l'association dans la table d'association. + */ + private final String dbColumnName; + /** + * Le nom de la table d'association. + */ + private final String tableName; + + private NmAssociation(String propertyName, String dbColumnName, String tableName) { + this.propertyName = propertyName; + this.dbColumnName = dbColumnName; + this.tableName = tableName; + } + + public String getPropertyName() { + return propertyName; + } + + public String getDbColumnName() { + return dbColumnName; + } + + public String getTableName() { + return tableName; + } + } + + public InsertSqlStatementGenerator(TopiaMetadataEntity metadataEntity, Class<R> dtoType) { + this.schemaName = metadataEntity.getDbSchemaName(); + this.tableName = metadataEntity.getDbTableName(); + Set<String> propertyNamesSet = metadataEntity.getProperties().keySet(); + this.simplePropertyNames = propertyNamesSet.toArray(new String[propertyNamesSet.size()]); + Set<String> compositionPropertyNamesSet = metadataEntity.getRequired().keySet(); + this.compositionPropertyNames = propertyNamesSet.toArray(new String[compositionPropertyNamesSet.size()]); + + Map<String, String> nmAssociationsMap = metadataEntity.getNmAssociations(); + this.nmAssociations = new LinkedHashSet<>(); + for (Map.Entry<String, String> entry : nmAssociationsMap.entrySet()) { + String propertyName = entry.getKey(); + String dbColumnName = metadataEntity.getDbColumnName(propertyName); + String tableName = metadataEntity.getBdNmAssociationName(propertyName); + NmAssociation nmAssociation = new NmAssociation(propertyName, dbColumnName, tableName); + nmAssociations.add(nmAssociation); + } + this.columnNames = computeColumnNames(metadataEntity, simplePropertyNames, compositionPropertyNames); + this.binder = BinderFactory.newBinder(dtoType); + } + + public String generateSql(R referentialDto) { + + Set<String> parameters = new LinkedHashSet<>(); + + addStringParameter(referentialDto.getId(), parameters); + addOtherTypeParameter(referentialDto.getVersion(), parameters); + addOtherTypeParameter(referentialDto.getCreateDate(), parameters); + + Map<String, Object> simpleParameters = binder.obtainProperties(referentialDto, true, simplePropertyNames); + for (Object parameterValue : simpleParameters.values()) { + + if (parameterValue == null) { + addNullParameter(parameters); + continue; + } + if (parameterValue instanceof String) { + addStringParameter((String) parameterValue, parameters); + continue; + } + if (parameterValue instanceof Date) { + addDateParameter((Date) parameterValue, parameters); + continue; + } + if (parameterValue instanceof Enum) { + addEnumParameter((Enum) parameterValue, parameters); + continue; + } + addOtherTypeParameter(parameterValue, parameters); + + } + + Map<String, Object> compositionParameters = binder.obtainProperties(referentialDto, true, compositionPropertyNames); + for (Object parameterValue : compositionParameters.values()) { + + if (parameterValue == null) { + addNullParameter(parameters); + continue; + } + if (parameterValue instanceof ReferentialDto) { + addReferentialDtoParameter((ReferentialDto) parameterValue, parameters); + continue; + } + if (parameterValue instanceof ReferentialReference) { + addReferentialReferenceParameter((ReferentialReference) parameterValue, parameters); + } + + } + + String result = String.format(INSERT_STATEMENT, + schemaName, + tableName, + String.join(",", columnNames), + String.join(",", parameters)); + + if (log.isDebugEnabled()) { + log.debug("sql: " + result); + } + for (NmAssociation nmAssociation : nmAssociations) { + String nmAssociationSql = generateNmAssociationSql(referentialDto, nmAssociation); + result += nmAssociationSql; + } + + return result; + + } + + private String generateNmAssociationSql(R referentialDto, NmAssociation nmAssociation) { + + StringBuilder builder = new StringBuilder(); + + Collection<ReferentialReference<?>> nmAssociationValues = binder.obtainSourceProperty(referentialDto, nmAssociation.getPropertyName()); + if (CollectionUtils.isNotEmpty(nmAssociationValues)) { + + String nmAssociationTableName = nmAssociation.getTableName(); + String nmAssociationDbColumnName = nmAssociation.getDbColumnName(); + String referentialDtoId = referentialDto.getId(); + + for (ReferentialReference<?> nmAssociationValue : nmAssociationValues) { + + String sql = String.format(NM_ASSOCIATION_INSERT_STATEMENT, + schemaName, + nmAssociationTableName, + this.tableName, + nmAssociationDbColumnName, + referentialDtoId, + nmAssociationValue.getId()); + if (log.isDebugEnabled()) { + log.debug("sql: " + sql); + } + builder.append(sql); + + } + } + + return builder.toString(); + + } + + private Set<String> computeColumnNames(TopiaMetadataEntity metadataEntity, + String[] simplePropertyNames, + String[] compositionPropertyNames) { + Set<String> columnNames = new LinkedHashSet<>(); + columnNames.add(TopiaEntity.PROPERTY_TOPIA_ID); + columnNames.add(TopiaEntity.PROPERTY_TOPIA_VERSION); + columnNames.add(TopiaEntity.PROPERTY_TOPIA_CREATE_DATE); + + for (String propertyName : simplePropertyNames) { + columnNames.add(metadataEntity.getDbColumnName(propertyName)); + } + for (String propertyName : compositionPropertyNames) { + columnNames.add(metadataEntity.getDbColumnName(propertyName)); + } + return columnNames; + } + + private void addNullParameter(Set<String> parameters) { + parameters.add("NULL"); + } + + private void addStringParameter(String parameter, Set<String> parameters) { + parameters.add("'" + parameter.replaceAll("'", "''") + "'"); + } + + private void addDateParameter(Date parameter, Set<String> parameters) { + parameters.add("'" + parameter + "'"); + } + + private void addEnumParameter(Enum parameter, Set<String> parameters) { + parameters.add("" + parameter.ordinal()); + } + + private void addOtherTypeParameter(Object parameter, Set<String> parameters) { + parameters.add("" + parameter); + } + + private void addReferentialReferenceParameter(ReferentialReference parameter, Set<String> parameters) { + addStringParameter(parameter.getId(), parameters); + } + + private void addReferentialDtoParameter(ReferentialDto parameter, Set<String> parameters) { + addStringParameter(parameter.getId(), parameters); + } +} diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UpdateSqlStatementGenerator.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UpdateSqlStatementGenerator.java new file mode 100644 index 0000000..d238410 --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UpdateSqlStatementGenerator.java @@ -0,0 +1,269 @@ +package fr.ird.observe.services.service.actions.synchro; + +import fr.ird.observe.services.dto.referential.ReferentialDto; +import fr.ird.observe.services.dto.referential.ReferentialReference; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.metadata.TopiaMetadataEntity; +import org.nuiton.util.beans.Binder; +import org.nuiton.util.beans.BinderFactory; + +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * Pour générer une requète sql de mise à jour à partir d'un référentiel donné. + * + * Created on 29/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class UpdateSqlStatementGenerator<R extends ReferentialDto> { + + /** Logger. */ + private static final Log log = LogFactory.getLog(UpdateSqlStatementGenerator.class); + + private static final String UPDATE_STATEMENT = "UPDATE %s.%s %s WHERE topiaId ='%s';\n"; + private static final String NM_ASSOCIATION_DELETE_STATEMENT = "DELETE FROM %s.%s WHERE %s = '%s';\n"; + private static final String NM_ASSOCIATION_INSERT_STATEMENT = "INSERT INTO %s.%s(%s, %s) VALUES ('%s', '%s');\n"; + + private final Map<String, String> columnNames; + private final String schemaName; + private final String tableName; + private final Binder<R, R> binder; + private final String[] simplePropertyNames; + private final String[] compositionPropertyNames; + private final Set<NmAssociation> nmAssociations; + + /** + * Pour décrire une association nm. + */ + private static class NmAssociation { + + /** + * Le nom de la propriété dans l'objet. + */ + private final String propertyName; + /** + * Le nom de la colonne de l'association dans la table d'association. + */ + private final String dbColumnName; + /** + * Le nom de la table d'association. + */ + private final String tableName; + + private NmAssociation(String propertyName, String dbColumnName, String tableName) { + this.propertyName = propertyName; + this.dbColumnName = dbColumnName; + this.tableName = tableName; + } + + public String getPropertyName() { + return propertyName; + } + + public String getDbColumnName() { + return dbColumnName; + } + + public String getTableName() { + return tableName; + } + } + + public UpdateSqlStatementGenerator(TopiaMetadataEntity metadataEntity, Class<R> dtoType) { + this.schemaName = metadataEntity.getDbSchemaName(); + this.tableName = metadataEntity.getDbTableName(); + Set<String> propertyNamesSet = metadataEntity.getProperties().keySet(); + this.simplePropertyNames = propertyNamesSet.toArray(new String[propertyNamesSet.size()]); + Set<String> compositionPropertyNamesSet = metadataEntity.getRequired().keySet(); + this.compositionPropertyNames = propertyNamesSet.toArray(new String[compositionPropertyNamesSet.size()]); + + Map<String, String> nmAssociationsMap = metadataEntity.getNmAssociations(); + this.nmAssociations = new LinkedHashSet<>(); + for (Map.Entry<String, String> entry : nmAssociationsMap.entrySet()) { + String propertyName = entry.getKey(); + String dbColumnName = metadataEntity.getDbColumnName(propertyName); + String tableName = metadataEntity.getBdNmAssociationName(propertyName); + NmAssociation nmAssociation = new NmAssociation(propertyName, dbColumnName, tableName); + nmAssociations.add(nmAssociation); + } + this.columnNames = computeColumnNames(metadataEntity, simplePropertyNames, compositionPropertyNames); + this.binder = BinderFactory.newBinder(dtoType); + } + + public String generateSql(R referentialDto) { + + StringBuilder parameters = new StringBuilder(); + + addStringParameter(TopiaEntity.PROPERTY_TOPIA_ID, referentialDto.getId(), parameters); + addOtherTypeParameter(TopiaEntity.PROPERTY_TOPIA_VERSION, referentialDto.getVersion(), parameters); + addOtherTypeParameter(TopiaEntity.PROPERTY_TOPIA_CREATE_DATE, referentialDto.getCreateDate(), parameters); + + Map<String, Object> simpleParameters = binder.obtainProperties(referentialDto, true, simplePropertyNames); + for (Map.Entry<String, Object> entry : simpleParameters.entrySet()) { + + String parameterName = entry.getKey(); + String columnName = columnNames.get(parameterName); + Object parameterValue = entry.getValue(); + + if (parameterValue == null) { + addNullParameter(columnName, parameters); + continue; + } + if (parameterValue instanceof String) { + addStringParameter(columnName, (String) parameterValue, parameters); + continue; + } + if (parameterValue instanceof Date) { + addDateParameter(columnName, (Date) parameterValue, parameters); + continue; + } + if (parameterValue instanceof Enum) { + addEnumParameter(columnName, (Enum) parameterValue, parameters); + continue; + } + addOtherTypeParameter(columnName, parameterValue, parameters); + + } + + + Map<String, Object> compositionParameters = binder.obtainProperties(referentialDto, true, compositionPropertyNames); + for (Map.Entry<String, Object> entry : compositionParameters.entrySet()) { + + String parameterName = entry.getKey(); + String columnName = columnNames.get(parameterName); + Object parameterValue = entry.getValue(); + + if (parameterValue == null) { + addNullParameter(columnName, parameters); + continue; + } + if (parameterValue instanceof ReferentialDto) { + addReferentialDtoParameter(columnName, (ReferentialDto) parameterValue, parameters); + continue; + } + if (parameterValue instanceof ReferentialReference) { + addReferentialReferenceParameter(columnName, (ReferentialReference) parameterValue, parameters); + } + + } + + String result = String.format(UPDATE_STATEMENT, + schemaName, + tableName, + parameters.substring(2), + referentialDto.getId()); + + if (log.isDebugEnabled()) { + log.debug("sql: " + result); + } + + for (NmAssociation nmAssociation : nmAssociations) { + String nmAssociationSql = generateNmAssociationSql(referentialDto, nmAssociation); + result += nmAssociationSql; + } + + return result; + + } + + private String generateNmAssociationSql(R referentialDto, NmAssociation nmAssociation) { + + StringBuilder builder = new StringBuilder(); + + String referentialDtoId = referentialDto.getId(); + String nmAssociationTableName = nmAssociation.getTableName(); + + // On commence toujours par supprimer toutes les anciennes associations, elles seront ré-ajoutées juste après + String deleteSql = String.format(NM_ASSOCIATION_DELETE_STATEMENT, + schemaName, + nmAssociationTableName, + tableName, + referentialDtoId); + builder.append(deleteSql); + if (log.isDebugEnabled()) { + log.debug("sql: " + deleteSql); + } + + Collection<ReferentialReference<?>> nmAssociationValues = binder.obtainSourceProperty(referentialDto, nmAssociation.getPropertyName()); + if (CollectionUtils.isNotEmpty(nmAssociationValues)) { + + + String nmAssociationDbColumnName = nmAssociation.getDbColumnName(); + + + for (ReferentialReference<?> nmAssociationValue : nmAssociationValues) { + + String sql = String.format(NM_ASSOCIATION_INSERT_STATEMENT, + schemaName, + nmAssociationTableName, + tableName, + nmAssociationDbColumnName, + referentialDtoId, + nmAssociationValue.getId()); + if (log.isDebugEnabled()) { + log.debug("sql: " + sql); + } + builder.append(sql); + + } + } + + return builder.toString(); + + } + + private Map<String, String> computeColumnNames(TopiaMetadataEntity metadataEntity, + String[] simplePropertyNames, + String[] compositionPropertyNames) { + Map<String, String> columnNames = new TreeMap<>(); + + for (String propertyName : simplePropertyNames) { + columnNames.put(propertyName, metadataEntity.getDbColumnName(propertyName)); + } + for (String propertyName : compositionPropertyNames) { + columnNames.put(propertyName, metadataEntity.getDbColumnName(propertyName)); + } + return columnNames; + } + + private void addNullParameter(String columnName, StringBuilder parameters) { + addParameter0(columnName, "NULL", parameters); + } + + private void addStringParameter(String columnName, String parameter, StringBuilder parameters) { + addParameter0(columnName, "'" + parameter.replaceAll("'", "''") + "'", parameters); + } + + private void addDateParameter(String columnName, Date parameter, StringBuilder parameters) { + addParameter0(columnName, "'" + parameter + "'", parameters); + } + + private void addEnumParameter(String columnName, Enum parameter, StringBuilder parameters) { + addParameter0(columnName, "" + parameter.ordinal(), parameters); + } + + private void addOtherTypeParameter(String columnName, Object parameter, StringBuilder parameters) { + addParameter0(columnName, "" + parameter, parameters); + } + + private void addReferentialReferenceParameter(String columnName, ReferentialReference parameter, StringBuilder parameters) { + addStringParameter(columnName, parameter.getId(), parameters); + } + + private void addReferentialDtoParameter(String columnName, ReferentialDto parameter, StringBuilder parameters) { + addStringParameter(columnName, parameter.getId(), parameters); + } + + private void addParameter0(String columnName, String value, StringBuilder parameters) { + parameters.append(", SET ").append(columnName).append(" = ").append(value); + } +} -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/7739 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 394b8fc137f15becfb56630d7f58dbfedfffa0c8 Author: Tony CHEMIT <chemit@codelutin.com> Date: Wed Jun 29 12:39:49 2016 +0200 Mise en place de la génération des requètes sql et de leur application (See #7739) --- ...UnidirectionalReferentialSynchronizeEngine.java | 15 ++- ...ectionalReferentialSynchronizeLocalService.java | 23 ++++ ...nidirectionalReferentialSynchronizeRequest.java | 57 +++++++--- ...nalReferentialSynchronizeLocalServiceTopia.java | 121 ++++++++++++++++----- 4 files changed, 170 insertions(+), 46 deletions(-) diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeEngine.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeEngine.java index 9df5e43..44f22f6 100644 --- a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeEngine.java +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeEngine.java @@ -33,17 +33,24 @@ public class UnidirectionalReferentialSynchronizeEngine { LocalReferentialStates localReferentialStates = localService.getLocalSourceReferentialStates(); RemoteReferentialDiff remoteReferentialDiff = remoteService.getReferentialDifferential(localReferentialStates); + Set<String> sqlRequests = new LinkedHashSet<>(); for (String referentialName : remoteReferentialDiff.getReferentialNames()) { - UnidirectionalReferentialSynchronizeRequest referentialSynchronizeRequest = buildReferentialSynchronizeRequest(callback, referentialName, remoteReferentialDiff); + UnidirectionalReferentialSynchronizeRequest<?> referentialSynchronizeRequest = + buildReferentialSynchronizeRequest(callback, referentialName, remoteReferentialDiff); + + Set<String> sqlRequestsforReferential = localService.generateSqlRequests(referentialSynchronizeRequest); + sqlRequests.addAll(sqlRequestsforReferential); } + localService.applySqlRequests(sqlRequests); + } private <R extends ReferentialDto> UnidirectionalReferentialSynchronizeRequest buildReferentialSynchronizeRequest(Callback callback, String referentialName, RemoteReferentialDiff remoteReferentialDiff) { - UnidirectionalReferentialSynchronizeRequest.Builder builder = UnidirectionalReferentialSynchronizeRequest.builder(referentialName); + UnidirectionalReferentialSynchronizeRequest.Builder<R> builder = UnidirectionalReferentialSynchronizeRequest.builder(referentialName); Collection<R> referentialsToAdd = remoteReferentialDiff.getReferentialsToAdd(referentialName); if (CollectionUtils.isNotEmpty(referentialsToAdd)) { @@ -101,8 +108,8 @@ public class UnidirectionalReferentialSynchronizeEngine { // calcul de l'univers de référentiels disponibles pour les remplacements - ReferentialReferenceSet<R> localSourceEnabledReferenceSet = remoteService.getEnabledReferentialReferenceSet(referentialName); - Set<ReferentialReference<R>> availableReferentials = localSourceEnabledReferenceSet.getReferences(); + ReferentialReferenceSet<R> availableReferenceSet = remoteService.getEnabledReferentialReferenceSet(referentialName); + Set<ReferentialReference<R>> availableReferentials = availableReferenceSet.getReferences(); if (needCallbackForRemove) { diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalService.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalService.java index a1b4b22..0c2caa2 100644 --- a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalService.java +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalService.java @@ -1,6 +1,11 @@ package fr.ird.observe.services.service.actions.synchro; +import fr.ird.observe.services.dto.referential.ReferentialDto; +import fr.ird.observe.services.spi.NoDataAccess; +import fr.ird.observe.services.spi.PostRequest; import fr.ird.observe.services.spi.ReadReferentialPermission; +import fr.ird.observe.services.spi.Write; +import fr.ird.observe.services.spi.WriteReferentialPermission; import java.util.Collection; import java.util.Set; @@ -34,4 +39,22 @@ public interface UnidirectionalReferentialSynchronizeLocalService { @ReadReferentialPermission Set<String> filterIdsUsedInLocalSource(String referentialName, Collection<String> ids); + /** + * Pour produire le code sql à partir de la demande pour un référentiel donné. + * + * @param request la demande des actions à produire pour un référentiel donné + * @return l'ensemble des requètes sql à appliquer. + */ + @NoDataAccess + <R extends ReferentialDto> Set<String> generateSqlRequests(UnidirectionalReferentialSynchronizeRequest<R> request); + + /** + * Pour appliquer les requètes sql de mise à jour du réferentiel. + * + * @param sqlRequests les requètes sql à appliquer + */ + @WriteReferentialPermission + @Write + @PostRequest + void applySqlRequests(Set<String> sqlRequests); } diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeRequest.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeRequest.java index 4cbe9ed..d049d04 100644 --- a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeRequest.java +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeRequest.java @@ -1,5 +1,6 @@ package fr.ird.observe.services.service.actions.synchro; +import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import fr.ird.observe.services.dto.referential.ReferentialDto; @@ -14,15 +15,15 @@ import fr.ird.observe.services.dto.referential.ReferentialDto; * @author Tony Chemit - chemit@codelutin.com * @since 5.0 */ -public class UnidirectionalReferentialSynchronizeRequest { +public class UnidirectionalReferentialSynchronizeRequest<R extends ReferentialDto> { - public static Builder builder(String referentialName) { - return new Builder(referentialName); + public static <R extends ReferentialDto> Builder<R> builder(String referentialName) { + return new Builder<>(referentialName); } private final String referentialName; - private final ImmutableSet<ReferentialDto> referentialToAdd; - private final ImmutableSet<ReferentialDto> referentialToUpdate; + private final ImmutableSet<R> referentialToAdd; + private final ImmutableSet<R> referentialToUpdate; private final ImmutableSet<String> referentialToRemove; private final ImmutableMap<String, String> referentialToReplace; @@ -30,11 +31,11 @@ public class UnidirectionalReferentialSynchronizeRequest { return referentialName; } - public ImmutableSet<ReferentialDto> getReferentialToAdd() { + public ImmutableSet<R> getReferentialToAdd() { return referentialToAdd; } - public ImmutableSet<ReferentialDto> getReferentialToUpdate() { + public ImmutableSet<R> getReferentialToUpdate() { return referentialToUpdate; } @@ -46,9 +47,33 @@ public class UnidirectionalReferentialSynchronizeRequest { return referentialToReplace; } + public boolean withReferentialToAdd() { + return !referentialToAdd.isEmpty(); + } + public boolean withReferentialToUpdate() { + return !referentialToUpdate.isEmpty(); + } + public boolean withReferentialToRemove() { + return !referentialToRemove.isEmpty(); + } + public boolean withReferentialToReplace() { + return !referentialToReplace.isEmpty(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("referentialName", referentialName) + .add("referentialToAdd", referentialToAdd.size()) + .add("referentialToUpdate", referentialToUpdate.size()) + .add("referentialToRemove", referentialToRemove.size()) + .add("referentialToReplace", referentialToReplace.size()) + .toString(); + } + private UnidirectionalReferentialSynchronizeRequest(String referentialName, - ImmutableSet<ReferentialDto> referentialToAdd, - ImmutableSet<ReferentialDto> referentialToUpdate, + ImmutableSet<R> referentialToAdd, + ImmutableSet<R> referentialToUpdate, ImmutableSet<String> referentialToRemove, ImmutableMap<String, String> toReplace) { this.referentialName = referentialName; @@ -58,20 +83,20 @@ public class UnidirectionalReferentialSynchronizeRequest { this.referentialToReplace = toReplace; } - public static class Builder { + public static class Builder<R extends ReferentialDto> { private final String referentialName; - private final ImmutableSet.Builder<ReferentialDto> toAddBuilder = ImmutableSet.builder(); - private final ImmutableSet.Builder<ReferentialDto> toUpdateBuilder = ImmutableSet.builder(); + private final ImmutableSet.Builder<R> toAddBuilder = ImmutableSet.builder(); + private final ImmutableSet.Builder<R> toUpdateBuilder = ImmutableSet.builder(); private final ImmutableSet.Builder<String> toRemoveBuilder = ImmutableSet.builder(); private final ImmutableMap.Builder<String, String> toReplaceBuilder = ImmutableMap.builder(); - public Builder entityToAdd(ReferentialDto referentialDto) { + public Builder entityToAdd(R referentialDto) { toAddBuilder.add(referentialDto); return this; } - public Builder entityToUpdate(ReferentialDto referentialDto) { + public Builder entityToUpdate(R referentialDto) { toUpdateBuilder.add(referentialDto); return this; } @@ -86,9 +111,9 @@ public class UnidirectionalReferentialSynchronizeRequest { return this; } - public UnidirectionalReferentialSynchronizeRequest build() { + public UnidirectionalReferentialSynchronizeRequest<R> build() { - return new UnidirectionalReferentialSynchronizeRequest( + return new UnidirectionalReferentialSynchronizeRequest<>( referentialName, toAddBuilder.build(), toUpdateBuilder.build(), diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalServiceTopia.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalServiceTopia.java index e9c2245..79ab42f 100644 --- a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalServiceTopia.java +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalServiceTopia.java @@ -4,17 +4,19 @@ import fr.ird.observe.ObserveEntityEnum; import fr.ird.observe.entities.Entities; import fr.ird.observe.entities.referentiel.ObserveReferentialEntity; import fr.ird.observe.services.ObserveServiceTopia; +import fr.ird.observe.services.binder.BinderEngine; import fr.ird.observe.services.dto.referential.ReferentialDto; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.topia.persistence.TopiaDao; import org.nuiton.topia.persistence.TopiaEntity; import org.nuiton.topia.persistence.metadata.TopiaMetadataEntity; -import org.nuiton.util.beans.Binder; -import org.nuiton.util.beans.BinderFactory; +import org.nuiton.topia.persistence.support.TopiaSqlWork; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; import java.util.Collection; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -67,35 +69,71 @@ public class UnidirectionalReferentialSynchronizeLocalServiceTopia extends Obser } - private <E extends ObserveReferentialEntity, R extends ReferentialDto> void generateInsertSqlStatements0(StringBuilder builder, - Class<E> entityType, - Class<R> dtoType, - TopiaMetadataEntity metadataEntity, - Collection<R> referentialsToAdd) { - - Set<String> columnNames = new LinkedHashSet<>(); - columnNames.add(TopiaEntity.PROPERTY_TOPIA_ID); - columnNames.add(TopiaEntity.PROPERTY_TOPIA_VERSION); - columnNames.add(TopiaEntity.PROPERTY_TOPIA_CREATE_DATE); - - Set<String> propertyNamesSet = metadataEntity.getProperties().keySet(); - String[] propertyNames = propertyNamesSet.toArray(new String[propertyNamesSet.size()]); - for (String propertyName : propertyNames) { - columnNames.add(metadataEntity.getDbColumnName(propertyName)); + @Override + public <R extends ReferentialDto> Set<String> generateSqlRequests(UnidirectionalReferentialSynchronizeRequest<R> request) { + + if (log.isTraceEnabled()) { + log.trace("generateSqlRequests(" + request + ")"); + } + + Set<String> result = new LinkedHashSet<>(); + + String referentialName = request.getReferentialName(); + + ObserveEntityEnum entityEnum = ObserveEntityEnum.valueOf(referentialName); + Class entityType = entityEnum.getContract(); + Class<R> dtoType = BinderEngine.get().getReferentialDtoType(entityType); + + TopiaMetadataEntity metadataEntity = serviceContext.getTopiaApplicationContext().getMetadataModel().getEntity(referentialName); + if (request.withReferentialToAdd()) { + + InsertSqlStatementGenerator<R> sqlStatementGenerator = new InsertSqlStatementGenerator<>(metadataEntity, dtoType); + for (R referentialDto : request.getReferentialToAdd()) { + String sql = sqlStatementGenerator.generateSql(referentialDto); + result.add(sql); + } + } + + if (request.withReferentialToUpdate()) { + + UpdateSqlStatementGenerator<R> sqlStatementGenerator = new UpdateSqlStatementGenerator<R>(metadataEntity, dtoType); + for (R referentialDto : request.getReferentialToUpdate()) { + String sql = sqlStatementGenerator.generateSql(referentialDto); + result.add(sql); + } + + } + + if (request.withReferentialToReplace()) { + + //TODO + + } + if (request.withReferentialToRemove()) { + + DeleteSqlStatementGenerator sqlStatementGenerator = new DeleteSqlStatementGenerator(metadataEntity); + for (String id : request.getReferentialToRemove()) { + String sql = sqlStatementGenerator.generateSql(id); + result.add(sql); + } + } - Binder<R, R> binder = BinderFactory.newBinder(dtoType); - for (R referentialToAdd : referentialsToAdd) { - Map<String,Object> properties = new LinkedHashMap<>(); - properties.put(TopiaEntity.PROPERTY_TOPIA_ID, referentialToAdd.getId()); - properties.put(TopiaEntity.PROPERTY_TOPIA_VERSION, referentialToAdd.getVersion()); - properties.put(TopiaEntity.PROPERTY_TOPIA_CREATE_DATE, referentialToAdd.getCreateDate()); + return result; + + } - Map<String, Object> obtainProperties = binder.obtainProperties(referentialToAdd, true, propertyNames); - properties.putAll(obtainProperties); + @Override + public void applySqlRequests(Set<String> sqlRequests) { + if (log.isTraceEnabled()) { + log.trace("applySqlRequests(" + sqlRequests + ")"); } + + TopiaSqlWork applySqlWork = new ApplySqlRequestWork(sqlRequests); + getTopiaPersistenceContext().getSqlSupport().doSqlWork(applySqlWork); + } private <E extends ObserveReferentialEntity> void getLocalSourceReferentialVersions0(String entityName, Class<E> entityType, LocalReferentialStates localReferentialStates) { @@ -120,4 +158,35 @@ public class UnidirectionalReferentialSynchronizeLocalServiceTopia extends Obser } + private static class ApplySqlRequestWork implements TopiaSqlWork { + + private static final int BATCH_SIZE = 100; + + private final Set<String> sqlRequests; + + ApplySqlRequestWork(Set<String> sqlRequests) { + this.sqlRequests = sqlRequests; + } + + @Override + public void execute(Connection connection) throws SQLException { + + Statement statement = connection.createStatement(); + + int count = 0; + for (String sqlRequest : sqlRequests) { + statement.addBatch(sqlRequest); + if ((count % BATCH_SIZE) == 0) { + flush(statement); + } + } + flush(statement); + + } + + private void flush(Statement statement) throws SQLException { + statement.executeBatch(); + statement.clearBatch(); + } + } } -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
participants (1)
-
codelutin.com scm