Add count distinct option to count action

This commit is contained in:
2023-04-24 12:12:41 -05:00
parent 2495989584
commit 1407f3c63c
5 changed files with 112 additions and 1 deletions

View File

@ -38,6 +38,7 @@ public class CountInput extends AbstractTableActionInput
private QQueryFilter filter;
private List<QueryJoin> queryJoins = null;
private Boolean includeDistinctCount = false;
@ -120,4 +121,35 @@ public class CountInput extends AbstractTableActionInput
return (this);
}
/*******************************************************************************
** Getter for includeDistinctCount
*******************************************************************************/
public Boolean getIncludeDistinctCount()
{
return (this.includeDistinctCount);
}
/*******************************************************************************
** Setter for includeDistinctCount
*******************************************************************************/
public void setIncludeDistinctCount(Boolean includeDistinctCount)
{
this.includeDistinctCount = includeDistinctCount;
}
/*******************************************************************************
** Fluent setter for includeDistinctCount
*******************************************************************************/
public CountInput withIncludeDistinctCount(Boolean includeDistinctCount)
{
this.includeDistinctCount = includeDistinctCount;
return (this);
}
}

View File

@ -32,6 +32,7 @@ import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
public class CountOutput extends AbstractActionOutput
{
private Integer count;
private Integer distinctCount;
@ -52,4 +53,47 @@ public class CountOutput extends AbstractActionOutput
{
this.count = count;
}
/*******************************************************************************
** Getter for distinctCount
*******************************************************************************/
public Integer getDistinctCount()
{
return (this.distinctCount);
}
/*******************************************************************************
** Setter for distinctCount
*******************************************************************************/
public void setDistinctCount(Integer distinctCount)
{
this.distinctCount = distinctCount;
}
/*******************************************************************************
** Fluent setter for distinctCount
*******************************************************************************/
public CountOutput withDistinctCount(Integer distinctCount)
{
this.distinctCount = distinctCount;
return (this);
}
/*******************************************************************************
** Fluent setter for count
*******************************************************************************/
public CountOutput withCount(Integer count)
{
this.count = count;
return (this);
}
}

View File

@ -36,6 +36,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.JoinsContext;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
import org.apache.commons.lang.BooleanUtils;
/*******************************************************************************
@ -63,6 +64,11 @@ public class RDBMSCountAction extends AbstractRDBMSAction implements CountInterf
String primaryKeyColumn = escapeIdentifier(fieldAndTableNameOrAlias.tableNameOrAlias()) + "." + escapeIdentifier(fieldAndTableNameOrAlias.field().getName());
String clausePrefix = (requiresDistinct) ? "SELECT COUNT(DISTINCT (" + primaryKeyColumn + "))" : "SELECT COUNT(*)";
if(BooleanUtils.isTrue(countInput.getIncludeDistinctCount()))
{
clausePrefix = "SELECT COUNT(DISTINCT (" + primaryKeyColumn + ")) AS distinct_count, COUNT(*)";
}
String sql = clausePrefix + " AS record_count FROM "
+ makeFromClause(countInput.getInstance(), table.getName(), joinsContext);
@ -81,6 +87,11 @@ public class RDBMSCountAction extends AbstractRDBMSAction implements CountInterf
if(resultSet.next())
{
rs.setCount(resultSet.getInt("record_count"));
if(BooleanUtils.isTrue(countInput.getIncludeDistinctCount()))
{
rs.setDistinctCount(resultSet.getInt("distinct_count"));
}
}
}), params);

View File

@ -788,6 +788,7 @@ public class QJavalinImplementation
}
countInput.setQueryJoins(processQueryJoinsParam(context));
countInput.setIncludeDistinctCount(QJavalinUtils.queryParamIsTrue(context, "includeDistinct"));
CountAction countAction = new CountAction();
CountOutput countOutput = countAction.execute(countInput);
@ -861,6 +862,11 @@ public class QJavalinImplementation
QueryAction queryAction = new QueryAction();
QueryOutput queryOutput = queryAction.execute(queryInput);
int rowIndex = 0;
for(QRecord record : queryOutput.getRecords())
{
record.setValue("__qRowIndex", rowIndex++);
}
QJavalinAccessLogger.logEndSuccess(logPair("recordCount", queryOutput.getRecords().size()), logPairIfSlow("filter", filter, SLOW_LOG_THRESHOLD_MS));
context.result(JsonUtils.toJson(queryOutput));

View File

@ -22,6 +22,7 @@
package com.kingsrook.qqq.backend.javalin;
import java.util.Objects;
import com.kingsrook.qqq.backend.core.exceptions.QValueException;
import com.kingsrook.qqq.backend.core.utils.StringUtils;
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
@ -52,6 +53,23 @@ public class QJavalinUtils
/*******************************************************************************
** Returns true iff context has a valid query parameter by the given name, with
** a value of "true".
*******************************************************************************/
public static boolean queryParamIsTrue(Context context, String name) throws QValueException
{
String value = context.queryParam(name);
if(Objects.equals(value, "true"))
{
return (true);
}
return (false);
}
/*******************************************************************************
** Returns Integer if context has a valid int form parameter by the given name,
** Returns null if no param (or empty value).