mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Add joins and ChildRecordList widget
This commit is contained in:
@ -22,11 +22,15 @@
|
||||
package com.kingsrook.qqq.backend.core.actions.dashboard;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.actions.ActionHelper;
|
||||
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -44,6 +48,18 @@ public class RenderWidgetAction
|
||||
ActionHelper.validateSession(input);
|
||||
|
||||
AbstractWidgetRenderer widgetRenderer = QCodeLoader.getAdHoc(AbstractWidgetRenderer.class, input.getWidgetMetaData().getCodeReference());
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// move default values from meta data into this render input //
|
||||
///////////////////////////////////////////////////////////////
|
||||
if(input.getWidgetMetaData() instanceof QWidgetMetaData widgetMetaData)
|
||||
{
|
||||
for(Map.Entry<String, Serializable> entry : widgetMetaData.getDefaultValues().entrySet())
|
||||
{
|
||||
input.getQueryParams().putIfAbsent(entry.getKey(), ValueUtils.getValueAsString(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
return (widgetRenderer.render(input));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.actions.dashboard.widgets;
|
||||
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.actions.dashboard.AbstractWidgetRenderer;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ChildRecordListData;
|
||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Generic widget for display a list of child records.
|
||||
*******************************************************************************/
|
||||
public class ChildRecordListRenderer extends AbstractWidgetRenderer
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static QWidgetMetaData defineWidgetFromJoin(QJoinMetaData join)
|
||||
{
|
||||
return (new QWidgetMetaData()
|
||||
.withName(join.getName())
|
||||
.withCodeReference(new QCodeReference(ChildRecordListRenderer.class, null))
|
||||
.withType(WidgetType.CHILD_RECORD_LIST.getType())
|
||||
.withDefaultValue("joinName", join.getName()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public RenderWidgetOutput render(RenderWidgetInput input) throws QException
|
||||
{
|
||||
String widgetLabel = input.getQueryParams().get("widgetLabel");
|
||||
String joinName = input.getQueryParams().get("joinName");
|
||||
QJoinMetaData join = input.getInstance().getJoin(joinName);
|
||||
String id = input.getQueryParams().get("id");
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// fetch the record that we're getting children for. //
|
||||
// e.g., the left-side of the join, with the input id //
|
||||
////////////////////////////////////////////////////////
|
||||
GetInput getInput = new GetInput(input.getInstance());
|
||||
getInput.setSession(input.getSession());
|
||||
getInput.setTableName(join.getLeftTable());
|
||||
getInput.setPrimaryKey(id);
|
||||
GetOutput getOutput = new GetAction().execute(getInput);
|
||||
QRecord record = getOutput.getRecord();
|
||||
|
||||
if(record == null)
|
||||
{
|
||||
QTableMetaData table = input.getInstance().getTable(join.getLeftTable());
|
||||
throw (new QNotFoundException("Could not find " + (table == null ? "" : table.getLabel()) + " with primary key " + id));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// set up the query - for the table on the right side of the join //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
QQueryFilter filter = new QQueryFilter();
|
||||
for(JoinOn joinOn : join.getJoinOns())
|
||||
{
|
||||
filter.addCriteria(new QFilterCriteria(joinOn.getRightField(), QCriteriaOperator.EQUALS, List.of(record.getValue(joinOn.getLeftField()))));
|
||||
}
|
||||
filter.setOrderBys(join.getOrderBys());
|
||||
|
||||
QueryInput queryInput = new QueryInput(input.getInstance());
|
||||
queryInput.setSession(input.getSession());
|
||||
queryInput.setTableName(join.getRightTable());
|
||||
queryInput.setShouldTranslatePossibleValues(true);
|
||||
queryInput.setShouldGenerateDisplayValues(true);
|
||||
queryInput.setFilter(filter);
|
||||
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||
|
||||
QTableMetaData table = input.getInstance().getTable(join.getRightTable());
|
||||
String tablePath = input.getInstance().getTablePath(input, table.getName());
|
||||
String viewAllLink = tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), Charset.defaultCharset());
|
||||
|
||||
return (new RenderWidgetOutput(new ChildRecordListData(widgetLabel, queryOutput, table, tablePath, viewAllLink)));
|
||||
}
|
||||
|
||||
}
|
@ -285,7 +285,7 @@ public class QInstanceValidator
|
||||
{
|
||||
for(QFieldSection section : table.getSections())
|
||||
{
|
||||
validateFieldSection(table, section, fieldNamesInSections);
|
||||
validateTableSection(qInstance, table, section, fieldNamesInSections);
|
||||
if(section.getTier().equals(Tier.T1))
|
||||
{
|
||||
assertCondition(tier1Section == null, "Table " + tableName + " has more than 1 section listed as Tier 1");
|
||||
@ -658,13 +658,17 @@ public class QInstanceValidator
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void validateFieldSection(QTableMetaData table, QFieldSection section, Set<String> fieldNamesInSections)
|
||||
private void validateTableSection(QInstance qInstance, QTableMetaData table, QFieldSection section, Set<String> fieldNamesInSections)
|
||||
{
|
||||
assertCondition(StringUtils.hasContent(section.getName()), "Missing a name for field section in table " + table.getName() + ".");
|
||||
assertCondition(StringUtils.hasContent(section.getLabel()), "Missing a label for field section in table " + table.getLabel() + ".");
|
||||
if(assertCondition(CollectionUtils.nullSafeHasContents(section.getFieldNames()), "Table " + table.getName() + " section " + section.getName() + " does not have any fields."))
|
||||
|
||||
boolean hasFields = CollectionUtils.nullSafeHasContents(section.getFieldNames());
|
||||
boolean hasWidget = StringUtils.hasContent(section.getWidgetName());
|
||||
|
||||
if(assertCondition(hasFields || hasWidget, "Table " + table.getName() + " section " + section.getName() + " does not have any fields or a widget."))
|
||||
{
|
||||
if(table.getFields() != null)
|
||||
if(table.getFields() != null && hasFields)
|
||||
{
|
||||
for(String fieldName : section.getFieldNames())
|
||||
{
|
||||
@ -674,6 +678,10 @@ public class QInstanceValidator
|
||||
fieldNamesInSections.add(fieldName);
|
||||
}
|
||||
}
|
||||
else if(hasWidget)
|
||||
{
|
||||
assertCondition(qInstance.getWidget(section.getWidgetName()) != null, "Table " + table.getName() + " section " + section.getName() + " specifies widget " + section.getWidgetName() + ", which is not a widget in this instance.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.model.dashboard.widgets;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Model containing data structure expected by frontend ChildRecordList widget
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class ChildRecordListData implements QWidget
|
||||
{
|
||||
private String title;
|
||||
private QueryOutput queryOutput;
|
||||
private QTableMetaData childTableMetaData;
|
||||
|
||||
private String tablePath;
|
||||
private String viewAllLink;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ChildRecordListData(String title, QueryOutput queryOutput, QTableMetaData childTableMetaData, String tablePath, String viewAllLink)
|
||||
{
|
||||
this.title = title;
|
||||
this.queryOutput = queryOutput;
|
||||
this.childTableMetaData = childTableMetaData;
|
||||
this.tablePath = tablePath;
|
||||
this.viewAllLink = viewAllLink;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getType()
|
||||
{
|
||||
return WidgetType.CHILD_RECORD_LIST.getType();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getTitle()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ChildRecordListData withTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for queryOutput
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QueryOutput getQueryOutput()
|
||||
{
|
||||
return queryOutput;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for queryOutput
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setQueryOutput(QueryOutput queryOutput)
|
||||
{
|
||||
this.queryOutput = queryOutput;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for queryOutput
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ChildRecordListData withQueryOutput(QueryOutput queryOutput)
|
||||
{
|
||||
this.queryOutput = queryOutput;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for childTableMetaData
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QTableMetaData getChildTableMetaData()
|
||||
{
|
||||
return childTableMetaData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for childTableMetaData
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setChildTableMetaData(QTableMetaData childTableMetaData)
|
||||
{
|
||||
this.childTableMetaData = childTableMetaData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for childTableMetaData
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ChildRecordListData withChildTableMetaData(QTableMetaData childTableMetaData)
|
||||
{
|
||||
this.childTableMetaData = childTableMetaData;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for tablePath
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getTablePath()
|
||||
{
|
||||
return tablePath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for tablePath
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setTablePath(String tablePath)
|
||||
{
|
||||
this.tablePath = tablePath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for viewAllLink
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getViewAllLink()
|
||||
{
|
||||
return viewAllLink;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for viewAllLink
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setViewAllLink(String viewAllLink)
|
||||
{
|
||||
this.viewAllLink = viewAllLink;
|
||||
}
|
||||
}
|
@ -35,7 +35,8 @@ public enum WidgetType
|
||||
QUICK_SIGHT_CHART("quickSightChart"),
|
||||
STATISTICS("statistics"),
|
||||
STEPPER("stepper"),
|
||||
TABLE("table");
|
||||
TABLE("table"),
|
||||
CHILD_RECORD_LIST("childRecordList");
|
||||
|
||||
|
||||
private final String type;
|
||||
|
@ -28,10 +28,18 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.kingsrook.qqq.backend.core.actions.metadata.MetaDataAction;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.instances.QInstanceValidationKey;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.automation.QAutomationProviderMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.branding.QBrandingMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNode;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNodeType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||
@ -64,6 +72,7 @@ public class QInstance
|
||||
// Important to use LinkedHashmap here, to preserve the order in which entries are added. //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
private Map<String, QTableMetaData> tables = new LinkedHashMap<>();
|
||||
private Map<String, QJoinMetaData> joins = new LinkedHashMap<>();
|
||||
private Map<String, QPossibleValueSource> possibleValueSources = new LinkedHashMap<>();
|
||||
private Map<String, QProcessMetaData> processes = new LinkedHashMap<>();
|
||||
private Map<String, QAppMetaData> apps = new LinkedHashMap<>();
|
||||
@ -79,6 +88,9 @@ public class QInstance
|
||||
@JsonIgnore
|
||||
private boolean hasBeenValidated = false;
|
||||
|
||||
private Map<String, String> memoizedTablePaths = new HashMap<>();
|
||||
private Map<String, String> memoizedProcessPaths = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -118,6 +130,71 @@ public class QInstance
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Get the full path to a table
|
||||
*******************************************************************************/
|
||||
public String getTablePath(AbstractActionInput actionInput, String tableName) throws QException
|
||||
{
|
||||
if(!memoizedTablePaths.containsKey(tableName))
|
||||
{
|
||||
MetaDataInput input = new MetaDataInput(this);
|
||||
input.setSession(actionInput.getSession());
|
||||
MetaDataOutput output = new MetaDataAction().execute(input);
|
||||
memoizedTablePaths.put(tableName, searchAppTree(output.getAppTree(), tableName, AppTreeNodeType.TABLE, ""));
|
||||
}
|
||||
return (memoizedTablePaths.get(tableName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Get the full path to a process
|
||||
*******************************************************************************/
|
||||
public String getProcessPath(AbstractActionInput actionInput, String processName) throws QException
|
||||
{
|
||||
if(!memoizedProcessPaths.containsKey(processName))
|
||||
{
|
||||
MetaDataInput input = new MetaDataInput(this);
|
||||
input.setSession(actionInput.getSession());
|
||||
MetaDataOutput output = new MetaDataAction().execute(input);
|
||||
return searchAppTree(output.getAppTree(), processName, AppTreeNodeType.PROCESS, "");
|
||||
}
|
||||
return (memoizedProcessPaths.get(processName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String searchAppTree(List<AppTreeNode> appTree, String tableName, AppTreeNodeType treeNodeType, String path)
|
||||
{
|
||||
if(appTree == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
for(AppTreeNode appTreeNode : appTree)
|
||||
{
|
||||
if(appTreeNode.getType().equals(treeNodeType) && appTreeNode.getName().equals(tableName))
|
||||
{
|
||||
return (path + "/" + tableName);
|
||||
}
|
||||
else if(appTreeNode.getType().equals(AppTreeNodeType.APP))
|
||||
{
|
||||
String subResult = searchAppTree(appTreeNode.getChildren(), tableName, treeNodeType, path + "/" + appTreeNode.getName());
|
||||
if(subResult != null)
|
||||
{
|
||||
return (subResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -243,6 +320,71 @@ public class QInstance
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addJoin(QJoinMetaData join)
|
||||
{
|
||||
addJoin(join.getName(), join);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addJoin(String name, QJoinMetaData join)
|
||||
{
|
||||
if(!StringUtils.hasContent(name))
|
||||
{
|
||||
throw (new IllegalArgumentException("Attempted to add a join without a name."));
|
||||
}
|
||||
if(this.joins.containsKey(name))
|
||||
{
|
||||
throw (new IllegalArgumentException("Attempted to add a second join with name: " + name));
|
||||
}
|
||||
this.joins.put(name, join);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QJoinMetaData getJoin(String name)
|
||||
{
|
||||
if(this.joins == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
return (this.joins.get(name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for joins
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Map<String, QJoinMetaData> getJoins()
|
||||
{
|
||||
return joins;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for joins
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setJoins(Map<String, QJoinMetaData> joins)
|
||||
{
|
||||
this.joins = joins;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
@ -35,7 +35,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.Capability;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -92,11 +91,6 @@ public class QFrontendTableMetaData
|
||||
this.iconName = tableMetaData.getIcon().getName();
|
||||
}
|
||||
|
||||
if(CollectionUtils.nullSafeHasContents(tableMetaData.getWidgets()))
|
||||
{
|
||||
this.widgets = tableMetaData.getWidgets();
|
||||
}
|
||||
|
||||
setCapabilities(backendForTable, tableMetaData);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.model.metadata.joins;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class JoinOn
|
||||
{
|
||||
private String leftField;
|
||||
private String rightField;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public JoinOn()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public JoinOn(String leftField, String rightField)
|
||||
{
|
||||
this.leftField = leftField;
|
||||
this.rightField = rightField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for leftField
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getLeftField()
|
||||
{
|
||||
return leftField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for leftField
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setLeftField(String leftField)
|
||||
{
|
||||
this.leftField = leftField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for leftField
|
||||
**
|
||||
*******************************************************************************/
|
||||
public JoinOn withLeftField(String leftField)
|
||||
{
|
||||
this.leftField = leftField;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for rightField
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getRightField()
|
||||
{
|
||||
return rightField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for rightField
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setRightField(String rightField)
|
||||
{
|
||||
this.rightField = rightField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for rightField
|
||||
**
|
||||
*******************************************************************************/
|
||||
public JoinOn withRightField(String rightField)
|
||||
{
|
||||
this.rightField = rightField;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.model.metadata.joins;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Type for a QJoin.
|
||||
**
|
||||
** - One to One - what about zero??
|
||||
** - One to Many - e.g., where the parent record really "owns" all of the child
|
||||
** records. Like Order -> OrderLine.
|
||||
** - Many to One - e.g., where a child references a parent, but we'd never really
|
||||
** view or manage all of the children under the parent.
|
||||
** - Many to Many - e.g., through an intersection table... ? Needs more thought.
|
||||
*******************************************************************************/
|
||||
public enum JoinType
|
||||
{
|
||||
ONE_TO_ONE,
|
||||
ONE_TO_MANY,
|
||||
MANY_TO_ONE,
|
||||
MANY_TO_MANY
|
||||
}
|
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.model.metadata.joins;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QJoinMetaData
|
||||
{
|
||||
private String name;
|
||||
private JoinType type;
|
||||
private String leftTable;
|
||||
private String rightTable;
|
||||
|
||||
private List<JoinOn> joinOns;
|
||||
private List<QFilterOrderBy> orderBys;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for name
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for name
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for name
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QJoinMetaData withName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public JoinType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setType(JoinType type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QJoinMetaData withType(JoinType type)
|
||||
{
|
||||
this.type = type;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for leftTable
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getLeftTable()
|
||||
{
|
||||
return leftTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for leftTable
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setLeftTable(String leftTable)
|
||||
{
|
||||
this.leftTable = leftTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for leftTable
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QJoinMetaData withLeftTable(String leftTable)
|
||||
{
|
||||
this.leftTable = leftTable;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for rightTable
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getRightTable()
|
||||
{
|
||||
return rightTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for rightTable
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setRightTable(String rightTable)
|
||||
{
|
||||
this.rightTable = rightTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for rightTable
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QJoinMetaData withRightTable(String rightTable)
|
||||
{
|
||||
this.rightTable = rightTable;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for joinOns
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<JoinOn> getJoinOns()
|
||||
{
|
||||
return joinOns;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for joinOns
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setJoinOns(List<JoinOn> joinOns)
|
||||
{
|
||||
this.joinOns = joinOns;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for joinOns
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QJoinMetaData withJoinOns(List<JoinOn> joinOns)
|
||||
{
|
||||
this.joinOns = joinOns;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for joinOns
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QJoinMetaData withJoinOn(JoinOn joinOn)
|
||||
{
|
||||
if(this.joinOns == null)
|
||||
{
|
||||
this.joinOns = new ArrayList<>();
|
||||
}
|
||||
this.joinOns.add(joinOn);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for orderBys
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QFilterOrderBy> getOrderBys()
|
||||
{
|
||||
return orderBys;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for orderBys
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setOrderBys(List<QFilterOrderBy> orderBys)
|
||||
{
|
||||
this.orderBys = orderBys;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for orderBys
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QJoinMetaData withOrderBys(List<QFilterOrderBy> orderBys)
|
||||
{
|
||||
this.orderBys = orderBys;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for orderBys
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QJoinMetaData withOrderBy(QFilterOrderBy orderBy)
|
||||
{
|
||||
if(this.orderBys == null)
|
||||
{
|
||||
this.orderBys = new ArrayList<>();
|
||||
}
|
||||
this.orderBys.add(orderBy);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QJoinMetaData withInferredName()
|
||||
{
|
||||
if(!StringUtils.hasContent(getLeftTable()) || !StringUtils.hasContent(getRightTable()))
|
||||
{
|
||||
throw (new IllegalStateException("Missing either a left or right table name when trying to set inferred name for join"));
|
||||
}
|
||||
return (withName(getLeftTable() + "Join" + getRightTable()));
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||
|
||||
/*******************************************************************************
|
||||
** A section of fields - a logical grouping.
|
||||
** TODO - this class should be named QTableSection!
|
||||
*******************************************************************************/
|
||||
public class QFieldSection
|
||||
{
|
||||
@ -36,6 +37,7 @@ public class QFieldSection
|
||||
private Tier tier;
|
||||
|
||||
private List<String> fieldNames;
|
||||
private String widgetName;
|
||||
private QIcon icon;
|
||||
|
||||
private boolean isHidden = false;
|
||||
@ -78,6 +80,18 @@ public class QFieldSection
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFieldSection(String name, QIcon icon, Tier tier)
|
||||
{
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
this.tier = tier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for name
|
||||
**
|
||||
@ -280,4 +294,38 @@ public class QFieldSection
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for widgetName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getWidgetName()
|
||||
{
|
||||
return widgetName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for widgetName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setWidgetName(String widgetName)
|
||||
{
|
||||
this.widgetName = widgetName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for widgetName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFieldSection withWidgetName(String widgetName)
|
||||
{
|
||||
this.widgetName = widgetName;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -80,7 +80,6 @@ public class QTableMetaData implements QAppChildMetaData, Serializable
|
||||
|
||||
private List<QFieldSection> sections;
|
||||
|
||||
private List<String> widgets;
|
||||
private List<AssociatedScript> associatedScripts;
|
||||
|
||||
private Set<Capability> enabledCapabilities = new HashSet<>();
|
||||
@ -726,40 +725,6 @@ public class QTableMetaData implements QAppChildMetaData, Serializable
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for widgets
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<String> getWidgets()
|
||||
{
|
||||
return widgets;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for widgets
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setWidgets(List<String> widgets)
|
||||
{
|
||||
this.widgets = widgets;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for widgets
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QTableMetaData withWidgets(List<String> widgets)
|
||||
{
|
||||
this.widgets = widgets;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for associatedScripts
|
||||
**
|
||||
|
@ -128,6 +128,8 @@ public class MemoryRecordStore
|
||||
}
|
||||
}
|
||||
|
||||
BackendQueryFilterUtils.sortRecordList(input.getFilter(), records);
|
||||
|
||||
return (records);
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutp
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||
@ -62,6 +63,9 @@ import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.DisplayFormat;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.PVSValueFormatAndFields;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValue;
|
||||
@ -116,8 +120,10 @@ public class TestUtils
|
||||
public static final String APP_NAME_PEOPLE = "peopleApp";
|
||||
public static final String APP_NAME_MISCELLANEOUS = "miscellaneous";
|
||||
|
||||
public static final String TABLE_NAME_PERSON = "person";
|
||||
public static final String TABLE_NAME_SHAPE = "shape";
|
||||
public static final String TABLE_NAME_PERSON = "person";
|
||||
public static final String TABLE_NAME_SHAPE = "shape";
|
||||
public static final String TABLE_NAME_ORDER = "order";
|
||||
public static final String TABLE_NAME_LINE_ITEM = "orderLine";
|
||||
|
||||
public static final String PROCESS_NAME_GREET_PEOPLE = "greet";
|
||||
public static final String PROCESS_NAME_GREET_PEOPLE_INTERACTIVE = "greetInteractive";
|
||||
@ -161,6 +167,10 @@ public class TestUtils
|
||||
qInstance.addTable(defineTableIdAndNameOnly());
|
||||
qInstance.addTable(defineTableShape());
|
||||
qInstance.addTable(defineTableBasepull());
|
||||
qInstance.addTable(defineTableOrder());
|
||||
qInstance.addTable(defineTableLineItem());
|
||||
|
||||
qInstance.addJoin(defineJoinOrderLineItem());
|
||||
|
||||
qInstance.addPossibleValueSource(defineAutomationStatusPossibleValueSource());
|
||||
qInstance.addPossibleValueSource(defineStatesPossibleValueSource());
|
||||
@ -444,6 +454,60 @@ public class TestUtils
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Define the order table used in standard tests.
|
||||
*******************************************************************************/
|
||||
public static QTableMetaData defineTableOrder()
|
||||
{
|
||||
return new QTableMetaData()
|
||||
.withName(TABLE_NAME_ORDER)
|
||||
.withBackendName(MEMORY_BACKEND_NAME)
|
||||
.withPrimaryKeyField("id")
|
||||
.withField(new QFieldMetaData("id", QFieldType.INTEGER).withIsEditable(false))
|
||||
.withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME).withIsEditable(false))
|
||||
.withField(new QFieldMetaData("modifyDate", QFieldType.DATE_TIME).withIsEditable(false))
|
||||
.withField(new QFieldMetaData("orderDate", QFieldType.DATE))
|
||||
.withField(new QFieldMetaData("total", QFieldType.DECIMAL).withDisplayFormat(DisplayFormat.CURRENCY));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Define the lineItem table used in standard tests.
|
||||
*******************************************************************************/
|
||||
public static QTableMetaData defineTableLineItem()
|
||||
{
|
||||
return new QTableMetaData()
|
||||
.withName(TABLE_NAME_LINE_ITEM)
|
||||
.withBackendName(MEMORY_BACKEND_NAME)
|
||||
.withPrimaryKeyField("id")
|
||||
.withField(new QFieldMetaData("id", QFieldType.INTEGER).withIsEditable(false))
|
||||
.withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME).withIsEditable(false))
|
||||
.withField(new QFieldMetaData("modifyDate", QFieldType.DATE_TIME).withIsEditable(false))
|
||||
.withField(new QFieldMetaData("orderId", QFieldType.INTEGER))
|
||||
.withField(new QFieldMetaData("lineNumber", QFieldType.STRING))
|
||||
.withField(new QFieldMetaData("sku", QFieldType.STRING))
|
||||
.withField(new QFieldMetaData("quantity", QFieldType.INTEGER));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static QJoinMetaData defineJoinOrderLineItem()
|
||||
{
|
||||
return new QJoinMetaData()
|
||||
.withName("orderLineItem")
|
||||
.withType(JoinType.ONE_TO_MANY)
|
||||
.withLeftTable(TABLE_NAME_ORDER)
|
||||
.withRightTable(TABLE_NAME_LINE_ITEM)
|
||||
.withJoinOn(new JoinOn("id", "orderId"))
|
||||
.withOrderBy(new QFilterOrderBy("lineNumber"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
Reference in New Issue
Block a user