diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java new file mode 100644 index 00000000..59980b81 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java @@ -0,0 +1,155 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.actions; + + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.interfaces.FunctionBody; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionRequest; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionResult; +import com.kingsrook.qqq.backend.core.model.actions.query.QueryRequest; +import com.kingsrook.qqq.backend.core.model.actions.query.QueryResult; +import com.kingsrook.qqq.backend.core.model.metadata.QCodeReference; +import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionInputMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListMetaData; + + +/******************************************************************************* + ** Action handler for running q-functions. + * + *******************************************************************************/ +public class RunFunctionAction +{ + + /******************************************************************************* + ** + *******************************************************************************/ + public RunFunctionResult execute(RunFunctionRequest runFunctionRequest) throws QException + { + /////////////////////////////////////////////////////// + // todo - shouldn't meta-data validation catch this? // + /////////////////////////////////////////////////////// + QProcessMetaData process = runFunctionRequest.getInstance().getProcess(runFunctionRequest.getProcessName()); + if(process == null) + { + throw new QException("Process [" + runFunctionRequest.getProcessName() + "] is not defined in this instance."); + } + + QFunctionMetaData function = process.getFunction(runFunctionRequest.getFunctionName()); + if(function == null) + { + throw new QException("Function [" + runFunctionRequest.getFunctionName() + "] is not defined in the process [" + process.getName() + "]"); + } + + ////////////////////////////////////////////////////////////////////////////////////// + // ensure input data is set as needed - use callback object to get anything missing // + ////////////////////////////////////////////////////////////////////////////////////// + ensureRecordsAreInRequest(runFunctionRequest, function); + ensureInputFieldsAreInRequest(runFunctionRequest, function); + + //////////////////////////////////////////////////////////////////// + // load and run the user-defined code that actually does the work // + //////////////////////////////////////////////////////////////////// + RunFunctionResult runFunctionResult = runFunctionBodyCode(function.getCode(), runFunctionRequest); + + return (runFunctionResult); + } + + + + /******************************************************************************* + ** check if this function needs any input fields - and if so, if we need to get one + ** via the callback + ** + *******************************************************************************/ + private void ensureInputFieldsAreInRequest(RunFunctionRequest runFunctionRequest, QFunctionMetaData function) + { + QFunctionInputMetaData inputMetaData = function.getInputMetaData(); + + List fieldsToGet = new ArrayList<>(); + for(QFieldMetaData field : inputMetaData.getFieldList()) + { + Serializable value = runFunctionRequest.getValue(field.getName()); + if(value == null) + { + // todo - check if required? + fieldsToGet.add(field); + } + } + + Map fieldValues = runFunctionRequest.getCallback().getFieldValues(fieldsToGet); + for(Map.Entry entry : fieldValues.entrySet()) + { + runFunctionRequest.addValue(entry.getKey(), entry.getValue()); + // todo - check to make sure got values back? + } + } + + + + /******************************************************************************* + ** check if this function uses a record list - and if so, if we need to get one + ** via the callback + *******************************************************************************/ + private void ensureRecordsAreInRequest(RunFunctionRequest runFunctionRequest, QFunctionMetaData function) throws QException + { + QFunctionInputMetaData inputMetaData = function.getInputMetaData(); + QRecordListMetaData recordListMetaData = inputMetaData.getRecordListMetaData(); + if(recordListMetaData != null) + { + if(runFunctionRequest.getRecords() == null) + { + QueryRequest queryRequest = new QueryRequest(runFunctionRequest.getInstance()); + queryRequest.setTableName(inputMetaData.getRecordListMetaData().getTableName()); + + // todo - handle this being async (e.g., http) + // seems like it just needs to throw, breaking this flow, and to send a response to the frontend, directing it to prompt the user for the needed data + // then this function can re-run, hopefully with the needed data. + queryRequest.setFilter(runFunctionRequest.getCallback().getQueryFilter()); + + QueryResult queryResult = new QueryAction().execute(queryRequest); + runFunctionRequest.setRecords(queryResult.getRecords()); + // todo - handle 0 results found? + } + } + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private RunFunctionResult runFunctionBodyCode(QCodeReference code, RunFunctionRequest runFunctionRequest) + { + RunFunctionResult runFunctionResult; + try + { + Class codeClass = Class.forName(code.getName()); + Object codeObject = codeClass.getConstructor().newInstance(); + if(!(codeObject instanceof FunctionBody)) + { + throw (new QException("The supplied code [" + codeClass.getName() + "] is not an instance of FunctionBody")); + } + + FunctionBody functionBodyCodeObject = (FunctionBody) codeObject; + runFunctionResult = functionBodyCodeObject.run(runFunctionRequest); + } + catch(Exception e) + { + runFunctionResult = new RunFunctionResult(); + runFunctionResult.setError("Error running function code: " + e.getMessage()); + e.printStackTrace(); + } + + return (runFunctionResult); + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java new file mode 100644 index 00000000..7b88d48a --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java @@ -0,0 +1,68 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.actions; + + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.interfaces.FunctionBody; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionRequest; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionResult; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessRequest; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessResult; +import com.kingsrook.qqq.backend.core.model.actions.query.QueryRequest; +import com.kingsrook.qqq.backend.core.model.actions.query.QueryResult; +import com.kingsrook.qqq.backend.core.model.metadata.QCodeReference; +import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionInputMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListMetaData; + + +/******************************************************************************* + ** Action handler for running q-processes (which are a sequence of q-functions). + * + *******************************************************************************/ +public class RunProcessAction +{ + + /******************************************************************************* + ** + *******************************************************************************/ + public RunProcessResult execute(RunProcessRequest runProcessRequest) throws QException + { + /////////////////////////////////////////////////////// + // todo - shouldn't meta-data validation catch this? // + /////////////////////////////////////////////////////// + QProcessMetaData process = runProcessRequest.getInstance().getProcess(runProcessRequest.getProcessName()); + if(process == null) + { + throw new QException("Process [" + runProcessRequest.getProcessName() + "] is not defined in this instance."); + } + + RunProcessResult runProcessResult = runProcessFunctions(process); + + return (runProcessResult); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private RunProcessResult runProcessFunctions(QProcessMetaData process) + { + List functionList = process.getFunctionList(); + for(QFunctionMetaData qFunctionMetaData : functionList) + { + // todo - custom routing? + } + } + +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/callbacks/QProcessCallback.java b/src/main/java/com/kingsrook/qqq/backend/core/callbacks/QProcessCallback.java new file mode 100644 index 00000000..f56fe681 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/callbacks/QProcessCallback.java @@ -0,0 +1,24 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.callbacks; + + +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.model.actions.query.QQueryFilter; +import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; + + +/******************************************************************************* + ** When a process/function can't run because it's missing data, this interface + ** defines how the core framework goes back to a middleware (and possibly to a + ** frontend) to get the data. + *******************************************************************************/ +public interface QProcessCallback +{ + QQueryFilter getQueryFilter(); + Map getFieldValues(List fields); +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/interfaces/FunctionBody.java b/src/main/java/com/kingsrook/qqq/backend/core/interfaces/FunctionBody.java new file mode 100644 index 00000000..3448d2ee --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/interfaces/FunctionBody.java @@ -0,0 +1,18 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.interfaces; + + +import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionRequest; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionResult; + + +/******************************************************************************* + ** + *******************************************************************************/ +public interface FunctionBody +{ + RunFunctionResult run(RunFunctionRequest runFunctionRequest); +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/interfaces/mock/MockFunctionBody.java b/src/main/java/com/kingsrook/qqq/backend/core/interfaces/mock/MockFunctionBody.java new file mode 100644 index 00000000..a0364d68 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/interfaces/mock/MockFunctionBody.java @@ -0,0 +1,33 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.interfaces.mock; + + +import com.kingsrook.qqq.backend.core.interfaces.FunctionBody; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionRequest; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionResult; + + +/******************************************************************************* + ** Mock implementation of a FunctionBody. + ** + ** Basically just passes data from the request to the response. + *******************************************************************************/ +public class MockFunctionBody implements FunctionBody +{ + @Override + public RunFunctionResult run(RunFunctionRequest runFunctionRequest) + { + RunFunctionResult runFunctionResult = new RunFunctionResult(); + runFunctionResult.setRecords(runFunctionRequest.getRecords()); + + runFunctionResult.getRecords().forEach(r -> r.setValue("mockValue", "Ha ha!")); + + runFunctionResult.setValues(runFunctionRequest.getValues()); + runFunctionResult.addValue("mockValue", "You so silly"); + + return (runFunctionResult); + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunFunctionRequest.java b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunFunctionRequest.java new file mode 100644 index 00000000..a9eb94e0 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunFunctionRequest.java @@ -0,0 +1,283 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.actions.processes; + + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.callbacks.QProcessCallback; +import com.kingsrook.qqq.backend.core.model.actions.AbstractQRequest; +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.processes.QFunctionMetaData; + + +/******************************************************************************* + ** Request data container for the RunFunction action + ** + *******************************************************************************/ +public class RunFunctionRequest extends AbstractQRequest +{ + private String processName; + private String functionName; + private List records; + private Map values; + private QProcessCallback callback; + + + + /******************************************************************************* + ** + *******************************************************************************/ + public RunFunctionRequest() + { + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public RunFunctionRequest(QInstance instance) + { + super(instance); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public QFunctionMetaData getFunctionMetaData() + { + return (instance.getFunction(getProcessName(), getFunctionName())); + } + + + + /******************************************************************************* + ** Getter for processName + ** + *******************************************************************************/ + public String getProcessName() + { + return processName; + } + + + + /******************************************************************************* + ** Setter for processName + ** + *******************************************************************************/ + public void setProcessName(String processName) + { + this.processName = processName; + } + + + + /******************************************************************************* + ** Setter for processName + ** + *******************************************************************************/ + public RunFunctionRequest withProcessName(String processName) + { + this.processName = processName; + return (this); + } + + + + /******************************************************************************* + ** Getter for functionName + ** + *******************************************************************************/ + public String getFunctionName() + { + return functionName; + } + + + + /******************************************************************************* + ** Setter for functionName + ** + *******************************************************************************/ + public void setFunctionName(String functionName) + { + this.functionName = functionName; + } + + + + /******************************************************************************* + ** Setter for functionName + ** + *******************************************************************************/ + public RunFunctionRequest withFunctionName(String functionName) + { + this.functionName = functionName; + return (this); + } + + + + /******************************************************************************* + ** Getter for records + ** + *******************************************************************************/ + public List getRecords() + { + return records; + } + + + + /******************************************************************************* + ** Setter for records + ** + *******************************************************************************/ + public void setRecords(List records) + { + this.records = records; + } + + + + /******************************************************************************* + ** Setter for records + ** + *******************************************************************************/ + public RunFunctionRequest withRecords(List records) + { + this.records = records; + return (this); + } + + + + /******************************************************************************* + ** Getter for values + ** + *******************************************************************************/ + public Map getValues() + { + return values; + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public void setValues(Map values) + { + this.values = values; + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public RunFunctionRequest withValues(Map values) + { + this.values = values; + return (this); + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public RunFunctionRequest addValue(String fieldName, Serializable value) + { + if(this.values == null) + { + this.values = new HashMap<>(); + } + this.values.put(fieldName, value); + return (this); + } + + + + /******************************************************************************* + ** Getter for callback + ** + *******************************************************************************/ + public QProcessCallback getCallback() + { + return callback; + } + + + + /******************************************************************************* + ** Setter for callback + ** + *******************************************************************************/ + public void setCallback(QProcessCallback callback) + { + this.callback = callback; + } + + + + /******************************************************************************* + ** Setter for callback + ** + *******************************************************************************/ + public RunFunctionRequest withCallback(QProcessCallback callback) + { + this.callback = callback; + return (this); + } + + + + /******************************************************************************* + ** Getter for a single field's value + ** + *******************************************************************************/ + public Serializable getValue(String fieldName) + { + if(values == null) + { + return (null); + } + return (values.get(fieldName)); + } + + + + /******************************************************************************* + ** Getter for a single field's value + ** + *******************************************************************************/ + public String getValueString(String fieldName) + { + return ((String) getValue(fieldName)); + } + + + + /******************************************************************************* + ** Getter for a single field's value + ** + *******************************************************************************/ + public Integer getValueInteger(String fieldName) + { + return ((Integer) getValue(fieldName)); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunFunctionResult.java b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunFunctionResult.java new file mode 100644 index 00000000..7bdb1329 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunFunctionResult.java @@ -0,0 +1,140 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.actions.processes; + + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.model.actions.AbstractQResult; +import com.kingsrook.qqq.backend.core.model.data.QRecord; + + +/******************************************************************************* + ** Result data container for the RunFunction action + ** + *******************************************************************************/ +public class RunFunctionResult extends AbstractQResult +{ + private List records; + private Map values; + private String error; + + + + /******************************************************************************* + ** + *******************************************************************************/ + public RunFunctionResult() + { + } + + + + /******************************************************************************* + ** Getter for records + ** + *******************************************************************************/ + public List getRecords() + { + return records; + } + + + + /******************************************************************************* + ** Setter for records + ** + *******************************************************************************/ + public void setRecords(List records) + { + this.records = records; + } + + + + /******************************************************************************* + ** Setter for records + ** + *******************************************************************************/ + public RunFunctionResult withRecords(List records) + { + this.records = records; + return (this); + } + + + + /******************************************************************************* + ** Getter for values + ** + *******************************************************************************/ + public Map getValues() + { + return values; + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public void setValues(Map values) + { + this.values = values; + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public RunFunctionResult withValues(Map values) + { + this.values = values; + return (this); + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public RunFunctionResult addValue(String fieldName, Serializable value) + { + if(this.values == null) + { + this.values = new HashMap<>(); + } + this.values.put(fieldName, value); + return (this); + } + + + + /******************************************************************************* + ** Getter for error + ** + *******************************************************************************/ + public String getError() + { + return error; + } + + + + /******************************************************************************* + ** Setter for error + ** + *******************************************************************************/ + public void setError(String error) + { + this.error = error; + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunProcessRequest.java b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunProcessRequest.java new file mode 100644 index 00000000..b7a02538 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunProcessRequest.java @@ -0,0 +1,248 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.actions.processes; + + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.callbacks.QProcessCallback; +import com.kingsrook.qqq.backend.core.model.actions.AbstractQRequest; +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.processes.QProcessMetaData; + + +/******************************************************************************* + ** Request data container for the RunProcess action + ** + *******************************************************************************/ +public class RunProcessRequest extends AbstractQRequest +{ + private String processName; + private List records; + private Map values; + private QProcessCallback callback; + + + + /******************************************************************************* + ** + *******************************************************************************/ + public RunProcessRequest() + { + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public RunProcessRequest(QInstance instance) + { + super(instance); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public QProcessMetaData getProcessMetaData() + { + return (instance.getProcess(getProcessName())); + } + + + + /******************************************************************************* + ** Getter for processName + ** + *******************************************************************************/ + public String getProcessName() + { + return processName; + } + + + + /******************************************************************************* + ** Setter for processName + ** + *******************************************************************************/ + public void setProcessName(String processName) + { + this.processName = processName; + } + + + + /******************************************************************************* + ** Setter for processName + ** + *******************************************************************************/ + public RunProcessRequest withProcessName(String processName) + { + this.processName = processName; + return (this); + } + + + + /******************************************************************************* + ** Getter for records + ** + *******************************************************************************/ + public List getRecords() + { + return records; + } + + + + /******************************************************************************* + ** Setter for records + ** + *******************************************************************************/ + public void setRecords(List records) + { + this.records = records; + } + + + + /******************************************************************************* + ** Setter for records + ** + *******************************************************************************/ + public RunProcessRequest withRecords(List records) + { + this.records = records; + return (this); + } + + + + /******************************************************************************* + ** Getter for values + ** + *******************************************************************************/ + public Map getValues() + { + return values; + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public void setValues(Map values) + { + this.values = values; + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public RunProcessRequest withValues(Map values) + { + this.values = values; + return (this); + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public RunProcessRequest addValue(String fieldName, Serializable value) + { + if(this.values == null) + { + this.values = new HashMap<>(); + } + this.values.put(fieldName, value); + return (this); + } + + + + /******************************************************************************* + ** Getter for callback + ** + *******************************************************************************/ + public QProcessCallback getCallback() + { + return callback; + } + + + + /******************************************************************************* + ** Setter for callback + ** + *******************************************************************************/ + public void setCallback(QProcessCallback callback) + { + this.callback = callback; + } + + + + /******************************************************************************* + ** Setter for callback + ** + *******************************************************************************/ + public RunProcessRequest withCallback(QProcessCallback callback) + { + this.callback = callback; + return (this); + } + + + + /******************************************************************************* + ** Getter for a single field's value + ** + *******************************************************************************/ + public Serializable getValue(String fieldName) + { + if(values == null) + { + return (null); + } + return (values.get(fieldName)); + } + + + + /******************************************************************************* + ** Getter for a single field's value + ** + *******************************************************************************/ + public String getValueString(String fieldName) + { + return ((String) getValue(fieldName)); + } + + + + /******************************************************************************* + ** Getter for a single field's value + ** + *******************************************************************************/ + public Integer getValueInteger(String fieldName) + { + return ((Integer) getValue(fieldName)); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunProcessResult.java b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunProcessResult.java new file mode 100644 index 00000000..5bab2fb9 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/processes/RunProcessResult.java @@ -0,0 +1,140 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.actions.processes; + + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.model.actions.AbstractQResult; +import com.kingsrook.qqq.backend.core.model.data.QRecord; + + +/******************************************************************************* + ** Result data container for the RunProcess action + ** + *******************************************************************************/ +public class RunProcessResult extends AbstractQResult +{ + private List records; + private Map values; + private String error; + + + + /******************************************************************************* + ** + *******************************************************************************/ + public RunProcessResult() + { + } + + + + /******************************************************************************* + ** Getter for records + ** + *******************************************************************************/ + public List getRecords() + { + return records; + } + + + + /******************************************************************************* + ** Setter for records + ** + *******************************************************************************/ + public void setRecords(List records) + { + this.records = records; + } + + + + /******************************************************************************* + ** Setter for records + ** + *******************************************************************************/ + public RunProcessResult withRecords(List records) + { + this.records = records; + return (this); + } + + + + /******************************************************************************* + ** Getter for values + ** + *******************************************************************************/ + public Map getValues() + { + return values; + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public void setValues(Map values) + { + this.values = values; + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public RunProcessResult withValues(Map values) + { + this.values = values; + return (this); + } + + + + /******************************************************************************* + ** Setter for values + ** + *******************************************************************************/ + public RunProcessResult addValue(String fieldName, Serializable value) + { + if(this.values == null) + { + this.values = new HashMap<>(); + } + this.values.put(fieldName, value); + return (this); + } + + + + /******************************************************************************* + ** Getter for error + ** + *******************************************************************************/ + public String getError() + { + return error; + } + + + + /******************************************************************************* + ** Setter for error + ** + *******************************************************************************/ + public void setError(String error) + { + this.error = error; + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QCodeReference.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QCodeReference.java new file mode 100644 index 00000000..45ec1b6e --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QCodeReference.java @@ -0,0 +1,119 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.metadata; + + +/******************************************************************************* + ** + *******************************************************************************/ +public class QCodeReference +{ + private String name; + private QCodeType codeType; + private QCodeUsage codeUsage; + + + + /******************************************************************************* + ** Getter for name + ** + *******************************************************************************/ + public String getName() + { + return name; + } + + + + /******************************************************************************* + ** Setter for name + ** + *******************************************************************************/ + public void setName(String name) + { + this.name = name; + } + + + + /******************************************************************************* + ** Setter for name + ** + *******************************************************************************/ + public QCodeReference withName(String name) + { + this.name = name; + return (this); + } + + + + /******************************************************************************* + ** Getter for codeType + ** + *******************************************************************************/ + public QCodeType getCodeType() + { + return codeType; + } + + + + /******************************************************************************* + ** Setter for codeType + ** + *******************************************************************************/ + public void setCodeType(QCodeType codeType) + { + this.codeType = codeType; + } + + + + /******************************************************************************* + ** Setter for codeType + ** + *******************************************************************************/ + public QCodeReference withCodeType(QCodeType codeType) + { + this.codeType = codeType; + return (this); + } + + + + /******************************************************************************* + ** Getter for codeUsage + ** + *******************************************************************************/ + public QCodeUsage getCodeUsage() + { + return codeUsage; + } + + + + /******************************************************************************* + ** Setter for codeUsage + ** + *******************************************************************************/ + public void setCodeUsage(QCodeUsage codeUsage) + { + this.codeUsage = codeUsage; + } + + + + /******************************************************************************* + ** Setter for codeUsage + ** + *******************************************************************************/ + public QCodeReference withCodeUsage(QCodeUsage codeUsage) + { + this.codeUsage = codeUsage; + return (this); + } + +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QCodeType.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QCodeType.java new file mode 100644 index 00000000..9c50ac8d --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QCodeType.java @@ -0,0 +1,15 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.metadata; + + +/******************************************************************************* + ** Possible types for Q-Code entities + ** + *******************************************************************************/ +public enum QCodeType +{ + JAVA +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QCodeUsage.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QCodeUsage.java new file mode 100644 index 00000000..7e0347cc --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QCodeUsage.java @@ -0,0 +1,15 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.metadata; + + +/******************************************************************************* + ** Possible usages for Q-Code entities + ** + *******************************************************************************/ +public enum QCodeUsage +{ + FUNCTION +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java index bd248ecc..57c4cafd 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java @@ -5,10 +5,14 @@ package com.kingsrook.qqq.backend.core.model.metadata; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.fasterxml.jackson.annotation.JsonIgnore; import com.kingsrook.qqq.backend.core.instances.QInstanceValidationKey; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; /******************************************************************************* @@ -24,6 +28,7 @@ public class QInstance private Map backends = new HashMap<>(); private Map tables = new HashMap<>(); + private Map processes = new HashMap<>(); // todo - lock down the object (no more changes allowed) after it's been validated? @JsonIgnore @@ -52,6 +57,22 @@ public class QInstance } + /******************************************************************************* + ** + *******************************************************************************/ + public List getProcessesForTable(String tableName) + { + List rs = new ArrayList<>(); + for(QProcessMetaData process : processes.values()) + { + if (tableName.equals(process.getTableName())) + { + rs.add(process); + } + } + return (rs); + } + /******************************************************************************* ** Setter for hasBeenValidated @@ -104,6 +125,16 @@ public class QInstance + /******************************************************************************* + ** + *******************************************************************************/ + public void addProcess(QProcessMetaData process) + { + this.processes.put(process.getName(), process); + } + + + /******************************************************************************* ** *******************************************************************************/ @@ -124,6 +155,32 @@ public class QInstance + /******************************************************************************* + ** + *******************************************************************************/ + public QFunctionMetaData getFunction(String processName, String functionName) + { + QProcessMetaData qProcessMetaData = this.processes.get(processName); + if(qProcessMetaData == null) + { + return (null); + } + + return (qProcessMetaData.getFunction(functionName)); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public QProcessMetaData getProcess(String name) + { + return (this.processes.get(name)); + } + + + /******************************************************************************* ** Getter for backends ** @@ -168,6 +225,28 @@ public class QInstance + /******************************************************************************* + ** Getter for processes + ** + *******************************************************************************/ + public Map getProcesses() + { + return processes; + } + + + + /******************************************************************************* + ** Setter for processes + ** + *******************************************************************************/ + public void setProcesses(Map processes) + { + this.processes = processes; + } + + + /******************************************************************************* ** Getter for hasBeenValidated ** @@ -177,4 +256,5 @@ public class QInstance return hasBeenValidated; } + } diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionInputMetaData.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionInputMetaData.java new file mode 100644 index 00000000..1c17e373 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionInputMetaData.java @@ -0,0 +1,106 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.metadata.processes; + + +import java.util.ArrayList; +import java.util.List; +import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; + + +/******************************************************************************* + ** Meta-Data to define the Input Data for a QQQ Function + ** + *******************************************************************************/ +public class QFunctionInputMetaData +{ + private QRecordListMetaData recordListMetaData; + private List fieldList; + + + + /******************************************************************************* + ** Getter for recordListMetaData + ** + *******************************************************************************/ + public QRecordListMetaData getRecordListMetaData() + { + return recordListMetaData; + } + + + + /******************************************************************************* + ** Setter for recordListMetaData + ** + *******************************************************************************/ + public void setRecordListMetaData(QRecordListMetaData recordListMetaData) + { + this.recordListMetaData = recordListMetaData; + } + + + + /******************************************************************************* + ** Setter for recordListMetaData + ** + *******************************************************************************/ + public QFunctionInputMetaData withRecordListMetaData(QRecordListMetaData recordListMetaData) + { + this.recordListMetaData = recordListMetaData; + return (this); + } + + + + /******************************************************************************* + ** Getter for fieldList + ** + *******************************************************************************/ + public List getFieldList() + { + return fieldList; + } + + + + /******************************************************************************* + ** Setter for fieldList + ** + *******************************************************************************/ + public void setFieldList(List fieldList) + { + this.fieldList = fieldList; + } + + + + /******************************************************************************* + ** Setter for fieldList + ** + *******************************************************************************/ + public QFunctionInputMetaData withFieldList(List fieldList) + { + this.fieldList = fieldList; + return (this); + } + + + + /******************************************************************************* + ** Setter for fieldList + ** + *******************************************************************************/ + public QFunctionInputMetaData addField(QFieldMetaData field) + { + if(this.fieldList == null) + { + this.fieldList = new ArrayList<>(); + } + this.fieldList.add(field); + return (this); + } + +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionMetaData.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionMetaData.java new file mode 100644 index 00000000..6732a404 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionMetaData.java @@ -0,0 +1,227 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.metadata.processes; + + +import com.kingsrook.qqq.backend.core.model.metadata.QCodeReference; + + +/******************************************************************************* + ** Meta-Data to define a function in a QQQ instance. + ** + *******************************************************************************/ +public class QFunctionMetaData +{ + private String name; + private String label; + private QFunctionInputMetaData inputMetaData; + private QFunctionOutputMetaData outputMetaData; + private QCodeReference code; + private QOutputView outputView; + + + + /******************************************************************************* + ** Getter for name + ** + *******************************************************************************/ + public String getName() + { + return name; + } + + + + /******************************************************************************* + ** Setter for name + ** + *******************************************************************************/ + public void setName(String name) + { + this.name = name; + } + + + + /******************************************************************************* + ** Setter for name + ** + *******************************************************************************/ + public QFunctionMetaData withName(String name) + { + this.name = name; + return (this); + } + + + + /******************************************************************************* + ** Getter for label + ** + *******************************************************************************/ + public String getLabel() + { + return label; + } + + + + /******************************************************************************* + ** Setter for label + ** + *******************************************************************************/ + public void setLabel(String label) + { + this.label = label; + } + + + + /******************************************************************************* + ** Setter for label + ** + *******************************************************************************/ + public QFunctionMetaData withLabel(String label) + { + this.label = label; + return (this); + } + + + + /******************************************************************************* + ** Getter for inputData + ** + *******************************************************************************/ + public QFunctionInputMetaData getInputMetaData() + { + return inputMetaData; + } + + + + /******************************************************************************* + ** Setter for inputData + ** + *******************************************************************************/ + public void setInputMetaData(QFunctionInputMetaData inputMetaData) + { + this.inputMetaData = inputMetaData; + } + + + + /******************************************************************************* + ** Setter for inputData + ** + *******************************************************************************/ + public QFunctionMetaData withInputData(QFunctionInputMetaData inputData) + { + this.inputMetaData = inputData; + return (this); + } + + + + /******************************************************************************* + ** Getter for outputData + ** + *******************************************************************************/ + public QFunctionOutputMetaData getOutputMetaData() + { + return outputMetaData; + } + + + + /******************************************************************************* + ** Setter for outputData + ** + *******************************************************************************/ + public void setOutputMetaData(QFunctionOutputMetaData outputMetaData) + { + this.outputMetaData = outputMetaData; + } + + + + /******************************************************************************* + ** Setter for outputData + ** + *******************************************************************************/ + public QFunctionMetaData withOutputMetaData(QFunctionOutputMetaData outputMetaData) + { + this.outputMetaData = outputMetaData; + return(this); + } + + + + /******************************************************************************* + ** Getter for code + ** + *******************************************************************************/ + public QCodeReference getCode() + { + return code; + } + + + + /******************************************************************************* + ** Setter for code + ** + *******************************************************************************/ + public void setCode(QCodeReference code) + { + this.code = code; + } + + + + /******************************************************************************* + ** Setter for code + ** + *******************************************************************************/ + public QFunctionMetaData withCode(QCodeReference code) + { + this.code = code; + return (this); + } + + + + /******************************************************************************* + ** Getter for outputView + ** + *******************************************************************************/ + public QOutputView getOutputView() + { + return outputView; + } + + + + /******************************************************************************* + ** Setter for outputView + ** + *******************************************************************************/ + public void setOutputView(QOutputView outputView) + { + this.outputView = outputView; + } + + + + /******************************************************************************* + ** Setter for outputView + ** + *******************************************************************************/ + public QFunctionMetaData withOutputView(QOutputView outputView) + { + this.outputView = outputView; + return (this); + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionOutputMetaData.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionOutputMetaData.java new file mode 100644 index 00000000..c8e944b8 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QFunctionOutputMetaData.java @@ -0,0 +1,107 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.metadata.processes; + + +import java.util.ArrayList; +import java.util.List; +import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; + + +/******************************************************************************* + ** Meta-Data to define the Output Data for a QQQ Function + ** + *******************************************************************************/ +public class QFunctionOutputMetaData +{ + private QRecordListMetaData recordListMetaData; + private List fieldList; + + + + /******************************************************************************* + ** Getter for recordListMetaData + ** + *******************************************************************************/ + public QRecordListMetaData getRecordListMetaData() + { + return recordListMetaData; + } + + + + /******************************************************************************* + ** Setter for recordListMetaData + ** + *******************************************************************************/ + public void setRecordListMetaData(QRecordListMetaData recordListMetaData) + { + this.recordListMetaData = recordListMetaData; + } + + + + /******************************************************************************* + ** Setter for recordListMetaData + ** + *******************************************************************************/ + public QFunctionOutputMetaData withRecordListMetaData(QRecordListMetaData recordListMetaData) + { + this.recordListMetaData = recordListMetaData; + return (this); + } + + + + /******************************************************************************* + ** Getter for fieldList + ** + *******************************************************************************/ + public List getFieldList() + { + return fieldList; + } + + + + /******************************************************************************* + ** Setter for fieldList + ** + *******************************************************************************/ + public void setFieldList(List fieldList) + { + this.fieldList = fieldList; + } + + + + /******************************************************************************* + ** Setter for fieldList + ** + *******************************************************************************/ + public QFunctionOutputMetaData withFieldList(List fieldList) + { + this.fieldList = fieldList; + return (this); + } + + + + /******************************************************************************* + ** Setter for fieldList + ** + *******************************************************************************/ + public QFunctionOutputMetaData addField(QFieldMetaData field) + { + if(this.fieldList == null) + { + this.fieldList = new ArrayList<>(); + } + this.fieldList.add(field); + return (this); + } + +} + diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QOutputView.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QOutputView.java new file mode 100644 index 00000000..998ff842 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QOutputView.java @@ -0,0 +1,86 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.metadata.processes; + + +/******************************************************************************* + ** Meta-Data to define the Output View for a QQQ Function + ** + *******************************************************************************/ +public class QOutputView +{ + private String messageField; + private QRecordListView recordListView; + + + + /******************************************************************************* + ** Getter for message + ** + *******************************************************************************/ + public String getMessageField() + { + return messageField; + } + + + + /******************************************************************************* + ** Setter for message + ** + *******************************************************************************/ + public void setMessage(String message) + { + this.messageField = message; + } + + + + /******************************************************************************* + ** Setter for message + ** + *******************************************************************************/ + public QOutputView withMessageField(String messageField) + { + this.messageField = messageField; + return(this); + } + + + + /******************************************************************************* + ** Getter for recordListView + ** + *******************************************************************************/ + public QRecordListView getRecordListView() + { + return recordListView; + } + + + + /******************************************************************************* + ** Setter for recordListView + ** + *******************************************************************************/ + public void setRecordListView(QRecordListView recordListView) + { + this.recordListView = recordListView; + } + + + + /******************************************************************************* + ** Setter for recordListView + ** + *******************************************************************************/ + public QOutputView withRecordListView(QRecordListView recordListView) + { + this.recordListView = recordListView; + return(this); + } + + +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QProcessMetaData.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QProcessMetaData.java new file mode 100644 index 00000000..c08fc892 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QProcessMetaData.java @@ -0,0 +1,155 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.metadata.processes; + + +import java.util.ArrayList; +import java.util.List; + + +/******************************************************************************* + ** Meta-Data to define a process in a QQQ instance. + ** + *******************************************************************************/ +public class QProcessMetaData +{ + private String name; + private String tableName; + private List functionList; + + + + /******************************************************************************* + ** Getter for name + ** + *******************************************************************************/ + public String getName() + { + return name; + } + + + + /******************************************************************************* + ** Setter for name + ** + *******************************************************************************/ + public void setName(String name) + { + this.name = name; + } + + + + /******************************************************************************* + ** Setter for name + ** + *******************************************************************************/ + public QProcessMetaData withName(String name) + { + this.name = name; + return (this); + } + + /******************************************************************************* + ** Getter for tableName + ** + *******************************************************************************/ + public String getTableName() + { + return tableName; + } + + + + /******************************************************************************* + ** Setter for tableName + ** + *******************************************************************************/ + public void setTableName(String tableName) + { + this.tableName = tableName; + } + + + + /******************************************************************************* + ** Setter for tableName + ** + *******************************************************************************/ + public QProcessMetaData withTableName(String tableName) + { + this.tableName = tableName; + return (this); + } + + + + /******************************************************************************* + ** Getter for functionList + ** + *******************************************************************************/ + public List getFunctionList() + { + return functionList; + } + + + + /******************************************************************************* + ** Setter for functionList + ** + *******************************************************************************/ + public QProcessMetaData withFunctionList(List functionList) + { + this.functionList = functionList; + return (this); + } + + + + /******************************************************************************* + ** Setter for functionList + ** + *******************************************************************************/ + public QProcessMetaData addFunction(QFunctionMetaData function) + { + if(this.functionList == null) + { + this.functionList = new ArrayList<>(); + } + this.functionList.add(function); + return (this); + } + + + + /******************************************************************************* + ** Setter for functionList + ** + *******************************************************************************/ + public void setFunctionList(List functionList) + { + this.functionList = functionList; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public QFunctionMetaData getFunction(String functionName) + { + for(QFunctionMetaData function : functionList) + { + if(function.getName().equals(functionName)) + { + return (function); + } + } + + return (null); + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QRecordListMetaData.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QRecordListMetaData.java new file mode 100644 index 00000000..c28c2bd1 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QRecordListMetaData.java @@ -0,0 +1,123 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.metadata.processes; + + +import java.util.LinkedHashMap; +import java.util.Map; +import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; + + +/******************************************************************************* + ** + *******************************************************************************/ +public class QRecordListMetaData +{ + private String tableName; + private Map fields; + + + + /******************************************************************************* + ** + *******************************************************************************/ + public QFieldMetaData getField(String fieldName) + { + if(fields == null) + { + return (null); + } + + QFieldMetaData field = getFields().get(fieldName); + if(field == null) + { + throw (new IllegalArgumentException("Field [" + fieldName + "] was not found.")); + } + + return (field); + } + + + + /******************************************************************************* + ** Getter for tableName + ** + *******************************************************************************/ + public String getTableName() + { + return tableName; + } + + + + /******************************************************************************* + ** Setter for tableName + ** + *******************************************************************************/ + public void setTableName(String tableName) + { + this.tableName = tableName; + } + + + + /******************************************************************************* + ** Setter for tableName + ** + *******************************************************************************/ + public QRecordListMetaData withTableName(String tableName) + { + this.tableName = tableName; + return (this); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public Map getFields() + { + return fields; + } + + + + /******************************************************************************* + ** Setter for fields + ** + *******************************************************************************/ + public void setFields(Map fields) + { + this.fields = fields; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public QRecordListMetaData withFields(Map fields) + { + this.fields = fields; + return (this); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public QRecordListMetaData addField(QFieldMetaData field) + { + if(this.fields == null) + { + this.fields = new LinkedHashMap<>(); + } + this.fields.put(field.getName(), field); + return (this); + } + +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QRecordListView.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QRecordListView.java new file mode 100644 index 00000000..0bb10131 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/processes/QRecordListView.java @@ -0,0 +1,70 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.model.metadata.processes; + + +import java.util.ArrayList; +import java.util.List; + + +/******************************************************************************* + ** Meta-Data to define how to view a qqq record list (e.g., what fields to show). + ** + *******************************************************************************/ +public class QRecordListView +{ + private List fieldNames; + + + + /******************************************************************************* + ** Getter for fieldNames + ** + *******************************************************************************/ + public List getFieldNames() + { + return fieldNames; + } + + + + /******************************************************************************* + ** Setter for fieldNames + ** + *******************************************************************************/ + public void setFieldNames(List fieldNames) + { + this.fieldNames = fieldNames; + } + + + + /******************************************************************************* + ** Setter for fieldNames + ** + *******************************************************************************/ + public QRecordListView withFieldNames(List fieldNames) + { + this.fieldNames = fieldNames; + return (this); + } + + + + /******************************************************************************* + ** Setter for fieldNames + ** + *******************************************************************************/ + public QRecordListView addFieldName(String fieldName) + { + if(this.fieldNames == null) + { + this.fieldNames = new ArrayList<>(); + } + this.fieldNames.add(fieldName); + return (this); + } + +} diff --git a/src/test/java/com/kingsrook/qqq/backend/core/actions/RunFunctionTest.java b/src/test/java/com/kingsrook/qqq/backend/core/actions/RunFunctionTest.java new file mode 100644 index 00000000..3968e267 --- /dev/null +++ b/src/test/java/com/kingsrook/qqq/backend/core/actions/RunFunctionTest.java @@ -0,0 +1,102 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . All Rights Reserved. + */ + +package com.kingsrook.qqq.backend.core.actions; + + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.callbacks.QProcessCallback; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionRequest; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunFunctionResult; +import com.kingsrook.qqq.backend.core.model.actions.query.QQueryFilter; +import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; +import com.kingsrook.qqq.backend.core.utils.TestUtils; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/******************************************************************************* + ** + *******************************************************************************/ +public class RunFunctionTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + public void test() throws QException + { + TestCallback callback = new TestCallback(); + RunFunctionRequest request = new RunFunctionRequest(TestUtils.defineInstance()); + request.setProcessName("greet"); + request.setFunctionName("prepare"); + request.setCallback(callback); + RunFunctionResult result = new RunFunctionAction().execute(request); + assertNotNull(result); + assertNull(result.getError()); + assertTrue(result.getRecords().stream().allMatch(r -> r.getValues().containsKey("mockValue")), "records should have a mock value"); + assertTrue(result.getValues().containsKey("mockValue"), "result object should have a mock value"); + assertEquals("ABC", result.getValues().get("greetingPrefix"), "result object should have value from our callback"); + assertTrue(callback.wasCalledForQueryFilter, "callback was used for query filter"); + assertTrue(callback.wasCalledForFieldValues, "callback was used for field values"); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private static class TestCallback implements QProcessCallback + { + private boolean wasCalledForQueryFilter = false; + private boolean wasCalledForFieldValues = false; + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public QQueryFilter getQueryFilter() + { + wasCalledForQueryFilter = true; + return (new QQueryFilter()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public Map getFieldValues(List fields) + { + wasCalledForFieldValues = true; + Map rs = new HashMap<>(); + for(QFieldMetaData field : fields) + { + rs.put(field.getName(), switch(field.getType()) + { + case STRING -> "ABC"; + case INTEGER -> 42; + case DECIMAL -> new BigDecimal("47"); + case DATE, DATE_TIME -> null; + case TEXT -> """ + ABC + XYZ"""; + case HTML -> "Oh my"; + case PASSWORD -> "myPa**word"; + }); + } + return (rs); + } + } +}