mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Checkpoint
This commit is contained in:
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2023. 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.actions.automation;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.RunAdHocRecordScriptAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.scripts.RunAdHocRecordScriptInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.scripts.RunAdHocRecordScriptOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryJoin;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.automation.RecordAutomationInput;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.AdHocScriptCodeReference;
|
||||
import com.kingsrook.qqq.backend.core.model.scripts.Script;
|
||||
import com.kingsrook.qqq.backend.core.model.scripts.ScriptRevision;
|
||||
import com.kingsrook.qqq.backend.core.model.scripts.ScriptType;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class RunRecordScriptsAutomationHandler extends RecordAutomationHandler
|
||||
{
|
||||
private static final QLogger LOG = QLogger.getLogger(RunRecordScriptsAutomationHandler.class);
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void execute(RecordAutomationInput recordAutomationInput) throws QException
|
||||
{
|
||||
String tableName = recordAutomationInput.getTableName();
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(ScriptRevision.TABLE_NAME);
|
||||
queryInput.setFilter(new QQueryFilter(
|
||||
new QFilterCriteria("script.tableName", QCriteriaOperator.EQUALS, tableName),
|
||||
new QFilterCriteria("scriptType.name", QCriteriaOperator.EQUALS, "Record Script") // todo... no. something about post-insert/update?
|
||||
));
|
||||
queryInput.withQueryJoin(new QueryJoin(Script.TABLE_NAME).withBaseTableOrAlias(ScriptRevision.TABLE_NAME).withJoinMetaData(QContext.getQInstance().getJoin("currentScriptRevision")));
|
||||
queryInput.withQueryJoin(new QueryJoin(ScriptType.TABLE_NAME).withBaseTableOrAlias(Script.TABLE_NAME));
|
||||
|
||||
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||
for(QRecord scriptRevision : CollectionUtils.nonNullList(queryOutput.getRecords()))
|
||||
{
|
||||
// todo - refresh the records if more than 1 script
|
||||
|
||||
LOG.info("Running script against records", logPair("scriptRevisionId", scriptRevision.getValue("id")), logPair("scriptId", scriptRevision.getValue("scriptIdd")));
|
||||
RunAdHocRecordScriptInput input = new RunAdHocRecordScriptInput();
|
||||
input.setCodeReference(new AdHocScriptCodeReference().withScriptRevisionRecord(scriptRevision));
|
||||
input.setTableName(tableName);
|
||||
input.setRecordList(recordAutomationInput.getRecordList());
|
||||
RunAdHocRecordScriptOutput output = new RunAdHocRecordScriptOutput();
|
||||
new RunAdHocRecordScriptAction().run(input, output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -23,25 +23,38 @@ package com.kingsrook.qqq.backend.core.actions.scripts;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import com.kingsrook.qqq.backend.core.actions.ActionHelper;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.logging.QCodeExecutionLoggerInterface;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.logging.ScriptExecutionLoggerInterface;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.logging.StoreScriptLogAndScriptLogLineExecutionLogger;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.scripts.RunAdHocRecordScriptInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.scripts.RunAdHocRecordScriptOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryJoin;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.AdHocScriptCodeReference;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.scripts.Script;
|
||||
import com.kingsrook.qqq.backend.core.model.scripts.ScriptRevision;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -49,7 +62,10 @@ import com.kingsrook.qqq.backend.core.model.scripts.ScriptRevision;
|
||||
*******************************************************************************/
|
||||
public class RunAdHocRecordScriptAction
|
||||
{
|
||||
// todo! private Map<AssociatedScriptCodeReference, ScriptRevision> scriptRevisionCache = new HashMap<>();
|
||||
private static final QLogger LOG = QLogger.getLogger(RunAdHocRecordScriptAction.class);
|
||||
|
||||
private Map<Integer, ScriptRevision> scriptRevisionCacheByScriptRevisionId = new HashMap<>();
|
||||
private Map<Integer, ScriptRevision> scriptRevisionCacheByScriptId = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
@ -60,18 +76,43 @@ public class RunAdHocRecordScriptAction
|
||||
{
|
||||
ActionHelper.validateSession(input);
|
||||
|
||||
/////////////////////////
|
||||
// figure out the code //
|
||||
/////////////////////////
|
||||
ScriptRevision scriptRevision = getScriptRevision(input);
|
||||
if(scriptRevision == null)
|
||||
{
|
||||
throw (new QException("Script revision was not found."));
|
||||
}
|
||||
|
||||
GetInput getInput = new GetInput();
|
||||
getInput.setTableName(input.getTableName());
|
||||
getInput.setPrimaryKey(input.getRecordPrimaryKey());
|
||||
GetOutput getOutput = new GetAction().execute(getInput);
|
||||
QRecord record = getOutput.getRecord();
|
||||
// todo err if not found
|
||||
////////////////////////////
|
||||
// figure out the records //
|
||||
////////////////////////////
|
||||
QTableMetaData table = QContext.getQInstance().getTable(input.getTableName());
|
||||
if(CollectionUtils.nullSafeIsEmpty(input.getRecordList()))
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(input.getTableName());
|
||||
queryInput.setFilter(new QQueryFilter(new QFilterCriteria(table.getPrimaryKeyField(), QCriteriaOperator.IN, input.getRecordPrimaryKeyList())));
|
||||
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||
input.setRecordList(queryOutput.getRecords());
|
||||
}
|
||||
|
||||
if(CollectionUtils.nullSafeIsEmpty(input.getRecordList()))
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// just return if nothing found? idk //
|
||||
////////////////////////////////////////
|
||||
LOG.info("No records supplied as input (or found via primary keys); exiting with noop");
|
||||
return;
|
||||
}
|
||||
|
||||
/////////////
|
||||
// run it! //
|
||||
/////////////
|
||||
ExecuteCodeInput executeCodeInput = new ExecuteCodeInput();
|
||||
executeCodeInput.setInput(new HashMap<>(Objects.requireNonNullElseGet(input.getInputValues(), HashMap::new)));
|
||||
executeCodeInput.getInput().put("record", record);
|
||||
executeCodeInput.getInput().put("records", new ArrayList<>(input.getRecordList()));
|
||||
executeCodeInput.setContext(new HashMap<>());
|
||||
if(input.getOutputObject() != null)
|
||||
{
|
||||
@ -82,10 +123,8 @@ public class RunAdHocRecordScriptAction
|
||||
{
|
||||
executeCodeInput.getContext().put("scriptUtils", input.getScriptUtils());
|
||||
}
|
||||
else
|
||||
{
|
||||
executeCodeInput.getContext().put("scriptUtils", new ScriptApiUtils());
|
||||
}
|
||||
|
||||
executeCodeInput.getContext().put("api", new ScriptApi());
|
||||
|
||||
executeCodeInput.setCodeReference(new QCodeReference().withInlineCode(scriptRevision.getContents()).withCodeType(QCodeType.JAVA_SCRIPT)); // todo - code type as attribute of script!!
|
||||
|
||||
@ -116,34 +155,57 @@ public class RunAdHocRecordScriptAction
|
||||
*******************************************************************************/
|
||||
private ScriptRevision getScriptRevision(RunAdHocRecordScriptInput input) throws QException
|
||||
{
|
||||
// todo if(!scriptRevisionCache.containsKey(input.getCodeReference()))
|
||||
AdHocScriptCodeReference codeReference = input.getCodeReference();
|
||||
if(codeReference.getScriptRevisionRecord() != null)
|
||||
{
|
||||
Serializable scriptId = input.getCodeReference().getScriptId();
|
||||
/*
|
||||
if(scriptId == null)
|
||||
{
|
||||
throw (new QNotFoundException("The input record [" + input.getCodeReference().getScriptId() + "][" + input.getCodeReference().getRecordPrimaryKey()
|
||||
+ "] does not have a script specified for [" + input.getCodeReference().getFieldName() + "]"));
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
Script script = getScript(input, scriptId);
|
||||
/* todo
|
||||
if(script.getCurrentScriptRevisionId() == null)
|
||||
{
|
||||
throw (new QNotFoundException("The script for record [" + input.getCodeReference().getRecordTable() + "][" + input.getCodeReference().getRecordPrimaryKey()
|
||||
+ "] (scriptId=" + scriptId + ") does not have a current version."));
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
ScriptRevision scriptRevision = getCurrentScriptRevision(input, script.getCurrentScriptRevisionId());
|
||||
// scriptRevisionCache.put(input.getCodeReference(), scriptRevision);
|
||||
return scriptRevision;
|
||||
return (new ScriptRevision(codeReference.getScriptRevisionRecord()));
|
||||
}
|
||||
|
||||
// return scriptRevisionCache.get(input.getCodeReference());
|
||||
if(codeReference.getScriptRevisionId() != null)
|
||||
{
|
||||
if(!scriptRevisionCacheByScriptRevisionId.containsKey(codeReference.getScriptRevisionId()))
|
||||
{
|
||||
GetInput getInput = new GetInput();
|
||||
getInput.setTableName(ScriptRevision.TABLE_NAME);
|
||||
getInput.setPrimaryKey(codeReference.getScriptRevisionId());
|
||||
GetOutput getOutput = new GetAction().execute(getInput);
|
||||
if(getOutput.getRecord() != null)
|
||||
{
|
||||
scriptRevisionCacheByScriptRevisionId.put(codeReference.getScriptRevisionId(), new ScriptRevision(getOutput.getRecord()));
|
||||
}
|
||||
else
|
||||
{
|
||||
scriptRevisionCacheByScriptRevisionId.put(codeReference.getScriptRevisionId(), null);
|
||||
}
|
||||
}
|
||||
|
||||
return (scriptRevisionCacheByScriptRevisionId.get(codeReference.getScriptRevisionId()));
|
||||
}
|
||||
|
||||
if(codeReference.getScriptId() != null)
|
||||
{
|
||||
if(!scriptRevisionCacheByScriptId.containsKey(codeReference.getScriptId()))
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(ScriptRevision.TABLE_NAME);
|
||||
queryInput.setFilter(new QQueryFilter(new QFilterCriteria("script.id", QCriteriaOperator.EQUALS, codeReference.getScriptId())));
|
||||
queryInput.withQueryJoin(new QueryJoin(Script.TABLE_NAME).withBaseTableOrAlias(ScriptRevision.TABLE_NAME).withJoinMetaData(QContext.getQInstance().getJoin("currentScriptRevision")));
|
||||
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||
|
||||
if(CollectionUtils.nullSafeHasContents(queryOutput.getRecords()))
|
||||
{
|
||||
scriptRevisionCacheByScriptId.put(codeReference.getScriptId(), new ScriptRevision(queryOutput.getRecords().get(0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
scriptRevisionCacheByScriptId.put(codeReference.getScriptId(), null);
|
||||
}
|
||||
}
|
||||
|
||||
return (scriptRevisionCacheByScriptId.get(codeReference.getScriptId()));
|
||||
}
|
||||
|
||||
throw (new QException("Code reference did not contain a scriptRevision, scriptRevisionId, or scriptId"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2023. 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.actions.scripts;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
||||
import com.kingsrook.qqq.backend.core.actions.permissions.TablePermissionSubType;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction;
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
$api.query("order", null);
|
||||
$api.query($utils.newQueryInput().withTable("order").withLimit(1).withShouldGenerateDisplayValues())
|
||||
*******************************************************************************/
|
||||
public class ScriptApi implements Serializable
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QueryInput newQueryInput()
|
||||
{
|
||||
return (new QueryInput());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QQueryFilter newQueryFilter()
|
||||
{
|
||||
return (new QQueryFilter());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFilterCriteria newFilterCriteria()
|
||||
{
|
||||
return (new QFilterCriteria());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFilterOrderBy newFilterOrderBy()
|
||||
{
|
||||
return (new QFilterOrderBy());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QRecord newRecord()
|
||||
{
|
||||
return (new QRecord());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QRecord> query(String tableName, QQueryFilter filter) throws QException
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(tableName);
|
||||
queryInput.setFilter(filter);
|
||||
PermissionsHelper.checkTablePermissionThrowing(queryInput, TablePermissionSubType.READ);
|
||||
return (new QueryAction().execute(queryInput).getRecords());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QRecord> query(QueryInput queryInput) throws QException
|
||||
{
|
||||
PermissionsHelper.checkTablePermissionThrowing(queryInput, TablePermissionSubType.READ);
|
||||
return (new QueryAction().execute(queryInput).getRecords());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void insert(String tableName, QRecord record) throws QException
|
||||
{
|
||||
insert(tableName, List.of(record));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void insert(String tableName, List<QRecord> recordList) throws QException
|
||||
{
|
||||
InsertInput insertInput = new InsertInput();
|
||||
insertInput.setTableName(tableName);
|
||||
insertInput.setRecords(recordList);
|
||||
PermissionsHelper.checkTablePermissionThrowing(insertInput, TablePermissionSubType.INSERT);
|
||||
new InsertAction().execute(insertInput);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void update(String tableName, QRecord record) throws QException
|
||||
{
|
||||
update(tableName, List.of(record));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void update(String tableName, List<QRecord> recordList) throws QException
|
||||
{
|
||||
UpdateInput updateInput = new UpdateInput();
|
||||
updateInput.setTableName(tableName);
|
||||
updateInput.setRecords(recordList);
|
||||
PermissionsHelper.checkTablePermissionThrowing(updateInput, TablePermissionSubType.EDIT);
|
||||
new UpdateAction().execute(updateInput);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void delete(String tableName, Serializable primaryKey) throws QException
|
||||
{
|
||||
delete(tableName, List.of(primaryKey));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void delete(String tableName, QRecord record) throws QException
|
||||
{
|
||||
delete(tableName, List.of(record));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void delete(String tableName, List<?> recordOrPrimaryKeyList) throws QException
|
||||
{
|
||||
QTableMetaData table = QContext.getQInstance().getTable(tableName);
|
||||
DeleteInput deleteInput = new DeleteInput();
|
||||
deleteInput.setTableName(tableName);
|
||||
List<Serializable> primaryKeyList = new ArrayList<>();
|
||||
for(Object o : recordOrPrimaryKeyList)
|
||||
{
|
||||
if(o instanceof QRecord qRecord)
|
||||
{
|
||||
primaryKeyList.add(qRecord.getValue(table.getPrimaryKeyField()));
|
||||
}
|
||||
else
|
||||
{
|
||||
primaryKeyList.add((Serializable) o);
|
||||
}
|
||||
}
|
||||
deleteInput.setPrimaryKeys(primaryKeyList);
|
||||
PermissionsHelper.checkTablePermissionThrowing(deleteInput, TablePermissionSubType.DELETE);
|
||||
new DeleteAction().execute(deleteInput);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void delete(String tableName, QQueryFilter filter) throws QException
|
||||
{
|
||||
DeleteInput deleteInput = new DeleteInput();
|
||||
deleteInput.setTableName(tableName);
|
||||
deleteInput.setQueryFilter(filter);
|
||||
PermissionsHelper.checkTablePermissionThrowing(deleteInput, TablePermissionSubType.DELETE);
|
||||
new DeleteAction().execute(deleteInput);
|
||||
}
|
||||
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2023. 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.actions.scripts;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
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.tables.query.QQueryFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
$utils.query("order", null);
|
||||
$utils.query($utils.newQueryInput().withTable("order").withLimit(1).withShouldGenerateDisplayValues())
|
||||
*******************************************************************************/
|
||||
public class ScriptApiUtils implements Serializable
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QueryInput newQueryInput()
|
||||
{
|
||||
return (new QueryInput());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QRecord newQRecord()
|
||||
{
|
||||
return (new QRecord());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QRecord> query(String table, QQueryFilter filter) throws QException
|
||||
{
|
||||
QueryInput queryInput = new QueryInput();
|
||||
queryInput.setTableName(table);
|
||||
queryInput.setFilter(filter);
|
||||
return (new QueryAction().execute(queryInput).getRecords());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QRecord> query(QueryInput queryInput) throws QException
|
||||
{
|
||||
return (new QueryAction().execute(queryInput).getRecords());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void update(String table, List<QRecord> recordList) throws QException
|
||||
{
|
||||
UpdateInput updateInput = new UpdateInput();
|
||||
updateInput.setTableName(table);
|
||||
updateInput.setRecords(recordList);
|
||||
new UpdateAction().execute(updateInput);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void update(String table, QRecord record) throws QException
|
||||
{
|
||||
UpdateInput updateInput = new UpdateInput();
|
||||
updateInput.setTableName(table);
|
||||
updateInput.setRecords(List.of(record));
|
||||
new UpdateAction().execute(updateInput);
|
||||
}
|
||||
|
||||
}
|
@ -23,9 +23,11 @@ package com.kingsrook.qqq.backend.core.model.actions.scripts;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.logging.QCodeExecutionLoggerInterface;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.AdHocScriptCodeReference;
|
||||
|
||||
|
||||
@ -36,7 +38,8 @@ public class RunAdHocRecordScriptInput extends AbstractTableActionInput
|
||||
{
|
||||
private AdHocScriptCodeReference codeReference;
|
||||
private Map<String, Serializable> inputValues;
|
||||
private Serializable recordPrimaryKey;
|
||||
private List<Serializable> recordPrimaryKeyList; // can either supply recordList, or recordPrimaryKeyList
|
||||
private List<QRecord> recordList;
|
||||
private String tableName;
|
||||
private QCodeExecutionLoggerInterface logger;
|
||||
|
||||
@ -207,37 +210,6 @@ public class RunAdHocRecordScriptInput extends AbstractTableActionInput
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for recordPrimaryKey
|
||||
*******************************************************************************/
|
||||
public Serializable getRecordPrimaryKey()
|
||||
{
|
||||
return (this.recordPrimaryKey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for recordPrimaryKey
|
||||
*******************************************************************************/
|
||||
public void setRecordPrimaryKey(Serializable recordPrimaryKey)
|
||||
{
|
||||
this.recordPrimaryKey = recordPrimaryKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for recordPrimaryKey
|
||||
*******************************************************************************/
|
||||
public RunAdHocRecordScriptInput withRecordPrimaryKey(Serializable recordPrimaryKey)
|
||||
{
|
||||
this.recordPrimaryKey = recordPrimaryKey;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for tableName
|
||||
*******************************************************************************/
|
||||
@ -267,4 +239,66 @@ public class RunAdHocRecordScriptInput extends AbstractTableActionInput
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for recordList
|
||||
*******************************************************************************/
|
||||
public List<QRecord> getRecordList()
|
||||
{
|
||||
return (this.recordList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for recordList
|
||||
*******************************************************************************/
|
||||
public void setRecordList(List<QRecord> recordList)
|
||||
{
|
||||
this.recordList = recordList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for recordList
|
||||
*******************************************************************************/
|
||||
public RunAdHocRecordScriptInput withRecordList(List<QRecord> recordList)
|
||||
{
|
||||
this.recordList = recordList;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for recordPrimaryKeyList
|
||||
*******************************************************************************/
|
||||
public List<Serializable> getRecordPrimaryKeyList()
|
||||
{
|
||||
return (this.recordPrimaryKeyList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for recordPrimaryKeyList
|
||||
*******************************************************************************/
|
||||
public void setRecordPrimaryKeyList(List<Serializable> recordPrimaryKeyList)
|
||||
{
|
||||
this.recordPrimaryKeyList = recordPrimaryKeyList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for recordPrimaryKeyList
|
||||
*******************************************************************************/
|
||||
public RunAdHocRecordScriptInput withRecordPrimaryKeyList(List<Serializable> recordPrimaryKeyList)
|
||||
{
|
||||
this.recordPrimaryKeyList = recordPrimaryKeyList;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,12 +22,22 @@
|
||||
package com.kingsrook.qqq.backend.core.model.metadata.code;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class AdHocScriptCodeReference extends QCodeReference
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// can supply scriptId (in which case, current revisionId will be looked up), //
|
||||
// or revisionId (in which case, record will be looked up) //
|
||||
// or, the record. //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
private Integer scriptId;
|
||||
private Integer scriptRevisionId;
|
||||
private QRecord scriptRevisionRecord;
|
||||
|
||||
|
||||
|
||||
@ -60,4 +70,66 @@ public class AdHocScriptCodeReference extends QCodeReference
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for scriptRevisionId
|
||||
*******************************************************************************/
|
||||
public Integer getScriptRevisionId()
|
||||
{
|
||||
return (this.scriptRevisionId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for scriptRevisionId
|
||||
*******************************************************************************/
|
||||
public void setScriptRevisionId(Integer scriptRevisionId)
|
||||
{
|
||||
this.scriptRevisionId = scriptRevisionId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for scriptRevisionId
|
||||
*******************************************************************************/
|
||||
public AdHocScriptCodeReference withScriptRevisionId(Integer scriptRevisionId)
|
||||
{
|
||||
this.scriptRevisionId = scriptRevisionId;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for scriptRevisionRecord
|
||||
*******************************************************************************/
|
||||
public QRecord getScriptRevisionRecord()
|
||||
{
|
||||
return (this.scriptRevisionRecord);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for scriptRevisionRecord
|
||||
*******************************************************************************/
|
||||
public void setScriptRevisionRecord(QRecord scriptRevisionRecord)
|
||||
{
|
||||
this.scriptRevisionRecord = scriptRevisionRecord;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for scriptRevisionRecord
|
||||
*******************************************************************************/
|
||||
public AdHocScriptCodeReference withScriptRevisionRecord(QRecord scriptRevisionRecord)
|
||||
{
|
||||
this.scriptRevisionRecord = scriptRevisionRecord;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,12 +23,16 @@ package com.kingsrook.qqq.backend.core.model.metadata.tables;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.instances.QInstanceEnricher;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.PVSValueFormatAndFields;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValue;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSourceType;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -53,9 +57,15 @@ public class TablesPossibleValueSourceMetaDataProvider
|
||||
List<QPossibleValue<?>> enumValues = new ArrayList<>();
|
||||
for(QTableMetaData table : qInstance.getTables().values())
|
||||
{
|
||||
enumValues.add(new QPossibleValue<>(table.getName(), table.getLabel()));
|
||||
if(BooleanUtils.isNotTrue(table.getIsHidden()))
|
||||
{
|
||||
String label = StringUtils.hasContent(table.getLabel()) ? table.getLabel() : QInstanceEnricher.nameToLabel(table.getName());
|
||||
enumValues.add(new QPossibleValue<>(table.getName(), label));
|
||||
}
|
||||
}
|
||||
|
||||
enumValues.sort(Comparator.comparing(QPossibleValue::getLabel));
|
||||
|
||||
possibleValueSource.withEnumValues(enumValues);
|
||||
return (possibleValueSource);
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ public class ScriptsMetaDataProvider
|
||||
.withName("storeScriptRevision")
|
||||
.withStepList(List.of(
|
||||
new QBackendStepMetaData()
|
||||
.withName("main")
|
||||
.withCode(new QCodeReference(StoreScriptRevisionProcessStep.class))
|
||||
)));
|
||||
}
|
||||
@ -118,6 +119,30 @@ public class ScriptsMetaDataProvider
|
||||
.withJoinOn(new JoinOn("id", "scriptLogId"))
|
||||
.withOrderBy(new QFilterOrderBy("id"))
|
||||
.withInferredName());
|
||||
|
||||
instance.addJoin(new QJoinMetaData()
|
||||
.withType(JoinType.ONE_TO_MANY)
|
||||
.withLeftTable(Script.TABLE_NAME)
|
||||
.withRightTable(ScriptRevision.TABLE_NAME)
|
||||
.withJoinOn(new JoinOn("id", "scriptId"))
|
||||
.withOrderBy(new QFilterOrderBy("id"))
|
||||
.withInferredName());
|
||||
|
||||
instance.addJoin(new QJoinMetaData()
|
||||
.withType(JoinType.ONE_TO_ONE)
|
||||
.withLeftTable(Script.TABLE_NAME)
|
||||
.withRightTable(ScriptRevision.TABLE_NAME)
|
||||
.withJoinOn(new JoinOn("currentScriptRevisionId", "id"))
|
||||
.withName("currentScriptRevision"));
|
||||
|
||||
instance.addJoin(new QJoinMetaData()
|
||||
.withType(JoinType.ONE_TO_MANY)
|
||||
.withLeftTable(ScriptType.TABLE_NAME)
|
||||
.withRightTable(Script.TABLE_NAME)
|
||||
.withJoinOn(new JoinOn("id", "scriptTypeId"))
|
||||
.withOrderBy(new QFilterOrderBy("id"))
|
||||
.withInferredName());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,7 +67,7 @@ class RunAdHocRecordScriptActionTest extends BaseTest
|
||||
""");
|
||||
|
||||
RunAdHocRecordScriptInput runAdHocRecordScriptInput = new RunAdHocRecordScriptInput();
|
||||
runAdHocRecordScriptInput.setRecordPrimaryKey(1);
|
||||
runAdHocRecordScriptInput.setRecordPrimaryKeyList(List.of(1));
|
||||
runAdHocRecordScriptInput.setTableName(TestUtils.TABLE_NAME_PERSON_MEMORY);
|
||||
runAdHocRecordScriptInput.setCodeReference(new AdHocScriptCodeReference().withScriptId(scriptId));
|
||||
runAdHocRecordScriptInput.setLogger(new Log4jCodeExecutionLogger());
|
||||
|
Reference in New Issue
Block a user