mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Add count distinct option to count action
This commit is contained in:
@ -37,7 +37,8 @@ public class CountInput extends AbstractTableActionInput
|
|||||||
{
|
{
|
||||||
private QQueryFilter filter;
|
private QQueryFilter filter;
|
||||||
|
|
||||||
private List<QueryJoin> queryJoins = null;
|
private List<QueryJoin> queryJoins = null;
|
||||||
|
private Boolean includeDistinctCount = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -120,4 +121,35 @@ public class CountInput extends AbstractTableActionInput
|
|||||||
return (this);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
|
|||||||
public class CountOutput extends AbstractActionOutput
|
public class CountOutput extends AbstractActionOutput
|
||||||
{
|
{
|
||||||
private Integer count;
|
private Integer count;
|
||||||
|
private Integer distinctCount;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -52,4 +53,47 @@ public class CountOutput extends AbstractActionOutput
|
|||||||
{
|
{
|
||||||
this.count = count;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.actions.tables.query.QQueryFilter;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
|
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 primaryKeyColumn = escapeIdentifier(fieldAndTableNameOrAlias.tableNameOrAlias()) + "." + escapeIdentifier(fieldAndTableNameOrAlias.field().getName());
|
||||||
String clausePrefix = (requiresDistinct) ? "SELECT COUNT(DISTINCT (" + primaryKeyColumn + "))" : "SELECT COUNT(*)";
|
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 "
|
String sql = clausePrefix + " AS record_count FROM "
|
||||||
+ makeFromClause(countInput.getInstance(), table.getName(), joinsContext);
|
+ makeFromClause(countInput.getInstance(), table.getName(), joinsContext);
|
||||||
|
|
||||||
@ -81,6 +87,11 @@ public class RDBMSCountAction extends AbstractRDBMSAction implements CountInterf
|
|||||||
if(resultSet.next())
|
if(resultSet.next())
|
||||||
{
|
{
|
||||||
rs.setCount(resultSet.getInt("record_count"));
|
rs.setCount(resultSet.getInt("record_count"));
|
||||||
|
|
||||||
|
if(BooleanUtils.isTrue(countInput.getIncludeDistinctCount()))
|
||||||
|
{
|
||||||
|
rs.setDistinctCount(resultSet.getInt("distinct_count"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}), params);
|
}), params);
|
||||||
|
@ -788,6 +788,7 @@ public class QJavalinImplementation
|
|||||||
}
|
}
|
||||||
|
|
||||||
countInput.setQueryJoins(processQueryJoinsParam(context));
|
countInput.setQueryJoins(processQueryJoinsParam(context));
|
||||||
|
countInput.setIncludeDistinctCount(QJavalinUtils.queryParamIsTrue(context, "includeDistinct"));
|
||||||
|
|
||||||
CountAction countAction = new CountAction();
|
CountAction countAction = new CountAction();
|
||||||
CountOutput countOutput = countAction.execute(countInput);
|
CountOutput countOutput = countAction.execute(countInput);
|
||||||
@ -861,6 +862,11 @@ public class QJavalinImplementation
|
|||||||
|
|
||||||
QueryAction queryAction = new QueryAction();
|
QueryAction queryAction = new QueryAction();
|
||||||
QueryOutput queryOutput = queryAction.execute(queryInput);
|
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));
|
QJavalinAccessLogger.logEndSuccess(logPair("recordCount", queryOutput.getRecords().size()), logPairIfSlow("filter", filter, SLOW_LOG_THRESHOLD_MS));
|
||||||
context.result(JsonUtils.toJson(queryOutput));
|
context.result(JsonUtils.toJson(queryOutput));
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
package com.kingsrook.qqq.backend.javalin;
|
package com.kingsrook.qqq.backend.javalin;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QValueException;
|
import com.kingsrook.qqq.backend.core.exceptions.QValueException;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
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 Integer if context has a valid int form parameter by the given name,
|
||||||
** Returns null if no param (or empty value).
|
** Returns null if no param (or empty value).
|
||||||
|
Reference in New Issue
Block a user