Merge branch 'feature/sprint-9-support-updates' into feature/QQQ-37-streamed-processes

This commit is contained in:
2022-08-23 11:17:45 -05:00
40 changed files with 1269 additions and 407 deletions

View File

@ -22,6 +22,8 @@
package com.kingsrook.qqq.backend.core.actions.tables;
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.model.actions.tables.query.QueryInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
@ -76,4 +78,50 @@ class QueryActionTest
assertThat(record.getDisplayValues()).isNotEmpty();
}
}
/*******************************************************************************
** Test running with a recordPipe - using the shape table, which uses the memory
** backend, which is known to do an addAll to the query output.
**
*******************************************************************************/
@Test
public void testRecordPipeShapeTable() throws QException
{
TestUtils.insertDefaultShapes(TestUtils.defineInstance());
RecordPipe pipe = new RecordPipe();
QueryInput queryInput = new QueryInput(TestUtils.defineInstance());
queryInput.setSession(TestUtils.getMockSession());
queryInput.setTableName(TestUtils.TABLE_NAME_SHAPE);
queryInput.setRecordPipe(pipe);
QueryOutput queryOutput = new QueryAction().execute(queryInput);
assertNotNull(queryOutput);
List<QRecord> records = pipe.consumeAvailableRecords();
assertThat(records).isNotEmpty();
}
/*******************************************************************************
** Test running with a recordPipe - using the person table, which uses the mock
** backend, which is known to do a single-add (not addAll) to the query output.
**
*******************************************************************************/
@Test
public void testRecordPipePersonTable() throws QException
{
RecordPipe pipe = new RecordPipe();
QueryInput queryInput = new QueryInput(TestUtils.defineInstance());
queryInput.setSession(TestUtils.getMockSession());
queryInput.setTableName(TestUtils.TABLE_NAME_PERSON);
queryInput.setRecordPipe(pipe);
QueryOutput queryOutput = new QueryAction().execute(queryInput);
assertNotNull(queryOutput);
List<QRecord> records = pipe.consumeAvailableRecords();
assertThat(records).isNotEmpty();
}
}

View File

@ -25,30 +25,42 @@ package com.kingsrook.qqq.backend.core.actions.values;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
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.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.fields.DisplayFormat;
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.PVSValueFormatAndFields;
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.model.session.QSession;
import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore;
import com.kingsrook.qqq.backend.core.utils.TestUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
/*******************************************************************************
**
** Unit test for QPossibleValueTranslator
*******************************************************************************/
public class QPossibleValueTranslatorTest
{
/*******************************************************************************
**
*******************************************************************************/
@BeforeEach
void beforeEach()
{
MemoryRecordStore.getInstance().reset();
MemoryRecordStore.resetStatistics();
}
/*******************************************************************************
**
*******************************************************************************/
@ -90,22 +102,20 @@ public class QPossibleValueTranslatorTest
/////////////////////////////////////////////////////////////////
// assert the LABEL_ONLY format (when called out specifically) //
/////////////////////////////////////////////////////////////////
possibleValueSource.setValueFormat(QPossibleValueSource.ValueFormat.LABEL_ONLY);
possibleValueSource.setValueFields(QPossibleValueSource.ValueFields.LABEL_ONLY);
possibleValueSource.setValueFormatAndFields(PVSValueFormatAndFields.LABEL_ONLY);
assertEquals("IL", possibleValueTranslator.translatePossibleValue(stateField, 1));
///////////////////////////////////////
// assert the LABEL_PARAMS_ID format //
///////////////////////////////////////
possibleValueSource.setValueFormat(QPossibleValueSource.ValueFormat.LABEL_PARENS_ID);
possibleValueSource.setValueFields(QPossibleValueSource.ValueFields.LABEL_PARENS_ID);
possibleValueSource.setValueFormatAndFields(PVSValueFormatAndFields.LABEL_PARENS_ID);
assertEquals("IL (1)", possibleValueTranslator.translatePossibleValue(stateField, 1));
//////////////////////////////////////
// assert the ID_COLON_LABEL format //
//////////////////////////////////////
possibleValueSource.setValueFormat(QPossibleValueSource.ValueFormat.ID_COLON_LABEL);
possibleValueSource.setValueFields(QPossibleValueSource.ValueFields.ID_COLON_LABEL);
possibleValueSource.setValueFormat(PVSValueFormatAndFields.ID_COLON_LABEL.getFormat());
possibleValueSource.setValueFields(PVSValueFormatAndFields.ID_COLON_LABEL.getFields());
assertEquals("1: IL", possibleValueTranslator.translatePossibleValue(stateField, 1));
}
@ -123,16 +133,7 @@ public class QPossibleValueTranslatorTest
QFieldMetaData shapeField = qInstance.getTable(TestUtils.TABLE_NAME_PERSON).getField("favoriteShapeId");
QPossibleValueSource possibleValueSource = qInstance.getPossibleValueSource(shapeField.getPossibleValueSourceName());
List<QRecord> shapeRecords = List.of(
new QRecord().withTableName(shapeTable.getName()).withValue("id", 1).withValue("name", "Triangle"),
new QRecord().withTableName(shapeTable.getName()).withValue("id", 2).withValue("name", "Square"),
new QRecord().withTableName(shapeTable.getName()).withValue("id", 3).withValue("name", "Circle"));
InsertInput insertInput = new InsertInput(qInstance);
insertInput.setSession(new QSession());
insertInput.setTableName(shapeTable.getName());
insertInput.setRecords(shapeRecords);
new InsertAction().execute(insertInput);
TestUtils.insertDefaultShapes(qInstance);
//////////////////////////////////////////////////////////////////////////
// assert the default formatting for a not-found value is a null string //
@ -156,8 +157,7 @@ public class QPossibleValueTranslatorTest
///////////////////////////////////////
// assert the LABEL_PARAMS_ID format //
///////////////////////////////////////
possibleValueSource.setValueFormat(QPossibleValueSource.ValueFormat.LABEL_PARENS_ID);
possibleValueSource.setValueFields(QPossibleValueSource.ValueFields.LABEL_PARENS_ID);
possibleValueSource.setValueFormatAndFields(PVSValueFormatAndFields.LABEL_PARENS_ID);
assertEquals("Circle (3)", possibleValueTranslator.translatePossibleValue(shapeField, 3));
///////////////////////////////////////////////////////////
@ -195,19 +195,113 @@ public class QPossibleValueTranslatorTest
/*******************************************************************************
** Make sure that if we have 2 different PVS's pointed at the same 1 table,
** that we avoid re-doing queries, and that we actually get different (formatted) values.
*******************************************************************************/
@Test
void testPossibleValueTableMultiplePvsForATable() throws QException
{
QInstance qInstance = TestUtils.defineInstance();
QTableMetaData shapeTable = qInstance.getTable(TestUtils.TABLE_NAME_SHAPE);
QTableMetaData personTable = qInstance.getTable(TestUtils.TABLE_NAME_PERSON);
////////////////////////////////////////////////////////////////////
// define a second version of the Shape PVS, with a unique format //
////////////////////////////////////////////////////////////////////
qInstance.addPossibleValueSource(new QPossibleValueSource()
.withName("shapeV2")
.withType(QPossibleValueSourceType.TABLE)
.withTableName(TestUtils.TABLE_NAME_SHAPE)
.withValueFormat("%d: %s")
.withValueFields(List.of("id", "label"))
);
//////////////////////////////////////////////////////
// use that PVS in a new column on the person table //
//////////////////////////////////////////////////////
personTable.addField(new QFieldMetaData("currentShapeId", QFieldType.INTEGER)
.withPossibleValueSourceName("shapeV2")
);
TestUtils.insertDefaultShapes(qInstance);
///////////////////////////////////////////////////////
// define a list of persons pointing at those shapes //
///////////////////////////////////////////////////////
List<QRecord> personRecords = List.of(
new QRecord().withTableName(TestUtils.TABLE_NAME_PERSON).withValue("favoriteShapeId", 1).withValue("currentShapeId", 2),
new QRecord().withTableName(TestUtils.TABLE_NAME_PERSON).withValue("favoriteShapeId", 1).withValue("currentShapeId", 3),
new QRecord().withTableName(TestUtils.TABLE_NAME_PERSON).withValue("favoriteShapeId", 2).withValue("currentShapeId", 3),
new QRecord().withTableName(TestUtils.TABLE_NAME_PERSON).withValue("favoriteShapeId", 2).withValue("currentShapeId", 3)
);
/////////////////////////
// translate the PVS's //
/////////////////////////
MemoryRecordStore.setCollectStatistics(true);
new QPossibleValueTranslator(qInstance, new QSession()).translatePossibleValuesInRecords(personTable, personRecords);
/////////////////////////////////
// assert only 1 query was ran //
/////////////////////////////////
assertEquals(1, MemoryRecordStore.getStatistics().get(MemoryRecordStore.STAT_QUERIES_RAN), "Should only run 1 query");
////////////////////////////////////////
// assert expected values and formats //
////////////////////////////////////////
assertEquals("Triangle", personRecords.get(0).getDisplayValue("favoriteShapeId"));
assertEquals("2: Square", personRecords.get(0).getDisplayValue("currentShapeId"));
assertEquals("Triangle", personRecords.get(1).getDisplayValue("favoriteShapeId"));
assertEquals("3: Circle", personRecords.get(1).getDisplayValue("currentShapeId"));
assertEquals("Square", personRecords.get(2).getDisplayValue("favoriteShapeId"));
assertEquals("3: Circle", personRecords.get(2).getDisplayValue("currentShapeId"));
}
/*******************************************************************************
** Make sure that if we have 2 different PVS's pointed at the same 1 table,
** that we avoid re-doing queries, and that we actually get different (formatted) values.
*******************************************************************************/
@Test
void testCustomPossibleValue() throws QException
{
QInstance qInstance = TestUtils.defineInstance();
QTableMetaData personTable = qInstance.getTable(TestUtils.TABLE_NAME_PERSON);
String fieldName = "customValue";
//////////////////////////////////////////////////////////////
// define a list of persons with values in the custom field //
//////////////////////////////////////////////////////////////
List<QRecord> personRecords = List.of(
new QRecord().withTableName(TestUtils.TABLE_NAME_PERSON).withValue(fieldName, 1),
new QRecord().withTableName(TestUtils.TABLE_NAME_PERSON).withValue(fieldName, 2),
new QRecord().withTableName(TestUtils.TABLE_NAME_PERSON).withValue(fieldName, "Buckle my shoe")
);
/////////////////////////
// translate the PVS's //
/////////////////////////
new QPossibleValueTranslator(qInstance, new QSession()).translatePossibleValuesInRecords(personTable, personRecords);
////////////////////////////////////////
// assert expected values and formats //
////////////////////////////////////////
assertEquals("Custom[1]", personRecords.get(0).getDisplayValue(fieldName));
assertEquals("Custom[2]", personRecords.get(1).getDisplayValue(fieldName));
assertEquals("Custom[Buckle my shoe]", personRecords.get(2).getDisplayValue(fieldName));
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testSetDisplayValuesInRecords()
{
QTableMetaData table = new QTableMetaData()
.withRecordLabelFormat("%s %s")
.withRecordLabelFields("firstName", "lastName")
.withField(new QFieldMetaData("firstName", QFieldType.STRING))
.withField(new QFieldMetaData("lastName", QFieldType.STRING))
.withField(new QFieldMetaData("price", QFieldType.DECIMAL).withDisplayFormat(DisplayFormat.CURRENCY))
.withField(new QFieldMetaData("homeStateId", QFieldType.INTEGER).withPossibleValueSourceName(TestUtils.POSSIBLE_VALUE_SOURCE_STATE));
QTableMetaData table = TestUtils.defineTablePerson();
/////////////////////////////////////////////////////////////////
// first, make sure it doesn't crash with null or empty inputs //

View File

@ -292,6 +292,11 @@ class CsvToQRecordAdapterTest
void testByteOrderMarker()
{
CsvToQRecordAdapter csvToQRecordAdapter = new CsvToQRecordAdapter();
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// note - there's a zero-width non-breaking-space character (0xFEFF or some-such) //
// at the start of this string!! You may not be able to see it, depending on where you view this file. //
//////////////////////////////////////////////////////////////////////////////////////////////////////////
List<QRecord> records = csvToQRecordAdapter.buildRecordsFromCsv("""
id,firstName
1,John""", TestUtils.defineTablePerson(), null);

View File

@ -140,6 +140,7 @@ class QInstanceEnricherTest
assertEquals("Field 20", QInstanceEnricher.nameToLabel("field20"));
assertEquals("Something USA", QInstanceEnricher.nameToLabel("somethingUSA"));
assertEquals("Number 1 Dad", QInstanceEnricher.nameToLabel("number1Dad"));
assertEquals("Number 417 Dad", QInstanceEnricher.nameToLabel("number417Dad"));
}

View File

@ -27,9 +27,14 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizers;
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
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;
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeUsage;
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.layout.QAppMetaData;
@ -114,12 +119,13 @@ class QInstanceValidatorTest
@Test
public void test_validateNullTables()
{
assertValidationFailureReasonsAllowingExtraReasons((qInstance) ->
assertValidationFailureReasons((qInstance) ->
{
qInstance.setTables(null);
qInstance.setProcesses(null);
},
"At least 1 table must be defined");
"At least 1 table must be defined",
"Unrecognized table shape for possibleValueSource shape");
}
@ -131,12 +137,13 @@ class QInstanceValidatorTest
@Test
public void test_validateEmptyTables()
{
assertValidationFailureReasonsAllowingExtraReasons((qInstance) ->
assertValidationFailureReasons((qInstance) ->
{
qInstance.setTables(new HashMap<>());
qInstance.setProcesses(new HashMap<>());
},
"At least 1 table must be defined");
"At least 1 table must be defined",
"Unrecognized table shape for possibleValueSource shape");
}
@ -191,7 +198,6 @@ class QInstanceValidatorTest
/*******************************************************************************
**
*******************************************************************************/
@ -265,6 +271,138 @@ class QInstanceValidatorTest
/*******************************************************************************
**
*******************************************************************************/
@Test
void testTableCustomizers()
{
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference()),
"missing a code reference name", "missing a code type");
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference(null, QCodeType.JAVA, null)),
"missing a code reference name");
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference("", QCodeType.JAVA, null)),
"missing a code reference name");
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference("Test", null, null)),
"missing a code type");
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference("Test", QCodeType.JAVA, QCodeUsage.CUSTOMIZER)),
"Class for CodeReference could not be found");
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference(CustomizerWithNoVoidConstructor.class, QCodeUsage.CUSTOMIZER)),
"Instance of CodeReference could not be created");
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference(CustomizerThatIsNotAFunction.class, QCodeUsage.CUSTOMIZER)),
"CodeReference could not be casted");
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference(CustomizerFunctionWithIncorrectTypeParameters.class, QCodeUsage.CUSTOMIZER)),
"Error validating customizer type parameters");
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference(CustomizerFunctionWithIncorrectTypeParameter1.class, QCodeUsage.CUSTOMIZER)),
"Error validating customizer type parameters");
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference(CustomizerFunctionWithIncorrectTypeParameter2.class, QCodeUsage.CUSTOMIZER)),
"Error validating customizer type parameters");
assertValidationSuccess((qInstance) -> qInstance.getTable("person").withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference(CustomizerValid.class, QCodeUsage.CUSTOMIZER)));
}
/*******************************************************************************
**
*******************************************************************************/
public static class CustomizerWithNoVoidConstructor
{
public CustomizerWithNoVoidConstructor(boolean b)
{
}
}
/*******************************************************************************
**
*******************************************************************************/
public static class CustomizerWithOnlyPrivateConstructor
{
private CustomizerWithOnlyPrivateConstructor()
{
}
}
/*******************************************************************************
**
*******************************************************************************/
public static class CustomizerThatIsNotAFunction
{
}
/*******************************************************************************
**
*******************************************************************************/
public static class CustomizerFunctionWithIncorrectTypeParameters implements Function<String, String>
{
@Override
public String apply(String s)
{
return null;
}
}
/*******************************************************************************
**
*******************************************************************************/
public static class CustomizerFunctionWithIncorrectTypeParameter1 implements Function<String, QRecord>
{
@Override
public QRecord apply(String s)
{
return null;
}
}
/*******************************************************************************
**
*******************************************************************************/
public static class CustomizerFunctionWithIncorrectTypeParameter2 implements Function<QRecord, String>
{
@Override
public String apply(QRecord s)
{
return "Test";
}
}
/*******************************************************************************
**
*******************************************************************************/
public static class CustomizerValid implements Function<QRecord, QRecord>
{
@Override
public QRecord apply(QRecord record)
{
return null;
}
}
/*******************************************************************************
** Test that if a field specifies a backend that doesn't exist, that it fails.
**
@ -443,18 +581,6 @@ class QInstanceValidatorTest
/*******************************************************************************
**
*******************************************************************************/
@Test
void testPossibleValueSourceMissingIdType()
{
assertValidationFailureReasons((qInstance) -> qInstance.getPossibleValueSource(TestUtils.POSSIBLE_VALUE_SOURCE_STATE).setIdType(null),
"Missing an idType for possibleValueSource");
}
/*******************************************************************************
**
*******************************************************************************/
@ -516,7 +642,9 @@ class QInstanceValidatorTest
"is missing a customCodeReference");
assertValidationFailureReasons((qInstance) -> qInstance.getPossibleValueSource(TestUtils.POSSIBLE_VALUE_SOURCE_CUSTOM).setCustomCodeReference(new QCodeReference()),
"not a possibleValueProvider");
"not a possibleValueProvider",
"missing a code reference name",
"missing a code type");
}
@ -561,7 +689,8 @@ class QInstanceValidatorTest
{
if(!allowExtraReasons)
{
assertEquals(reasons.length, e.getReasons().size(), "Expected number of validation failure reasons\nExpected: " + String.join(",", reasons) + "\nActual: " + e.getReasons());
int noOfReasons = e.getReasons() == null ? 0 : e.getReasons().size();
assertEquals(reasons.length, noOfReasons, "Expected number of validation failure reasons.\nExpected reasons: " + String.join(",", reasons) + "\nActual reasons: " + e.getReasons());
}
for(String reason : reasons)
@ -573,6 +702,25 @@ class QInstanceValidatorTest
/*******************************************************************************
** Assert that an instance is valid!
*******************************************************************************/
private void assertValidationSuccess(Consumer<QInstance> setup)
{
try
{
QInstance qInstance = TestUtils.defineInstance();
setup.accept(qInstance);
new QInstanceValidator().validate(qInstance);
}
catch(QInstanceValidationException e)
{
fail("Expected no validation errors, but received: " + e.getMessage());
}
}
/*******************************************************************************
** utility method for asserting that a specific reason string is found within
** the list of reasons in the QInstanceValidationException.

View File

@ -24,7 +24,7 @@ package com.kingsrook.qqq.backend.core.modules.backend.implementations.memory;
import java.util.List;
import java.util.function.Function;
import com.kingsrook.qqq.backend.core.actions.customizers.Customizers;
import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizers;
import com.kingsrook.qqq.backend.core.actions.tables.CountAction;
import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction;
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
@ -36,6 +36,9 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteOutput;
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;
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.tables.update.UpdateInput;
@ -68,6 +71,7 @@ class MemoryBackendModuleTest
void beforeAndAfter()
{
MemoryRecordStore.getInstance().reset();
MemoryRecordStore.resetStatistics();
}
@ -122,8 +126,6 @@ class MemoryBackendModuleTest
assertEquals(3, new CountAction().execute(countInput).getCount());
// todo - filters in query
//////////////////
// do an update //
//////////////////
@ -152,6 +154,24 @@ class MemoryBackendModuleTest
assertEquals(3, new CountAction().execute(countInput).getCount());
/////////////////////////
// do a filtered query //
/////////////////////////
queryInput = new QueryInput(qInstance);
queryInput.setSession(session);
queryInput.setTableName(table.getName());
queryInput.setFilter(new QQueryFilter().withCriteria(new QFilterCriteria("id", QCriteriaOperator.IN, List.of(1, 3))));
queryOutput = new QueryAction().execute(queryInput);
assertEquals(2, queryOutput.getRecords().size());
assertTrue(queryOutput.getRecords().stream().anyMatch(r -> r.getValueInteger("id").equals(1)));
assertTrue(queryOutput.getRecords().stream().anyMatch(r -> r.getValueInteger("id").equals(3)));
/////////////////////////
// do a filtered count //
/////////////////////////
countInput.setFilter(queryInput.getFilter());
assertEquals(2, new CountAction().execute(countInput).getCount());
/////////////////
// do a delete //
/////////////////
@ -173,6 +193,57 @@ class MemoryBackendModuleTest
/*******************************************************************************
**
*******************************************************************************/
@Test
void testSerials() throws QException
{
QInstance qInstance = TestUtils.defineInstance();
QTableMetaData table = qInstance.getTable(TestUtils.TABLE_NAME_SHAPE);
QSession session = new QSession();
//////////////////
// do an insert //
//////////////////
InsertInput insertInput = new InsertInput(qInstance);
insertInput.setSession(session);
insertInput.setTableName(table.getName());
insertInput.setRecords(List.of(new QRecord().withTableName(table.getName()).withValue("name", "Shape 1")));
new InsertAction().execute(insertInput);
insertInput.setRecords(List.of(new QRecord().withTableName(table.getName()).withValue("name", "Shape 2")));
new InsertAction().execute(insertInput);
insertInput.setRecords(List.of(new QRecord().withTableName(table.getName()).withValue("name", "Shape 3")));
new InsertAction().execute(insertInput);
QueryInput queryInput = new QueryInput(qInstance);
queryInput.setSession(new QSession());
queryInput.setTableName(table.getName());
QueryOutput queryOutput = new QueryAction().execute(queryInput);
assertTrue(queryOutput.getRecords().stream().anyMatch(r -> r.getValueInteger("id").equals(1)));
assertTrue(queryOutput.getRecords().stream().anyMatch(r -> r.getValueInteger("id").equals(2)));
assertTrue(queryOutput.getRecords().stream().anyMatch(r -> r.getValueInteger("id").equals(3)));
insertInput.setRecords(List.of(new QRecord().withTableName(table.getName()).withValue("id", 4).withValue("name", "Shape 4")));
new InsertAction().execute(insertInput);
queryOutput = new QueryAction().execute(queryInput);
assertTrue(queryOutput.getRecords().stream().anyMatch(r -> r.getValueInteger("id").equals(4)));
insertInput.setRecords(List.of(new QRecord().withTableName(table.getName()).withValue("id", 6).withValue("name", "Shape 6")));
new InsertAction().execute(insertInput);
queryOutput = new QueryAction().execute(queryInput);
assertTrue(queryOutput.getRecords().stream().anyMatch(r -> r.getValueInteger("id").equals(6)));
insertInput.setRecords(List.of(new QRecord().withTableName(table.getName()).withValue("name", "Shape 7")));
new InsertAction().execute(insertInput);
queryOutput = new QueryAction().execute(queryInput);
assertTrue(queryOutput.getRecords().stream().anyMatch(r -> r.getValueInteger("id").equals(7)));
}
/*******************************************************************************
**
*******************************************************************************/
@ -215,7 +286,7 @@ class MemoryBackendModuleTest
///////////////////////////////////
// add a customizer to the table //
///////////////////////////////////
table.withCustomizer(Customizers.POST_QUERY_RECORD, new QCodeReference(ShapeTestCustomizer.class, QCodeUsage.CUSTOMIZER));
table.withCustomizer(TableCustomizers.POST_QUERY_RECORD.getRole(), new QCodeReference(ShapeTestCustomizer.class, QCodeUsage.CUSTOMIZER));
//////////////////
// do an insert //

View File

@ -26,9 +26,11 @@ import java.io.Serializable;
import java.util.List;
import com.kingsrook.qqq.backend.core.actions.processes.person.addtopeoplesage.AddAge;
import com.kingsrook.qqq.backend.core.actions.processes.person.addtopeoplesage.GetAgeStatistics;
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.values.QCustomPossibleValueProvider;
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.tables.query.QueryInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
@ -447,6 +449,25 @@ public class TestUtils
/*******************************************************************************
**
*******************************************************************************/
public static void insertDefaultShapes(QInstance qInstance) throws QException
{
List<QRecord> shapeRecords = List.of(
new QRecord().withTableName(TABLE_NAME_SHAPE).withValue("id", 1).withValue("name", "Triangle"),
new QRecord().withTableName(TABLE_NAME_SHAPE).withValue("id", 2).withValue("name", "Square"),
new QRecord().withTableName(TABLE_NAME_SHAPE).withValue("id", 3).withValue("name", "Circle"));
InsertInput insertInput = new InsertInput(qInstance);
insertInput.setSession(new QSession());
insertInput.setTableName(TABLE_NAME_SHAPE);
insertInput.setRecords(shapeRecords);
new InsertAction().execute(insertInput);
}
/*******************************************************************************
**
*******************************************************************************/