mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Initial checkin
This commit is contained in:
@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* 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.actions.scripts;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
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.exceptions.QException;
|
||||||
|
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.metadata.code.QCodeReference;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeType;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.scripts.Script;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.scripts.ScriptRevision;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class RunAdHocRecordScriptAction
|
||||||
|
{
|
||||||
|
// todo! private Map<AssociatedScriptCodeReference, ScriptRevision> scriptRevisionCache = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void run(RunAdHocRecordScriptInput input, RunAdHocRecordScriptOutput output) throws QException
|
||||||
|
{
|
||||||
|
ActionHelper.validateSession(input);
|
||||||
|
|
||||||
|
ScriptRevision scriptRevision = getScriptRevision(input);
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
ExecuteCodeInput executeCodeInput = new ExecuteCodeInput();
|
||||||
|
executeCodeInput.setInput(new HashMap<>(Objects.requireNonNullElseGet(input.getInputValues(), HashMap::new)));
|
||||||
|
executeCodeInput.getInput().put("record", record);
|
||||||
|
executeCodeInput.setContext(new HashMap<>());
|
||||||
|
if(input.getOutputObject() != null)
|
||||||
|
{
|
||||||
|
executeCodeInput.getContext().put("output", input.getOutputObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(input.getScriptUtils() != null)
|
||||||
|
{
|
||||||
|
executeCodeInput.getContext().put("scriptUtils", input.getScriptUtils());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
executeCodeInput.getContext().put("scriptUtils", new ScriptApiUtils());
|
||||||
|
}
|
||||||
|
|
||||||
|
executeCodeInput.setCodeReference(new QCodeReference().withInlineCode(scriptRevision.getContents()).withCodeType(QCodeType.JAVA_SCRIPT)); // todo - code type as attribute of script!!
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// let caller supply a logger, or by default use StoreScriptLogAndScriptLogLineExecutionLogger //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
QCodeExecutionLoggerInterface executionLogger = Objects.requireNonNullElseGet(input.getLogger(), () -> new StoreScriptLogAndScriptLogLineExecutionLogger(scriptRevision.getScriptId(), scriptRevision.getId()));
|
||||||
|
executeCodeInput.setExecutionLogger(executionLogger);
|
||||||
|
if(executionLogger instanceof ScriptExecutionLoggerInterface scriptExecutionLoggerInterface)
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if logger is aware of scripts (as opposed to a generic CodeExecution logger), give it the ids. //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
scriptExecutionLoggerInterface.setScriptId(scriptRevision.getScriptId());
|
||||||
|
scriptExecutionLoggerInterface.setScriptRevisionId(scriptRevision.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
ExecuteCodeOutput executeCodeOutput = new ExecuteCodeOutput();
|
||||||
|
new ExecuteCodeAction().run(executeCodeInput, executeCodeOutput);
|
||||||
|
|
||||||
|
output.setOutput(executeCodeOutput.getOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private ScriptRevision getScriptRevision(RunAdHocRecordScriptInput input) throws QException
|
||||||
|
{
|
||||||
|
// todo if(!scriptRevisionCache.containsKey(input.getCodeReference()))
|
||||||
|
{
|
||||||
|
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 scriptRevisionCache.get(input.getCodeReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private ScriptRevision getCurrentScriptRevision(RunAdHocRecordScriptInput input, Serializable scriptRevisionId) throws QException
|
||||||
|
{
|
||||||
|
GetInput getInput = new GetInput();
|
||||||
|
getInput.setTableName("scriptRevision");
|
||||||
|
getInput.setPrimaryKey(scriptRevisionId);
|
||||||
|
GetOutput getOutput = new GetAction().execute(getInput);
|
||||||
|
if(getOutput.getRecord() == null)
|
||||||
|
{
|
||||||
|
/* todo
|
||||||
|
throw (new QNotFoundException("The current revision of the script for record [" + input.getCodeReference().getRecordTable() + "][" + input.getCodeReference().getRecordPrimaryKey() + "]["
|
||||||
|
+ input.getCodeReference().getFieldName() + "] (scriptRevisionId=" + scriptRevisionId + ") was not found."));
|
||||||
|
|
||||||
|
*/
|
||||||
|
throw (new IllegalStateException("todo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (new ScriptRevision(getOutput.getRecord()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private Script getScript(RunAdHocRecordScriptInput input, Serializable scriptId) throws QException
|
||||||
|
{
|
||||||
|
GetInput getInput = new GetInput();
|
||||||
|
getInput.setTableName("script");
|
||||||
|
getInput.setPrimaryKey(scriptId);
|
||||||
|
GetOutput getOutput = new GetAction().execute(getInput);
|
||||||
|
|
||||||
|
if(getOutput.getRecord() == null)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
throw (new QNotFoundException("The script for record [" + input.getCodeReference().getRecordTable() + "][" + input.getCodeReference().getRecordPrimaryKey() + "]["
|
||||||
|
+ input.getCodeReference().getFieldName() + "] (script id=" + scriptId + ") was not found."));
|
||||||
|
|
||||||
|
*/
|
||||||
|
throw (new IllegalStateException("todo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (new Script(getOutput.getRecord()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
* 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.model.actions.scripts;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
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.metadata.code.AdHocScriptCodeReference;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class RunAdHocRecordScriptInput extends AbstractTableActionInput
|
||||||
|
{
|
||||||
|
private AdHocScriptCodeReference codeReference;
|
||||||
|
private Map<String, Serializable> inputValues;
|
||||||
|
private Serializable recordPrimaryKey;
|
||||||
|
private String tableName;
|
||||||
|
private QCodeExecutionLoggerInterface logger;
|
||||||
|
|
||||||
|
private Serializable outputObject;
|
||||||
|
|
||||||
|
private Serializable scriptUtils;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public RunAdHocRecordScriptInput()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for inputValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Map<String, Serializable> getInputValues()
|
||||||
|
{
|
||||||
|
return inputValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for inputValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setInputValues(Map<String, Serializable> inputValues)
|
||||||
|
{
|
||||||
|
this.inputValues = inputValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for inputValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public RunAdHocRecordScriptInput withInputValues(Map<String, Serializable> inputValues)
|
||||||
|
{
|
||||||
|
this.inputValues = inputValues;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for outputObject
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Serializable getOutputObject()
|
||||||
|
{
|
||||||
|
return outputObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for outputObject
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setOutputObject(Serializable outputObject)
|
||||||
|
{
|
||||||
|
this.outputObject = outputObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for outputObject
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public RunAdHocRecordScriptInput withOutputObject(Serializable outputObject)
|
||||||
|
{
|
||||||
|
this.outputObject = outputObject;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for logger
|
||||||
|
*******************************************************************************/
|
||||||
|
public QCodeExecutionLoggerInterface getLogger()
|
||||||
|
{
|
||||||
|
return (this.logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for logger
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setLogger(QCodeExecutionLoggerInterface logger)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for logger
|
||||||
|
*******************************************************************************/
|
||||||
|
public RunAdHocRecordScriptInput withLogger(QCodeExecutionLoggerInterface logger)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for scriptUtils
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Serializable getScriptUtils()
|
||||||
|
{
|
||||||
|
return scriptUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for scriptUtils
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setScriptUtils(Serializable scriptUtils)
|
||||||
|
{
|
||||||
|
this.scriptUtils = scriptUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for codeReference
|
||||||
|
*******************************************************************************/
|
||||||
|
public AdHocScriptCodeReference getCodeReference()
|
||||||
|
{
|
||||||
|
return (this.codeReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for codeReference
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setCodeReference(AdHocScriptCodeReference codeReference)
|
||||||
|
{
|
||||||
|
this.codeReference = codeReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for codeReference
|
||||||
|
*******************************************************************************/
|
||||||
|
public RunAdHocRecordScriptInput withCodeReference(AdHocScriptCodeReference codeReference)
|
||||||
|
{
|
||||||
|
this.codeReference = codeReference;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** 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
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getTableName()
|
||||||
|
{
|
||||||
|
return (this.tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for tableName
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setTableName(String tableName)
|
||||||
|
{
|
||||||
|
this.tableName = tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for tableName
|
||||||
|
*******************************************************************************/
|
||||||
|
public RunAdHocRecordScriptInput withTableName(String tableName)
|
||||||
|
{
|
||||||
|
this.tableName = tableName;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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.model.actions.scripts;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class RunAdHocRecordScriptOutput extends AbstractActionOutput
|
||||||
|
{
|
||||||
|
private Serializable output;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for output
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Serializable getOutput()
|
||||||
|
{
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for output
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setOutput(Serializable output)
|
||||||
|
{
|
||||||
|
this.output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for output
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public RunAdHocRecordScriptOutput withOutput(Serializable output)
|
||||||
|
{
|
||||||
|
this.output = output;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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.model.metadata.code;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class AdHocScriptCodeReference extends QCodeReference
|
||||||
|
{
|
||||||
|
private Integer scriptId;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for scriptId
|
||||||
|
*******************************************************************************/
|
||||||
|
public Integer getScriptId()
|
||||||
|
{
|
||||||
|
return (this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for scriptId
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setScriptId(Integer scriptId)
|
||||||
|
{
|
||||||
|
this.scriptId = scriptId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for scriptId
|
||||||
|
*******************************************************************************/
|
||||||
|
public AdHocScriptCodeReference withScriptId(Integer scriptId)
|
||||||
|
{
|
||||||
|
this.scriptId = scriptId;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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.model.metadata.tables;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class TablesPossibleValueSourceMetaDataProvider
|
||||||
|
{
|
||||||
|
public static final String NAME = "tables";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public static QPossibleValueSource defineTablesPossibleValueSource(QInstance qInstance)
|
||||||
|
{
|
||||||
|
QPossibleValueSource possibleValueSource = new QPossibleValueSource()
|
||||||
|
.withName(NAME)
|
||||||
|
.withType(QPossibleValueSourceType.ENUM)
|
||||||
|
.withValueFormatAndFields(PVSValueFormatAndFields.LABEL_ONLY);
|
||||||
|
|
||||||
|
List<QPossibleValue<?>> enumValues = new ArrayList<>();
|
||||||
|
for(QTableMetaData table : qInstance.getTables().values())
|
||||||
|
{
|
||||||
|
enumValues.add(new QPossibleValue<>(table.getName(), table.getLabel()));
|
||||||
|
}
|
||||||
|
|
||||||
|
possibleValueSource.withEnumValues(enumValues);
|
||||||
|
return (possibleValueSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* 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.processes.implementations.scripts;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.ActionHelper;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||||
|
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.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.get.GetInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||||
|
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.query.QCriteriaOperator;
|
||||||
|
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.query.QueryOutput;
|
||||||
|
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.utils.StringUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Action to store a new version of a script, associated with a record.
|
||||||
|
**
|
||||||
|
** If there's never been a script assigned to the record (for the specified field),
|
||||||
|
** then a new Script record is first inserted.
|
||||||
|
**
|
||||||
|
** The script referenced by the record is always updated to point at the new
|
||||||
|
** scriptRevision record that is inserted.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class StoreScriptRevisionProcessStep implements BackendStep
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public void run(RunBackendStepInput input, RunBackendStepOutput output) throws QException
|
||||||
|
{
|
||||||
|
ActionHelper.validateSession(input);
|
||||||
|
|
||||||
|
/*
|
||||||
|
QTableMetaData table = input.getTable();
|
||||||
|
Optional<AssociatedScript> optAssociatedScript = table.getAssociatedScripts().stream().filter(as -> as.getFieldName().equals(input.getFieldName())).findFirst();
|
||||||
|
if(optAssociatedScript.isEmpty())
|
||||||
|
{
|
||||||
|
throw (new QException("Field to update associated script for is not an associated script field."));
|
||||||
|
}
|
||||||
|
AssociatedScript associatedScript = optAssociatedScript.get();
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
// get the record that the script is to be associated with //
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
QRecord associatedRecord;
|
||||||
|
{
|
||||||
|
GetInput getInput = new GetInput();
|
||||||
|
getInput.setTableName(input.getTableName());
|
||||||
|
getInput.setPrimaryKey(input.getRecordPrimaryKey());
|
||||||
|
getInput.setShouldGenerateDisplayValues(true);
|
||||||
|
GetOutput getOutput = new GetAction().execute(getInput);
|
||||||
|
associatedRecord = getOutput.getRecord();
|
||||||
|
}
|
||||||
|
if(associatedRecord == null)
|
||||||
|
{
|
||||||
|
throw (new QException("Record to associated with script was not found."));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// check if there's currently a script referenced by the record //
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
Integer scriptId = input.getValueInteger("scriptId");
|
||||||
|
Integer nextSequenceNo = 1;
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
// get the existing script, to update //
|
||||||
|
////////////////////////////////////////
|
||||||
|
GetInput getInput = new GetInput();
|
||||||
|
getInput.setTableName("script");
|
||||||
|
getInput.setPrimaryKey(scriptId);
|
||||||
|
GetOutput getOutput = new GetAction().execute(getInput);
|
||||||
|
QRecord script = getOutput.getRecord();
|
||||||
|
|
||||||
|
QueryInput queryInput = new QueryInput();
|
||||||
|
queryInput.setTableName("scriptRevision");
|
||||||
|
queryInput.setFilter(new QQueryFilter()
|
||||||
|
.withCriteria(new QFilterCriteria("scriptId", QCriteriaOperator.EQUALS, List.of(script.getValue("id"))))
|
||||||
|
.withOrderBy(new QFilterOrderBy("sequenceNo", false))
|
||||||
|
);
|
||||||
|
queryInput.setLimit(1);
|
||||||
|
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||||
|
if(!queryOutput.getRecords().isEmpty())
|
||||||
|
{
|
||||||
|
nextSequenceNo = queryOutput.getRecords().get(0).getValueInteger("sequenceNo") + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// insert a new script revision //
|
||||||
|
//////////////////////////////////
|
||||||
|
String commitMessage = input.getValueString("commitMessage");
|
||||||
|
if(!StringUtils.hasContent(commitMessage))
|
||||||
|
{
|
||||||
|
if(nextSequenceNo == 1)
|
||||||
|
{
|
||||||
|
commitMessage = "Initial version";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
commitMessage = "No commit message given";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QRecord scriptRevision = new QRecord()
|
||||||
|
.withValue("scriptId", script.getValue("id"))
|
||||||
|
.withValue("contents", input.getValueString("contents"))
|
||||||
|
.withValue("commitMessage", commitMessage)
|
||||||
|
.withValue("sequenceNo", nextSequenceNo);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
scriptRevision.setValue("author", input.getSession().getUser().getFullName());
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
scriptRevision.setValue("author", "Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertInput insertInput = new InsertInput();
|
||||||
|
insertInput.setTableName("scriptRevision");
|
||||||
|
insertInput.setRecords(List.of(scriptRevision));
|
||||||
|
InsertOutput insertOutput = new InsertAction().execute(insertInput);
|
||||||
|
scriptRevision = insertOutput.getRecords().get(0);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
// update the script to point at the new revision //
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
script.setValue("currentScriptRevisionId", scriptRevision.getValue("id"));
|
||||||
|
UpdateInput updateInput = new UpdateInput();
|
||||||
|
updateInput.setTableName("script");
|
||||||
|
updateInput.setRecords(List.of(script));
|
||||||
|
new UpdateAction().execute(updateInput);
|
||||||
|
|
||||||
|
output.addValue("scriptId", script.getValueInteger("id"));
|
||||||
|
output.addValue("scriptName", script.getValueString("name"));
|
||||||
|
output.addValue("scriptRevisionId", scriptRevision.getValueInteger("id"));
|
||||||
|
output.addValue("scriptRevisionSequenceNo", scriptRevision.getValueInteger("sequenceNo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* 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.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.scripts.logging.Log4jCodeExecutionLogger;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||||
|
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.scripts.RunAdHocRecordScriptInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.scripts.RunAdHocRecordScriptOutput;
|
||||||
|
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.QInstance;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.code.AdHocScriptCodeReference;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.AssociatedScript;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.scripts.ScriptsMetaDataProvider;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for RunAdHocRecordScriptAction
|
||||||
|
*******************************************************************************/
|
||||||
|
class RunAdHocRecordScriptActionTest extends BaseTest
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void test() throws QException
|
||||||
|
{
|
||||||
|
setupInstance();
|
||||||
|
|
||||||
|
Integer scriptId = insertScript("""
|
||||||
|
return "Hello";
|
||||||
|
""");
|
||||||
|
|
||||||
|
RunAdHocRecordScriptInput runAdHocRecordScriptInput = new RunAdHocRecordScriptInput();
|
||||||
|
runAdHocRecordScriptInput.setRecordPrimaryKey(1);
|
||||||
|
runAdHocRecordScriptInput.setTableName(TestUtils.TABLE_NAME_PERSON_MEMORY);
|
||||||
|
runAdHocRecordScriptInput.setCodeReference(new AdHocScriptCodeReference().withScriptId(scriptId));
|
||||||
|
runAdHocRecordScriptInput.setLogger(new Log4jCodeExecutionLogger());
|
||||||
|
|
||||||
|
RunAdHocRecordScriptOutput runAdHocRecordScriptOutput = new RunAdHocRecordScriptOutput();
|
||||||
|
new RunAdHocRecordScriptAction().run(runAdHocRecordScriptInput, runAdHocRecordScriptOutput);
|
||||||
|
|
||||||
|
/*
|
||||||
|
RunAssociatedScriptInput runAssociatedScriptInput = new RunAssociatedScriptInput();
|
||||||
|
runAssociatedScriptInput.setInputValues(Map.of());
|
||||||
|
runAssociatedScriptInput.setTableName(TestUtils.TABLE_NAME_PERSON_MEMORY);
|
||||||
|
runAssociatedScriptInput.setCodeReference(new AssociatedScriptCodeReference()
|
||||||
|
.withRecordTable(TestUtils.TABLE_NAME_PERSON_MEMORY)
|
||||||
|
.withRecordPrimaryKey(1)
|
||||||
|
.withFieldName("testScriptId")
|
||||||
|
);
|
||||||
|
RunAssociatedScriptOutput runAssociatedScriptOutput = new RunAssociatedScriptOutput();
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ok - since the core module doesn't have the javascript language support module as a dep, this action will fail - but at least we can confirm it fails with this specific exception! //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
assertThatThrownBy(() -> new RunAssociatedScriptAction().run(runAssociatedScriptInput, runAssociatedScriptOutput))
|
||||||
|
.isInstanceOf(QException.class)
|
||||||
|
.hasRootCauseInstanceOf(ClassNotFoundException.class)
|
||||||
|
.hasRootCauseMessage("com.kingsrook.qqq.languages.javascript.QJavaScriptExecutor");
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// assert that a log was generated //
|
||||||
|
/////////////////////////////////////
|
||||||
|
assertEquals(1, TestUtils.queryTable(ScriptLog.TABLE_NAME).size());
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private void setupInstance() throws QException
|
||||||
|
{
|
||||||
|
QInstance instance = QContext.getQInstance();
|
||||||
|
QTableMetaData personMemory = instance.getTable(TestUtils.TABLE_NAME_PERSON_MEMORY)
|
||||||
|
.withField(new QFieldMetaData("testScriptId", QFieldType.INTEGER))
|
||||||
|
.withAssociatedScript(new AssociatedScript()
|
||||||
|
.withScriptTypeId(1)
|
||||||
|
.withFieldName("testScriptId")
|
||||||
|
);
|
||||||
|
|
||||||
|
new ScriptsMetaDataProvider().defineAll(instance, TestUtils.MEMORY_BACKEND_NAME, null);
|
||||||
|
|
||||||
|
TestUtils.insertRecords(instance, personMemory, List.of(
|
||||||
|
new QRecord().withValue("id", 1),
|
||||||
|
new QRecord().withValue("id", 2)
|
||||||
|
));
|
||||||
|
|
||||||
|
TestUtils.insertRecords(instance, instance.getTable("scriptType"), List.of(
|
||||||
|
new QRecord().withValue("id", 1).withValue("name", "Test Script Type")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private Integer insertScript(String code) throws QException
|
||||||
|
{
|
||||||
|
InsertInput insertInput = new InsertInput();
|
||||||
|
insertInput.setTableName("script");
|
||||||
|
insertInput.setRecords(List.of(new QRecord().withValue("name", "Test script")));
|
||||||
|
InsertOutput insertOutput = new InsertAction().execute(insertInput);
|
||||||
|
Integer scriptId = insertOutput.getRecords().get(0).getValueInteger("id");
|
||||||
|
|
||||||
|
insertInput = new InsertInput();
|
||||||
|
insertInput.setTableName("scriptRevision");
|
||||||
|
insertInput.setRecords(List.of(new QRecord().withValue("scriptId", scriptId).withValue("code", code)));
|
||||||
|
insertOutput = new InsertAction().execute(insertInput);
|
||||||
|
Integer scriptRevisionId = insertOutput.getRecords().get(0).getValueInteger("id");
|
||||||
|
|
||||||
|
UpdateInput updateInput = new UpdateInput();
|
||||||
|
updateInput.setTableName("script");
|
||||||
|
updateInput.setRecords(List.of(new QRecord().withValue("id", scriptId).withValue("currentScriptRevisionId", scriptRevisionId)));
|
||||||
|
UpdateOutput updateOutput = new UpdateAction().execute(updateInput);
|
||||||
|
|
||||||
|
return (scriptId);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user