From 2aa2e4643e07eed040cfbbf856ec9b592326ef9c Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 14 Jul 2025 15:55:56 -0500 Subject: [PATCH] Add method identifyJoinTablesInFilter --- .../utils/BackendQueryFilterUtils.java | 52 +++++++++++++++++++ .../utils/BackendQueryFilterUtilsTest.java | 43 ++++++++++++++- 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/utils/BackendQueryFilterUtils.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/utils/BackendQueryFilterUtils.java index be9bd626..245e89ca 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/utils/BackendQueryFilterUtils.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/utils/BackendQueryFilterUtils.java @@ -27,11 +27,14 @@ import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDate; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +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.query.CriteriaOption; @@ -41,9 +44,12 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions.AbstractFilterExpression; import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAndJoinTable; 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.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; +import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.core.utils.ValueUtils; import org.apache.commons.lang.NotImplementedException; import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; @@ -721,4 +727,50 @@ public class BackendQueryFilterUtils return regex.toString(); } + + + /*************************************************************************** + * + ***************************************************************************/ + public static Set identifyJoinTablesInFilter(String mainTableName, QQueryFilter filter) throws QException + { + Set rs = new HashSet<>(); + + QTableMetaData mainTable = QContext.getQInstance().getTable(mainTableName); + + for(QFilterCriteria criteria : CollectionUtils.nonNullList(filter.getCriteria())) + { + FieldAndJoinTable fieldAndJoinTable = FieldAndJoinTable.get(mainTable, criteria.getFieldName()); + if(!fieldAndJoinTable.joinTable().getName().equals(mainTableName)) + { + rs.add(fieldAndJoinTable.joinTable().getName()); + } + + if(StringUtils.hasContent(criteria.getOtherFieldName())) + { + FieldAndJoinTable otherFieldAndJoinTable = FieldAndJoinTable.get(mainTable, criteria.getOtherFieldName()); + if(!otherFieldAndJoinTable.joinTable().getName().equals(mainTableName)) + { + rs.add(otherFieldAndJoinTable.joinTable().getName()); + } + } + } + + for(QFilterOrderBy orderBy : CollectionUtils.nonNullList(filter.getOrderBys())) + { + FieldAndJoinTable fieldAndJoinTable = FieldAndJoinTable.get(mainTable, orderBy.getFieldName()); + if(!fieldAndJoinTable.joinTable().getName().equals(mainTableName)) + { + rs.add(fieldAndJoinTable.joinTable().getName()); + } + } + + for(QQueryFilter subFilter : CollectionUtils.nonNullList(filter.getSubFilters())) + { + rs.addAll(identifyJoinTablesInFilter(mainTableName, subFilter)); + } + + return (rs); + } + } diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/utils/BackendQueryFilterUtilsTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/utils/BackendQueryFilterUtilsTest.java index 1f922a2e..d9ec89a5 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/utils/BackendQueryFilterUtilsTest.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/utils/BackendQueryFilterUtilsTest.java @@ -24,12 +24,17 @@ package com.kingsrook.qqq.backend.core.modules.backend.implementations.utils; import java.io.Serializable; import java.util.List; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import com.kingsrook.qqq.backend.core.BaseTest; +import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.model.actions.tables.query.CriteriaOption; 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.QFilterOrderBy; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.utils.TestUtils; import com.kingsrook.qqq.backend.core.utils.collections.ListBuilder; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -41,7 +46,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; /******************************************************************************* ** Unit test for BackendQueryFilterUtils *******************************************************************************/ -class BackendQueryFilterUtilsTest +class BackendQueryFilterUtilsTest extends BaseTest { /******************************************************************************* @@ -524,4 +529,40 @@ class BackendQueryFilterUtilsTest } } + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testIdentifyJoinTablesInFilter() throws QException + { + QFilterCriteria lineItemCriteria = new QFilterCriteria(TestUtils.TABLE_NAME_LINE_ITEM + ".sku", QCriteriaOperator.EQUALS, "BASIC1"); + QFilterCriteria lineItemCriteriaOtherFieldName = new QFilterCriteria("orderNo", QCriteriaOperator.EQUALS).withOtherFieldName(TestUtils.TABLE_NAME_LINE_ITEM + ".sku"); + + assertEquals(Set.of(), BackendQueryFilterUtils.identifyJoinTablesInFilter(TestUtils.TABLE_NAME_ORDER, + new QQueryFilter())); + + assertEquals(Set.of(), BackendQueryFilterUtils.identifyJoinTablesInFilter(TestUtils.TABLE_NAME_ORDER, + new QQueryFilter(new QFilterCriteria("id", QCriteriaOperator.IS_NOT_BLANK)))); + + assertEquals(Set.of(TestUtils.TABLE_NAME_LINE_ITEM), BackendQueryFilterUtils.identifyJoinTablesInFilter(TestUtils.TABLE_NAME_ORDER, + new QQueryFilter().withCriteria(lineItemCriteria))); + + assertEquals(Set.of(TestUtils.TABLE_NAME_LINE_ITEM), BackendQueryFilterUtils.identifyJoinTablesInFilter(TestUtils.TABLE_NAME_ORDER, + new QQueryFilter().withCriteria(lineItemCriteriaOtherFieldName))); + + assertEquals(Set.of(TestUtils.TABLE_NAME_LINE_ITEM), BackendQueryFilterUtils.identifyJoinTablesInFilter(TestUtils.TABLE_NAME_ORDER, + new QQueryFilter().withSubFilter(new QQueryFilter().withCriteria(lineItemCriteria)))); + + assertEquals(Set.of(TestUtils.TABLE_NAME_LINE_ITEM_EXTRINSIC), BackendQueryFilterUtils.identifyJoinTablesInFilter(TestUtils.TABLE_NAME_ORDER, + new QQueryFilter().withOrderBy(new QFilterOrderBy(TestUtils.TABLE_NAME_LINE_ITEM_EXTRINSIC + ".id")))); + + assertEquals(Set.of(TestUtils.TABLE_NAME_LINE_ITEM, TestUtils.TABLE_NAME_LINE_ITEM_EXTRINSIC), BackendQueryFilterUtils.identifyJoinTablesInFilter(TestUtils.TABLE_NAME_ORDER, + new QQueryFilter() + .withCriteria(lineItemCriteria) + .withOrderBy(new QFilterOrderBy(TestUtils.TABLE_NAME_LINE_ITEM_EXTRINSIC + ".id")))); + + } + } \ No newline at end of file