mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Support searching for a localdate or instant.
This commit is contained in:
@ -23,6 +23,8 @@ package com.kingsrook.qqq.backend.core.actions.values;
|
|||||||
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -208,41 +210,54 @@ public class SearchPossibleValueSourceAction
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(StringUtils.hasContent(input.getSearchTerm()))
|
String searchTerm = input.getSearchTerm();
|
||||||
|
if(StringUtils.hasContent(searchTerm))
|
||||||
{
|
{
|
||||||
for(String valueField : possibleValueSource.getSearchFields())
|
for(String valueField : possibleValueSource.getSearchFields())
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
QFieldMetaData field = table.getField(valueField);
|
QFieldMetaData field = table.getField(valueField);
|
||||||
if(field.getType().equals(QFieldType.STRING))
|
if(field.getType().equals(QFieldType.STRING))
|
||||||
{
|
{
|
||||||
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.STARTS_WITH, List.of(input.getSearchTerm())));
|
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.STARTS_WITH, List.of(searchTerm)));
|
||||||
}
|
}
|
||||||
else if(field.getType().equals(QFieldType.DATE) || field.getType().equals(QFieldType.DATE_TIME))
|
else if(field.getType().equals(QFieldType.DATE))
|
||||||
{
|
{
|
||||||
LOG.debug("Not querying PVS [" + possibleValueSource.getName() + "] on date field [" + field.getName() + "]");
|
LocalDate searchDate = ValueUtils.getValueAsLocalDate(searchTerm);
|
||||||
// todo - what? queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.STARTS_WITH, List.of(input.getSearchTerm())));
|
if(searchDate != null)
|
||||||
|
{
|
||||||
|
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.EQUALS, searchDate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(field.getType().equals(QFieldType.DATE_TIME))
|
||||||
|
{
|
||||||
|
Instant searchDate = ValueUtils.getValueAsInstant(searchTerm);
|
||||||
|
if(searchDate != null)
|
||||||
|
{
|
||||||
|
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.EQUALS, searchDate));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
Integer valueAsInteger = ValueUtils.getValueAsInteger(searchTerm);
|
||||||
{
|
|
||||||
Integer valueAsInteger = ValueUtils.getValueAsInteger(input.getSearchTerm());
|
|
||||||
if(valueAsInteger != null)
|
if(valueAsInteger != null)
|
||||||
{
|
{
|
||||||
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.EQUALS, List.of(valueAsInteger)));
|
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.EQUALS, List.of(valueAsInteger)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// write a FALSE criteria if the value isn't a number //
|
// write a FALSE criteria upon exceptions (e.g., type conversion fails) //
|
||||||
////////////////////////////////////////////////////////
|
// Why are we doing this? so a single-field query finds nothing instead of everything. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.IN, List.of()));
|
queryFilter.addCriteria(new QFilterCriteria(valueField, QCriteriaOperator.IN, List.of()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// todo - skip & limit as params
|
// todo - skip & limit as params
|
||||||
queryFilter.setLimit(250);
|
queryFilter.setLimit(250);
|
||||||
|
@ -23,12 +23,18 @@ package com.kingsrook.qqq.backend.core.actions.values;
|
|||||||
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.Month;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.kingsrook.qqq.backend.core.BaseTest;
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.values.SearchPossibleValueSourceInput;
|
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.actions.values.SearchPossibleValueSourceOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||||
import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore;
|
import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore;
|
||||||
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
@ -224,6 +230,74 @@ class SearchPossibleValueSourceActionTest extends BaseTest
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testSearchPvsAction_tableByIdOnlyNonNumeric() throws QException
|
||||||
|
{
|
||||||
|
QContext.getQInstance().getPossibleValueSource(TestUtils.TABLE_NAME_SHAPE)
|
||||||
|
.withSearchFields(List.of("id"));
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// a non-integer input should find nothing //
|
||||||
|
// the catch { (IN, empty) } code makes this happen - without that, all records are found. //
|
||||||
|
// (furthermore, i think that's only exposed if there's only 1 search field, maybe) //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
SearchPossibleValueSourceOutput output = getSearchPossibleValueSourceOutput("A", TestUtils.TABLE_NAME_SHAPE);
|
||||||
|
assertEquals(0, output.getResults().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testSearchPvsAction_tableByLocalDate() throws QException
|
||||||
|
{
|
||||||
|
MemoryRecordStore.getInstance().reset();
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
// make a PVS for the person-memory table //
|
||||||
|
////////////////////////////////////////////
|
||||||
|
QContext.getQInstance().addPossibleValueSource(QPossibleValueSource.newForTable(TestUtils.TABLE_NAME_PERSON_MEMORY)
|
||||||
|
.withSearchFields(List.of("id", "firstName", "birthDate"))
|
||||||
|
);
|
||||||
|
|
||||||
|
List<QRecord> shapeRecords = List.of(
|
||||||
|
new QRecord().withValue("id", 1).withValue("firstName", "Homer").withValue("birthDate", LocalDate.of(1960, Month.JANUARY, 1)),
|
||||||
|
new QRecord().withValue("id", 2).withValue("firstName", "Marge").withValue("birthDate", LocalDate.of(1961, Month.FEBRUARY, 2)),
|
||||||
|
new QRecord().withValue("id", 3).withValue("firstName", "Bart").withValue("birthDate", LocalDate.of(1980, Month.MARCH, 3)));
|
||||||
|
|
||||||
|
InsertInput insertInput = new InsertInput();
|
||||||
|
insertInput.setTableName(TestUtils.TABLE_NAME_PERSON_MEMORY);
|
||||||
|
insertInput.setRecords(shapeRecords);
|
||||||
|
new InsertAction().execute(insertInput);
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// a parseable date yields a match //
|
||||||
|
/////////////////////////////////////
|
||||||
|
SearchPossibleValueSourceOutput output = getSearchPossibleValueSourceOutput("1960-01-01", TestUtils.TABLE_NAME_PERSON_MEMORY);
|
||||||
|
assertEquals(1, output.getResults().size());
|
||||||
|
assertThat(output.getResults()).anyMatch(pv -> pv.getId().equals(1));
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// alternative date format also works (thanks to ValueUtils parsing) //
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
output = getSearchPossibleValueSourceOutput("1/1/1960", TestUtils.TABLE_NAME_PERSON_MEMORY);
|
||||||
|
assertEquals(1, output.getResults().size());
|
||||||
|
assertThat(output.getResults()).anyMatch(pv -> pv.getId().equals(1));
|
||||||
|
|
||||||
|
///////////////////////////////////
|
||||||
|
// incomplete date finds nothing //
|
||||||
|
///////////////////////////////////
|
||||||
|
output = getSearchPossibleValueSourceOutput("1960-01", TestUtils.TABLE_NAME_PERSON_MEMORY);
|
||||||
|
assertEquals(0, output.getResults().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
Reference in New Issue
Block a user