mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Update query action cache helper to respect if a table says it can't do QUERY - to do GET instead
This commit is contained in:
@ -196,14 +196,7 @@ public class GetAction
|
||||
}
|
||||
|
||||
queryInput.setFilter(filter);
|
||||
queryInput.setTransaction(getInput.getTransaction());
|
||||
queryInput.setIncludeAssociations(getInput.getIncludeAssociations());
|
||||
queryInput.setAssociationNamesToInclude(getInput.getAssociationNamesToInclude());
|
||||
queryInput.setShouldTranslatePossibleValues(getInput.getShouldTranslatePossibleValues());
|
||||
queryInput.setShouldGenerateDisplayValues(getInput.getShouldGenerateDisplayValues());
|
||||
queryInput.setShouldFetchHeavyFields(getInput.getShouldFetchHeavyFields());
|
||||
queryInput.setShouldMaskPasswords(getInput.getShouldMaskPasswords());
|
||||
queryInput.setShouldOmitHiddenFields(getInput.getShouldOmitHiddenFields());
|
||||
queryInput.setCommonParamsFrom(getInput);
|
||||
return queryInput;
|
||||
}
|
||||
|
||||
|
@ -34,12 +34,16 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction;
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
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.get.GetInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||
@ -50,6 +54,8 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.Capability;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.UniqueKey;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.cache.CacheUseCase;
|
||||
@ -532,7 +538,7 @@ public class QueryActionCacheHelper
|
||||
|
||||
if(CacheUseCase.Type.UNIQUE_KEY_TO_UNIQUE_KEY.equals(activeCacheUseCase))
|
||||
{
|
||||
recordsFromSource = getFromCachedSourceForUniqueKeyToUniqueKey(uniqueKeyValues, table.getCacheOf().getSourceTable());
|
||||
recordsFromSource = getFromCachedSourceForUniqueKeyToUniqueKey(queryInput, uniqueKeyValues, table.getCacheOf().getSourceTable());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -548,30 +554,69 @@ public class QueryActionCacheHelper
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private List<QRecord> getFromCachedSourceForUniqueKeyToUniqueKey(Set<List<Serializable>> uniqueKeyValues, String sourceTableName) throws QException
|
||||
private List<QRecord> getFromCachedSourceForUniqueKeyToUniqueKey(QueryInput cacheQueryInput, Set<List<Serializable>> uniqueKeyValues, String sourceTableName) throws QException
|
||||
{
|
||||
///////////////////////////////////////////////////////
|
||||
// do a Query on the source table, by the unique key //
|
||||
///////////////////////////////////////////////////////
|
||||
QueryInput sourceQueryInput = new QueryInput();
|
||||
sourceQueryInput.setTableName(sourceTableName);
|
||||
QTableMetaData sourceTable = QContext.getQInstance().getTable(sourceTableName);
|
||||
QBackendMetaData sourceBackend = QContext.getQInstance().getBackendForTable(sourceTableName);
|
||||
|
||||
QQueryFilter filter = new QQueryFilter().withBooleanOperator(QQueryFilter.BooleanOperator.OR);
|
||||
sourceQueryInput.setFilter(filter);
|
||||
|
||||
for(List<Serializable> uniqueKeyValue : uniqueKeyValues)
|
||||
if(sourceTable.isCapabilityEnabled(sourceBackend, Capability.TABLE_QUERY))
|
||||
{
|
||||
QQueryFilter subFilter = new QQueryFilter();
|
||||
filter.addSubFilter(subFilter);
|
||||
///////////////////////////////////////////////////////
|
||||
// do a Query on the source table, by the unique key //
|
||||
///////////////////////////////////////////////////////
|
||||
QueryInput sourceQueryInput = new QueryInput();
|
||||
sourceQueryInput.setTableName(sourceTableName);
|
||||
|
||||
for(int i = 0; i < cacheUniqueKey.getFieldNames().size(); i++)
|
||||
QQueryFilter filter = new QQueryFilter().withBooleanOperator(QQueryFilter.BooleanOperator.OR);
|
||||
sourceQueryInput.setFilter(filter);
|
||||
sourceQueryInput.setCommonParamsFrom(cacheQueryInput);
|
||||
|
||||
for(List<Serializable> uniqueKeyValue : uniqueKeyValues)
|
||||
{
|
||||
subFilter.addCriteria(new QFilterCriteria(cacheUniqueKey.getFieldNames().get(i), QCriteriaOperator.EQUALS, uniqueKeyValue.get(i)));
|
||||
}
|
||||
}
|
||||
QQueryFilter subFilter = new QQueryFilter();
|
||||
filter.addSubFilter(subFilter);
|
||||
|
||||
QueryOutput sourceQueryOutput = new QueryAction().execute(sourceQueryInput);
|
||||
return (sourceQueryOutput.getRecords());
|
||||
for(int i = 0; i < cacheUniqueKey.getFieldNames().size(); i++)
|
||||
{
|
||||
subFilter.addCriteria(new QFilterCriteria(cacheUniqueKey.getFieldNames().get(i), QCriteriaOperator.EQUALS, uniqueKeyValue.get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
QueryOutput sourceQueryOutput = new QueryAction().execute(sourceQueryInput);
|
||||
return (sourceQueryOutput.getRecords());
|
||||
}
|
||||
else if(sourceTable.isCapabilityEnabled(sourceBackend, Capability.TABLE_GET))
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// if the table only supports GET, then do a GET for each unique key //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
List<QRecord> outputRecords = new ArrayList<>();
|
||||
for(List<Serializable> uniqueKeyValue : uniqueKeyValues)
|
||||
{
|
||||
Map<String, Serializable> uniqueKey = new HashMap<>();
|
||||
for(int i = 0; i < cacheUniqueKey.getFieldNames().size(); i++)
|
||||
{
|
||||
uniqueKey.put(cacheUniqueKey.getFieldNames().get(i), uniqueKeyValue.get(i));
|
||||
}
|
||||
|
||||
GetInput getInput = new GetInput();
|
||||
getInput.setTableName(sourceTableName);
|
||||
getInput.setUniqueKey(uniqueKey);
|
||||
getInput.setCommonParamsFrom(cacheQueryInput);
|
||||
GetOutput getOutput = new GetAction().execute(getInput);
|
||||
|
||||
if(getOutput.getRecord() != null)
|
||||
{
|
||||
outputRecords.add(getOutput.getRecord());
|
||||
}
|
||||
}
|
||||
|
||||
return (outputRecords);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw (new QException("Cache source table " + sourceTableName + " does not support Query or Get capability."));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2023. 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.tables;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Common getters & setters, shared by both QueryInput and GetInput.
|
||||
**
|
||||
** Original impetus for this class is the setCommonParamsFrom() method - for cases
|
||||
** where we need to change a Query to a Get, or vice-versa, and we want to copy over
|
||||
** all of those input params.
|
||||
*******************************************************************************/
|
||||
public interface QueryOrGetInputInterface
|
||||
{
|
||||
/*******************************************************************************
|
||||
** Set in THIS, the "common params" (e.g., common to both Query & Get inputs)
|
||||
** from the parameter SOURCE object.
|
||||
*******************************************************************************/
|
||||
default void setCommonParamsFrom(QueryOrGetInputInterface source)
|
||||
{
|
||||
this.setTransaction(source.getTransaction());
|
||||
this.setShouldTranslatePossibleValues(source.getShouldTranslatePossibleValues());
|
||||
this.setShouldGenerateDisplayValues(source.getShouldGenerateDisplayValues());
|
||||
this.setShouldFetchHeavyFields(source.getShouldFetchHeavyFields());
|
||||
this.setShouldOmitHiddenFields(source.getShouldOmitHiddenFields());
|
||||
this.setShouldMaskPasswords(source.getShouldMaskPasswords());
|
||||
this.setIncludeAssociations(source.getIncludeAssociations());
|
||||
this.setAssociationNamesToInclude(source.getAssociationNamesToInclude());
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for transaction
|
||||
*******************************************************************************/
|
||||
QBackendTransaction getTransaction();
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for transaction
|
||||
*******************************************************************************/
|
||||
void setTransaction(QBackendTransaction transaction);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for shouldTranslatePossibleValues
|
||||
*******************************************************************************/
|
||||
boolean getShouldTranslatePossibleValues();
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for shouldTranslatePossibleValues
|
||||
*******************************************************************************/
|
||||
void setShouldTranslatePossibleValues(boolean shouldTranslatePossibleValues);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for shouldGenerateDisplayValues
|
||||
*******************************************************************************/
|
||||
boolean getShouldGenerateDisplayValues();
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for shouldGenerateDisplayValues
|
||||
*******************************************************************************/
|
||||
void setShouldGenerateDisplayValues(boolean shouldGenerateDisplayValues);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for shouldFetchHeavyFields
|
||||
*******************************************************************************/
|
||||
boolean getShouldFetchHeavyFields();
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for shouldFetchHeavyFields
|
||||
*******************************************************************************/
|
||||
void setShouldFetchHeavyFields(boolean shouldFetchHeavyFields);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for shouldOmitHiddenFields
|
||||
*******************************************************************************/
|
||||
boolean getShouldOmitHiddenFields();
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for shouldOmitHiddenFields
|
||||
*******************************************************************************/
|
||||
void setShouldOmitHiddenFields(boolean shouldOmitHiddenFields);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for shouldMaskPasswords
|
||||
*******************************************************************************/
|
||||
boolean getShouldMaskPasswords();
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for shouldMaskPasswords
|
||||
*******************************************************************************/
|
||||
void setShouldMaskPasswords(boolean shouldMaskPasswords);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for includeAssociations
|
||||
*******************************************************************************/
|
||||
boolean getIncludeAssociations();
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for includeAssociations
|
||||
*******************************************************************************/
|
||||
void setIncludeAssociations(boolean includeAssociations);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for associationNamesToInclude
|
||||
*******************************************************************************/
|
||||
Collection<String> getAssociationNamesToInclude();
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for associationNamesToInclude
|
||||
*******************************************************************************/
|
||||
void setAssociationNamesToInclude(Collection<String> associationNamesToInclude);
|
||||
|
||||
}
|
@ -27,13 +27,14 @@ import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.QueryOrGetInputInterface;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Input data for the Get action
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class GetInput extends AbstractTableActionInput
|
||||
public class GetInput extends AbstractTableActionInput implements QueryOrGetInputInterface
|
||||
{
|
||||
private QBackendTransaction transaction;
|
||||
|
||||
|
@ -29,13 +29,14 @@ import java.util.Set;
|
||||
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
|
||||
import com.kingsrook.qqq.backend.core.actions.reporting.RecordPipe;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.QueryOrGetInputInterface;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Input data for the Query action
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QueryInput extends AbstractTableActionInput
|
||||
public class QueryInput extends AbstractTableActionInput implements QueryOrGetInputInterface
|
||||
{
|
||||
private QBackendTransaction transaction;
|
||||
private QQueryFilter filter;
|
||||
|
Reference in New Issue
Block a user