From 4aa1aed632fef6738210946b10e2d3c56e8c3455 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Wed, 3 May 2023 16:36:42 -0500 Subject: [PATCH] Fixes for expoesd joins --- .../core/actions/values/QValueFormatter.java | 69 ++++++++++++++++++- .../columnstats/ColumnStatsStep.java | 47 +++++++++++-- 2 files changed, 111 insertions(+), 5 deletions(-) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java index f47029dc..684146e5 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java @@ -29,12 +29,16 @@ import java.time.LocalTime; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; +import com.kingsrook.qqq.backend.core.context.QContext; import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.tables.ExposedJoin; 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; @@ -292,9 +296,34 @@ public class QValueFormatter return; } + Map fieldMap = new HashMap<>(); + for(QRecord record : records) { - setDisplayValuesInRecord(table.getFields().values(), record); + for(String fieldName : record.getValues().keySet()) + { + if(!fieldMap.containsKey(fieldName)) + { + if(fieldName.contains(".")) + { + String[] nameParts = fieldName.split("\\.", 2); + for(ExposedJoin exposedJoin : CollectionUtils.nonNullList(table.getExposedJoins())) + { + if(exposedJoin.getJoinTable().equals(nameParts[0])) + { + QTableMetaData joinTable = QContext.getQInstance().getTable(nameParts[0]); + fieldMap.put(fieldName, joinTable.getField(nameParts[1])); + } + } + } + else + { + fieldMap.put(fieldName, table.getField(fieldName)); + } + } + } + + setDisplayValuesInRecord(fieldMap, record); record.setRecordLabel(formatRecordLabel(table, record)); } } @@ -319,6 +348,24 @@ public class QValueFormatter + /******************************************************************************* + ** For a list of records, set their recordLabels and display values + *******************************************************************************/ + public static void setDisplayValuesInRecords(Map fields, List records) + { + if(records == null) + { + return; + } + + for(QRecord record : records) + { + setDisplayValuesInRecord(fields, record); + } + } + + + /******************************************************************************* ** For a list of records, set their display values *******************************************************************************/ @@ -336,6 +383,26 @@ public class QValueFormatter + /******************************************************************************* + ** For a list of records, set their display values + *******************************************************************************/ + public static void setDisplayValuesInRecord(Map fields, QRecord record) + { + for(Map.Entry entry : fields.entrySet()) + { + String fieldName = entry.getKey(); + QFieldMetaData field = entry.getValue(); + + if(record.getDisplayValue(fieldName) == null) + { + String formattedValue = formatValue(field, record.getValue(fieldName)); + record.setDisplayValue(fieldName, formattedValue); + } + } + } + + + /******************************************************************************* ** *******************************************************************************/ diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/columnstats/ColumnStatsStep.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/columnstats/ColumnStatsStep.java index 24efecdb..dee5e4d1 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/columnstats/ColumnStatsStep.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/columnstats/ColumnStatsStep.java @@ -25,6 +25,7 @@ package com.kingsrook.qqq.backend.core.processes.implementations.columnstats; import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import java.util.Map; import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper; import com.kingsrook.qqq.backend.core.actions.permissions.TablePermissionSubType; import com.kingsrook.qqq.backend.core.actions.processes.BackendStep; @@ -47,10 +48,12 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.aggregate.QFilterOrde 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.QueryInput; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryJoin; import com.kingsrook.qqq.backend.core.model.data.QRecord; 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.tables.ExposedJoin; 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.JsonUtils; @@ -102,8 +105,34 @@ public class ColumnStatsStep implements BackendStep filter = new QQueryFilter(); } - QTableMetaData table = QContext.getQInstance().getTable(tableName); - QFieldMetaData field = table.getField(fieldName); + QueryJoin queryJoin = null; + QTableMetaData table = QContext.getQInstance().getTable(tableName); + QFieldMetaData field = null; + if(fieldName.contains(".")) + { + String[] parts = fieldName.split("\\.", 2); + for(ExposedJoin exposedJoin : CollectionUtils.nonNullList(table.getExposedJoins())) + { + if(exposedJoin.getJoinTable().equals(parts[0])) + { + field = QContext.getQInstance().getTable(exposedJoin.getJoinTable()).getField(parts[1]); + queryJoin = new QueryJoin() + .withJoinTable(exposedJoin.getJoinTable()) + .withSelect(true) + .withType(QueryJoin.Type.INNER); + break; + } + } + } + else + { + field = table.getField(fieldName); + } + + if(field == null) + { + throw (new QException("Could not find field by name: " + fieldName)); + } //////////////////////////////////////////// // do a count query grouped by this field // @@ -148,6 +177,12 @@ public class ColumnStatsStep implements BackendStep aggregateInput.setTableName(tableName); aggregateInput.setFilter(filter); aggregateInput.setLimit(limit); + + if(queryJoin != null) + { + aggregateInput.withQueryJoin(queryJoin); + } + AggregateOutput aggregateOutput = new AggregateAction().execute(aggregateInput); ArrayList valueCounts = new ArrayList<>(); @@ -160,8 +195,8 @@ public class ColumnStatsStep implements BackendStep QFieldMetaData countField = new QFieldMetaData("count", QFieldType.INTEGER).withDisplayFormat(DisplayFormat.COMMAS).withLabel("Count"); QPossibleValueTranslator qPossibleValueTranslator = new QPossibleValueTranslator(); - qPossibleValueTranslator.translatePossibleValuesInRecords(table, valueCounts, null, null); - QValueFormatter.setDisplayValuesInRecords(List.of(table.getField(fieldName), countField), valueCounts); + qPossibleValueTranslator.translatePossibleValuesInRecords(table, valueCounts, queryJoin == null ? null : List.of(queryJoin), null); + QValueFormatter.setDisplayValuesInRecords(Map.of(fieldName, field, "count", countField), valueCounts); runBackendStepOutput.addValue("valueCounts", valueCounts); @@ -275,6 +310,10 @@ public class ColumnStatsStep implements BackendStep statsAggregateInput.setTableName(tableName); filter.setOrderBys(new ArrayList<>()); statsAggregateInput.setFilter(filter); + if(queryJoin != null) + { + statsAggregateInput.withQueryJoin(queryJoin); + } AggregateOutput statsAggregateOutput = new AggregateAction().execute(statsAggregateInput); AggregateResult statsAggregateResult = statsAggregateOutput.getResults().get(0);