EJB-447 : Implement JPA 2.0 criteria apis (completed aggregation function support)
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17247 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
eb0396b1c6
commit
8465009b4b
|
@ -44,8 +44,7 @@ import org.hibernate.ejb.EntityManagerFactoryImpl;
|
||||||
import org.hibernate.ejb.criteria.expression.CompoundSelectionImpl;
|
import org.hibernate.ejb.criteria.expression.CompoundSelectionImpl;
|
||||||
import org.hibernate.ejb.criteria.expression.ParameterExpressionImpl;
|
import org.hibernate.ejb.criteria.expression.ParameterExpressionImpl;
|
||||||
import org.hibernate.ejb.criteria.expression.LiteralExpression;
|
import org.hibernate.ejb.criteria.expression.LiteralExpression;
|
||||||
import org.hibernate.ejb.criteria.expression.function.AverageAggregrateFunction;
|
import org.hibernate.ejb.criteria.expression.function.AggregationFunction;
|
||||||
import org.hibernate.ejb.criteria.expression.function.SumAggregateFunction;
|
|
||||||
import org.hibernate.ejb.criteria.predicate.BooleanExpressionPredicate;
|
import org.hibernate.ejb.criteria.predicate.BooleanExpressionPredicate;
|
||||||
import org.hibernate.ejb.criteria.predicate.ExplicitTruthValueCheck;
|
import org.hibernate.ejb.criteria.predicate.ExplicitTruthValueCheck;
|
||||||
import org.hibernate.ejb.criteria.predicate.TruthValue;
|
import org.hibernate.ejb.criteria.predicate.TruthValue;
|
||||||
|
@ -550,63 +549,57 @@ public class QueryBuilderImpl implements QueryBuilder, Serializable {
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public <N extends Number> Expression<Double> avg(Expression<N> x) {
|
public <N extends Number> AggregationFunction.AVG avg(Expression<N> x) {
|
||||||
return new AverageAggregrateFunction( this, x );
|
return new AggregationFunction.AVG( this, x );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public <N extends Number> Expression<N> sum(Expression<N> x) {
|
public <N extends Number> AggregationFunction.SUM<N> sum(Expression<N> x) {
|
||||||
return new SumAggregateFunction<N>( this, x );
|
return new AggregationFunction.SUM<N>( this, x );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public <N extends Number> Expression<N> max(Expression<N> x) {
|
public <N extends Number> AggregationFunction.MAX<N> max(Expression<N> x) {
|
||||||
// TODO : requires a MaxAggregrateFunction
|
return new AggregationFunction.MAX<N>( this, x );
|
||||||
throw new UnsupportedOperationException( "Note yet implemented!" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public <N extends Number> Expression<N> min(Expression<N> x) {
|
public <N extends Number> AggregationFunction.MIN<N> min(Expression<N> x) {
|
||||||
// TODO : requires a MaxAggregrateFunction
|
return new AggregationFunction.MIN<N>( this, x );
|
||||||
throw new UnsupportedOperationException( "Note yet implemented!" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public <X extends Comparable<X>> Expression<X> greatest(Expression<X> x) {
|
public <X extends Comparable<X>> Expression<X> greatest(Expression<X> x) {
|
||||||
// TODO : not exactly sure what this should be returning, same as #max ?
|
return new AggregationFunction.GREATEST<X>( this, x );
|
||||||
throw new UnsupportedOperationException( "Note yet implemented!" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public <X extends Comparable<X>> Expression<X> least(Expression<X> x) {
|
public <X extends Comparable<X>> Expression<X> least(Expression<X> x) {
|
||||||
// TODO : not exactly sure what this should be returning, same as #min ?
|
return new AggregationFunction.LEAST<X>( this, x );
|
||||||
throw new UnsupportedOperationException( "Note yet implemented!" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public Expression<Long> count(Expression<?> x) {
|
public Expression<Long> count(Expression<?> x) {
|
||||||
// TODO : CountAggregateFunction
|
return new AggregationFunction.COUNT( this, x, false );
|
||||||
throw new UnsupportedOperationException( "Note yet implemented!" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public Expression<Long> countDistinct(Expression<?> x) {
|
public Expression<Long> countDistinct(Expression<?> x) {
|
||||||
// TODO : CountDistinctAggregateFunction or CountAggregateFunction w/ distinct parameterization
|
return new AggregationFunction.COUNT( this, x, true );
|
||||||
throw new UnsupportedOperationException( "Note yet implemented!" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
package org.hibernate.ejb.criteria.expression.function;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.criteria.Expression;
|
||||||
|
import org.hibernate.ejb.criteria.QueryBuilderImpl;
|
||||||
|
import org.hibernate.ejb.criteria.expression.LiteralExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Models SQL aggregation functions (<tt>MIN</tt>, <tt>MAX</tt>, <tt>COUNT</tt>, etc).
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class AggregationFunction<T> extends BasicFunctionExpression<T> {
|
||||||
|
private static final List<Expression<?>> NO_ARGS = Collections.emptyList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an aggregation function with no arguments (<tt>COUNT(*)</tt> e.g.).
|
||||||
|
*
|
||||||
|
* @param queryBuilder The query builder instance.
|
||||||
|
* @param returnType The function return type.
|
||||||
|
* @param functionName The name of the function.
|
||||||
|
*/
|
||||||
|
public AggregationFunction(
|
||||||
|
QueryBuilderImpl queryBuilder,
|
||||||
|
Class<T> returnType,
|
||||||
|
String functionName) {
|
||||||
|
super( queryBuilder, returnType, functionName, NO_ARGS );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an aggregation function with a single literal argument.
|
||||||
|
*
|
||||||
|
* @param queryBuilder The query builder instance.
|
||||||
|
* @param returnType The function return type.
|
||||||
|
* @param functionName The name of the function.
|
||||||
|
* @param argument The literal argument
|
||||||
|
*/
|
||||||
|
public AggregationFunction(
|
||||||
|
QueryBuilderImpl queryBuilder,
|
||||||
|
Class<T> returnType,
|
||||||
|
String functionName,
|
||||||
|
Object argument) {
|
||||||
|
this( queryBuilder, returnType, functionName, new LiteralExpression( queryBuilder, argument ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an aggregation function with a single literal argument.
|
||||||
|
*
|
||||||
|
* @param queryBuilder The query builder instance.
|
||||||
|
* @param returnType The function return type.
|
||||||
|
* @param functionName The name of the function.
|
||||||
|
* @param argument The argument
|
||||||
|
*/
|
||||||
|
public AggregationFunction(
|
||||||
|
QueryBuilderImpl queryBuilder,
|
||||||
|
Class<T> returnType,
|
||||||
|
String functionName,
|
||||||
|
Expression<?> argument) {
|
||||||
|
super( queryBuilder, returnType, functionName, argument );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAggregation() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of a <tt>COUNT</tt> function providing convenience in construction.
|
||||||
|
* <p/>
|
||||||
|
* Parameterized as {@link Long} because thats what JPA states
|
||||||
|
* that the return from <tt>COUNT</tt> should be.
|
||||||
|
*/
|
||||||
|
public static class COUNT extends AggregationFunction<Long> {
|
||||||
|
public static final String NAME = "count";
|
||||||
|
|
||||||
|
private final boolean distinct;
|
||||||
|
|
||||||
|
public COUNT(QueryBuilderImpl queryBuilder, Expression<?> expression, boolean distinct) {
|
||||||
|
super( queryBuilder, Long.class, NAME , expression );
|
||||||
|
this.distinct = distinct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDistinct() {
|
||||||
|
return distinct;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of a <tt>AVG</tt> function providing convenience in construction.
|
||||||
|
* <p/>
|
||||||
|
* Parameterized as {@link Double} because thats what JPA states that the return from <tt>AVG</tt> should be.
|
||||||
|
*/
|
||||||
|
public static class AVG extends AggregationFunction<Double> {
|
||||||
|
public static final String NAME = "avg";
|
||||||
|
|
||||||
|
public AVG(QueryBuilderImpl queryBuilder, Expression<? extends Number> expression) {
|
||||||
|
super( queryBuilder, Double.class, NAME, expression );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of a <tt>SUM</tt> function providing convenience in construction.
|
||||||
|
* <p/>
|
||||||
|
* Parameterized as {@link Number N extends Number} because thats what JPA states
|
||||||
|
* that the return from <tt>SUM</tt> should be.
|
||||||
|
*/
|
||||||
|
public static class SUM<N extends Number> extends AggregationFunction<N> {
|
||||||
|
public static final String NAME = "sum";
|
||||||
|
|
||||||
|
public SUM(QueryBuilderImpl queryBuilder, Expression<N> expression) {
|
||||||
|
super( queryBuilder, expression.getJavaType(), NAME , expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of a <tt>MIN</tt> function providing convenience in construction.
|
||||||
|
* <p/>
|
||||||
|
* Parameterized as {@link Number N extends Number} because thats what JPA states
|
||||||
|
* that the return from <tt>MIN</tt> should be.
|
||||||
|
*/
|
||||||
|
public static class MIN<N extends Number> extends AggregationFunction<N> {
|
||||||
|
public static final String NAME = "min";
|
||||||
|
|
||||||
|
public MIN(QueryBuilderImpl queryBuilder, Expression<N> expression) {
|
||||||
|
super( queryBuilder, expression.getJavaType(), NAME , expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of a <tt>MAX</tt> function providing convenience in construction.
|
||||||
|
* <p/>
|
||||||
|
* Parameterized as {@link Number N extends Number} because thats what JPA states
|
||||||
|
* that the return from <tt>MAX</tt> should be.
|
||||||
|
*/
|
||||||
|
public static class MAX<N extends Number> extends AggregationFunction<N> {
|
||||||
|
public static final String NAME = "max";
|
||||||
|
|
||||||
|
public MAX(QueryBuilderImpl queryBuilder, Expression<N> expression) {
|
||||||
|
super( queryBuilder, expression.getJavaType(), NAME , expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Models the <tt>MIN</tt> function in terms of non-numeric expressions.
|
||||||
|
*
|
||||||
|
* @see MIN
|
||||||
|
*/
|
||||||
|
public static class LEAST<X extends Comparable<X>> extends AggregationFunction<X> {
|
||||||
|
public static final String NAME = "min";
|
||||||
|
|
||||||
|
public LEAST(QueryBuilderImpl queryBuilder, Expression<X> expression) {
|
||||||
|
super( queryBuilder, expression.getJavaType(), NAME , expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Models the <tt>MAX</tt> function in terms of non-numeric expressions.
|
||||||
|
*
|
||||||
|
* @see MAX
|
||||||
|
*/
|
||||||
|
public static class GREATEST<X extends Comparable<X>> extends AggregationFunction<X> {
|
||||||
|
public static final String NAME = "max";
|
||||||
|
|
||||||
|
public GREATEST(QueryBuilderImpl queryBuilder, Expression<X> expression) {
|
||||||
|
super( queryBuilder, expression.getJavaType(), NAME , expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Middleware LLC.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.ejb.criteria.expression.function;
|
|
||||||
|
|
||||||
import javax.persistence.criteria.Expression;
|
|
||||||
|
|
||||||
import org.hibernate.ejb.criteria.QueryBuilderImpl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of a <tt>AVG</tt> function providing convenience in construction.
|
|
||||||
* <p/>
|
|
||||||
* Parameterized as {@link Double} because thats what JPA states that the return
|
|
||||||
* from <tt>AVG</tt> should be.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class AverageAggregrateFunction extends BasicFunctionExpression<Double> {
|
|
||||||
public AverageAggregrateFunction(
|
|
||||||
QueryBuilderImpl queryBuilder,
|
|
||||||
Expression<? extends Number> expression) {
|
|
||||||
super( queryBuilder, Double.class, "avg", expression );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.ejb.criteria.expression.function;
|
package org.hibernate.ejb.criteria.expression.function;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import org.hibernate.ejb.criteria.expression.*;
|
import org.hibernate.ejb.criteria.expression.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -33,7 +34,7 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class BasicFunctionExpression<X> extends ExpressionImpl<X> implements Expression<X> {
|
public class BasicFunctionExpression<X> extends ExpressionImpl<X> implements FunctionExpression<X> {
|
||||||
private final String functionName;
|
private final String functionName;
|
||||||
private final List<Expression<?>> argumentExpressions;
|
private final List<Expression<?>> argumentExpressions;
|
||||||
|
|
||||||
|
@ -57,10 +58,27 @@ public class BasicFunctionExpression<X> extends ExpressionImpl<X> implements Exp
|
||||||
this.argumentExpressions = Arrays.asList( argumentExpressions );
|
this.argumentExpressions = Arrays.asList( argumentExpressions );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static List<Expression<?>> wrapAsLiterals(QueryBuilderImpl queryBuilder, Object... literalArguments) {
|
||||||
|
List<Expression<?>> arguments = new ArrayList<Expression<?>>( properSize( literalArguments.length) );
|
||||||
|
for ( Object o : literalArguments ) {
|
||||||
|
arguments.add( new LiteralExpression( queryBuilder, o ) );
|
||||||
|
}
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int properSize(int number) {
|
||||||
|
return number + (int)( number*.75 ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
public String getFunctionName() {
|
public String getFunctionName() {
|
||||||
return functionName;
|
return functionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAggregation() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<Expression<?>> getArgumentExpressions() {
|
public List<Expression<?>> getArgumentExpressions() {
|
||||||
return argumentExpressions;
|
return argumentExpressions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,10 @@ public class CastFunction<T,Y> extends ExpressionImpl<T> implements FunctionExpr
|
||||||
return CAST_NAME;
|
return CAST_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAggregation() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public ExpressionImpl<Y> getCastSource() {
|
public ExpressionImpl<Y> getCastSource() {
|
||||||
return castSource;
|
return castSource;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,5 +31,17 @@ import javax.persistence.criteria.Expression;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface FunctionExpression<T> extends Expression<T> {
|
public interface FunctionExpression<T> extends Expression<T> {
|
||||||
|
/**
|
||||||
|
* Retrieve the name of the function.
|
||||||
|
*
|
||||||
|
* @return The function name.
|
||||||
|
*/
|
||||||
public String getFunctionName();
|
public String getFunctionName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this function a value aggregator (like a <tt>COUNT</tt> or <tt>MAX</tt> function e.g.)?
|
||||||
|
*
|
||||||
|
* @return True if this functions does aggregation.
|
||||||
|
*/
|
||||||
|
public boolean isAggregation();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Middleware LLC.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.ejb.criteria.expression.function;
|
|
||||||
|
|
||||||
import javax.persistence.criteria.Expression;
|
|
||||||
|
|
||||||
import org.hibernate.ejb.criteria.QueryBuilderImpl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of a <tt>SUM</tt> function providing convenience in construction.
|
|
||||||
* <p/>
|
|
||||||
* Parameterized as {@link Number N extends Number} because thats what JPA states
|
|
||||||
* that the return from <tt>SUM</tt> should be.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class SumAggregateFunction<N extends Number> extends BasicFunctionExpression<N> {
|
|
||||||
public SumAggregateFunction(
|
|
||||||
QueryBuilderImpl queryBuilder,
|
|
||||||
Expression<N> expression) {
|
|
||||||
super( queryBuilder, expression.getJavaType(), "sum", expression );
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue