mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
added ability to use filters to stop certain records from being cached, fixed insert bug due to binding instants to its default timestamp
This commit is contained in:
@ -36,6 +36,8 @@ import com.kingsrook.qqq.backend.core.actions.interfaces.GetInterface;
|
|||||||
import com.kingsrook.qqq.backend.core.actions.values.QPossibleValueTranslator;
|
import com.kingsrook.qqq.backend.core.actions.values.QPossibleValueTranslator;
|
||||||
import com.kingsrook.qqq.backend.core.actions.values.QValueFormatter;
|
import com.kingsrook.qqq.backend.core.actions.values.QValueFormatter;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.logging.LogPair;
|
||||||
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
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.get.GetOutput;
|
||||||
@ -53,6 +55,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.cache.CacheUseCase;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.cache.CacheUseCase;
|
||||||
import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleDispatcher;
|
import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleDispatcher;
|
||||||
import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleInterface;
|
import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.modules.backend.implementations.utils.BackendQueryFilterUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
import org.apache.commons.lang.NotImplementedException;
|
import org.apache.commons.lang.NotImplementedException;
|
||||||
@ -64,6 +67,8 @@ import org.apache.commons.lang.NotImplementedException;
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class GetAction
|
public class GetAction
|
||||||
{
|
{
|
||||||
|
private static final QLogger LOG = QLogger.getLogger(InsertAction.class);
|
||||||
|
|
||||||
private Optional<AbstractPostQueryCustomizer> postGetRecordCustomizer;
|
private Optional<AbstractPostQueryCustomizer> postGetRecordCustomizer;
|
||||||
|
|
||||||
private GetInput getInput;
|
private GetInput getInput;
|
||||||
@ -125,13 +130,34 @@ public class GetAction
|
|||||||
QRecord recordFromSource = tryToGetFromCacheSource(getInput, getOutput);
|
QRecord recordFromSource = tryToGetFromCacheSource(getInput, getOutput);
|
||||||
if(recordFromSource != null)
|
if(recordFromSource != null)
|
||||||
{
|
{
|
||||||
QRecord recordToCache = mapSourceRecordToCacheRecord(table, recordFromSource);
|
QRecord recordToCache = mapSourceRecordToCacheRecord(table, recordFromSource);
|
||||||
|
boolean shouldCacheRecord = true;
|
||||||
|
|
||||||
InsertInput insertInput = new InsertInput();
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
insertInput.setTableName(getInput.getTableName());
|
// see if there are any exclustions that need to be considered for this table //
|
||||||
insertInput.setRecords(List.of(recordToCache));
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
InsertOutput insertOutput = new InsertAction().execute(insertInput);
|
recordMatchExclusionLoop:
|
||||||
getOutput.setRecord(insertOutput.getRecords().get(0));
|
for(CacheUseCase useCase : CollectionUtils.nonNullList(table.getCacheOf().getUseCases()))
|
||||||
|
{
|
||||||
|
for(QQueryFilter filter : CollectionUtils.nonNullList(useCase.getExcludeRecordsMatching()))
|
||||||
|
{
|
||||||
|
if(BackendQueryFilterUtils.doesRecordMatch(filter, recordToCache))
|
||||||
|
{
|
||||||
|
LOG.info("Not catching record because it matches a use case's filter exclusion", new LogPair("record", recordToCache), new LogPair("filter", filter));
|
||||||
|
shouldCacheRecord = false;
|
||||||
|
break recordMatchExclusionLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(shouldCacheRecord)
|
||||||
|
{
|
||||||
|
InsertInput insertInput = new InsertInput();
|
||||||
|
insertInput.setTableName(getInput.getTableName());
|
||||||
|
insertInput.setRecords(List.of(recordToCache));
|
||||||
|
InsertOutput insertOutput = new InsertAction().execute(insertInput);
|
||||||
|
getOutput.setRecord(insertOutput.getRecords().get(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -257,7 +283,9 @@ public class GetAction
|
|||||||
sourceGetInput.setTableName(sourceTableName);
|
sourceGetInput.setTableName(sourceTableName);
|
||||||
sourceGetInput.setUniqueKey(getInput.getUniqueKey());
|
sourceGetInput.setUniqueKey(getInput.getUniqueKey());
|
||||||
GetOutput sourceGetOutput = new GetAction().execute(sourceGetInput);
|
GetOutput sourceGetOutput = new GetAction().execute(sourceGetInput);
|
||||||
return (sourceGetOutput.getRecord());
|
QRecord outputRecord = sourceGetOutput.getRecord();
|
||||||
|
|
||||||
|
return (outputRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
package com.kingsrook.qqq.backend.core.model.metadata.tables.cache;
|
package com.kingsrook.qqq.backend.core.model.metadata.tables.cache;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.UniqueKey;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.UniqueKey;
|
||||||
|
|
||||||
|
|
||||||
@ -48,6 +50,8 @@ public class CacheUseCase
|
|||||||
private UniqueKey cacheUniqueKey;
|
private UniqueKey cacheUniqueKey;
|
||||||
private UniqueKey sourceUniqueKey;
|
private UniqueKey sourceUniqueKey;
|
||||||
|
|
||||||
|
private List<QQueryFilter> excludeRecordsMatching;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -184,4 +188,38 @@ public class CacheUseCase
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for excludeRecordsMatching
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public List<QQueryFilter> getExcludeRecordsMatching()
|
||||||
|
{
|
||||||
|
return excludeRecordsMatching;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for excludeRecordsMatching
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setExcludeRecordsMatching(List<QQueryFilter> excludeRecordsMatching)
|
||||||
|
{
|
||||||
|
this.excludeRecordsMatching = excludeRecordsMatching;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for excludeRecordsMatching
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public CacheUseCase withExcludeRecordsMatching(List<QQueryFilter> excludeRecordsMatching)
|
||||||
|
{
|
||||||
|
this.excludeRecordsMatching = excludeRecordsMatching;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,8 @@ class GetActionTest extends BaseTest
|
|||||||
TestUtils.insertRecords(qInstance, qInstance.getTable(TestUtils.TABLE_NAME_PERSON_MEMORY), List.of(
|
TestUtils.insertRecords(qInstance, qInstance.getTable(TestUtils.TABLE_NAME_PERSON_MEMORY), List.of(
|
||||||
new QRecord().withValue("id", 1).withValue("firstName", "George").withValue("lastName", "Washington").withValue("noOfShoes", 5),
|
new QRecord().withValue("id", 1).withValue("firstName", "George").withValue("lastName", "Washington").withValue("noOfShoes", 5),
|
||||||
new QRecord().withValue("id", 2).withValue("firstName", "John").withValue("lastName", "Adams"),
|
new QRecord().withValue("id", 2).withValue("firstName", "John").withValue("lastName", "Adams"),
|
||||||
new QRecord().withValue("id", 3).withValue("firstName", "Thomas").withValue("lastName", "Jefferson")
|
new QRecord().withValue("id", 3).withValue("firstName", "Thomas").withValue("lastName", "Jefferson"),
|
||||||
|
new QRecord().withValue("id", 3).withValue("firstName", "Thomas 503").withValue("lastName", "Jefferson")
|
||||||
));
|
));
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
@ -117,6 +118,17 @@ class GetActionTest extends BaseTest
|
|||||||
assertEquals(5, getOutput.getRecord().getValue("noOfShoes"));
|
assertEquals(5, getOutput.getRecord().getValue("noOfShoes"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// try to get from the table which caches it - but should not find because use case should filter out because of matching 503 //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
{
|
||||||
|
GetInput getInput = new GetInput();
|
||||||
|
getInput.setTableName(TestUtils.TABLE_NAME_PERSON_MEMORY_CACHE);
|
||||||
|
getInput.setUniqueKey(Map.of("firstName", "Thomas 503", "lastName", "Jefferson"));
|
||||||
|
GetOutput getOutput = new GetAction().execute(getInput);
|
||||||
|
assertNull(getOutput.getRecord());
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// request a row that doesn't exist in cache or source, should miss both //
|
// request a row that doesn't exist in cache or source, should miss both //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -739,6 +739,15 @@ public class TestUtils
|
|||||||
.withSourceUniqueKey(uniqueKey)
|
.withSourceUniqueKey(uniqueKey)
|
||||||
.withCacheUniqueKey(uniqueKey)
|
.withCacheUniqueKey(uniqueKey)
|
||||||
.withCacheSourceMisses(false)
|
.withCacheSourceMisses(false)
|
||||||
|
.withExcludeRecordsMatching(List.of(
|
||||||
|
new QQueryFilter(
|
||||||
|
new QFilterCriteria(
|
||||||
|
"firstName",
|
||||||
|
QCriteriaOperator.CONTAINS,
|
||||||
|
List.of("503")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,7 +739,7 @@ public class QueryManager
|
|||||||
}
|
}
|
||||||
else if(value instanceof Instant i)
|
else if(value instanceof Instant i)
|
||||||
{
|
{
|
||||||
statement.setString(index, i.toString());
|
statement.setString(index, i.toString().replaceAll("T", " ").replaceAll("Z", ""));
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
else if(value instanceof LocalDate ld)
|
else if(value instanceof LocalDate ld)
|
||||||
|
Reference in New Issue
Block a user