Update to allow includeAssociations when querying into a record pipe. This meant propagating a lot of exceptions...

This commit is contained in:
2023-04-28 12:14:12 -05:00
parent 6f99111c52
commit b7e39d6953
11 changed files with 93 additions and 54 deletions

View File

@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.actions.reporting;
import java.util.ArrayList;
import java.util.List;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
@ -63,7 +64,7 @@ public class BufferedRecordPipe extends RecordPipe
**
*******************************************************************************/
@Override
public void addRecord(QRecord record)
public void addRecord(QRecord record) throws QException
{
buffer.add(record);
if(buffer.size() >= bufferSize)
@ -78,7 +79,7 @@ public class BufferedRecordPipe extends RecordPipe
/*******************************************************************************
**
*******************************************************************************/
public void finalFlush()
public void finalFlush() throws QException
{
if(!buffer.isEmpty())
{

View File

@ -26,10 +26,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.logging.QLogger;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.utils.SleepUtils;
import com.kingsrook.qqq.backend.core.utils.lambdas.UnsafeConsumer;
/*******************************************************************************
@ -47,7 +48,7 @@ public class RecordPipe
private boolean isTerminated = false;
private Consumer<List<QRecord>> postRecordActions = null;
private UnsafeConsumer<List<QRecord>, QException> postRecordActions = null;
/////////////////////////////////////
// See usage below for explanation //
@ -93,7 +94,7 @@ public class RecordPipe
/*******************************************************************************
** Add a record to the pipe. Will block if the pipe is full. Will noop if pipe is terminated.
*******************************************************************************/
public void addRecord(QRecord record)
public void addRecord(QRecord record) throws QException
{
if(isTerminated)
{
@ -109,7 +110,7 @@ public class RecordPipe
// (which we'll create as a field in this class, to avoid always re-constructing) //
////////////////////////////////////////////////////////////////////////////////////
singleRecordListForPostRecordActions.add(record);
postRecordActions.accept(singleRecordListForPostRecordActions);
postRecordActions.run(singleRecordListForPostRecordActions);
record = singleRecordListForPostRecordActions.remove(0);
}
@ -152,11 +153,11 @@ public class RecordPipe
/*******************************************************************************
** Add a list of records to the pipe. Will block if the pipe is full. Will noop if pipe is terminated.
*******************************************************************************/
public void addRecords(List<QRecord> records)
public void addRecords(List<QRecord> records) throws QException
{
if(postRecordActions != null)
{
postRecordActions.accept(records);
postRecordActions.run(records);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
@ -207,7 +208,7 @@ public class RecordPipe
/*******************************************************************************
**
*******************************************************************************/
public void setPostRecordActions(Consumer<List<QRecord>> postRecordActions)
public void setPostRecordActions(UnsafeConsumer<List<QRecord>, QException> postRecordActions)
{
this.postRecordActions = postRecordActions;
}

View File

@ -85,14 +85,6 @@ public class QueryAction
queryInput.getRecordPipe().setPostRecordActions(this::postRecordActions);
}
if(queryInput.getIncludeAssociations() && queryInput.getRecordPipe() != null)
{
//////////////////////////////////////////////
// todo - support this in the future maybe? //
//////////////////////////////////////////////
throw (new QException("Associations may not be fetched into a RecordPipe."));
}
QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher();
QBackendModuleInterface qModule = qBackendModuleDispatcher.getQBackendModule(queryInput.getBackend());
// todo pre-customization - just get to modify the request?
@ -109,11 +101,6 @@ public class QueryAction
postRecordActions(queryOutput.getRecords());
}
if(queryInput.getIncludeAssociations())
{
manageAssociations(queryInput, queryOutput);
}
return queryOutput;
}
@ -122,7 +109,7 @@ public class QueryAction
/*******************************************************************************
**
*******************************************************************************/
private void manageAssociations(QueryInput queryInput, QueryOutput queryOutput) throws QException
private void manageAssociations(QueryInput queryInput, List<QRecord> queryOutputRecords) throws QException
{
QTableMetaData table = queryInput.getTable();
for(Association association : CollectionUtils.nonNullList(table.getAssociations()))
@ -147,7 +134,7 @@ public class QueryAction
{
JoinOn joinOn = join.getJoinOns().get(0);
Set<Serializable> values = new HashSet<>();
for(QRecord record : queryOutput.getRecords())
for(QRecord record : queryOutputRecords)
{
Serializable value = record.getValue(joinOn.getLeftField());
values.add(value);
@ -159,7 +146,7 @@ public class QueryAction
{
filter.setBooleanOperator(QQueryFilter.BooleanOperator.OR);
for(QRecord record : queryOutput.getRecords())
for(QRecord record : queryOutputRecords)
{
QQueryFilter subFilter = new QQueryFilter();
filter.addSubFilter(subFilter);
@ -227,7 +214,7 @@ public class QueryAction
** not one created via List.of()). This may include setting display values,
** translating possible values, and running post-record customizations.
*******************************************************************************/
public void postRecordActions(List<QRecord> records)
public void postRecordActions(List<QRecord> records) throws QException
{
if(this.postQueryRecordCustomizer.isPresent())
{
@ -247,5 +234,10 @@ public class QueryAction
{
QValueFormatter.setDisplayValuesInRecords(queryInput.getTable(), records);
}
if(queryInput.getIncludeAssociations())
{
manageAssociations(queryInput, records);
}
}
}

View File

@ -31,6 +31,7 @@ import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import com.kingsrook.qqq.backend.core.actions.reporting.RecordPipe;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.shared.mapping.AbstractQFieldMapping;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
@ -61,7 +62,7 @@ public class CsvToQRecordAdapter
** using a given mapping.
**
*******************************************************************************/
public void buildRecordsFromCsv(RecordPipe recordPipe, String csv, QTableMetaData table, AbstractQFieldMapping<?> mapping, Consumer<QRecord> recordCustomizer)
public void buildRecordsFromCsv(RecordPipe recordPipe, String csv, QTableMetaData table, AbstractQFieldMapping<?> mapping, Consumer<QRecord> recordCustomizer) throws QException
{
buildRecordsFromCsv(new InputWrapper().withRecordPipe(recordPipe).withCsv(csv).withTable(table).withMapping(mapping).withRecordCustomizer(recordCustomizer));
}
@ -73,7 +74,7 @@ public class CsvToQRecordAdapter
** using a given mapping.
**
*******************************************************************************/
public List<QRecord> buildRecordsFromCsv(String csv, QTableMetaData table, AbstractQFieldMapping<?> mapping)
public List<QRecord> buildRecordsFromCsv(String csv, QTableMetaData table, AbstractQFieldMapping<?> mapping) throws QException
{
buildRecordsFromCsv(new InputWrapper().withCsv(csv).withTable(table).withMapping(mapping));
return (recordList);
@ -87,7 +88,7 @@ public class CsvToQRecordAdapter
**
** todo - meta-data validation, type handling
*******************************************************************************/
public void buildRecordsFromCsv(InputWrapper inputWrapper)
public void buildRecordsFromCsv(InputWrapper inputWrapper) throws QException
{
String csv = inputWrapper.getCsv();
AbstractQFieldMapping<?> mapping = inputWrapper.getMapping();
@ -297,7 +298,7 @@ public class CsvToQRecordAdapter
/*******************************************************************************
** Add a record - either to the pipe, or list, whichever we're building.
*******************************************************************************/
private void addRecord(QRecord record)
private void addRecord(QRecord record) throws QException
{
if(recordPipe != null)
{

View File

@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.model.actions.tables.query;
import java.io.Serializable;
import java.util.List;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
@ -63,7 +64,7 @@ public class QueryOutput extends AbstractActionOutput implements Serializable
** that could be read asynchronously, at any time, by another thread - SO - only
** completely populated records should be passed into this method.
*******************************************************************************/
public void addRecord(QRecord record)
public void addRecord(QRecord record) throws QException
{
storage.addRecord(record);
}
@ -73,7 +74,7 @@ public class QueryOutput extends AbstractActionOutput implements Serializable
/*******************************************************************************
** add a list of records to this output
*******************************************************************************/
public void addRecords(List<QRecord> records)
public void addRecords(List<QRecord> records) throws QException
{
storage.addRecords(records);
}

View File

@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.model.actions.tables.query;
import java.util.List;
import com.kingsrook.qqq.backend.core.actions.reporting.RecordPipe;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.logging.QLogger;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
@ -53,7 +54,7 @@ class QueryOutputRecordPipe implements QueryOutputStorageInterface
** add a record to this output
*******************************************************************************/
@Override
public void addRecord(QRecord record)
public void addRecord(QRecord record) throws QException
{
recordPipe.addRecord(record);
}
@ -64,7 +65,7 @@ class QueryOutputRecordPipe implements QueryOutputStorageInterface
** add a list of records to this output
*******************************************************************************/
@Override
public void addRecords(List<QRecord> records)
public void addRecords(List<QRecord> records) throws QException
{
recordPipe.addRecords(records);
}

View File

@ -23,6 +23,7 @@ package com.kingsrook.qqq.backend.core.model.actions.tables.query;
import java.util.List;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
@ -36,13 +37,13 @@ interface QueryOutputStorageInterface
/*******************************************************************************
** add a records to this output
*******************************************************************************/
void addRecord(QRecord record);
void addRecord(QRecord record) throws QException;
/*******************************************************************************
** add a list of records to this output
*******************************************************************************/
void addRecords(List<QRecord> records);
void addRecords(List<QRecord> records) throws QException;
/*******************************************************************************
** Get all stored records