mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
QQQ-14 Initial version of running processes in javalin
This commit is contained in:
@ -33,9 +33,11 @@ import com.kingsrook.qqq.backend.core.actions.DeleteAction;
|
|||||||
import com.kingsrook.qqq.backend.core.actions.InsertAction;
|
import com.kingsrook.qqq.backend.core.actions.InsertAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.MetaDataAction;
|
import com.kingsrook.qqq.backend.core.actions.MetaDataAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.QueryAction;
|
import com.kingsrook.qqq.backend.core.actions.QueryAction;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.RunProcessAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.TableMetaDataAction;
|
import com.kingsrook.qqq.backend.core.actions.TableMetaDataAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.UpdateAction;
|
import com.kingsrook.qqq.backend.core.actions.UpdateAction;
|
||||||
import com.kingsrook.qqq.backend.core.adapters.QInstanceAdapter;
|
import com.kingsrook.qqq.backend.core.adapters.QInstanceAdapter;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractQRequest;
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractQRequest;
|
||||||
@ -47,17 +49,21 @@ import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataRequest;
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataResult;
|
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataResult;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.metadata.table.TableMetaDataRequest;
|
import com.kingsrook.qqq.backend.core.model.actions.metadata.table.TableMetaDataRequest;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.metadata.table.TableMetaDataResult;
|
import com.kingsrook.qqq.backend.core.model.actions.metadata.table.TableMetaDataResult;
|
||||||
|
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.QQueryFilter;
|
import com.kingsrook.qqq.backend.core.model.actions.query.QQueryFilter;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.query.QueryRequest;
|
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.actions.query.QueryResult;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateRequest;
|
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateRequest;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateResult;
|
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateResult;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
import com.kingsrook.qqq.backend.core.modules.QAuthenticationModuleDispatcher;
|
import com.kingsrook.qqq.backend.core.modules.QAuthenticationModuleDispatcher;
|
||||||
import com.kingsrook.qqq.backend.core.modules.interfaces.QAuthenticationModuleInterface;
|
import com.kingsrook.qqq.backend.core.modules.interfaces.QAuthenticationModuleInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.ExceptionUtils;
|
import com.kingsrook.qqq.backend.core.utils.ExceptionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
@ -84,6 +90,7 @@ import static io.javalin.apibuilder.ApiBuilder.put;
|
|||||||
public class QJavalinImplementation
|
public class QJavalinImplementation
|
||||||
{
|
{
|
||||||
private static final Logger LOG = LogManager.getLogger(QJavalinImplementation.class);
|
private static final Logger LOG = LogManager.getLogger(QJavalinImplementation.class);
|
||||||
|
|
||||||
private static final int SESSION_COOKIE_AGE = 60 * 60 * 24;
|
private static final int SESSION_COOKIE_AGE = 60 * 60 * 24;
|
||||||
|
|
||||||
private static QInstance qInstance;
|
private static QInstance qInstance;
|
||||||
@ -154,6 +161,7 @@ public class QJavalinImplementation
|
|||||||
path("/:table", () ->
|
path("/:table", () ->
|
||||||
{
|
{
|
||||||
get("", QJavalinImplementation::tableMetaData);
|
get("", QJavalinImplementation::tableMetaData);
|
||||||
|
// todo - process meta data - just under tables? or top-level too? maybe move tables to be under /tables/?
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
path("/data", () ->
|
path("/data", () ->
|
||||||
@ -172,6 +180,14 @@ public class QJavalinImplementation
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
path("/processes", () ->
|
||||||
|
{
|
||||||
|
path("/:process", () ->
|
||||||
|
{
|
||||||
|
get("/init", QJavalinImplementation::processInit);
|
||||||
|
get("/step", QJavalinImplementation::processStep);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,7 +438,6 @@ public class QJavalinImplementation
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.warn("Exception in javalin request", e);
|
LOG.warn("Exception in javalin request", e);
|
||||||
e.printStackTrace();
|
|
||||||
context.status(HttpStatus.INTERNAL_SERVER_ERROR_500)
|
context.status(HttpStatus.INTERNAL_SERVER_ERROR_500)
|
||||||
.result("{\"error\":\"" + e.getClass().getSimpleName() + " (" + e.getMessage() + ")\"}");
|
.result("{\"error\":\"" + e.getClass().getSimpleName() + " (" + e.getMessage() + ")\"}");
|
||||||
}
|
}
|
||||||
@ -462,4 +477,68 @@ public class QJavalinImplementation
|
|||||||
|
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Init a process (named in path param :process)
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static void processInit(Context context) throws QException
|
||||||
|
{
|
||||||
|
RunProcessRequest runProcessRequest = new RunProcessRequest(qInstance);
|
||||||
|
setupSession(context, runProcessRequest);
|
||||||
|
runProcessRequest.setProcessName(context.pathParam("process"));
|
||||||
|
runProcessRequest.setCallback(new QJavalinProcessCallback());
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// take values from query-string params, and put them into the run process request //
|
||||||
|
// todo - better from POST body, or with a "field-" type of prefix?? //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
for(Map.Entry<String, List<String>> queryParam : context.queryParamMap().entrySet())
|
||||||
|
{
|
||||||
|
String fieldName = queryParam.getKey();
|
||||||
|
List<String> values = queryParam.getValue();
|
||||||
|
if(CollectionUtils.nullSafeHasContents(values))
|
||||||
|
{
|
||||||
|
runProcessRequest.addValue(fieldName, values.get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
// run the process //
|
||||||
|
// todo - async? some "job id" to return to caller? //
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
LOG.info("Running process [" + runProcessRequest.getProcessName() + "]");
|
||||||
|
RunProcessResult runProcessResult = new RunProcessAction().execute(runProcessRequest);
|
||||||
|
LOG.info("Process result error? " + runProcessResult.getError());
|
||||||
|
for(QFieldMetaData outputField : qInstance.getProcess(runProcessRequest.getProcessName()).getOutputFields())
|
||||||
|
{
|
||||||
|
LOG.info("Process result output value: " + outputField.getName() + ": " + runProcessResult.getValues().get(outputField.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> resultForCaller = new HashMap<>();
|
||||||
|
resultForCaller.put("error", runProcessResult.getError());
|
||||||
|
resultForCaller.put("values", runProcessResult.getValues());
|
||||||
|
context.result(JsonUtils.toJson(resultForCaller));
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
handleException(context, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Run a step in a process (named in path param :process)
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static void processStep(Context context)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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.javalin;
|
||||||
|
|
||||||
|
|
||||||
|
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.query.QQueryFilter;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class QJavalinProcessCallback implements QProcessCallback
|
||||||
|
{
|
||||||
|
private static final Logger LOG = LogManager.getLogger(QJavalinProcessCallback.class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public QQueryFilter getQueryFilter()
|
||||||
|
{
|
||||||
|
LOG.warn("Getting a query filter in javalin is NOT yet implemented");
|
||||||
|
return (new QQueryFilter());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public Map<String, Serializable> getFieldValues(List<QFieldMetaData> fields)
|
||||||
|
{
|
||||||
|
LOG.warn("Getting field values in javalin is NOT yet implemented");
|
||||||
|
return (new HashMap<>());
|
||||||
|
}
|
||||||
|
}
|
@ -285,4 +285,43 @@ class QJavalinImplementationTest
|
|||||||
assertEquals(4, rowsFound);
|
assertEquals(4, rowsFound);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** test running a process
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test_processGreetInit() throws Exception
|
||||||
|
{
|
||||||
|
HttpResponse<String> response = Unirest.get(BASE_URL + "/processes/greet/init")
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.asString();
|
||||||
|
|
||||||
|
assertEquals(200, response.getStatus());
|
||||||
|
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||||
|
assertNotNull(jsonObject);
|
||||||
|
assertEquals("null X null", jsonObject.getJSONObject("values").getString("outputMessage"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** test running a process with field values on the query string
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test_processGreetInitWithQueryValues() throws Exception
|
||||||
|
{
|
||||||
|
HttpResponse<String> response = Unirest.get(BASE_URL + "/processes/greet/init?greetingPrefix=Hey&greetingSuffix=Jude")
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.asString();
|
||||||
|
|
||||||
|
assertEquals(200, response.getStatus());
|
||||||
|
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||||
|
assertNotNull(jsonObject);
|
||||||
|
assertEquals("Hey X Jude", jsonObject.getJSONObject("values").getString("outputMessage"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,13 +25,23 @@ package com.kingsrook.qqq.backend.javalin;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.interfaces.mock.MockFunctionBody;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.QCodeType;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QCodeUsage;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QFieldType;
|
import com.kingsrook.qqq.backend.core.model.metadata.QFieldType;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.module.rdbms.RDBMSBackendMetaData;
|
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.QFunctionOutputMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QOutputView;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListView;
|
||||||
|
import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData;
|
||||||
import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager;
|
import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager;
|
||||||
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
|
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
@ -53,7 +63,7 @@ public class TestUtils
|
|||||||
public static void primeTestDatabase() throws Exception
|
public static void primeTestDatabase() throws Exception
|
||||||
{
|
{
|
||||||
ConnectionManager connectionManager = new ConnectionManager();
|
ConnectionManager connectionManager = new ConnectionManager();
|
||||||
Connection connection = connectionManager.getConnection(new RDBMSBackendMetaData(TestUtils.defineBackend()));
|
Connection connection = connectionManager.getConnection(TestUtils.defineBackend());
|
||||||
InputStream primeTestDatabaseSqlStream = TestUtils.class.getResourceAsStream("/prime-test-database.sql");
|
InputStream primeTestDatabaseSqlStream = TestUtils.class.getResourceAsStream("/prime-test-database.sql");
|
||||||
assertNotNull(primeTestDatabaseSqlStream);
|
assertNotNull(primeTestDatabaseSqlStream);
|
||||||
List<String> lines = (List<String>) IOUtils.readLines(primeTestDatabaseSqlStream);
|
List<String> lines = (List<String>) IOUtils.readLines(primeTestDatabaseSqlStream);
|
||||||
@ -74,7 +84,7 @@ public class TestUtils
|
|||||||
public static void runTestSql(String sql, QueryManager.ResultSetProcessor resultSetProcessor) throws Exception
|
public static void runTestSql(String sql, QueryManager.ResultSetProcessor resultSetProcessor) throws Exception
|
||||||
{
|
{
|
||||||
ConnectionManager connectionManager = new ConnectionManager();
|
ConnectionManager connectionManager = new ConnectionManager();
|
||||||
Connection connection = connectionManager.getConnection(new RDBMSBackendMetaData(defineBackend()));
|
Connection connection = connectionManager.getConnection(defineBackend());
|
||||||
QueryManager.executeStatement(connection, sql, resultSetProcessor);
|
QueryManager.executeStatement(connection, sql, resultSetProcessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +100,7 @@ public class TestUtils
|
|||||||
qInstance.setAuthentication(defineAuthentication());
|
qInstance.setAuthentication(defineAuthentication());
|
||||||
qInstance.addBackend(defineBackend());
|
qInstance.addBackend(defineBackend());
|
||||||
qInstance.addTable(defineTablePerson());
|
qInstance.addTable(defineTablePerson());
|
||||||
|
qInstance.addProcess(defineProcessGreetPeople());
|
||||||
return (qInstance);
|
return (qInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,16 +123,16 @@ public class TestUtils
|
|||||||
** Define the h2 rdbms backend
|
** Define the h2 rdbms backend
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static QBackendMetaData defineBackend()
|
public static RDBMSBackendMetaData defineBackend()
|
||||||
{
|
{
|
||||||
return new QBackendMetaData()
|
RDBMSBackendMetaData rdbmsBackendMetaData = new RDBMSBackendMetaData()
|
||||||
.withName("default")
|
.withVendor("h2")
|
||||||
.withType("rdbms")
|
.withHostName("mem")
|
||||||
.withValue("vendor", "h2")
|
.withDatabaseName("test_database")
|
||||||
.withValue("hostName", "mem")
|
.withUsername("sa")
|
||||||
.withValue("databaseName", "test_database")
|
.withPassword("");
|
||||||
.withValue("username", "sa")
|
rdbmsBackendMetaData.setName("default");
|
||||||
.withValue("password", "");
|
return (rdbmsBackendMetaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -146,4 +157,38 @@ public class TestUtils
|
|||||||
.withField(new QFieldMetaData("email", QFieldType.STRING));
|
.withField(new QFieldMetaData("email", QFieldType.STRING));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Define the 'greet people' process
|
||||||
|
*******************************************************************************/
|
||||||
|
private static QProcessMetaData defineProcessGreetPeople()
|
||||||
|
{
|
||||||
|
return new QProcessMetaData()
|
||||||
|
.withName("greet")
|
||||||
|
.withTableName("person")
|
||||||
|
.addFunction(new QFunctionMetaData()
|
||||||
|
.withName("prepare")
|
||||||
|
.withCode(new QCodeReference()
|
||||||
|
.withName(MockFunctionBody.class.getName())
|
||||||
|
.withCodeType(QCodeType.JAVA)
|
||||||
|
.withCodeUsage(QCodeUsage.FUNCTION)) // todo - needed, or implied in this context?
|
||||||
|
.withInputData(new QFunctionInputMetaData()
|
||||||
|
.withRecordListMetaData(new QRecordListMetaData().withTableName("person"))
|
||||||
|
.withFieldList(List.of(
|
||||||
|
new QFieldMetaData("greetingPrefix", QFieldType.STRING),
|
||||||
|
new QFieldMetaData("greetingSuffix", QFieldType.STRING)
|
||||||
|
)))
|
||||||
|
.withOutputMetaData(new QFunctionOutputMetaData()
|
||||||
|
.withRecordListMetaData(new QRecordListMetaData()
|
||||||
|
.withTableName("person")
|
||||||
|
.addField(new QFieldMetaData("fullGreeting", QFieldType.STRING))
|
||||||
|
)
|
||||||
|
.withFieldList(List.of(new QFieldMetaData("outputMessage", QFieldType.STRING))))
|
||||||
|
.withOutputView(new QOutputView()
|
||||||
|
.withMessageField("outputMessage")
|
||||||
|
.withRecordListView(new QRecordListView().withFieldNames(List.of("id", "firstName", "lastName", "fullGreeting"))))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user