[Git][ultreiaio/ird-observe][feature/issue-2843] 3 commits: persistence - introduce ToolkitIdModificationsToSql
Tony CHEMIT pushed to branch feature/issue-2843 at ultreiaio / ird-observe Commits: 2c4fed94 by Tony Chemit at 2024-03-08T12:54:45+01:00 persistence - introduce ToolkitIdModificationsToSql - - - - - ae84f818 by Tony Chemit at 2024-03-08T12:54:52+01:00 persistence - introduce toSql method on consolidate engine to produce sql script of modifications - - - - - 6af33613 by Tony Chemit at 2024-03-08T12:54:58+01:00 persistence - on TripConsolidateEngine.consolidate, now use the generated sql script to finalize consolidation instead of letting Hibernate doing it for us - - - - - 4 changed files: - core/persistence/consolidation/src/main/java/fr/ird/observe/consolidation/data/ps/common/TripConsolidateEngine.java - core/persistence/consolidation/src/main/java/fr/ird/observe/consolidation/data/ps/logbook/ActivityConsolidateEngine.java - core/persistence/consolidation/src/main/java/fr/ird/observe/consolidation/data/ps/observation/ActivityConsolidateEngine.java - + toolkit/persistence/src/main/java/fr/ird/observe/spi/consolidation/ToolkitIdModificationsToSql.java Changes: ===================================== core/persistence/consolidation/src/main/java/fr/ird/observe/consolidation/data/ps/common/TripConsolidateEngine.java ===================================== @@ -33,13 +33,19 @@ import fr.ird.observe.dto.referential.ReferentialLocale; import fr.ird.observe.entities.ObserveTopiaDaoSupplier; import fr.ird.observe.entities.data.ps.common.Trip; import fr.ird.observe.entities.data.ps.localmarket.Batch; +import fr.ird.observe.entities.data.ps.logbook.SampleActivity; import fr.ird.observe.entities.referential.common.LengthLengthParameterCache; import fr.ird.observe.entities.referential.common.LengthWeightParameterCache; +import fr.ird.observe.spi.consolidation.ToolkitIdModificationsToSql; import fr.ird.observe.spi.service.ServiceContext; import io.ultreia.java4all.decoration.Decorator; +import io.ultreia.java4all.util.sql.SqlScript; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.nuiton.topia.service.sql.model.TopiaEntitySqlModel; +import java.io.IOException; +import java.nio.file.Path; import java.util.LinkedHashSet; import java.util.Optional; import java.util.Set; @@ -95,15 +101,38 @@ public class TripConsolidateEngine { decoratorService.installDecorator(Trip.class, trip); String tripLabel = trip.toString(); TripConsolidateResult result = new TripConsolidateResult(tripId, tripLabel, observationActivityConsolidateResults, logbookActivityConsolidateResults, logbookSampleActivityResults, localmarketBatchResults); - if (result.withModifications()) { + boolean withModifications = result.withModifications(); + if (withModifications) { log.info(String.format("Found some modifications on trip: %s - %s", tripId, result.getTripLabel())); } if (result.withWarnings()) { log.info(String.format("Found some warnings on trip: %s - %s", tripId, result.getTripLabel())); } + // clear hibernate session (See https://gitlab.com/ultreiaio/ird-observe/-/issues/2843) + context.getTopiaPersistenceContext().getHibernateSupport().clearSession(); + if (withModifications) { + // generate sql script + Path scriptPath = context.getTemporaryDirectoryRoot().resolve(String.format("TripConsolidateResult%d.sql", System.nanoTime())); + log.info("Produce TripConsolidateResult sql script to: {}", scriptPath); + SqlScript script = toSql(scriptPath, result, context.getTopiaApplicationContext().getModel()); + // consume sql script + context.getTopiaPersistenceContext().executeSqlScript(script); + } return Optional.of(result); } + public SqlScript toSql(Path scriptPath, TripConsolidateResult result, TopiaEntitySqlModel entitySqlModel) { + try (ToolkitIdModificationsToSql toolkitIdModificationsToSql = new ToolkitIdModificationsToSql(scriptPath, context.timestampNow(), entitySqlModel)) { + observationActivityConsolidateEngine.toSql(result.getActivityObservationResults(), toolkitIdModificationsToSql); + logbookActivityConsolidateEngine.toSql(result.getActivityLogbookResults(), toolkitIdModificationsToSql); + toolkitIdModificationsToSql.toSql(Batch.SPI, result.getLocalmarketBatchResults()); + toolkitIdModificationsToSql.toSql(SampleActivity.SPI, result.getLogbookSampleActivityResults()); + return toolkitIdModificationsToSql.build(); + } catch (IOException e) { + throw new IllegalStateException("Could not produce sql script to " + scriptPath, e); + } + } + private Set<ToolkitIdModifications> consolidateLogbookSampleActivities(Trip trip) { Set<ToolkitIdModifications> result = new LinkedHashSet<>(); if (trip.isWellEmpty() || trip.isSampleEmpty()) { ===================================== core/persistence/consolidation/src/main/java/fr/ird/observe/consolidation/data/ps/logbook/ActivityConsolidateEngine.java ===================================== @@ -33,6 +33,7 @@ import fr.ird.observe.entities.data.ps.logbook.Activity; import fr.ird.observe.entities.data.ps.logbook.FloatingObject; import fr.ird.observe.entities.data.ps.logbook.FloatingObjectPart; import fr.ird.observe.entities.data.ps.logbook.Route; +import fr.ird.observe.spi.consolidation.ToolkitIdModificationsToSql; import fr.ird.observe.spi.service.ServiceContext; import io.ultreia.java4all.decoration.Decorator; import io.ultreia.java4all.util.Dates; @@ -41,6 +42,7 @@ import org.apache.logging.log4j.Logger; import java.util.LinkedHashSet; import java.util.Optional; +import java.util.Set; /** * Created on 12/03/2023. @@ -60,6 +62,12 @@ public class ActivityConsolidateEngine { this.activityDecorator = context.getDecoratorService().getDecoratorByType(Activity.class, ActivityAware.CLASSIFIER_WITH_ROUTE); } + public void toSql(Set<ActivityConsolidateResult> activityLogbookResults, ToolkitIdModificationsToSql toolkitIdModificationsToSql) { + for (ActivityConsolidateResult activityConsolidateResult : activityLogbookResults) { + toolkitIdModificationsToSql.toSql(FloatingObject.SPI, activityConsolidateResult.getFloatingObjectModifications()); + } + } + public Optional<ActivityConsolidateResult> consolidateActivity(Trip trip, Route route, Activity activity, @@ -142,5 +150,4 @@ public class ActivityConsolidateEngine { } } } - } ===================================== core/persistence/consolidation/src/main/java/fr/ird/observe/consolidation/data/ps/observation/ActivityConsolidateEngine.java ===================================== @@ -30,11 +30,15 @@ import fr.ird.observe.dto.data.ps.observation.FloatingObjectPartDto; import fr.ird.observe.dto.referential.ReferentialLocale; import fr.ird.observe.entities.data.ps.common.Trip; import fr.ird.observe.entities.data.ps.observation.Activity; +import fr.ird.observe.entities.data.ps.observation.Catch; import fr.ird.observe.entities.data.ps.observation.FloatingObject; import fr.ird.observe.entities.data.ps.observation.FloatingObjectPart; import fr.ird.observe.entities.data.ps.observation.Route; +import fr.ird.observe.entities.data.ps.observation.SampleMeasure; +import fr.ird.observe.entities.data.ps.observation.Set; import fr.ird.observe.entities.referential.common.LengthLengthParameterCache; import fr.ird.observe.entities.referential.common.LengthWeightParameterCache; +import fr.ird.observe.spi.consolidation.ToolkitIdModificationsToSql; import fr.ird.observe.spi.service.ServiceContext; import io.ultreia.java4all.decoration.Decorator; import io.ultreia.java4all.util.Dates; @@ -70,6 +74,15 @@ public class ActivityConsolidateEngine { this.activityDecorator = context.getDecoratorService().getDecoratorByType(Activity.class, ActivityAware.CLASSIFIER_WITH_ROUTE); } + public void toSql(java.util.Set<ActivityConsolidateResult> activityObservationResults, ToolkitIdModificationsToSql toolkitIdModificationsToSql) { + for (ActivityConsolidateResult activityConsolidateResult : activityObservationResults) { + toolkitIdModificationsToSql.toSql(FloatingObject.SPI, activityConsolidateResult.getFloatingObjectModifications()); + toolkitIdModificationsToSql.toSql(Set.SPI, activityConsolidateResult.getSetModifications()); + toolkitIdModificationsToSql.toSql(Catch.SPI, activityConsolidateResult.getCatchModifications()); + toolkitIdModificationsToSql.toSql(SampleMeasure.SPI, activityConsolidateResult.getSampleMeasureModifications()); + } + } + public Optional<ActivityConsolidateResult> consolidateActivity(Trip trip, Route route, Activity activity, @@ -163,5 +176,4 @@ public class ActivityConsolidateEngine { } } } - } ===================================== toolkit/persistence/src/main/java/fr/ird/observe/spi/consolidation/ToolkitIdModificationsToSql.java ===================================== @@ -0,0 +1,153 @@ +package fr.ird.observe.spi.consolidation; + +/*- + * #%L + * ObServe Toolkit :: Persistence + * %% + * Copyright (C) 2008 - 2024 IRD, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.dto.ToolkitIdModifications; +import fr.ird.observe.entities.Entity; +import fr.ird.observe.spi.SqlConversions; +import fr.ird.observe.spi.context.DtoEntityContext; +import io.ultreia.java4all.bean.monitor.JavaBeanPropertyModification; +import io.ultreia.java4all.util.sql.SqlScript; +import io.ultreia.java4all.util.sql.SqlScriptWriter; +import org.nuiton.topia.service.sql.model.TopiaEntitySqlModel; +import org.nuiton.topia.service.sql.model.TopiaEntitySqlTable; + +import java.io.Closeable; +import java.io.IOException; +import java.nio.file.Path; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +/** + * To produce sql update code from some consolidation modifications. + * <p> + * Created at 04/03/2024. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 9.3.0 + */ +public class ToolkitIdModificationsToSql implements Closeable { + + public static final String UPDATE_SQL = "UPDATE %s SET %s WHERE topiaId = '%s';"; + public static final String SET_SQL_CLAUSE = "%s = %s"; + + /** + * Where to write sql statements. + */ + private final Path target; + /** + * Now timestamp to used in any sql statement that requires it. + */ + private final Timestamp now; + /** + * Topia Entity sql model used to perform conversions while writing sql statements. + */ + private final TopiaEntitySqlModel entitySqlModel; + /** + * Set of spi used to produce sql statements (we be used in method {@link #build()} to add extra sql statements + * to update {@code LastUpdateDate} table). + */ + private final Set<DtoEntityContext<?, ?, ?, ?>> spiUsed; + /** + * Internal writer used to store sql statements. + */ + private SqlScriptWriter writer; + + public ToolkitIdModificationsToSql(Path target, Timestamp now, TopiaEntitySqlModel entitySqlModel) { + this.target = Objects.requireNonNull(target); + this.now = Objects.requireNonNull(now); + this.entitySqlModel = Objects.requireNonNull(entitySqlModel); + this.spiUsed = new LinkedHashSet<>(); + } + + + public static String toSetClause(TopiaEntitySqlTable sqlModelDescriptorTable, String propertyName, Object value) { + String stringValue = SqlConversions.convertValue(sqlModelDescriptorTable, propertyName, value); + return String.format(SET_SQL_CLAUSE, propertyName, stringValue); + } + + public SqlScript build() { + SqlScriptWriter writer = writer(); + Set<String> lastUpdateDateStatements = new LinkedHashSet<>(); + spiUsed.forEach(spi -> spi.getUpdateLastUpdateDateTableScript().generate(now).forEach(l -> lastUpdateDateStatements.add(l.trim()))); + lastUpdateDateStatements.forEach(writer::writeSql); + return SqlScript.of(target); + } + + public void toSql(DtoEntityContext<?, ?, ?, ?> spi, ToolkitIdModifications modifications) { + if (modifications == null) { + return; + } + TopiaEntitySqlTable sqlModelDescriptorTable = entitySqlModel.getDescriptor(spi.toEntityType()).getTable(); + boolean used = toSql(sqlModelDescriptorTable, modifications); + if (used) { + spiUsed.add(spi); + } + } + + public void toSql(DtoEntityContext<?, ?, ?, ?> spi, Set<ToolkitIdModifications> modificationsSet) { + if (modificationsSet == null) { + return; + } + TopiaEntitySqlTable sqlModelDescriptorTable = entitySqlModel.getDescriptor(spi.toEntityType()).getTable(); + boolean used = false; + for (ToolkitIdModifications modifications : modificationsSet) { + used |= toSql(sqlModelDescriptorTable, modifications); + } + if (used) { + spiUsed.add(spi); + } + } + + @Override + public void close() throws IOException { + if (writer != null) { + writer.close(); + } + } + + protected SqlScriptWriter writer() { + return writer == null ? writer = SqlScriptWriter.of(target) : writer; + } + + protected boolean toSql(TopiaEntitySqlTable sqlModelDescriptorTable, ToolkitIdModifications modifications) { + if (modifications == null || !modifications.withModifications()) { + // only warning on this one + return false; + } + List<String> setClauses = new ArrayList<>(modifications.modificationsCount() + 2); + String schemaAndTableName = sqlModelDescriptorTable.getSchemaAndTableName(); + for (JavaBeanPropertyModification modification : modifications.getModifications()) { + setClauses.add(toSetClause(sqlModelDescriptorTable, modification.getPropertyName(), modification.getNewValue())); + } + setClauses.add(String.format(SET_SQL_CLAUSE, Entity.PROPERTY_TOPIA_VERSION, Entity.PROPERTY_TOPIA_VERSION + " + 1")); + setClauses.add(toSetClause(sqlModelDescriptorTable, Entity.PROPERTY_LAST_UPDATE_DATE, now)); + String sql = String.format(UPDATE_SQL, schemaAndTableName, String.join(", ", setClauses), modifications.getId()); + writer().writeSql(sql); + return true; + } +} View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/compare/7e395260dffcb63904ef21f95... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/compare/7e395260dffcb63904ef21f95... You're receiving this email because of your account on gitlab.com.
participants (1)
-
Tony CHEMIT (@tchemit)