#1331 - ENH: Support Aggregation formula with findSingleAttribute() ... max, min, avg, count and count(distinct ..)

This commit is contained in:
Rob Bygrave
2018-03-06 12:58:43 +13:00
parent ec2c3b13d4
commit 3ca4efc818
23 changed files with 783 additions and 51 deletions
@@ -62,11 +62,13 @@ import io.ebeaninternal.server.el.ElPropertyValue;
import io.ebeaninternal.server.persist.DmlUtil;
import io.ebeaninternal.server.query.CQueryPlan;
import io.ebeaninternal.server.query.CQueryPlanStatsCollector;
import io.ebeaninternal.server.query.SqlTreeProperty;
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
import io.ebeaninternal.server.rawsql.SpiRawSql;
import io.ebeaninternal.server.text.json.ReadJson;
import io.ebeaninternal.server.text.json.SpiJsonWriter;
import io.ebeaninternal.server.type.DataBind;
import io.ebeaninternal.server.type.ScalarType;
import io.ebeaninternal.util.SortByClause;
import io.ebeaninternal.util.SortByClauseParser;
import io.ebeanservice.docstore.api.DocStoreBeanAdapter;
@@ -112,6 +114,8 @@ public class BeanDescriptor<T> implements BeanType<T> {
private final ConcurrentHashMap<String, ElComparator<T>> comparatorCache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, SqlTreeProperty> dynamicProperty = new ConcurrentHashMap<>();
private final Map<String, SpiRawSql> namedRawSql;
private final Map<String, String> namedQuery;
@@ -1055,6 +1059,13 @@ public class BeanDescriptor<T> implements BeanType<T> {
return owner.getEncryptKey(tableName, columnName);
}
/**
* Return the Scalar type for the given JDBC type.
*/
public ScalarType<?> getScalarType(int jdbcType) {
return owner.getScalarType(jdbcType);
}
/**
* Return true if this bean type has a default select clause that is not
* simply select all properties.
@@ -2437,6 +2448,37 @@ public class BeanDescriptor<T> implements BeanType<T> {
return null;
}
/**
* Return a 'dynamic property' used to read a formula.
*/
private SqlTreeProperty findSqlTreeFormula(String formulaExpression) {
return dynamicProperty.computeIfAbsent(formulaExpression, (formula) -> {
FormulaPropertyPath propertyFormula = new FormulaPropertyPath(formula);
if (!propertyFormula.isFormula()) {
throw new IllegalStateException("unable to parse formula [" + formula + "} on bean type " + fullName);
}
String baseName = propertyFormula.basePropertyName();
BeanProperty base = _findBeanProperty(baseName);
if (base == null) {
throw new IllegalStateException("unable to find property [" + baseName + "] from formula [" + formula + "} on bean type " + fullName);
}
return propertyFormula.formulaProperty(base);
});
}
/**
* Return a property that is part of the SQL tree.
*
* The property can be a dynamic formula or a well known bean property.
*/
public SqlTreeProperty findSqlTreeProperty(String propName) {
if (propName.indexOf('(') > -1) {
return findSqlTreeFormula(propName);
}
return _findBeanProperty(propName);
}
/**
* Find a BeanProperty including searching the inheritance hierarchy.
* <p>