diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 00000000..0ef02745
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,77 @@
+version: 2.1
+
+executors:
+ java17:
+ docker:
+ - image: 'cimg/openjdk:17.0'
+ resource_class: small
+
+orbs:
+ slack: circleci/slack@4.10.1
+
+commands:
+ run_maven:
+ parameters:
+ maven_subcommand:
+ default: test
+ type: string
+ steps:
+ - checkout
+ - restore_cache:
+ keys:
+ - v1-dependencies-{{ checksum "pom.xml" }}
+ - run:
+ name: Run Maven
+ command: |
+ mvn -s .circleci/mvn-settings.xml << parameters.maven_subcommand >>
+ - run:
+ name: Save test results
+ command: |
+ mkdir -p ~/test-results/junit/
+ find . -type f -regex ".*/target/surefire-reports/.*xml" -exec cp {} ~/test-results/junit/ \;
+ when: always
+ - store_test_results:
+ path: ~/test-results
+ - save_cache:
+ paths:
+ - ~/.m2
+ key: v1-dependencies-{{ checksum "pom.xml" }}
+
+jobs:
+ mvn_test:
+ executor: java17
+ steps:
+ - run_maven:
+ maven_subcommand: test
+ - slack/notify:
+ event: fail
+
+ mvn_deploy:
+ executor: java17
+ steps:
+ - run_maven:
+ maven_subcommand: deploy
+ - slack/notify:
+ event: always
+
+workflows:
+ test_only:
+ jobs:
+ - mvn_test:
+ context: [ qqq-maven-registry-credentials, kingsrook-slack ]
+ filters:
+ branches:
+ ignore: /dev/
+ tags:
+ ignore: /(version|snapshot)-.*/
+
+ deploy:
+ jobs:
+ - mvn_deploy:
+ context: [ qqq-maven-registry-credentials, kingsrook-slack ]
+ filters:
+ branches:
+ only: /dev/
+ tags:
+ only: /(version|snapshot)-.*/
+
diff --git a/.circleci/mvn-settings.xml b/.circleci/mvn-settings.xml
new file mode 100644
index 00000000..b2a345f0
--- /dev/null
+++ b/.circleci/mvn-settings.xml
@@ -0,0 +1,9 @@
+
+
+
+ github-qqq-maven-registry
+ ${env.QQQ_MAVEN_REGISTRY_USERNAME}
+ ${env.QQQ_MAVEN_REGISTRY_PASSWORD}
+
+
+
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
deleted file mode 100644
index 80d00dfd..00000000
--- a/.github/workflows/maven.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
-# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
-
-name: Java CI with Maven
-
-on:
- push:
- branches: [ main ]
- pull_request:
- branches: [ main ]
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v2
- - name: Set up JDK 17
- uses: actions/setup-java@v2
- with:
- java-version: '17'
- distribution: 'adopt'
- cache: maven
- - name: maven-settings-xml-action
- uses: whelk-io/maven-settings-xml-action@v20
- with:
- servers: '[{ "id": "github-qqq-maven-registry", "username": "${{ secrets.QQQ_MAVEN_REGISTRY_USERNAME }}", "password": "${{ secrets.QQQ_MAVEN_REGISTRY_PASSWORD }}" }]'
- repositories: '[{ "id": "github-qqq-maven-registry", "url": "https://maven.pkg.github.com/Kingsrook/qqq-maven-registry", "snapshots": { "enabled": "true" }}]'
- - name: Build with Maven
- run: mvn -B package --file pom.xml
- - name: Publish to GitHub Packages Apache Maven
- run: mvn deploy
- env:
- GITHUB_TOKEN: ${{ github.token }}
diff --git a/README.md b/README.md
index cffb2382..3920b9a6 100644
--- a/README.md
+++ b/README.md
@@ -5,8 +5,7 @@ This is a qqq middleware module, providing [javalin](https://javalin.io) access
QQQ - Low-code Application Framework for Engineers. \
Copyright (C) 2022. Kingsrook, LLC \
651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States \
-contact@kingsrook.com
-https://github.com/Kingsrook/intellij-commentator-plugin
+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
diff --git a/checkstyle.xml b/checkstyle.xml
index dbaa3479..76f872ed 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -46,6 +46,7 @@
-->
+
@@ -171,7 +172,7 @@
-
+
-
+
4.0.0
com.kingsrook.qqq
qqq-middleware-javalin
- 0.0-SNAPSHOT
+ 0.0.0
+
+
+ scm:git:git@github.com:Kingsrook/qqq-middleware-javalin.git
+ scm:git:git@github.com:Kingsrook/qqq-middleware-javalin.git
+ HEAD
+
@@ -47,12 +51,12 @@
com.kingsrook.qqq
qqq-backend-core
- 0.0-SNAPSHOT
+ 0.0.0
com.kingsrook.qqq
qqq-backend-module-rdbms
- 0.0-SNAPSHOT
+ 0.0.0
test
@@ -71,23 +75,13 @@
com.h2database
h2
- 1.4.197
+ 2.1.210
test
org.slf4j
slf4j-simple
- 1.7.30
-
-
- org.slf4j
- slf4j-api
- 1.7.30
-
-
- org.slf4j
- slf4j-simple
- 1.7.30
+ 1.7.36
@@ -99,17 +93,17 @@
org.apache.logging.log4j
log4j-api
- 2.15.0
+ 2.17.2
org.apache.logging.log4j
log4j-core
- 2.15.0
+ 2.17.2
org.junit.jupiter
junit-jupiter-engine
- 5.8.1
+ 5.8.2
test
@@ -165,13 +159,28 @@
+
+ com.amashchenko.maven.plugin
+ gitflow-maven-plugin
+ 1.18.0
+
+
+ main
+ dev
+ version-
+
+ true
+ install
+ true
+ 1
+
+
-
- github
+ github-qqq-maven-registry
GitHub QQQ Maven Registry
https://maven.pkg.github.com/Kingsrook/qqq-maven-registry
diff --git a/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementation.java b/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementation.java
index ca33f553..6c68564d 100644
--- a/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementation.java
+++ b/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementation.java
@@ -29,13 +29,19 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import com.kingsrook.qqq.backend.core.actions.DeleteAction;
import com.kingsrook.qqq.backend.core.actions.InsertAction;
import com.kingsrook.qqq.backend.core.actions.MetaDataAction;
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.UpdateAction;
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.QUserFacingException;
import com.kingsrook.qqq.backend.core.model.actions.AbstractQRequest;
@@ -47,17 +53,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.table.TableMetaDataRequest;
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.QueryRequest;
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.UpdateResult;
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.QTableMetaData;
import com.kingsrook.qqq.backend.core.model.session.QSession;
import com.kingsrook.qqq.backend.core.modules.QAuthenticationModuleDispatcher;
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.JsonUtils;
import com.kingsrook.qqq.backend.core.utils.StringUtils;
@@ -84,6 +94,7 @@ import static io.javalin.apibuilder.ApiBuilder.put;
public class QJavalinImplementation
{
private static final Logger LOG = LogManager.getLogger(QJavalinImplementation.class);
+
private static final int SESSION_COOKIE_AGE = 60 * 60 * 24;
private static QInstance qInstance;
@@ -154,6 +165,7 @@ public class QJavalinImplementation
path("/:table", () ->
{
get("", QJavalinImplementation::tableMetaData);
+ // todo - process meta data - just under tables? or top-level too? maybe move tables to be under /tables/?
});
});
path("/data", () ->
@@ -172,6 +184,14 @@ public class QJavalinImplementation
});
});
});
+ path("/processes", () ->
+ {
+ path("/:process", () ->
+ {
+ get("/init", QJavalinImplementation::processInit);
+ get("/step", QJavalinImplementation::processStep);
+ });
+ });
});
}
@@ -183,7 +203,7 @@ public class QJavalinImplementation
private static void setupSession(Context context, AbstractQRequest request) throws QModuleDispatchException
{
QAuthenticationModuleDispatcher qAuthenticationModuleDispatcher = new QAuthenticationModuleDispatcher();
- QAuthenticationModuleInterface authenticationModule = qAuthenticationModuleDispatcher.getQModule(request.getAuthenticationMetaData());
+ QAuthenticationModuleInterface authenticationModule = qAuthenticationModuleDispatcher.getQModule(request.getAuthenticationMetaData());
// todo - does this need some per-provider logic actually? mmm...
Map authenticationContext = new HashMap<>();
@@ -203,7 +223,7 @@ public class QJavalinImplementation
{
try
{
- String table = context.pathParam("table");
+ String table = context.pathParam("table");
List primaryKeys = new ArrayList<>();
primaryKeys.add(context.pathParam("primaryKey"));
@@ -232,9 +252,9 @@ public class QJavalinImplementation
{
try
{
- String table = context.pathParam("table");
+ String table = context.pathParam("table");
List recordList = new ArrayList<>();
- QRecord record = new QRecord();
+ QRecord record = new QRecord();
record.setTableName(table);
recordList.add(record);
@@ -276,9 +296,9 @@ public class QJavalinImplementation
{
try
{
- String table = context.pathParam("table");
+ String table = context.pathParam("table");
List recordList = new ArrayList<>();
- QRecord record = new QRecord();
+ QRecord record = new QRecord();
record.setTableName(table);
recordList.add(record);
@@ -422,7 +442,6 @@ public class QJavalinImplementation
else
{
LOG.warn("Exception in javalin request", e);
- e.printStackTrace();
context.status(HttpStatus.INTERNAL_SERVER_ERROR_500)
.result("{\"error\":\"" + e.getClass().getSimpleName() + " (" + e.getMessage() + ")\"}");
}
@@ -462,4 +481,88 @@ public class QJavalinImplementation
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> queryParam : context.queryParamMap().entrySet())
+ {
+ String fieldName = queryParam.getKey();
+ List values = queryParam.getValue();
+ if(CollectionUtils.nullSafeHasContents(values))
+ {
+ runProcessRequest.addValue(fieldName, values.get(0));
+ }
+ }
+
+ try
+ {
+ ////////////////////////////////////////////////
+ // run the process //
+ // todo - some "job id" to return to caller? //
+ ////////////////////////////////////////////////
+ CompletableFuture future = CompletableFuture.supplyAsync(() ->
+ {
+ try
+ {
+ 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()));
+ }
+ return (runProcessResult);
+ }
+ catch(Exception e)
+ {
+ LOG.error("Error running future for process", e);
+ throw (new CompletionException(e));
+ }
+ });
+
+ Map resultForCaller = new HashMap<>();
+ try
+ {
+ RunProcessResult runProcessResult = future.get(3, TimeUnit.SECONDS);
+ resultForCaller.put("error", runProcessResult.getError());
+ resultForCaller.put("values", runProcessResult.getValues());
+ }
+ catch(TimeoutException te)
+ {
+ resultForCaller.put("jobId", "Job is running asynchronously... job id available in a later version.");
+ }
+ 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)
+ {
+
+ }
+
}
diff --git a/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessCallback.java b/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessCallback.java
new file mode 100644
index 00000000..328a66b2
--- /dev/null
+++ b/src/main/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessCallback.java
@@ -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 .
+ */
+
+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 getFieldValues(List fields)
+ {
+ LOG.warn("Getting field values in javalin is NOT yet implemented");
+ return (new HashMap<>());
+ }
+}
diff --git a/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementationTest.java b/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementationTest.java
index 5f17251a..f8376c5c 100644
--- a/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementationTest.java
+++ b/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinImplementationTest.java
@@ -203,6 +203,7 @@ class QJavalinImplementationTest
Map body = new HashMap<>();
body.put("firstName", "Bobby");
body.put("lastName", "Hull");
+ body.put("email", "bobby@hull.com");
HttpResponse response = Unirest.post(BASE_URL + "/data/person")
.header("Content-Type", "application/json")
@@ -284,4 +285,43 @@ class QJavalinImplementationTest
assertEquals(4, rowsFound);
}));
}
+
+
+
+ /*******************************************************************************
+ ** test running a process
+ **
+ *******************************************************************************/
+ @Test
+ public void test_processGreetInit() throws Exception
+ {
+ HttpResponse 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 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"));
+ }
+
}
diff --git a/src/test/java/com/kingsrook/qqq/backend/javalin/TestUtils.java b/src/test/java/com/kingsrook/qqq/backend/javalin/TestUtils.java
index 6d3c4e8f..a25a5104 100644
--- a/src/test/java/com/kingsrook/qqq/backend/javalin/TestUtils.java
+++ b/src/test/java/com/kingsrook/qqq/backend/javalin/TestUtils.java
@@ -25,13 +25,23 @@ package com.kingsrook.qqq.backend.javalin;
import java.io.InputStream;
import java.sql.Connection;
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.QInstance;
-import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
+import com.kingsrook.qqq.backend.core.model.metadata.QCodeReference;
+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.QFieldType;
+import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
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.QueryManager;
import org.apache.commons.io.IOUtils;
@@ -52,11 +62,12 @@ public class TestUtils
@SuppressWarnings("unchecked")
public static void primeTestDatabase() throws Exception
{
- ConnectionManager connectionManager = new ConnectionManager();
- Connection connection = connectionManager.getConnection(new RDBMSBackendMetaData(TestUtils.defineBackend()));
- InputStream primeTestDatabaseSqlStream = TestUtils.class.getResourceAsStream("/prime-test-database.sql");
+ ConnectionManager connectionManager = new ConnectionManager();
+ Connection connection = connectionManager.getConnection(TestUtils.defineBackend());
+ InputStream primeTestDatabaseSqlStream = TestUtils.class.getResourceAsStream("/prime-test-database.sql");
assertNotNull(primeTestDatabaseSqlStream);
List lines = (List) IOUtils.readLines(primeTestDatabaseSqlStream);
+ lines = lines.stream().filter(line -> !line.startsWith("-- ")).toList();
String joinedSQL = String.join("\n", lines);
for(String sql : joinedSQL.split(";"))
{
@@ -73,7 +84,7 @@ public class TestUtils
public static void runTestSql(String sql, QueryManager.ResultSetProcessor resultSetProcessor) throws Exception
{
ConnectionManager connectionManager = new ConnectionManager();
- Connection connection = connectionManager.getConnection(new RDBMSBackendMetaData(defineBackend()));
+ Connection connection = connectionManager.getConnection(defineBackend());
QueryManager.executeStatement(connection, sql, resultSetProcessor);
}
@@ -89,6 +100,7 @@ public class TestUtils
qInstance.setAuthentication(defineAuthentication());
qInstance.addBackend(defineBackend());
qInstance.addTable(defineTablePerson());
+ qInstance.addProcess(defineProcessGreetPeople());
return (qInstance);
}
@@ -111,16 +123,16 @@ public class TestUtils
** Define the h2 rdbms backend
**
*******************************************************************************/
- public static QBackendMetaData defineBackend()
+ public static RDBMSBackendMetaData defineBackend()
{
- return new QBackendMetaData()
- .withName("default")
- .withType("rdbms")
- .withValue("vendor", "h2")
- .withValue("hostName", "mem")
- .withValue("databaseName", "test_database")
- .withValue("username", "sa")
- .withValue("password", "");
+ RDBMSBackendMetaData rdbmsBackendMetaData = new RDBMSBackendMetaData()
+ .withVendor("h2")
+ .withHostName("mem")
+ .withDatabaseName("test_database")
+ .withUsername("sa")
+ .withPassword("");
+ rdbmsBackendMetaData.setName("default");
+ return (rdbmsBackendMetaData);
}
@@ -145,4 +157,38 @@ public class TestUtils
.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"))))
+ );
+ }
+
}
diff --git a/src/test/resources/prime-test-database.sql b/src/test/resources/prime-test-database.sql
index 6227f249..be858987 100644
--- a/src/test/resources/prime-test-database.sql
+++ b/src/test/resources/prime-test-database.sql
@@ -1,28 +1,28 @@
-/*
- * 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 .
- */
+--
+-- 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 .
+--
DROP TABLE IF EXISTS person;
CREATE TABLE person
(
- id SERIAL,
+ id INT AUTO_INCREMENT,
create_date TIMESTAMP DEFAULT now(),
modify_date TIMESTAMP DEFAULT now(),