Add LoadViaInsertOrUpdateStep; make PVS field labels not have Id suffix; add populateFromQRecord

This commit is contained in:
2022-10-11 16:28:18 -05:00
parent aa64f1b7f3
commit b91273a53a
7 changed files with 258 additions and 17 deletions

View File

@ -79,6 +79,11 @@ public class QInstanceEnricher
private final QInstance qInstance;
//////////////////////////////////////////////////////////
// todo - come up w/ a way for app devs to set configs! //
//////////////////////////////////////////////////////////
private boolean configRemoveIdFromNameWhenCreatingPossibleValueFieldLabels = true;
/*******************************************************************************
@ -229,7 +234,14 @@ public class QInstanceEnricher
{
if(!StringUtils.hasContent(field.getLabel()))
{
field.setLabel(nameToLabel(field.getName()));
if(configRemoveIdFromNameWhenCreatingPossibleValueFieldLabels && StringUtils.hasContent(field.getPossibleValueSourceName()) && field.getName() != null && field.getName().endsWith("Id"))
{
field.setLabel(nameToLabel(field.getName().substring(0, field.getName().length() - 2)));
}
else
{
field.setLabel(nameToLabel(field.getName()));
}
}
//////////////////////////////////////////////////////////////////////////

View File

@ -60,16 +60,32 @@ public abstract class QRecordEntity
try
{
T entity = c.getConstructor().newInstance();
entity.populateFromQRecord(qRecord);
return (entity);
}
catch(Exception e)
{
throw (new QException("Error building entity from qRecord.", e));
}
}
List<QRecordEntityField> fieldList = getFieldList(c);
/*******************************************************************************
** Build an entity of this QRecord type from a QRecord
**
*******************************************************************************/
protected <T extends QRecordEntity> void populateFromQRecord(QRecord qRecord) throws QException
{
try
{
List<QRecordEntityField> fieldList = getFieldList(this.getClass());
for(QRecordEntityField qRecordEntityField : fieldList)
{
Serializable value = qRecord.getValue(qRecordEntityField.getFieldName());
Object typedValue = qRecordEntityField.convertValueType(value);
qRecordEntityField.getSetter().invoke(entity, typedValue);
qRecordEntityField.getSetter().invoke(this, typedValue);
}
return (entity);
}
catch(Exception e)
{

View File

@ -0,0 +1,113 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2022. 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.processes.implementations.etl.streamedwithfrontend;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput;
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateOutput;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
/*******************************************************************************
** Generic implementation of a LoadStep - that runs Insert and/or Update
** actions for the destination table - where the presence or absence of the
** record's primaryKey field is the indicator for which to do. e.g., it assumes
** auto-generated ids, to be populated upon insert.
*******************************************************************************/
public class LoadViaInsertOrUpdateStep extends AbstractLoadStep
{
public static final String FIELD_DESTINATION_TABLE = "destinationTable";
/*******************************************************************************
** Execute the backend step - using the request as input, and the result as output.
**
*******************************************************************************/
@Override
public void run(RunBackendStepInput runBackendStepInput, RunBackendStepOutput runBackendStepOutput) throws QException
{
QTableMetaData tableMetaData = runBackendStepInput.getInstance().getTable(runBackendStepInput.getValueString(FIELD_DESTINATION_TABLE));
List<QRecord> recordsToInsert = new ArrayList<>();
List<QRecord> recordsToUpdate = new ArrayList<>();
for(QRecord record : runBackendStepInput.getRecords())
{
if(record.getValue(tableMetaData.getPrimaryKeyField()) == null)
{
recordsToInsert.add(record);
}
else
{
recordsToUpdate.add(record);
}
}
if(!recordsToInsert.isEmpty())
{
InsertInput insertInput = new InsertInput(runBackendStepInput.getInstance());
insertInput.setSession(runBackendStepInput.getSession());
insertInput.setTableName(tableMetaData.getName());
insertInput.setRecords(runBackendStepInput.getRecords());
getTransaction().ifPresent(insertInput::setTransaction);
InsertOutput insertOutput = new InsertAction().execute(insertInput);
runBackendStepOutput.getRecords().addAll(insertOutput.getRecords());
}
if(!recordsToUpdate.isEmpty())
{
UpdateInput updateInput = new UpdateInput(runBackendStepInput.getInstance());
updateInput.setSession(runBackendStepInput.getSession());
updateInput.setTableName(tableMetaData.getName());
updateInput.setRecords(runBackendStepInput.getRecords());
getTransaction().ifPresent(updateInput::setTransaction);
UpdateOutput updateOutput = new UpdateAction().execute(updateInput);
runBackendStepOutput.getRecords().addAll(updateOutput.getRecords());
}
}
/*******************************************************************************
**
*******************************************************************************/
@Override
public Optional<QBackendTransaction> openTransaction(RunBackendStepInput runBackendStepInput) throws QException
{
InsertInput insertInput = new InsertInput(runBackendStepInput.getInstance());
insertInput.setSession(runBackendStepInput.getSession());
insertInput.setTableName(runBackendStepInput.getValueString(FIELD_DESTINATION_TABLE));
return (Optional.of(new InsertAction().openTransaction(insertInput)));
}
}

View File

@ -80,10 +80,11 @@ public class StreamedETLWithFrontendProcess
public static final String FIELD_VALIDATION_SUMMARY = "validationSummary"; // List<ProcessSummaryLine>
public static final String FIELD_PROCESS_SUMMARY = "processResults"; // List<ProcessSummaryLine>
public static final String DEFAULT_PREVIEW_MESSAGE_FOR_INSERT = "This is a preview of the records that will be created.";
public static final String DEFAULT_PREVIEW_MESSAGE_FOR_UPDATE = "This is a preview of the records that will be updated.";
public static final String DEFAULT_PREVIEW_MESSAGE_FOR_DELETE = "This is a preview of the records that will be deleted.";
public static final String FIELD_PREVIEW_MESSAGE = "previewMessage";
public static final String DEFAULT_PREVIEW_MESSAGE_FOR_INSERT = "This is a preview of the records that will be created.";
public static final String DEFAULT_PREVIEW_MESSAGE_FOR_UPDATE = "This is a preview of the records that will be updated.";
public static final String DEFAULT_PREVIEW_MESSAGE_FOR_INSERT_OR_UPDATE = "This is a preview of the records that will be inserted or updated.";
public static final String DEFAULT_PREVIEW_MESSAGE_FOR_DELETE = "This is a preview of the records that will be deleted.";
public static final String FIELD_PREVIEW_MESSAGE = "previewMessage";