mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Checkpoint: Added Update (edit) action; Stub of PossibleValues, displayValues; Load definition from JSON
This commit is contained in:
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2021. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.actions;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
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.modules.QBackendModuleDispatcher;
|
||||||
|
import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Action to update one or more records.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class UpdateAction
|
||||||
|
{
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public UpdateResult execute(UpdateRequest updateRequest) throws QException
|
||||||
|
{
|
||||||
|
ActionHelper.validateSession(updateRequest);
|
||||||
|
|
||||||
|
QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher();
|
||||||
|
QBackendModuleInterface qModule = qBackendModuleDispatcher.getQModule(updateRequest.getBackend());
|
||||||
|
// todo pre-customization - just get to modify the request?
|
||||||
|
UpdateResult updateResult = qModule.getUpdateInterface().execute(updateRequest);
|
||||||
|
// todo post-customization - can do whatever w/ the result if you want
|
||||||
|
return updateResult;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2022. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.adapters;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Methods for adapting qInstances to serialized (string) formats (e.g., json),
|
||||||
|
** and vice versa.
|
||||||
|
*******************************************************************************/
|
||||||
|
public class QInstanceAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Convert a qInstance to JSON.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public String qInstanceToJson(QInstance qInstance)
|
||||||
|
{
|
||||||
|
return (JsonUtils.toJson(qInstance));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Convert a qInstance to JSON.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public String qInstanceToJsonIncludingBackend(QInstance qInstance)
|
||||||
|
{
|
||||||
|
String jsonString = JsonUtils.toJson(qInstance);
|
||||||
|
JSONObject jsonObject = JsonUtils.toJSONObject(jsonString);
|
||||||
|
|
||||||
|
String backendsJsonString = JsonUtils.toJson(qInstance.getBackends());
|
||||||
|
JSONObject backendsJsonObject = JsonUtils.toJSONObject(backendsJsonString);
|
||||||
|
jsonObject.put("backends", backendsJsonObject);
|
||||||
|
|
||||||
|
return (jsonObject.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Build a qInstance from JSON.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QInstance jsonToQInstance(String json) throws IOException
|
||||||
|
{
|
||||||
|
return (JsonUtils.toObject(json, QInstance.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Build a qInstance from JSON.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QInstance jsonToQInstanceIncludingBackends(String json) throws IOException
|
||||||
|
{
|
||||||
|
QInstance qInstance = JsonUtils.toObject(json, QInstance.class);
|
||||||
|
JSONObject jsonObject = JsonUtils.toJSONObject(json);
|
||||||
|
JSONObject backendsJsonObject = jsonObject.getJSONObject("backends");
|
||||||
|
Map<String, QBackendMetaData> backends = JsonUtils.toObject(backendsJsonObject.toString(), new TypeReference<>()
|
||||||
|
{
|
||||||
|
});
|
||||||
|
qInstance.setBackends(backends);
|
||||||
|
return qInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -60,27 +60,58 @@ public class QInstanceValidator
|
|||||||
List<String> errors = new ArrayList<>();
|
List<String> errors = new ArrayList<>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(assertCondition(errors, CollectionUtils.nullSafeHasContents(qInstance.getBackends()), "At least 1 backend must be defined."))
|
if(assertCondition(errors, CollectionUtils.nullSafeHasContents(qInstance.getBackends()),
|
||||||
|
"At least 1 backend must be defined."))
|
||||||
{
|
{
|
||||||
qInstance.getBackends().forEach((backendName, backend) ->
|
qInstance.getBackends().forEach((backendName, backend) ->
|
||||||
{
|
{
|
||||||
assertCondition(errors, Objects.equals(backendName, backend.getName()), "Inconsistent naming for backend: " + backendName + "/" + backend.getName() + ".");
|
assertCondition(errors, Objects.equals(backendName, backend.getName()),
|
||||||
|
"Inconsistent naming for backend: " + backendName + "/" + backend.getName() + ".");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(assertCondition(errors, CollectionUtils.nullSafeHasContents(qInstance.getTables()), "At least 1 table must be defined."))
|
/////////////////////////
|
||||||
|
// validate the tables //
|
||||||
|
/////////////////////////
|
||||||
|
if(assertCondition(errors, CollectionUtils.nullSafeHasContents(qInstance.getTables()),
|
||||||
|
"At least 1 table must be defined."))
|
||||||
{
|
{
|
||||||
qInstance.getTables().forEach((tableName, table) ->
|
qInstance.getTables().forEach((tableName, table) ->
|
||||||
{
|
{
|
||||||
assertCondition(errors, Objects.equals(tableName, table.getName()), "Inconsistent naming for table: " + tableName + "/" + table.getName() + ".");
|
assertCondition(errors, Objects.equals(tableName, table.getName()),
|
||||||
|
"Inconsistent naming for table: " + tableName + "/" + table.getName() + ".");
|
||||||
|
|
||||||
if(assertCondition(errors, StringUtils.hasContent(table.getBackendName()), "Missing backend name for table " + tableName + "."))
|
////////////////////////////////////////
|
||||||
|
// validate the backend for the table //
|
||||||
|
////////////////////////////////////////
|
||||||
|
if(assertCondition(errors, StringUtils.hasContent(table.getBackendName()),
|
||||||
|
"Missing backend name for table " + tableName + "."))
|
||||||
{
|
{
|
||||||
if(CollectionUtils.nullSafeHasContents(qInstance.getBackends()))
|
if(CollectionUtils.nullSafeHasContents(qInstance.getBackends()))
|
||||||
{
|
{
|
||||||
assertCondition(errors, qInstance.getBackendForTable(tableName) != null, "Unrecognized backend " + table.getBackendName() + " for table " + tableName + ".");
|
assertCondition(errors, qInstance.getBackendForTable(tableName) != null,
|
||||||
|
"Unrecognized backend " + table.getBackendName() + " for table " + tableName + ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// validate fields in the table //
|
||||||
|
//////////////////////////////////
|
||||||
|
if(assertCondition(errors, CollectionUtils.nullSafeHasContents(table.getFields()),
|
||||||
|
"At least 1 field must be defined in table " + tableName + "."))
|
||||||
|
{
|
||||||
|
table.getFields().forEach((fieldName, field) ->
|
||||||
|
{
|
||||||
|
assertCondition(errors, Objects.equals(fieldName, field.getName()),
|
||||||
|
"Inconsistent naming in table " + tableName + " for field " + fieldName + "/" + field.getName() + ".");
|
||||||
|
|
||||||
|
if(field.getPossibleValueSourceName() != null)
|
||||||
|
{
|
||||||
|
assertCondition(errors, qInstance.getPossibleValueSource(field.getPossibleValueSourceName()) != null,
|
||||||
|
"Unrecognized possibleValueSourceName " + field.getPossibleValueSourceName() + " in table " + tableName + " for field " + fieldName + ".");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2022. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.model.actions.update;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractQTableRequest;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Request data handler for the update action
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class UpdateRequest extends AbstractQTableRequest
|
||||||
|
{
|
||||||
|
private List<QRecord> records;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public UpdateRequest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public UpdateRequest(QInstance instance)
|
||||||
|
{
|
||||||
|
super(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for records
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public List<QRecord> getRecords()
|
||||||
|
{
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for records
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setRecords(List<QRecord> records)
|
||||||
|
{
|
||||||
|
this.records = records;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2022. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.model.actions.update;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractQResult;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.data.QRecordWithStatus;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Result for an update action
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
public class UpdateResult extends AbstractQResult
|
||||||
|
{
|
||||||
|
List<QRecordWithStatus> records;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public List<QRecordWithStatus> getRecords()
|
||||||
|
{
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setRecords(List<QRecordWithStatus> records)
|
||||||
|
{
|
||||||
|
this.records = records;
|
||||||
|
}
|
||||||
|
}
|
@ -13,12 +13,18 @@ import java.util.Map;
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Data Record within qqq. e.g., a single row from a database.
|
* Data Record within qqq. e.g., a single row from a database.
|
||||||
*
|
*
|
||||||
|
* Actual values (e.g., as stored in the backend system) are in the `values`
|
||||||
|
* map. Keys in this map are fieldNames from the QTableMetaData.
|
||||||
|
*
|
||||||
|
* "Display values" (e.g., labels for possible values, or formatted numbers
|
||||||
|
* (e.g., quantities with commas)) are in the displayValues map.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class QRecord
|
public class QRecord
|
||||||
{
|
{
|
||||||
private String tableName;
|
private String tableName;
|
||||||
private Serializable primaryKey;
|
//x private Serializable primaryKey;
|
||||||
private Map<String, Serializable> values;
|
private Map<String, Serializable> values = new LinkedHashMap<>();
|
||||||
|
private Map<String, String> displayValues = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -27,11 +33,6 @@ public class QRecord
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void setValue(String fieldName, Serializable value)
|
public void setValue(String fieldName, Serializable value)
|
||||||
{
|
{
|
||||||
if(values == null)
|
|
||||||
{
|
|
||||||
values = new LinkedHashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
values.put(fieldName, value);
|
values.put(fieldName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +49,27 @@ public class QRecord
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setDisplayValue(String fieldName, String displayValue)
|
||||||
|
{
|
||||||
|
displayValues.put(fieldName, displayValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QRecord withDisplayValue(String fieldName, String displayValue)
|
||||||
|
{
|
||||||
|
setDisplayValue(fieldName, displayValue);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for tableName
|
** Getter for tableName
|
||||||
**
|
**
|
||||||
@ -82,37 +104,37 @@ public class QRecord
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
//x /*******************************************************************************
|
||||||
** Getter for primaryKey
|
//x ** Getter for primaryKey
|
||||||
**
|
//x **
|
||||||
*******************************************************************************/
|
//x *******************************************************************************/
|
||||||
public Serializable getPrimaryKey()
|
//x public Serializable getPrimaryKey()
|
||||||
{
|
//x {
|
||||||
return primaryKey;
|
//x return primaryKey;
|
||||||
}
|
//x }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
//x /*******************************************************************************
|
||||||
** Setter for primaryKey
|
//x ** Setter for primaryKey
|
||||||
**
|
//x **
|
||||||
*******************************************************************************/
|
//x *******************************************************************************/
|
||||||
public void setPrimaryKey(Serializable primaryKey)
|
//x public void setPrimaryKey(Serializable primaryKey)
|
||||||
{
|
//x {
|
||||||
this.primaryKey = primaryKey;
|
//x this.primaryKey = primaryKey;
|
||||||
}
|
//x }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
//x /*******************************************************************************
|
||||||
** Setter for primaryKey
|
//x ** Setter for primaryKey
|
||||||
**
|
//x **
|
||||||
*******************************************************************************/
|
//x *******************************************************************************/
|
||||||
public QRecord withPrimaryKey(Serializable primaryKey)
|
//x public QRecord withPrimaryKey(Serializable primaryKey)
|
||||||
{
|
//x {
|
||||||
this.primaryKey = primaryKey;
|
//x this.primaryKey = primaryKey;
|
||||||
return (this);
|
//x return (this);
|
||||||
}
|
//x }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -149,6 +171,39 @@ public class QRecord
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for displayValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Map<String, String> getDisplayValues()
|
||||||
|
{
|
||||||
|
return displayValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for displayValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setDisplayValues(Map<String, String> displayValues)
|
||||||
|
{
|
||||||
|
this.displayValues = displayValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for a single field's value
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getDisplayValue(String fieldName)
|
||||||
|
{
|
||||||
|
return (displayValues.get(fieldName));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for a single field's value
|
** Getter for a single field's value
|
||||||
**
|
**
|
||||||
|
@ -36,7 +36,6 @@ public class QRecordWithStatus extends QRecord
|
|||||||
public QRecordWithStatus(QRecord record)
|
public QRecordWithStatus(QRecord record)
|
||||||
{
|
{
|
||||||
super.setTableName(record.getTableName());
|
super.setTableName(record.getTableName());
|
||||||
super.setPrimaryKey(record.getPrimaryKey());
|
|
||||||
super.setValues(record.getValues());
|
super.setValues(record.getValues());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ public class QFieldMetaData
|
|||||||
private String backendName;
|
private String backendName;
|
||||||
private QFieldType type;
|
private QFieldType type;
|
||||||
|
|
||||||
|
private String possibleValueSourceName;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -165,4 +167,36 @@ public class QFieldMetaData
|
|||||||
this.backendName = backendName;
|
this.backendName = backendName;
|
||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getPossibleValueSourceName()
|
||||||
|
{
|
||||||
|
return possibleValueSourceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setPossibleValueSourceName(String possibleValueSourceName)
|
||||||
|
{
|
||||||
|
this.possibleValueSourceName = possibleValueSourceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QFieldMetaData withPossibleValueSourceName(String possibleValueSourceName)
|
||||||
|
{
|
||||||
|
this.possibleValueSourceName = possibleValueSourceName;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.kingsrook.qqq.backend.core.instances.QInstanceValidationKey;
|
import com.kingsrook.qqq.backend.core.instances.QInstanceValidationKey;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionMetaData;
|
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.QProcessMetaData;
|
||||||
|
|
||||||
@ -30,9 +31,11 @@ public class QInstance
|
|||||||
private QAuthenticationMetaData authentication = null;
|
private QAuthenticationMetaData authentication = null;
|
||||||
|
|
||||||
private Map<String, QTableMetaData> tables = new HashMap<>();
|
private Map<String, QTableMetaData> tables = new HashMap<>();
|
||||||
|
private Map<String, QPossibleValueSource<?>> possibleValueSources = new HashMap<>();
|
||||||
private Map<String, QProcessMetaData> processes = new HashMap<>();
|
private Map<String, QProcessMetaData> processes = new HashMap<>();
|
||||||
|
|
||||||
// todo - lock down the object (no more changes allowed) after it's been validated?
|
// todo - lock down the object (no more changes allowed) after it's been validated?
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private boolean hasBeenValidated = false;
|
private boolean hasBeenValidated = false;
|
||||||
|
|
||||||
@ -147,6 +150,36 @@ public class QInstance
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void addPossibleValueSource(QPossibleValueSource<?> possibleValueSource)
|
||||||
|
{
|
||||||
|
this.possibleValueSources.put(possibleValueSource.getName(), possibleValueSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void addPossibleValueSource(String name, QPossibleValueSource possibleValueSource)
|
||||||
|
{
|
||||||
|
this.possibleValueSources.put(name, possibleValueSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QPossibleValueSource getPossibleValueSource(String name)
|
||||||
|
{
|
||||||
|
return (this.possibleValueSources.get(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -227,6 +260,28 @@ public class QInstance
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for possibleValueSources
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Map<String, QPossibleValueSource<?>> getPossibleValueSources()
|
||||||
|
{
|
||||||
|
return possibleValueSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for possibleValueSources
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setPossibleValueSources(Map<String, QPossibleValueSource<?>> possibleValueSources)
|
||||||
|
{
|
||||||
|
this.possibleValueSources = possibleValueSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for processes
|
** Getter for processes
|
||||||
**
|
**
|
||||||
|
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2022. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.model.metadata.possiblevalues;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Meta-data to represent a single field in a table.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class QPossibleValueSource<T>
|
||||||
|
{
|
||||||
|
private String name;
|
||||||
|
private QPossibleValueSourceType type;
|
||||||
|
|
||||||
|
// should these be in sub-types??
|
||||||
|
private List<T> enumValues;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QPossibleValueSource()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QPossibleValueSource<T> withName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QPossibleValueSourceType getType()
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setType(QPossibleValueSourceType type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QPossibleValueSource<T> withType(QPossibleValueSourceType type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for enumValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public List<T> getEnumValues()
|
||||||
|
{
|
||||||
|
return enumValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for enumValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setEnumValues(List<T> enumValues)
|
||||||
|
{
|
||||||
|
this.enumValues = enumValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for enumValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QPossibleValueSource<T> withEnumValues(List<T> enumValues)
|
||||||
|
{
|
||||||
|
this.enumValues = enumValues;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent adder for enumValues
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QPossibleValueSource<T> addEnumValue(T enumValue)
|
||||||
|
{
|
||||||
|
if(this.enumValues == null)
|
||||||
|
{
|
||||||
|
this.enumValues = new ArrayList<>();
|
||||||
|
}
|
||||||
|
this.enumValues.add(enumValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2021. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.model.metadata.possiblevalues;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Possible types (e.g, kinds of data sources) for a possible value source.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public enum QPossibleValueSourceType
|
||||||
|
{
|
||||||
|
ENUM,
|
||||||
|
TABLE,
|
||||||
|
CUSTOM
|
||||||
|
}
|
@ -49,12 +49,22 @@ public class QAuthenticationModuleDispatcher
|
|||||||
throw (new QModuleDispatchException("No authentication meta data defined."));
|
throw (new QModuleDispatchException("No authentication meta data defined."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return getQModule(authenticationMetaData.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QAuthenticationModuleInterface getQModule(String authenticationType) throws QModuleDispatchException
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String className = authenticationTypeToModuleClassNameMap.get(authenticationMetaData.getType());
|
String className = authenticationTypeToModuleClassNameMap.get(authenticationType);
|
||||||
if(className == null)
|
if(className == null)
|
||||||
{
|
{
|
||||||
throw (new QModuleDispatchException("Unrecognized authentication type [" + authenticationMetaData.getType() + "] in dispatcher."));
|
throw (new QModuleDispatchException("Unrecognized authentication type [" + authenticationType + "] in dispatcher."));
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<?> moduleClass = Class.forName(className);
|
Class<?> moduleClass = Class.forName(className);
|
||||||
@ -66,7 +76,8 @@ public class QAuthenticationModuleDispatcher
|
|||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
throw (new QModuleDispatchException("Error getting authentication module of type: " + authenticationMetaData.getType(), e));
|
throw (new QModuleDispatchException("Error getting authentication module of type: " + authenticationType, e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,15 @@ public interface QBackendModuleInterface
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
default UpdateInterface getUpdateInterface()
|
||||||
|
{
|
||||||
|
throwNotImplemented("Update");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2021. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.modules.interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateRequest;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateResult;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Interface for the update action.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public interface UpdateInterface
|
||||||
|
{
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
UpdateResult execute(UpdateRequest updateRequest) throws QException;
|
||||||
|
}
|
@ -9,6 +9,7 @@ import com.kingsrook.qqq.backend.core.modules.interfaces.DeleteInterface;
|
|||||||
import com.kingsrook.qqq.backend.core.modules.interfaces.InsertInterface;
|
import com.kingsrook.qqq.backend.core.modules.interfaces.InsertInterface;
|
||||||
import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface;
|
import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface;
|
||||||
import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface;
|
import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.modules.interfaces.UpdateInterface;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -41,6 +42,16 @@ public class MockBackendModule implements QBackendModuleInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public UpdateInterface getUpdateInterface()
|
||||||
|
{
|
||||||
|
return (new MockUpdateAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -31,7 +31,7 @@ public class MockDeleteAction implements DeleteInterface
|
|||||||
|
|
||||||
rs.setRecords(deleteRequest.getPrimaryKeys().stream().map(primaryKey ->
|
rs.setRecords(deleteRequest.getPrimaryKeys().stream().map(primaryKey ->
|
||||||
{
|
{
|
||||||
QRecord qRecord = new QRecord().withTableName(deleteRequest.getTableName()).withPrimaryKey(primaryKey);
|
QRecord qRecord = new QRecord().withTableName(deleteRequest.getTableName()).withValue("id", primaryKey);
|
||||||
return new QRecordWithStatus(qRecord);
|
return new QRecordWithStatus(qRecord);
|
||||||
}).toList());
|
}).toList());
|
||||||
|
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2021. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.modules.mock;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
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.QRecordWithStatus;
|
||||||
|
import com.kingsrook.qqq.backend.core.modules.interfaces.UpdateInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Mocked up version of update action.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class MockUpdateAction implements UpdateInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public UpdateResult execute(UpdateRequest updateRequest) throws QException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UpdateResult rs = new UpdateResult();
|
||||||
|
|
||||||
|
rs.setRecords(updateRequest.getRecords().stream().map(qRecord ->
|
||||||
|
{
|
||||||
|
return new QRecordWithStatus(qRecord);
|
||||||
|
}).toList());
|
||||||
|
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
throw new QException("Error executing update: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,10 +24,9 @@ public class ExceptionUtils
|
|||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e.getClass().equals(targetClass))
|
if(targetClass.isInstance(e))
|
||||||
{
|
{
|
||||||
//noinspection unchecked
|
return targetClass.cast(e);
|
||||||
return ((T) e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e.getCause() == null)
|
if(e.getCause() == null)
|
||||||
|
@ -7,6 +7,7 @@ package com.kingsrook.qqq.backend.core.utils;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
@ -91,6 +92,21 @@ public class JsonUtils
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** De-serialize a json string into an object of the specified class.
|
||||||
|
**
|
||||||
|
** Internally using jackson - so jackson annotations apply!
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public static <T> T toObject(String json, TypeReference<T> typeReference) throws IOException
|
||||||
|
{
|
||||||
|
ObjectMapper objectMapper = newObjectMapper();
|
||||||
|
T t = objectMapper.readValue(json, typeReference);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** De-serialize a json string into a JSONObject (string must start with "{")
|
** De-serialize a json string into a JSONObject (string must start with "{")
|
||||||
**
|
**
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2021. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.actions;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
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.utils.TestUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for UpdateAction
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
class UpdateActionTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** At the core level, there isn't much that can be asserted, as it uses the
|
||||||
|
** mock implementation - just confirming that all of the "wiring" works.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test() throws QException
|
||||||
|
{
|
||||||
|
UpdateRequest request = new UpdateRequest(TestUtils.defineInstance());
|
||||||
|
request.setSession(TestUtils.getMockSession());
|
||||||
|
request.setTableName("person");
|
||||||
|
List<QRecord> records =new ArrayList<>();
|
||||||
|
QRecord record = new QRecord();
|
||||||
|
record.setValue("id", "47");
|
||||||
|
record.setValue("firstName", "James");
|
||||||
|
records.add(record);
|
||||||
|
request.setRecords(records);
|
||||||
|
UpdateResult result = new UpdateAction().execute(request);
|
||||||
|
assertNotNull(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2022. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.adapters;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
class QInstanceAdapterTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void qInstanceToJson()
|
||||||
|
{
|
||||||
|
QInstance qInstance = TestUtils.defineInstance();
|
||||||
|
String json = new QInstanceAdapter().qInstanceToJson(qInstance);
|
||||||
|
System.out.println(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void qInstanceToJsonIncludingBackend()
|
||||||
|
{
|
||||||
|
QInstance qInstance = TestUtils.defineInstance();
|
||||||
|
String json = new QInstanceAdapter().qInstanceToJsonIncludingBackend(qInstance);
|
||||||
|
System.out.println(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void jsonToQInstance() throws IOException
|
||||||
|
{
|
||||||
|
String json = FileUtils.readFileToString(new File("src/test/resources/personQInstance.json"));
|
||||||
|
QInstance qInstance = new QInstanceAdapter().jsonToQInstance(json);
|
||||||
|
System.out.println(qInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void jsonToQInstanceIncludingBackend() throws IOException
|
||||||
|
{
|
||||||
|
String json = FileUtils.readFileToString(new File("src/test/resources/personQInstanceIncludingBackend.json"));
|
||||||
|
QInstance qInstance = new QInstanceAdapter().jsonToQInstanceIncludingBackends(json);
|
||||||
|
System.out.println(qInstance);
|
||||||
|
assertNotNull(qInstance.getBackends());
|
||||||
|
assertTrue(qInstance.getBackends().size() > 0);
|
||||||
|
}
|
||||||
|
}
|
@ -35,7 +35,7 @@ class QInstanceValidatorTest
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Test an instane with null backends - should throw.
|
** Test an instance with null backends - should throw.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
@ -57,7 +57,7 @@ class QInstanceValidatorTest
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Test an instane with empty map of backends - should throw.
|
** Test an instance with empty map of backends - should throw.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
@ -79,7 +79,7 @@ class QInstanceValidatorTest
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Test an instane with null tables - should throw.
|
** Test an instance with null tables - should throw.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
@ -101,7 +101,7 @@ class QInstanceValidatorTest
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Test an instane with empty map of tables - should throw.
|
** Test an instance with empty map of tables - should throw.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
@ -123,7 +123,7 @@ class QInstanceValidatorTest
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Test an instane where a table and a backend each have a name attribute that
|
** Test an instance where a table and a backend each have a name attribute that
|
||||||
** doesn't match the key that those objects have in the instance's maps - should throw.
|
** doesn't match the key that those objects have in the instance's maps - should throw.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -191,6 +191,62 @@ class QInstanceValidatorTest
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Test that a table with no fields fails.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test_validateTableWithNoFields()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
QInstance qInstance = TestUtils.defineInstance();
|
||||||
|
qInstance.getTable("person").setFields(null);
|
||||||
|
new QInstanceValidator().validate(qInstance);
|
||||||
|
fail("Should have thrown validationException");
|
||||||
|
}
|
||||||
|
catch(QInstanceValidationException e)
|
||||||
|
{
|
||||||
|
assertReason("At least 1 field", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
QInstance qInstance = TestUtils.defineInstance();
|
||||||
|
qInstance.getTable("person").setFields(new HashMap<>());
|
||||||
|
new QInstanceValidator().validate(qInstance);
|
||||||
|
fail("Should have thrown validationException");
|
||||||
|
}
|
||||||
|
catch(QInstanceValidationException e)
|
||||||
|
{
|
||||||
|
assertReason("At least 1 field", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Test that if a field specifies a backend that doesn't exist, that it fails.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test_validateFieldWithMissingPossibleValueSource()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
QInstance qInstance = TestUtils.defineInstance();
|
||||||
|
qInstance.getTable("person").getField("homeState").setPossibleValueSourceName("not a real possible value source");
|
||||||
|
new QInstanceValidator().validate(qInstance);
|
||||||
|
fail("Should have thrown validationException");
|
||||||
|
}
|
||||||
|
catch(QInstanceValidationException e)
|
||||||
|
{
|
||||||
|
assertReason("Unrecognized possibleValueSourceName", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** utility method for asserting that a specific reason string is found within
|
** utility method for asserting that a specific reason string is found within
|
||||||
** the list of reasons in the QInstanceValidationException.
|
** the list of reasons in the QInstanceValidationException.
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021-2021. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.modules;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.modules.interfaces.QAuthenticationModuleInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for QModuleDispatcher
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
class QAuthenticationModuleDispatcherTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Test success case - a valid backend.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test_getQAuthenticationModule() throws QModuleDispatchException
|
||||||
|
{
|
||||||
|
QAuthenticationModuleInterface mock = new QAuthenticationModuleDispatcher().getQModule(TestUtils.defineAuthentication());
|
||||||
|
assertNotNull(mock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Test success case - a valid backend.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test_getQAuthenticationModuleByType_valid() throws QModuleDispatchException
|
||||||
|
{
|
||||||
|
QAuthenticationModuleInterface mock = new QAuthenticationModuleDispatcher().getQModule("mock");
|
||||||
|
assertNotNull(mock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Test failure case, a backend name that doesn't exist
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test_getQAuthenticationModule_typeNotFound()
|
||||||
|
{
|
||||||
|
assertThrows(QModuleDispatchException.class, () ->
|
||||||
|
{
|
||||||
|
new QAuthenticationModuleDispatcher().getQModule("aTypeThatWontExist");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Test failure case, null argument
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void test_getQAuthenticationModule_nullArgument()
|
||||||
|
{
|
||||||
|
assertThrows(QModuleDispatchException.class, () ->
|
||||||
|
{
|
||||||
|
new QAuthenticationModuleDispatcher().getQModule((QAuthenticationMetaData) null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -44,7 +44,7 @@ class JsonUtilsTest
|
|||||||
{
|
{
|
||||||
QRecord qRecord = getQRecord();
|
QRecord qRecord = getQRecord();
|
||||||
String json = JsonUtils.toJson(qRecord);
|
String json = JsonUtils.toJson(qRecord);
|
||||||
assertEquals("{\"tableName\":\"foo\",\"primaryKey\":1,\"values\":{\"foo\":\"Foo\",\"bar\":3.14159}}", json);
|
assertEquals("{\"tableName\":\"foo\",\"values\":{\"foo\":\"Foo\",\"bar\":3.14159},\"displayValues\":{}}", json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ class JsonUtilsTest
|
|||||||
{
|
{
|
||||||
QRecord qRecord = new QRecord();
|
QRecord qRecord = new QRecord();
|
||||||
qRecord.setTableName("foo");
|
qRecord.setTableName("foo");
|
||||||
qRecord.setPrimaryKey(1);
|
qRecord.setValue("id", 1);
|
||||||
Map<String, Serializable> values = new LinkedHashMap<>();
|
Map<String, Serializable> values = new LinkedHashMap<>();
|
||||||
qRecord.setValues(values);
|
qRecord.setValues(values);
|
||||||
values.put("foo", "Foo");
|
values.put("foo", "Foo");
|
||||||
|
@ -15,6 +15,8 @@ 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.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.metadata.possiblevalues.QPossibleValueSource;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSourceType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionInputMetaData;
|
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.QFunctionMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionOutputMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionOutputMetaData;
|
||||||
@ -42,17 +44,32 @@ public class TestUtils
|
|||||||
qInstance.setAuthentication(defineAuthentication());
|
qInstance.setAuthentication(defineAuthentication());
|
||||||
qInstance.addBackend(defineBackend());
|
qInstance.addBackend(defineBackend());
|
||||||
qInstance.addTable(defineTablePerson());
|
qInstance.addTable(defineTablePerson());
|
||||||
|
qInstance.addPossibleValueSource(defineStatesPossibleValueSource());
|
||||||
qInstance.addProcess(defineProcessGreetPeople());
|
qInstance.addProcess(defineProcessGreetPeople());
|
||||||
return (qInstance);
|
return (qInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Define the "states" possible value source used in standard tests
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static QPossibleValueSource<String> defineStatesPossibleValueSource()
|
||||||
|
{
|
||||||
|
return new QPossibleValueSource<String>()
|
||||||
|
.withName("state")
|
||||||
|
.withType(QPossibleValueSourceType.ENUM)
|
||||||
|
.withEnumValues(List.of("IL", "MO"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Define the authentication used in standard tests - using 'mock' type.
|
** Define the authentication used in standard tests - using 'mock' type.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private static QAuthenticationMetaData defineAuthentication()
|
public static QAuthenticationMetaData defineAuthentication()
|
||||||
{
|
{
|
||||||
return new QAuthenticationMetaData()
|
return new QAuthenticationMetaData()
|
||||||
.withName("mock")
|
.withName("mock")
|
||||||
@ -89,7 +106,8 @@ public class TestUtils
|
|||||||
.withField(new QFieldMetaData("firstName", QFieldType.STRING))
|
.withField(new QFieldMetaData("firstName", QFieldType.STRING))
|
||||||
.withField(new QFieldMetaData("lastName", QFieldType.STRING))
|
.withField(new QFieldMetaData("lastName", QFieldType.STRING))
|
||||||
.withField(new QFieldMetaData("birthDate", QFieldType.DATE))
|
.withField(new QFieldMetaData("birthDate", QFieldType.DATE))
|
||||||
.withField(new QFieldMetaData("email", QFieldType.STRING));
|
.withField(new QFieldMetaData("email", QFieldType.STRING))
|
||||||
|
.withField(new QFieldMetaData("homeState", QFieldType.STRING).withPossibleValueSourceName("state"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
156
src/test/resources/personQInstance.json
Normal file
156
src/test/resources/personQInstance.json
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
{
|
||||||
|
"authentication": {
|
||||||
|
"name": "mock",
|
||||||
|
"type": "mock",
|
||||||
|
"values": null
|
||||||
|
},
|
||||||
|
"tables": {
|
||||||
|
"person": {
|
||||||
|
"name": "person",
|
||||||
|
"label": "Person",
|
||||||
|
"backendName": "default",
|
||||||
|
"primaryKeyField": "id",
|
||||||
|
"fields": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "INTEGER",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"createDate": {
|
||||||
|
"name": "createDate",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "DATE_TIME",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"modifyDate": {
|
||||||
|
"name": "modifyDate",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "DATE_TIME",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"firstName": {
|
||||||
|
"name": "firstName",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"lastName": {
|
||||||
|
"name": "lastName",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"birthDate": {
|
||||||
|
"name": "birthDate",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "DATE",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"homeState": {
|
||||||
|
"name": "homeState",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": "state"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"possibleValueSources": {
|
||||||
|
"state": {
|
||||||
|
"name": "state",
|
||||||
|
"type": "ENUM",
|
||||||
|
"enumValues": [
|
||||||
|
"IL",
|
||||||
|
"MO"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"processes": {
|
||||||
|
"greet": {
|
||||||
|
"name": "greet",
|
||||||
|
"tableName": "person",
|
||||||
|
"functionList": [
|
||||||
|
{
|
||||||
|
"name": "prepare",
|
||||||
|
"label": null,
|
||||||
|
"inputMetaData": {
|
||||||
|
"recordListMetaData": {
|
||||||
|
"tableName": "person",
|
||||||
|
"fields": null
|
||||||
|
},
|
||||||
|
"fieldList": [
|
||||||
|
{
|
||||||
|
"name": "greetingPrefix",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "greetingSuffix",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"outputMetaData": {
|
||||||
|
"recordListMetaData": {
|
||||||
|
"tableName": "person",
|
||||||
|
"fields": {
|
||||||
|
"fullGreeting": {
|
||||||
|
"name": "fullGreeting",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fieldList": [
|
||||||
|
{
|
||||||
|
"name": "outputMessage",
|
||||||
|
"label": null,
|
||||||
|
"backendName": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"name": "com.kingsrook.qqq.backend.core.interfaces.mock.MockFunctionBody",
|
||||||
|
"codeType": "JAVA",
|
||||||
|
"codeUsage": "FUNCTION"
|
||||||
|
},
|
||||||
|
"outputView": {
|
||||||
|
"messageField": "outputMessage",
|
||||||
|
"recordListView": {
|
||||||
|
"fieldNames": [
|
||||||
|
"id",
|
||||||
|
"firstName",
|
||||||
|
"lastName",
|
||||||
|
"fullGreeting"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
163
src/test/resources/personQInstanceIncludingBackend.json
Normal file
163
src/test/resources/personQInstanceIncludingBackend.json
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
{
|
||||||
|
"tables": {
|
||||||
|
"person": {
|
||||||
|
"primaryKeyField": "id",
|
||||||
|
"name": "person",
|
||||||
|
"backendName": "default",
|
||||||
|
"label": "Person",
|
||||||
|
"fields": {
|
||||||
|
"firstName": {
|
||||||
|
"name": "firstName",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"lastName": {
|
||||||
|
"name": "lastName",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"modifyDate": {
|
||||||
|
"name": "modifyDate",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "DATE_TIME",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"homeState": {
|
||||||
|
"name": "homeState",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": "state"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "INTEGER",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"birthDate": {
|
||||||
|
"name": "birthDate",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "DATE",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
"createDate": {
|
||||||
|
"name": "createDate",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "DATE_TIME",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"processes": {
|
||||||
|
"greet": {
|
||||||
|
"functionList": [
|
||||||
|
{
|
||||||
|
"code": {
|
||||||
|
"codeUsage": "FUNCTION",
|
||||||
|
"codeType": "JAVA",
|
||||||
|
"name": "com.kingsrook.qqq.backend.core.interfaces.mock.MockFunctionBody"
|
||||||
|
},
|
||||||
|
"inputMetaData": {
|
||||||
|
"recordListMetaData": {
|
||||||
|
"fields": null,
|
||||||
|
"tableName": "person"
|
||||||
|
},
|
||||||
|
"fieldList": [
|
||||||
|
{
|
||||||
|
"name": "greetingPrefix",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "greetingSuffix",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"outputMetaData": {
|
||||||
|
"recordListMetaData": {
|
||||||
|
"fields": {
|
||||||
|
"fullGreeting": {
|
||||||
|
"name": "fullGreeting",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tableName": "person"
|
||||||
|
},
|
||||||
|
"fieldList": [
|
||||||
|
{
|
||||||
|
"name": "outputMessage",
|
||||||
|
"backendName": null,
|
||||||
|
"label": null,
|
||||||
|
"type": "STRING",
|
||||||
|
"possibleValueSourceName": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"outputView": {
|
||||||
|
"messageField": "outputMessage",
|
||||||
|
"recordListView": {
|
||||||
|
"fieldNames": [
|
||||||
|
"id",
|
||||||
|
"firstName",
|
||||||
|
"lastName",
|
||||||
|
"fullGreeting"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "prepare",
|
||||||
|
"label": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "greet",
|
||||||
|
"tableName": "person"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"possibleValueSources": {
|
||||||
|
"state": {
|
||||||
|
"name": "state",
|
||||||
|
"type": "ENUM",
|
||||||
|
"enumValues": [
|
||||||
|
"IL",
|
||||||
|
"MO"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backends": {
|
||||||
|
"default": {
|
||||||
|
"values": null,
|
||||||
|
"name": "default",
|
||||||
|
"type": "mock"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authentication": {
|
||||||
|
"values": null,
|
||||||
|
"name": "mock",
|
||||||
|
"type": "mock"
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user