diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/tablesync/AbstractTableSyncTransformStep.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/tablesync/AbstractTableSyncTransformStep.java index a6acf84a..73a81b00 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/tablesync/AbstractTableSyncTransformStep.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/tablesync/AbstractTableSyncTransformStep.java @@ -72,6 +72,18 @@ public abstract class AbstractTableSyncTransformStep extends AbstractTransformSt private ProcessSummaryLine okToInsert = StandardProcessSummaryLineProducer.getOkToInsertLine(); private ProcessSummaryLine okToUpdate = StandardProcessSummaryLineProducer.getOkToUpdateLine(); + private ProcessSummaryLine willNotInsert = new ProcessSummaryLine(Status.INFO) + .withMessageSuffix("because of this process' configuration.") + .withSingularFutureMessage("will not be inserted ") + .withPluralFutureMessage("will not be inserted ") + .withSingularPastMessage("was not inserted ") + .withPluralPastMessage("were not inserted "); + private ProcessSummaryLine willNotUpdate = new ProcessSummaryLine(Status.INFO) + .withMessageSuffix("because of this process' configuration.") + .withSingularFutureMessage("will not be updated ") + .withPluralFutureMessage("will not be updated ") + .withSingularPastMessage("was not updated ") + .withPluralPastMessage("were not updated "); private ProcessSummaryLine errorMissingKeyField = new ProcessSummaryLine(Status.ERROR) .withMessageSuffix("missing a value for the key field.") .withSingularFutureMessage("will not be synced, because it is ") @@ -92,7 +104,16 @@ public abstract class AbstractTableSyncTransformStep extends AbstractTransformSt @Override public ArrayList getProcessSummary(RunBackendStepOutput runBackendStepOutput, boolean isForResultScreen) { - return (StandardProcessSummaryLineProducer.toArrayList(okToInsert, okToUpdate, errorMissingKeyField)); + ArrayList processSummaryLineList = StandardProcessSummaryLineProducer.toArrayList(okToInsert, okToUpdate, errorMissingKeyField); + if(willNotInsert.getCount() > 0) + { + processSummaryLineList.add(willNotInsert); + } + if(willNotUpdate.getCount() > 0) + { + processSummaryLineList.add(willNotUpdate); + } + return (processSummaryLineList); } @@ -145,6 +166,11 @@ public abstract class AbstractTableSyncTransformStep extends AbstractTransformSt *******************************************************************************/ public record SyncProcessConfig(String sourceTable, String sourceTableKeyField, String destinationTable, String destinationTableForeignKey) { + public static boolean performUpdates = true; + public static boolean performInserts = true; + + + /******************************************************************************* ** artificial method, here to make jacoco see that this class is indeed ** included in test coverage... @@ -153,6 +179,75 @@ public abstract class AbstractTableSyncTransformStep extends AbstractTransformSt { System.out.println("noop"); } + + + + /******************************************************************************* + ** Getter for performUpdates + ** + *******************************************************************************/ + public boolean getPerformUpdates() + { + return performUpdates; + } + + + + /******************************************************************************* + ** Setter for performUpdates + ** + *******************************************************************************/ + public void setPerformUpdates(boolean performUpdates) + { + SyncProcessConfig.performUpdates = performUpdates; + } + + + + /******************************************************************************* + ** Fluent setter for performUpdates + ** + *******************************************************************************/ + public SyncProcessConfig withPerformUpdates(boolean performUpdates) + { + SyncProcessConfig.performUpdates = performUpdates; + return (this); + } + + + + /******************************************************************************* + ** Getter for performInserts + ** + *******************************************************************************/ + public boolean getPerformInserts() + { + return performInserts; + } + + + + /******************************************************************************* + ** Setter for performInserts + ** + *******************************************************************************/ + public void setPerformInserts(boolean performInserts) + { + SyncProcessConfig.performInserts = performInserts; + } + + + + /******************************************************************************* + ** Fluent setter for performInserts + ** + *******************************************************************************/ + public SyncProcessConfig withPerformInserts(boolean performInserts) + { + SyncProcessConfig.performInserts = performInserts; + return (this); + } + } @@ -271,16 +366,30 @@ public abstract class AbstractTableSyncTransformStep extends AbstractTransformSt QRecord existingRecord = existingRecordsByForeignKey.get(sourceKeyValueInTargetFieldType); QRecord recordToStore; - if(existingRecord != null) + if(existingRecord != null && config.getPerformUpdates()) { recordToStore = existingRecord; okToUpdate.incrementCount(); } - else + else if(existingRecord == null && config.getPerformInserts()) { recordToStore = new QRecord(); okToInsert.incrementCount(); } + else + { + if(existingRecord != null) + { + LOG.info("Skipping storing existing record because this sync process is set to not perform updates"); + willNotInsert.incrementCount(); + } + else + { + LOG.info("Skipping storing new record because this sync process is set to not perform inserts"); + willNotUpdate.incrementCount(); + } + continue; + } recordToStore = populateRecordToStore(runBackendStepInput, recordToStore, sourceRecord); runBackendStepOutput.addRecord(recordToStore); diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/ValueUtils.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/ValueUtils.java index 8a65227f..6ecc2dc8 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/ValueUtils.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/ValueUtils.java @@ -503,6 +503,11 @@ public class ValueUtils ////////////////////////// return Instant.parse(s + ":00Z"); } + else if(s.matches("^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.0$")) + { + s = s.replaceAll(" ", "T").replaceAll("\\..*$", "Z"); + return Instant.parse(s); + } else { try @@ -646,16 +651,16 @@ public class ValueUtils public static Serializable getValueAsFieldType(QFieldType type, Serializable value) { return switch(type) - { - case STRING, TEXT, HTML, PASSWORD -> getValueAsString(value); - case INTEGER -> getValueAsInteger(value); - case DECIMAL -> getValueAsBigDecimal(value); - case BOOLEAN -> getValueAsBoolean(value); - case DATE -> getValueAsLocalDate(value); - case TIME -> getValueAsLocalTime(value); - case DATE_TIME -> getValueAsInstant(value); - case BLOB -> getValueAsByteArray(value); - }; + { + case STRING, TEXT, HTML, PASSWORD -> getValueAsString(value); + case INTEGER -> getValueAsInteger(value); + case DECIMAL -> getValueAsBigDecimal(value); + case BOOLEAN -> getValueAsBoolean(value); + case DATE -> getValueAsLocalDate(value); + case TIME -> getValueAsLocalTime(value); + case DATE_TIME -> getValueAsInstant(value); + case BLOB -> getValueAsByteArray(value); + }; } diff --git a/qqq-dev-tools/bin/end-of-sprint-release.sh b/qqq-dev-tools/bin/end-of-sprint-release.sh index 423165a9..9b6e701f 100755 --- a/qqq-dev-tools/bin/end-of-sprint-release.sh +++ b/qqq-dev-tools/bin/end-of-sprint-release.sh @@ -68,7 +68,7 @@ gumBanner "Running mvn gitflow:release-start" mvn gitflow:release-start gumConfirmProceed "Can we Proceed, or were there errors from the gitflow:release-start?" "Proceed" "There were errors..." -gumBanner "Pushining release branch to origin" +gumBanner "Pushing release branch to origin" git push --set-upstream origin "$(git rev-parse --abbrev-ref HEAD)" gumBanner "Please wait for a green run in CI on the release branch..."