Add action flags to insert, update, delete inputs

This commit is contained in:
2025-06-16 09:43:34 -05:00
parent 55e372a70f
commit cb6101d0ed
9 changed files with 313 additions and 7 deletions

View File

@ -401,6 +401,7 @@ public class DeleteAction
if(CollectionUtils.nullSafeHasContents(associatedKeys)) if(CollectionUtils.nullSafeHasContents(associatedKeys))
{ {
DeleteInput nextLevelDeleteInput = new DeleteInput(); DeleteInput nextLevelDeleteInput = new DeleteInput();
nextLevelDeleteInput.setFlags(deleteInput.getFlags());
nextLevelDeleteInput.setTransaction(deleteInput.getTransaction()); nextLevelDeleteInput.setTransaction(deleteInput.getTransaction());
nextLevelDeleteInput.setTableName(association.getAssociatedTableName()); nextLevelDeleteInput.setTableName(association.getAssociatedTableName());
nextLevelDeleteInput.setPrimaryKeys(associatedKeys); nextLevelDeleteInput.setPrimaryKeys(associatedKeys);

View File

@ -34,7 +34,6 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction; import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction;
import com.kingsrook.qqq.backend.core.actions.ActionHelper; import com.kingsrook.qqq.backend.core.actions.ActionHelper;
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
import com.kingsrook.qqq.backend.core.actions.audits.DMLAuditAction; import com.kingsrook.qqq.backend.core.actions.audits.DMLAuditAction;
import com.kingsrook.qqq.backend.core.actions.automation.AutomationStatus; import com.kingsrook.qqq.backend.core.actions.automation.AutomationStatus;
import com.kingsrook.qqq.backend.core.actions.automation.RecordAutomationStatusUpdater; import com.kingsrook.qqq.backend.core.actions.automation.RecordAutomationStatusUpdater;
@ -158,7 +157,7 @@ public class InsertAction extends AbstractQActionFunction<InsertInput, InsertOut
////////////////////////////////////////////////// //////////////////////////////////////////////////
// insert any associations in the input records // // insert any associations in the input records //
////////////////////////////////////////////////// //////////////////////////////////////////////////
manageAssociations(table, insertOutput.getRecords(), insertInput.getTransaction()); manageAssociations(table, insertOutput.getRecords(), insertInput);
////////////////// //////////////////
// do the audit // // do the audit //
@ -386,7 +385,7 @@ public class InsertAction extends AbstractQActionFunction<InsertInput, InsertOut
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
private void manageAssociations(QTableMetaData table, List<QRecord> insertedRecords, QBackendTransaction transaction) throws QException private void manageAssociations(QTableMetaData table, List<QRecord> insertedRecords, InsertInput insertInput) throws QException
{ {
for(Association association : CollectionUtils.nonNullList(table.getAssociations())) for(Association association : CollectionUtils.nonNullList(table.getAssociations()))
{ {
@ -419,7 +418,8 @@ public class InsertAction extends AbstractQActionFunction<InsertInput, InsertOut
if(CollectionUtils.nullSafeHasContents(nextLevelInserts)) if(CollectionUtils.nullSafeHasContents(nextLevelInserts))
{ {
InsertInput nextLevelInsertInput = new InsertInput(); InsertInput nextLevelInsertInput = new InsertInput();
nextLevelInsertInput.setTransaction(transaction); nextLevelInsertInput.withFlags(insertInput.getFlags());
nextLevelInsertInput.setTransaction(insertInput.getTransaction());
nextLevelInsertInput.setTableName(association.getAssociatedTableName()); nextLevelInsertInput.setTableName(association.getAssociatedTableName());
nextLevelInsertInput.setRecords(nextLevelInserts); nextLevelInsertInput.setRecords(nextLevelInserts);
InsertOutput nextLevelInsertOutput = new InsertAction().execute(nextLevelInsertInput); InsertOutput nextLevelInsertOutput = new InsertAction().execute(nextLevelInsertInput);

View File

@ -126,6 +126,7 @@ public class ReplaceAction extends AbstractQActionFunction<ReplaceInput, Replace
InsertInput insertInput = new InsertInput(); InsertInput insertInput = new InsertInput();
insertInput.setTableName(table.getName()); insertInput.setTableName(table.getName());
insertInput.setRecords(insertList); insertInput.setRecords(insertList);
insertInput.withFlags(input.getFlags());
insertInput.setTransaction(transaction); insertInput.setTransaction(transaction);
insertInput.setOmitDmlAudit(input.getOmitDmlAudit()); insertInput.setOmitDmlAudit(input.getOmitDmlAudit());
InsertOutput insertOutput = new InsertAction().execute(insertInput); InsertOutput insertOutput = new InsertAction().execute(insertInput);
@ -135,6 +136,7 @@ public class ReplaceAction extends AbstractQActionFunction<ReplaceInput, Replace
UpdateInput updateInput = new UpdateInput(); UpdateInput updateInput = new UpdateInput();
updateInput.setTableName(table.getName()); updateInput.setTableName(table.getName());
updateInput.setRecords(updateList); updateInput.setRecords(updateList);
updateInput.withFlags(input.getFlags());
updateInput.setTransaction(transaction); updateInput.setTransaction(transaction);
updateInput.setOmitDmlAudit(input.getOmitDmlAudit()); updateInput.setOmitDmlAudit(input.getOmitDmlAudit());
UpdateOutput updateOutput = new UpdateAction().execute(updateInput); UpdateOutput updateOutput = new UpdateAction().execute(updateInput);
@ -151,6 +153,7 @@ public class ReplaceAction extends AbstractQActionFunction<ReplaceInput, Replace
DeleteInput deleteInput = new DeleteInput(); DeleteInput deleteInput = new DeleteInput();
deleteInput.setTableName(table.getName()); deleteInput.setTableName(table.getName());
deleteInput.setQueryFilter(deleteFilter); deleteInput.setQueryFilter(deleteFilter);
deleteInput.withFlags(input.getFlags());
deleteInput.setTransaction(transaction); deleteInput.setTransaction(transaction);
deleteInput.setOmitDmlAudit(input.getOmitDmlAudit()); deleteInput.setOmitDmlAudit(input.getOmitDmlAudit());
DeleteOutput deleteOutput = new DeleteAction().execute(deleteInput); DeleteOutput deleteOutput = new DeleteAction().execute(deleteInput);

View File

@ -605,6 +605,7 @@ public class UpdateAction
{ {
LOG.debug("Deleting associatedRecords", logPair("associatedTable", associatedTable.getName()), logPair("noOfRecords", queryOutput.getRecords().size())); LOG.debug("Deleting associatedRecords", logPair("associatedTable", associatedTable.getName()), logPair("noOfRecords", queryOutput.getRecords().size()));
DeleteInput deleteInput = new DeleteInput(); DeleteInput deleteInput = new DeleteInput();
deleteInput.setFlags(updateInput.getFlags());
deleteInput.setTransaction(updateInput.getTransaction()); deleteInput.setTransaction(updateInput.getTransaction());
deleteInput.setTableName(association.getAssociatedTableName()); deleteInput.setTableName(association.getAssociatedTableName());
deleteInput.setPrimaryKeys(queryOutput.getRecords().stream().map(r -> r.getValue(associatedTable.getPrimaryKeyField())).collect(Collectors.toList())); deleteInput.setPrimaryKeys(queryOutput.getRecords().stream().map(r -> r.getValue(associatedTable.getPrimaryKeyField())).collect(Collectors.toList()));
@ -617,6 +618,7 @@ public class UpdateAction
LOG.debug("Updating associatedRecords", logPair("associatedTable", associatedTable.getName()), logPair("noOfRecords", nextLevelUpdates.size())); LOG.debug("Updating associatedRecords", logPair("associatedTable", associatedTable.getName()), logPair("noOfRecords", nextLevelUpdates.size()));
UpdateInput nextLevelUpdateInput = new UpdateInput(); UpdateInput nextLevelUpdateInput = new UpdateInput();
nextLevelUpdateInput.setTransaction(updateInput.getTransaction()); nextLevelUpdateInput.setTransaction(updateInput.getTransaction());
nextLevelUpdateInput.setFlags(updateInput.getFlags());
nextLevelUpdateInput.setTableName(association.getAssociatedTableName()); nextLevelUpdateInput.setTableName(association.getAssociatedTableName());
nextLevelUpdateInput.setRecords(nextLevelUpdates); nextLevelUpdateInput.setRecords(nextLevelUpdates);
UpdateOutput nextLevelUpdateOutput = new UpdateAction().execute(nextLevelUpdateInput); UpdateOutput nextLevelUpdateOutput = new UpdateAction().execute(nextLevelUpdateInput);
@ -627,6 +629,7 @@ public class UpdateAction
LOG.debug("Inserting associatedRecords", logPair("associatedTable", associatedTable.getName()), logPair("noOfRecords", nextLevelUpdates.size())); LOG.debug("Inserting associatedRecords", logPair("associatedTable", associatedTable.getName()), logPair("noOfRecords", nextLevelUpdates.size()));
InsertInput nextLevelInsertInput = new InsertInput(); InsertInput nextLevelInsertInput = new InsertInput();
nextLevelInsertInput.setTransaction(updateInput.getTransaction()); nextLevelInsertInput.setTransaction(updateInput.getTransaction());
nextLevelInsertInput.setFlags(updateInput.getFlags());
nextLevelInsertInput.setTableName(association.getAssociatedTableName()); nextLevelInsertInput.setTableName(association.getAssociatedTableName());
nextLevelInsertInput.setRecords(nextLevelInserts); nextLevelInsertInput.setRecords(nextLevelInserts);
InsertOutput nextLevelInsertOutput = new InsertAction().execute(nextLevelInsertInput); InsertOutput nextLevelInsertOutput = new InsertAction().execute(nextLevelInsertInput);

View File

@ -0,0 +1,35 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2025. Kingsrook, LLC
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
* contact@kingsrook.com
* https://github.com/Kingsrook/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.kingsrook.qqq.backend.core.model.actions.tables;
import java.io.Serializable;
/*******************************************************************************
** interface to mark enums (presumably classes too, but the original intent is
** enums) that can be added to insert/update/delete action inputs to flag behaviors
*******************************************************************************/
public interface ActionFlag extends Serializable
{
}

View File

@ -24,9 +24,12 @@ package com.kingsrook.qqq.backend.core.model.actions.tables.delete;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction; import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput; import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.ActionFlag;
import com.kingsrook.qqq.backend.core.model.actions.tables.InputSource; import com.kingsrook.qqq.backend.core.model.actions.tables.InputSource;
import com.kingsrook.qqq.backend.core.model.actions.tables.QInputSource; import com.kingsrook.qqq.backend.core.model.actions.tables.QInputSource;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
@ -47,6 +50,8 @@ public class DeleteInput extends AbstractTableActionInput
private boolean omitDmlAudit = false; private boolean omitDmlAudit = false;
private String auditContext = null; private String auditContext = null;
private Set<ActionFlag> flags;
/******************************************************************************* /*******************************************************************************
@ -295,4 +300,65 @@ public class DeleteInput extends AbstractTableActionInput
return (this); return (this);
} }
/*******************************************************************************
** Getter for flags
*******************************************************************************/
public Set<ActionFlag> getFlags()
{
return (this.flags);
}
/*******************************************************************************
** Setter for flags
*******************************************************************************/
public void setFlags(Set<ActionFlag> flags)
{
this.flags = flags;
}
/*******************************************************************************
** Fluent setter for flags
*******************************************************************************/
public DeleteInput withFlags(Set<ActionFlag> flags)
{
this.flags = flags;
return (this);
}
/***************************************************************************
**
***************************************************************************/
public DeleteInput withFlag(ActionFlag flag)
{
if(this.flags == null)
{
this.flags = new HashSet<>();
}
this.flags.add(flag);
return (this);
}
/***************************************************************************
**
***************************************************************************/
public boolean hasFlag(ActionFlag flag)
{
if(this.flags == null)
{
return (false);
}
return (this.flags.contains(flag));
}
} }

View File

@ -23,9 +23,12 @@ package com.kingsrook.qqq.backend.core.model.actions.tables.insert;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction; import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput; import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.ActionFlag;
import com.kingsrook.qqq.backend.core.model.actions.tables.InputSource; import com.kingsrook.qqq.backend.core.model.actions.tables.InputSource;
import com.kingsrook.qqq.backend.core.model.actions.tables.QInputSource; import com.kingsrook.qqq.backend.core.model.actions.tables.QInputSource;
import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecord;
@ -48,6 +51,8 @@ public class InsertInput extends AbstractTableActionInput
private boolean omitDmlAudit = false; private boolean omitDmlAudit = false;
private String auditContext = null; private String auditContext = null;
private Set<ActionFlag> flags;
/******************************************************************************* /*******************************************************************************
@ -316,4 +321,65 @@ public class InsertInput extends AbstractTableActionInput
return (this); return (this);
} }
/*******************************************************************************
** Getter for flags
*******************************************************************************/
public Set<ActionFlag> getFlags()
{
return (this.flags);
}
/*******************************************************************************
** Setter for flags
*******************************************************************************/
public void setFlags(Set<ActionFlag> flags)
{
this.flags = flags;
}
/*******************************************************************************
** Fluent setter for flags
*******************************************************************************/
public InsertInput withFlags(Set<ActionFlag> flags)
{
this.flags = flags;
return (this);
}
/***************************************************************************
**
***************************************************************************/
public InsertInput withFlag(ActionFlag flag)
{
if(this.flags == null)
{
this.flags = new HashSet<>();
}
this.flags.add(flag);
return (this);
}
/***************************************************************************
**
***************************************************************************/
public boolean hasFlag(ActionFlag flag)
{
if(this.flags == null)
{
return (false);
}
return (this.flags.contains(flag));
}
} }

View File

@ -22,9 +22,12 @@
package com.kingsrook.qqq.backend.core.model.actions.tables.replace; package com.kingsrook.qqq.backend.core.model.actions.tables.replace;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction; import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput; import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.ActionFlag;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.tables.UniqueKey; import com.kingsrook.qqq.backend.core.model.metadata.tables.UniqueKey;
@ -45,6 +48,8 @@ public class ReplaceInput extends AbstractTableActionInput
private boolean omitDmlAudit = false; private boolean omitDmlAudit = false;
private Set<ActionFlag> flags;
/******************************************************************************* /*******************************************************************************
@ -303,4 +308,65 @@ public class ReplaceInput extends AbstractTableActionInput
return (this); return (this);
} }
/*******************************************************************************
** Getter for flags
*******************************************************************************/
public Set<ActionFlag> getFlags()
{
return (this.flags);
}
/*******************************************************************************
** Setter for flags
*******************************************************************************/
public void setFlags(Set<ActionFlag> flags)
{
this.flags = flags;
}
/*******************************************************************************
** Fluent setter for flags
*******************************************************************************/
public ReplaceInput withFlags(Set<ActionFlag> flags)
{
this.flags = flags;
return (this);
}
/***************************************************************************
**
***************************************************************************/
public ReplaceInput withFlag(ActionFlag flag)
{
if(this.flags == null)
{
this.flags = new HashSet<>();
}
this.flags.add(flag);
return (this);
}
/***************************************************************************
**
***************************************************************************/
public boolean hasFlag(ActionFlag flag)
{
if(this.flags == null)
{
return (false);
}
return (this.flags.contains(flag));
}
} }

View File

@ -23,9 +23,12 @@ package com.kingsrook.qqq.backend.core.model.actions.tables.update;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction; import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput; import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.ActionFlag;
import com.kingsrook.qqq.backend.core.model.actions.tables.InputSource; import com.kingsrook.qqq.backend.core.model.actions.tables.InputSource;
import com.kingsrook.qqq.backend.core.model.actions.tables.QInputSource; import com.kingsrook.qqq.backend.core.model.actions.tables.QInputSource;
import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecord;
@ -56,6 +59,8 @@ public class UpdateInput extends AbstractTableActionInput
private boolean omitModifyDateUpdate = false; private boolean omitModifyDateUpdate = false;
private String auditContext = null; private String auditContext = null;
private Set<ActionFlag> flags;
/******************************************************************************* /*******************************************************************************
@ -385,4 +390,65 @@ public class UpdateInput extends AbstractTableActionInput
return (this); return (this);
} }
/*******************************************************************************
** Getter for flags
*******************************************************************************/
public Set<ActionFlag> getFlags()
{
return (this.flags);
}
/*******************************************************************************
** Setter for flags
*******************************************************************************/
public void setFlags(Set<ActionFlag> flags)
{
this.flags = flags;
}
/*******************************************************************************
** Fluent setter for flags
*******************************************************************************/
public UpdateInput withFlags(Set<ActionFlag> flags)
{
this.flags = flags;
return (this);
}
/***************************************************************************
**
***************************************************************************/
public UpdateInput withFlag(ActionFlag flag)
{
if(this.flags == null)
{
this.flags = new HashSet<>();
}
this.flags.add(flag);
return (this);
}
/***************************************************************************
**
***************************************************************************/
public boolean hasFlag(ActionFlag flag)
{
if(this.flags == null)
{
return (false);
}
return (this.flags.contains(flag));
}
} }