mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-20 06:00:44 +00:00
Updating to support possible value searching
This commit is contained in:
@ -111,7 +111,35 @@ public class QPossibleValueTranslator
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Translate a list of ids to a list of possible values (e.g., w/ rendered values)
|
||||
*******************************************************************************/
|
||||
public List<QPossibleValue<?>> buildTranslatedPossibleValueList(QPossibleValueSource possibleValueSource, List<Serializable> ids)
|
||||
{
|
||||
if(ids == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
if(ids.isEmpty())
|
||||
{
|
||||
return (new ArrayList<>());
|
||||
}
|
||||
|
||||
List<QPossibleValue<?>> rs = new ArrayList<>();
|
||||
primePvsCache(possibleValueSource.getTableName(), List.of(possibleValueSource), ids);
|
||||
for(Serializable id : ids)
|
||||
{
|
||||
String translated = translatePossibleValue(possibleValueSource, id);
|
||||
rs.add(new QPossibleValue<>(id, translated));
|
||||
}
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** For a given field and (raw/id) value, get the translated (string) value.
|
||||
*******************************************************************************/
|
||||
String translatePossibleValue(QFieldMetaData field, Serializable value)
|
||||
{
|
||||
@ -122,6 +150,16 @@ public class QPossibleValueTranslator
|
||||
return (null);
|
||||
}
|
||||
|
||||
return translatePossibleValue(possibleValueSource, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** For a given PossibleValueSource and (raw/id) value, get the translated (string) value.
|
||||
*******************************************************************************/
|
||||
String translatePossibleValue(QPossibleValueSource possibleValueSource, Serializable value)
|
||||
{
|
||||
String resultValue = null;
|
||||
if(possibleValueSource.getType().equals(QPossibleValueSourceType.ENUM))
|
||||
{
|
||||
@ -129,15 +167,15 @@ public class QPossibleValueTranslator
|
||||
}
|
||||
else if(possibleValueSource.getType().equals(QPossibleValueSourceType.TABLE))
|
||||
{
|
||||
resultValue = translatePossibleValueTable(field, value, possibleValueSource);
|
||||
resultValue = translatePossibleValueTable(value, possibleValueSource);
|
||||
}
|
||||
else if(possibleValueSource.getType().equals(QPossibleValueSourceType.CUSTOM))
|
||||
{
|
||||
resultValue = translatePossibleValueCustom(field, value, possibleValueSource);
|
||||
resultValue = translatePossibleValueCustom(value, possibleValueSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.error("Unrecognized possibleValueSourceType [" + possibleValueSource.getType() + "] in PVS named [" + possibleValueSource.getName() + "] on field [" + field.getName() + "]");
|
||||
LOG.error("Unrecognized possibleValueSourceType [" + possibleValueSource.getType() + "] in PVS named [" + possibleValueSource.getName() + "]");
|
||||
}
|
||||
|
||||
if(resultValue == null)
|
||||
@ -151,7 +189,7 @@ public class QPossibleValueTranslator
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** do translation for an enum-type PVS
|
||||
*******************************************************************************/
|
||||
private String translatePossibleValueEnum(Serializable value, QPossibleValueSource possibleValueSource)
|
||||
{
|
||||
@ -169,9 +207,9 @@ public class QPossibleValueTranslator
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** do translation for a table-type PVS
|
||||
*******************************************************************************/
|
||||
private String translatePossibleValueTable(QFieldMetaData field, Serializable value, QPossibleValueSource possibleValueSource)
|
||||
String translatePossibleValueTable(Serializable value, QPossibleValueSource possibleValueSource)
|
||||
{
|
||||
/////////////////////////////////
|
||||
// null input gets null output //
|
||||
@ -197,9 +235,9 @@ public class QPossibleValueTranslator
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** do translation for a custom-type PVS
|
||||
*******************************************************************************/
|
||||
private String translatePossibleValueCustom(QFieldMetaData field, Serializable value, QPossibleValueSource possibleValueSource)
|
||||
private String translatePossibleValueCustom(Serializable value, QPossibleValueSource possibleValueSource)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -208,7 +246,7 @@ public class QPossibleValueTranslator
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
LOG.warn("Error sending [" + value + "] for field [" + field + "] through custom code for PVS [" + field.getPossibleValueSourceName() + "]", e);
|
||||
LOG.warn("Error sending [" + value + "] for through custom code for PVS [" + possibleValueSource.getName() + "]", e);
|
||||
}
|
||||
|
||||
return (null);
|
||||
|
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* 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.values;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
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.values.SearchPossibleValueSourceInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.values.SearchPossibleValueSourceOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
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.possiblevalues.QPossibleValue;
|
||||
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.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Class responsible for looking up possible-values for fields/records and
|
||||
** make them into display values.
|
||||
*******************************************************************************/
|
||||
public class SearchPossibleValueSourceAction
|
||||
{
|
||||
private static final Logger LOG = LogManager.getLogger(SearchPossibleValueSourceAction.class);
|
||||
|
||||
private QPossibleValueTranslator possibleValueTranslator;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceOutput execute(SearchPossibleValueSourceInput input) throws QException
|
||||
{
|
||||
QInstance qInstance = input.getInstance();
|
||||
QPossibleValueSource possibleValueSource = qInstance.getPossibleValueSource(input.getPossibleValueSourceName());
|
||||
if(possibleValueSource == null)
|
||||
{
|
||||
throw new QException("Missing possible value source named [" + input.getPossibleValueSourceName() + "]");
|
||||
}
|
||||
|
||||
possibleValueTranslator = new QPossibleValueTranslator(input.getInstance(), input.getSession());
|
||||
SearchPossibleValueSourceOutput output = null;
|
||||
if(possibleValueSource.getType().equals(QPossibleValueSourceType.ENUM))
|
||||
{
|
||||
output = searchPossibleValueEnum(input, possibleValueSource);
|
||||
}
|
||||
else if(possibleValueSource.getType().equals(QPossibleValueSourceType.TABLE))
|
||||
{
|
||||
output = searchPossibleValueTable(input, possibleValueSource);
|
||||
}
|
||||
else if(possibleValueSource.getType().equals(QPossibleValueSourceType.CUSTOM))
|
||||
{
|
||||
output = searchPossibleValueCustom(input, possibleValueSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.error("Unrecognized possibleValueSourceType [" + possibleValueSource.getType() + "] in PVS named [" + possibleValueSource.getName() + "]");
|
||||
}
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private SearchPossibleValueSourceOutput searchPossibleValueEnum(SearchPossibleValueSourceInput input, QPossibleValueSource possibleValueSource)
|
||||
{
|
||||
SearchPossibleValueSourceOutput output = new SearchPossibleValueSourceOutput();
|
||||
List<Serializable> matchingIds = new ArrayList<>();
|
||||
|
||||
for(QPossibleValue<?> possibleValue : possibleValueSource.getEnumValues())
|
||||
{
|
||||
boolean match = false;
|
||||
|
||||
if(input.getIdList() != null)
|
||||
{
|
||||
if(input.getIdList().contains(possibleValue.getId()))
|
||||
{
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(StringUtils.hasContent(input.getSearchTerm()))
|
||||
{
|
||||
match = (Objects.equals(ValueUtils.getValueAsString(possibleValue.getId()).toLowerCase(), input.getSearchTerm().toLowerCase())
|
||||
|| possibleValue.getLabel().toLowerCase().startsWith(input.getSearchTerm().toLowerCase()));
|
||||
}
|
||||
else
|
||||
{
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(match)
|
||||
{
|
||||
matchingIds.add((Serializable) possibleValue.getId());
|
||||
}
|
||||
|
||||
// todo - skip & limit?
|
||||
// todo - default filter
|
||||
}
|
||||
|
||||
List<QPossibleValue<?>> qPossibleValues = possibleValueTranslator.buildTranslatedPossibleValueList(possibleValueSource, matchingIds);
|
||||
output.setResults(qPossibleValues);
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private SearchPossibleValueSourceOutput searchPossibleValueTable(SearchPossibleValueSourceInput input, QPossibleValueSource possibleValueSource) throws QException
|
||||
{
|
||||
SearchPossibleValueSourceOutput output = new SearchPossibleValueSourceOutput();
|
||||
|
||||
QueryInput queryInput = new QueryInput(input.getInstance());
|
||||
queryInput.setSession(input.getSession());
|
||||
queryInput.setTableName(possibleValueSource.getTableName());
|
||||
|
||||
QTableMetaData table = input.getInstance().getTable(possibleValueSource.getTableName());
|
||||
|
||||
QQueryFilter queryFilter = new QQueryFilter();
|
||||
queryFilter.setBooleanOperator(QQueryFilter.BooleanOperator.OR);
|
||||
queryInput.setFilter(queryFilter);
|
||||
|
||||
if(input.getIdList() != null)
|
||||
{
|
||||
queryFilter.addCriteria(new QFilterCriteria(table.getPrimaryKeyField(), QCriteriaOperator.IN, input.getIdList()));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(StringUtils.hasContent(input.getSearchTerm()))
|
||||
{
|
||||
for(String valueField : possibleValueSource.getSearchFields())
|
||||
{
|
||||
QFieldMetaData field = table.getField(valueField);
|
||||
if(field.getType().equals(QFieldType.STRING))
|
||||
{
|
||||
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.STARTS_WITH, List.of(input.getSearchTerm())));
|
||||
}
|
||||
else if(field.getType().equals(QFieldType.DATE) || field.getType().equals(QFieldType.DATE_TIME))
|
||||
{
|
||||
LOG.debug("Not querying PVS [" + possibleValueSource.getName() + "] on date field [" + field.getName() + "]");
|
||||
// todo - what? queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.STARTS_WITH, List.of(input.getSearchTerm())));
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Integer valueAsInteger = ValueUtils.getValueAsInteger(input.getSearchTerm());
|
||||
if(valueAsInteger != null)
|
||||
{
|
||||
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.EQUALS, List.of(valueAsInteger)));
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
////////////////////////////////////////////////////////
|
||||
// write a FALSE criteria if the value isn't a number //
|
||||
////////////////////////////////////////////////////////
|
||||
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.IN, List.of()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
queryFilter.setOrderBys(possibleValueSource.getOrderByFields());
|
||||
|
||||
// todo - default filter
|
||||
|
||||
// todo - skip & limit as params
|
||||
queryInput.setLimit(250);
|
||||
|
||||
QueryOutput queryOutput = new QueryAction().execute(queryInput);
|
||||
List<Serializable> ids = queryOutput.getRecords().stream().map(r -> r.getValue(table.getPrimaryKeyField())).toList();
|
||||
List<QPossibleValue<?>> qPossibleValues = possibleValueTranslator.buildTranslatedPossibleValueList(possibleValueSource, ids);
|
||||
output.setResults(qPossibleValues);
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private SearchPossibleValueSourceOutput searchPossibleValueCustom(SearchPossibleValueSourceInput input, QPossibleValueSource possibleValueSource)
|
||||
{
|
||||
try
|
||||
{
|
||||
// QCustomPossibleValueProvider customPossibleValueProvider = QCodeLoader.getCustomPossibleValueProvider(possibleValueSource);
|
||||
// return (formatPossibleValue(possibleValueSource, customPossibleValueProvider.getPossibleValue(value)));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// LOG.warn("Error sending [" + value + "] for field [" + field + "] through custom code for PVS [" + field.getPossibleValueSourceName() + "]", e);
|
||||
}
|
||||
|
||||
throw new NotImplementedException("Not impleemnted");
|
||||
// return (null);
|
||||
}
|
||||
|
||||
}
|
@ -121,6 +121,11 @@ public class QInstanceEnricher
|
||||
{
|
||||
qInstance.getReports().values().forEach(this::enrichReport);
|
||||
}
|
||||
|
||||
if(qInstance.getPossibleValueSources() != null)
|
||||
{
|
||||
qInstance.getPossibleValueSources().values().forEach(this::enrichPossibleValueSource);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -748,4 +753,50 @@ public class QInstanceEnricher
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void enrichPossibleValueSource(QPossibleValueSource possibleValueSource)
|
||||
{
|
||||
if(QPossibleValueSourceType.TABLE.equals(possibleValueSource.getType()))
|
||||
{
|
||||
if(CollectionUtils.nullSafeIsEmpty(possibleValueSource.getSearchFields()))
|
||||
{
|
||||
QTableMetaData table = qInstance.getTable(possibleValueSource.getTableName());
|
||||
if(table != null)
|
||||
{
|
||||
if(table.getPrimaryKeyField() != null)
|
||||
{
|
||||
possibleValueSource.withSearchField(table.getPrimaryKeyField());
|
||||
}
|
||||
|
||||
for(String recordLabelField : CollectionUtils.nonNullList(table.getRecordLabelFields()))
|
||||
{
|
||||
possibleValueSource.withSearchField(recordLabelField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(CollectionUtils.nullSafeIsEmpty(possibleValueSource.getOrderByFields()))
|
||||
{
|
||||
QTableMetaData table = qInstance.getTable(possibleValueSource.getTableName());
|
||||
if(table != null)
|
||||
{
|
||||
for(String recordLabelField : CollectionUtils.nonNullList(table.getRecordLabelFields()))
|
||||
{
|
||||
possibleValueSource.withOrderByField(recordLabelField);
|
||||
}
|
||||
|
||||
if(table.getPrimaryKeyField() != null)
|
||||
{
|
||||
possibleValueSource.withOrderByField(table.getPrimaryKeyField());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizers;
|
||||
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||
import com.kingsrook.qqq.backend.core.actions.values.QCustomPossibleValueProvider;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeType;
|
||||
@ -715,6 +716,8 @@ public class QInstanceValidator
|
||||
case ENUM ->
|
||||
{
|
||||
assertCondition(!StringUtils.hasContent(possibleValueSource.getTableName()), "enum-type possibleValueSource " + pvsName + " should not have a tableName.");
|
||||
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getSearchFields()), "enum-type possibleValueSource " + pvsName + " should not have searchFields.");
|
||||
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getOrderByFields()), "enum-type possibleValueSource " + pvsName + " should not have orderByFields.");
|
||||
assertCondition(possibleValueSource.getCustomCodeReference() == null, "enum-type possibleValueSource " + pvsName + " should not have a customCodeReference.");
|
||||
|
||||
assertCondition(CollectionUtils.nullSafeHasContents(possibleValueSource.getEnumValues()), "enum-type possibleValueSource " + pvsName + " is missing enum values");
|
||||
@ -724,15 +727,44 @@ public class QInstanceValidator
|
||||
assertCondition(CollectionUtils.nullSafeIsEmpty(possibleValueSource.getEnumValues()), "table-type possibleValueSource " + pvsName + " should not have enum values.");
|
||||
assertCondition(possibleValueSource.getCustomCodeReference() == null, "table-type possibleValueSource " + pvsName + " should not have a customCodeReference.");
|
||||
|
||||
QTableMetaData tableMetaData = null;
|
||||
if(assertCondition(StringUtils.hasContent(possibleValueSource.getTableName()), "table-type possibleValueSource " + pvsName + " is missing a tableName."))
|
||||
{
|
||||
assertCondition(qInstance.getTable(possibleValueSource.getTableName()) != null, "Unrecognized table " + possibleValueSource.getTableName() + " for possibleValueSource " + pvsName + ".");
|
||||
tableMetaData = qInstance.getTable(possibleValueSource.getTableName());
|
||||
assertCondition(tableMetaData != null, "Unrecognized table " + possibleValueSource.getTableName() + " for possibleValueSource " + pvsName + ".");
|
||||
}
|
||||
|
||||
if(assertCondition(CollectionUtils.nullSafeHasContents(possibleValueSource.getSearchFields()), "table-type possibleValueSource " + pvsName + " is missing searchFields."))
|
||||
{
|
||||
if(tableMetaData != null)
|
||||
{
|
||||
QTableMetaData finalTableMetaData = tableMetaData;
|
||||
for(String searchField : possibleValueSource.getSearchFields())
|
||||
{
|
||||
assertNoException(() -> finalTableMetaData.getField(searchField), "possibleValueSource " + pvsName + " has an unrecognized searchField: " + searchField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(assertCondition(CollectionUtils.nullSafeHasContents(possibleValueSource.getOrderByFields()), "table-type possibleValueSource " + pvsName + " is missing orderByFields."))
|
||||
{
|
||||
if(tableMetaData != null)
|
||||
{
|
||||
QTableMetaData finalTableMetaData = tableMetaData;
|
||||
|
||||
for(QFilterOrderBy orderByField : possibleValueSource.getOrderByFields())
|
||||
{
|
||||
assertNoException(() -> finalTableMetaData.getField(orderByField.getFieldName()), "possibleValueSource " + pvsName + " has an unrecognized orderByField: " + orderByField.getFieldName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case CUSTOM ->
|
||||
{
|
||||
assertCondition(CollectionUtils.nullSafeIsEmpty(possibleValueSource.getEnumValues()), "custom-type possibleValueSource " + pvsName + " should not have enum values.");
|
||||
assertCondition(!StringUtils.hasContent(possibleValueSource.getTableName()), "custom-type possibleValueSource " + pvsName + " should not have a tableName.");
|
||||
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getSearchFields()), "custom-type possibleValueSource " + pvsName + " should not have searchFields.");
|
||||
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getOrderByFields()), "custom-type possibleValueSource " + pvsName + " should not have orderByFields.");
|
||||
|
||||
if(assertCondition(possibleValueSource.getCustomCodeReference() != null, "custom-type possibleValueSource " + pvsName + " is missing a customCodeReference."))
|
||||
{
|
||||
|
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* 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.actions.values;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Input for the Search possible value source action
|
||||
*******************************************************************************/
|
||||
public class SearchPossibleValueSourceInput extends AbstractActionInput
|
||||
{
|
||||
private String possibleValueSourceName;
|
||||
private QQueryFilter defaultQueryFilter;
|
||||
private String searchTerm;
|
||||
private List<Serializable> idList;
|
||||
|
||||
private Integer skip = 0;
|
||||
private Integer limit = 100;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceInput()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceInput(QInstance instance)
|
||||
{
|
||||
super(instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for possibleValueSourceName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getPossibleValueSourceName()
|
||||
{
|
||||
return possibleValueSourceName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for possibleValueSourceName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setPossibleValueSourceName(String possibleValueSourceName)
|
||||
{
|
||||
this.possibleValueSourceName = possibleValueSourceName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for possibleValueSourceName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceInput withPossibleValueSourceName(String possibleValueSourceName)
|
||||
{
|
||||
this.possibleValueSourceName = possibleValueSourceName;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for defaultQueryFilter
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QQueryFilter getDefaultQueryFilter()
|
||||
{
|
||||
return defaultQueryFilter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for defaultQueryFilter
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setDefaultQueryFilter(QQueryFilter defaultQueryFilter)
|
||||
{
|
||||
this.defaultQueryFilter = defaultQueryFilter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for defaultQueryFilter
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceInput withDefaultQueryFilter(QQueryFilter defaultQueryFilter)
|
||||
{
|
||||
this.defaultQueryFilter = defaultQueryFilter;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for searchTerm
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getSearchTerm()
|
||||
{
|
||||
return searchTerm;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for searchTerm
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setSearchTerm(String searchTerm)
|
||||
{
|
||||
this.searchTerm = searchTerm;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for searchTerm
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceInput withSearchTerm(String searchTerm)
|
||||
{
|
||||
this.searchTerm = searchTerm;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for idList
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<Serializable> getIdList()
|
||||
{
|
||||
return idList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for idList
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setIdList(List<Serializable> idList)
|
||||
{
|
||||
this.idList = idList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for idList
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceInput withIdList(List<Serializable> idList)
|
||||
{
|
||||
this.idList = idList;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for skip
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Integer getSkip()
|
||||
{
|
||||
return skip;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for skip
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setSkip(Integer skip)
|
||||
{
|
||||
this.skip = skip;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for skip
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceInput withSkip(Integer skip)
|
||||
{
|
||||
this.skip = skip;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for limit
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Integer getLimit()
|
||||
{
|
||||
return limit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for limit
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setLimit(Integer limit)
|
||||
{
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for limit
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceInput withLimit(Integer limit)
|
||||
{
|
||||
this.limit = limit;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.actions.values;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValue;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Output for the Search possible value source action
|
||||
*******************************************************************************/
|
||||
public class SearchPossibleValueSourceOutput extends AbstractActionOutput
|
||||
{
|
||||
private List<QPossibleValue<?>> results = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceOutput()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addResult(QPossibleValue<?> possibleValue)
|
||||
{
|
||||
results.add(possibleValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for results
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QPossibleValue<?>> getResults()
|
||||
{
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for results
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setResults(List<QPossibleValue<?>> results)
|
||||
{
|
||||
this.results = results;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for results
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SearchPossibleValueSourceOutput withResults(List<QPossibleValue<?>> results)
|
||||
{
|
||||
this.results = results;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.model.metadata.possiblevalues;
|
||||
|
||||
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.model.metadata.code.QCodeReference;
|
||||
|
||||
|
||||
@ -48,8 +49,9 @@ public class QPossibleValueSource
|
||||
//////////////////////
|
||||
// for type = TABLE //
|
||||
//////////////////////
|
||||
private String tableName;
|
||||
// todo - override labelFormat & labelFields?
|
||||
private String tableName;
|
||||
private List<String> searchFields;
|
||||
private List<QFilterOrderBy> orderByFields;
|
||||
|
||||
/////////////////////
|
||||
// for type = ENUM //
|
||||
@ -304,6 +306,128 @@ public class QPossibleValueSource
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for searchFields
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<String> getSearchFields()
|
||||
{
|
||||
return searchFields;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for searchFields
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setSearchFields(List<String> searchFields)
|
||||
{
|
||||
this.searchFields = searchFields;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for searchFields
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QPossibleValueSource withSearchFields(List<String> searchFields)
|
||||
{
|
||||
this.searchFields = searchFields;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for searchFields
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QPossibleValueSource withSearchField(String searchField)
|
||||
{
|
||||
if(this.searchFields == null)
|
||||
{
|
||||
this.searchFields = new ArrayList<>();
|
||||
}
|
||||
this.searchFields.add(searchField);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for orderByFields
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QFilterOrderBy> getOrderByFields()
|
||||
{
|
||||
return orderByFields;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for orderByFields
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setOrderByFields(List<QFilterOrderBy> orderByFields)
|
||||
{
|
||||
this.orderByFields = orderByFields;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for orderByFields
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QPossibleValueSource withOrderByFields(List<QFilterOrderBy> orderByFields)
|
||||
{
|
||||
this.orderByFields = orderByFields;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for orderByFields
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QPossibleValueSource withOrderByField(QFilterOrderBy orderByField)
|
||||
{
|
||||
if(this.orderByFields == null)
|
||||
{
|
||||
this.orderByFields = new ArrayList<>();
|
||||
}
|
||||
this.orderByFields.add(orderByField);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for orderByFields - default to ASCENDING
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QPossibleValueSource withOrderByField(String fieldName)
|
||||
{
|
||||
return (withOrderByField(new QFilterOrderBy(fieldName)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for orderByFields
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QPossibleValueSource withOrderByField(String fieldName, boolean isAscending)
|
||||
{
|
||||
return (withOrderByField(new QFilterOrderBy(fieldName, isAscending)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for enumValues
|
||||
**
|
||||
|
@ -364,7 +364,17 @@ public class MemoryRecordStore
|
||||
return (false);
|
||||
}
|
||||
|
||||
if(!value.equals(criterion.getValues().get(0)))
|
||||
Serializable criteriaValue = criterion.getValues().get(0);
|
||||
if(value instanceof String && criteriaValue instanceof Number)
|
||||
{
|
||||
criteriaValue = String.valueOf(criteriaValue);
|
||||
}
|
||||
else if(criteriaValue instanceof String && value instanceof Number)
|
||||
{
|
||||
value = String.valueOf(value);
|
||||
}
|
||||
|
||||
if(!value.equals(criteriaValue))
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
|
@ -454,7 +454,14 @@ public class ValueUtils
|
||||
return (null);
|
||||
}
|
||||
|
||||
return Instant.parse(s);
|
||||
try
|
||||
{
|
||||
return Instant.parse(s);
|
||||
}
|
||||
catch(DateTimeParseException e)
|
||||
{
|
||||
return tryAlternativeInstantParsing(s, e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -473,6 +480,26 @@ public class ValueUtils
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static Instant tryAlternativeInstantParsing(String s, DateTimeParseException e)
|
||||
{
|
||||
if(s.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}$"))
|
||||
{
|
||||
//////////////////////////
|
||||
// todo ... time zone?? //
|
||||
//////////////////////////
|
||||
return Instant.parse(s + ":00Z");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw (e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
Reference in New Issue
Block a user