Checkpoint

This commit is contained in:
2023-03-06 09:40:15 -06:00
parent 22644b6a36
commit 68686c0e17
9 changed files with 601 additions and 183 deletions

View File

@ -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);
}
}
}

View File

@ -23,25 +23,38 @@ package com.kingsrook.qqq.backend.core.actions.scripts;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import com.kingsrook.qqq.backend.core.actions.ActionHelper; 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.QCodeExecutionLoggerInterface;
import com.kingsrook.qqq.backend.core.actions.scripts.logging.ScriptExecutionLoggerInterface; 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.scripts.logging.StoreScriptLogAndScriptLogLineExecutionLogger;
import com.kingsrook.qqq.backend.core.actions.tables.GetAction; 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.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.ExecuteCodeInput;
import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeOutput; 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.RunAdHocRecordScriptInput;
import com.kingsrook.qqq.backend.core.model.actions.scripts.RunAdHocRecordScriptOutput; 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.GetInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput; 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.QCodeReference;
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeType; 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.Script;
import com.kingsrook.qqq.backend.core.model.scripts.ScriptRevision; 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 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); ActionHelper.validateSession(input);
/////////////////////////
// figure out the code //
/////////////////////////
ScriptRevision scriptRevision = getScriptRevision(input); ScriptRevision scriptRevision = getScriptRevision(input);
if(scriptRevision == null)
{
throw (new QException("Script revision was not found."));
}
GetInput getInput = new GetInput(); ////////////////////////////
getInput.setTableName(input.getTableName()); // figure out the records //
getInput.setPrimaryKey(input.getRecordPrimaryKey()); ////////////////////////////
GetOutput getOutput = new GetAction().execute(getInput); QTableMetaData table = QContext.getQInstance().getTable(input.getTableName());
QRecord record = getOutput.getRecord(); if(CollectionUtils.nullSafeIsEmpty(input.getRecordList()))
// todo err if not found {
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 executeCodeInput = new ExecuteCodeInput();
executeCodeInput.setInput(new HashMap<>(Objects.requireNonNullElseGet(input.getInputValues(), HashMap::new))); 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<>()); executeCodeInput.setContext(new HashMap<>());
if(input.getOutputObject() != null) if(input.getOutputObject() != null)
{ {
@ -82,10 +123,8 @@ public class RunAdHocRecordScriptAction
{ {
executeCodeInput.getContext().put("scriptUtils", input.getScriptUtils()); executeCodeInput.getContext().put("scriptUtils", input.getScriptUtils());
} }
else
{ executeCodeInput.getContext().put("api", new ScriptApi());
executeCodeInput.getContext().put("scriptUtils", new ScriptApiUtils());
}
executeCodeInput.setCodeReference(new QCodeReference().withInlineCode(scriptRevision.getContents()).withCodeType(QCodeType.JAVA_SCRIPT)); // todo - code type as attribute of script!! 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 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(); return (new ScriptRevision(codeReference.getScriptRevisionRecord()));
/*
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 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"));
} }

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -23,9 +23,11 @@ package com.kingsrook.qqq.backend.core.model.actions.scripts;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
import java.util.Map; import java.util.Map;
import com.kingsrook.qqq.backend.core.actions.scripts.logging.QCodeExecutionLoggerInterface; 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.actions.AbstractTableActionInput;
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.metadata.code.AdHocScriptCodeReference;
@ -36,7 +38,8 @@ public class RunAdHocRecordScriptInput extends AbstractTableActionInput
{ {
private AdHocScriptCodeReference codeReference; private AdHocScriptCodeReference codeReference;
private Map<String, Serializable> inputValues; 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 String tableName;
private QCodeExecutionLoggerInterface logger; 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 ** Getter for tableName
*******************************************************************************/ *******************************************************************************/
@ -267,4 +239,66 @@ public class RunAdHocRecordScriptInput extends AbstractTableActionInput
return (this); 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);
}
} }

View File

@ -22,12 +22,22 @@
package com.kingsrook.qqq.backend.core.model.metadata.code; package com.kingsrook.qqq.backend.core.model.metadata.code;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
public class AdHocScriptCodeReference extends QCodeReference 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 scriptId;
private Integer scriptRevisionId;
private QRecord scriptRevisionRecord;
@ -60,4 +70,66 @@ public class AdHocScriptCodeReference extends QCodeReference
return (this); 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);
}
} }

View File

@ -23,12 +23,16 @@ package com.kingsrook.qqq.backend.core.model.metadata.tables;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; 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.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.PVSValueFormatAndFields; 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.QPossibleValue;
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource; 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.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<>(); List<QPossibleValue<?>> enumValues = new ArrayList<>();
for(QTableMetaData table : qInstance.getTables().values()) 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); possibleValueSource.withEnumValues(enumValues);
return (possibleValueSource); return (possibleValueSource);
} }

View File

@ -81,6 +81,7 @@ public class ScriptsMetaDataProvider
.withName("storeScriptRevision") .withName("storeScriptRevision")
.withStepList(List.of( .withStepList(List.of(
new QBackendStepMetaData() new QBackendStepMetaData()
.withName("main")
.withCode(new QCodeReference(StoreScriptRevisionProcessStep.class)) .withCode(new QCodeReference(StoreScriptRevisionProcessStep.class))
))); )));
} }
@ -118,6 +119,30 @@ public class ScriptsMetaDataProvider
.withJoinOn(new JoinOn("id", "scriptLogId")) .withJoinOn(new JoinOn("id", "scriptLogId"))
.withOrderBy(new QFilterOrderBy("id")) .withOrderBy(new QFilterOrderBy("id"))
.withInferredName()); .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());
} }

View File

@ -67,7 +67,7 @@ class RunAdHocRecordScriptActionTest extends BaseTest
"""); """);
RunAdHocRecordScriptInput runAdHocRecordScriptInput = new RunAdHocRecordScriptInput(); RunAdHocRecordScriptInput runAdHocRecordScriptInput = new RunAdHocRecordScriptInput();
runAdHocRecordScriptInput.setRecordPrimaryKey(1); runAdHocRecordScriptInput.setRecordPrimaryKeyList(List.of(1));
runAdHocRecordScriptInput.setTableName(TestUtils.TABLE_NAME_PERSON_MEMORY); runAdHocRecordScriptInput.setTableName(TestUtils.TABLE_NAME_PERSON_MEMORY);
runAdHocRecordScriptInput.setCodeReference(new AdHocScriptCodeReference().withScriptId(scriptId)); runAdHocRecordScriptInput.setCodeReference(new AdHocScriptCodeReference().withScriptId(scriptId));
runAdHocRecordScriptInput.setLogger(new Log4jCodeExecutionLogger()); runAdHocRecordScriptInput.setLogger(new Log4jCodeExecutionLogger());