added math methods to QMath

added subquery and union support to querydsl-sql
moved SubQuery to querydsl-core
This commit is contained in:
Timo Westkämper 2009-01-19 15:11:10 +00:00
parent 0c531271fe
commit 2d988f9456
9 changed files with 201 additions and 33 deletions

View File

@ -14,10 +14,4 @@ package com.mysema.query.alias;
*/
public interface ManagedObject {
void setElementType(Class<?> type);
void setKeyType(Class<?> type);
void setValueType(Class<?> type);
}

View File

@ -38,12 +38,9 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
private final AliasFactory aliasFactory;
// private final JavaSerializer serializer = new JavaSerializer(new JavaOps());
// private final JavaSerializer serializer = new JavaSerializer(new JavaOps());
private String toString;
private Class<?> elementType, keyType, valueType;
private final Map<String,Expr<?>> propToExpr = new HashMap<String,Expr<?>>();
private final Map<String,Object> propToObj = new HashMap<String,Object>();
@ -98,11 +95,13 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
aliasFactory.setCurrent(propToExpr.get(ptyName));
}else if (isListElementAccess(method)){
// TODO : manage cases where the argument is based on a property invocation
String ptyName = "_get" + args[0];
if (propToObj.containsKey(ptyName)){
rv = propToObj.get(ptyName);
}else{
PathMetadata<Integer> pm = PathMetadata.forListAccess((PList<?>)path, (Integer)args[0]);
Class<?> elementType = ((PCollection<?>)path).getElementType();
if (elementType != null){
rv = newInstance(elementType, elementType, proxy, ptyName, pm);
}else{
@ -119,18 +118,7 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
aliasFactory.setCurrent(Grammar.in(args[0], (CollectionType<Object>)path));
}else if (isToString(method)){
// TODO
// if (toString == null) toString = serializer.handle(path).toString();
// rv = toString;
}else if (method.getName().equals("setElementType")){
elementType = (Class<?>) args[0];
}else if (method.getName().equals("setKeyType")){
keyType = (Class<?>) args[0];
}else if (method.getName().equals("setValueType")){
valueType = (Class<?>) args[0];
rv = path.toString();
}else{
// rv = methodProxy.invokeSuper(proxy, args);

View File

@ -25,6 +25,8 @@ import com.mysema.query.grammar.types.Expr.EComparable;
*/
public class Grammar {
protected Grammar(){};
public static <A extends Number & Comparable<A>> Expr.EComparable<A> add(Expr<A> left, A right) {
return createNumber(Ops.ADD, left, createConstant(right));
}
@ -360,10 +362,6 @@ public class Grammar {
return createStringArray(Ops.SPLIT, left, createConstant(regex));
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> sqrt(Expr<A> left) {
return createNumber(Ops.SQRT, left);
}
public static EBoolean startsWith(Expr<String> left, Expr<String> right) {
return createBoolean(Ops.STARTSWITH, left, right);
}

View File

@ -53,7 +53,7 @@ public interface Ops {
Op<Number> DIV = new Op<Number>();
Op<Number> MOD = new Op<Number>();
Op<Number> MULT = new Op<Number>();
Op<Number> SQRT = new Op<Number>();
// Op<Number> SQRT = new Op<Number>();
Op<Number> SUB = new Op<Number>();
// String
@ -83,8 +83,31 @@ public interface Ops {
* The Interface OpNumberAgg.
*/
public interface OpNumberAgg{
Op<java.lang.Number> AVG = new Op<java.lang.Number>();
Op<java.lang.Number> MAX = new Op<java.lang.Number>();
Op<java.lang.Number> MIN = new Op<java.lang.Number>();
Op<Number> AVG = new Op<Number>();
Op<Number> MAX = new Op<Number>();
Op<Number> MIN = new Op<Number>();
}
public interface OpMath{
Op<Number> ABS = new Op<Number>();
Op<Number> ACOS = new Op<Number>();
Op<Number> ASIN = new Op<Number>();
Op<Number> ATAN = new Op<Number>();
Op<Number> CEIL = new Op<Number>();
Op<Number> COS = new Op<Number>();
Op<Number> TAN = new Op<Number>();
Op<Number> SQRT = new Op<Number>();
Op<Number> SIN = new Op<Number>();
Op<Number> ROUND = new Op<Number>();
Op<Number> RANDOM = new Op<Number>();
Op<Number> POWER = new Op<Number>();
Op<Number> MIN = new Op<Number>();
Op<Number> MAX = new Op<Number>();
Op<Number> MOD = new Op<Number>();
Op<Number> LOG10 = new Op<Number>();
Op<Number> LOG = new Op<Number>();
Op<Number> FLOOR = new Op<Number>();
Op<Number> EXP = new Op<Number>();
}
}

View File

@ -0,0 +1,91 @@
package com.mysema.query.grammar;
import com.mysema.query.grammar.Ops.OpMath;
import com.mysema.query.grammar.types.Expr;
import static com.mysema.query.grammar.types.Factory.*;
/**
* QMath provides
*
* @author tiwe
* @version $Id$
*/
public class QMath {
public static <A extends Number & Comparable<A>> Expr.EComparable<A> abs(Expr<A> left){
return createNumber(OpMath.ABS, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> acos(Expr<A> left){
return createNumber(OpMath.ACOS, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> asin(Expr<A> left){
return createNumber(OpMath.ASIN, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> atan(Expr<A> left){
return createNumber(OpMath.ATAN, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> ceil(Expr<A> left){
return createNumber(OpMath.CEIL, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> cos(Expr<A> left){
return createNumber(OpMath.COS, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> exp(Expr<A> left){
return createNumber(OpMath.EXP, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> floor(Expr<A> left){
return createNumber(OpMath.FLOOR, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> log(Expr<A> left){
return createNumber(OpMath.LOG, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> log10(Expr<A> left){
return createNumber(OpMath.LOG10, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> max(Expr<A> left, Expr<A> right){
return createNumber(OpMath.MAX, left, right);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> min(Expr<A> left, Expr<A> right){
return createNumber(OpMath.MIN, left, right);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> mod(Expr<A> left, Expr<A> right){
return createNumber(OpMath.MOD, left, right);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> pow(Expr<A> left, Expr<A> right){
return createNumber(OpMath.POWER, left, right);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> random(){
return createNumber(OpMath.RANDOM);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> round(Expr<A> left){
return createNumber(OpMath.ROUND, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> sin(Expr<A> left){
return createNumber(OpMath.SIN, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> sqrt(Expr<A> left){
return createNumber(OpMath.SQRT, left);
}
public static <A extends Number & Comparable<A>> Expr.EComparable<A> tan(Expr<A> left){
return createNumber(OpMath.TAN, left);
}
}

View File

@ -5,7 +5,10 @@
*/
package com.mysema.query.grammar.types;
import com.mysema.query.Query;
import com.mysema.query.QueryBase;
import com.mysema.query.grammar.Grammar;
import com.mysema.query.grammar.OrderSpecifier;
/**
@ -87,5 +90,5 @@ public class ExtTypes {
public EString toLowerCase(){ return lower(); }
public EString toUpperCase(){ return upper(); }
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.grammar.types;
import com.mysema.query.Query;
import com.mysema.query.QueryBase;
import com.mysema.query.grammar.OrderSpecifier;
/**
*
* SubQuery provides
*
* @author tiwe
* @version $Id$
*
* @param <A>
*/
public class SubQuery<JM,A> extends Expr<A> implements Query<SubQuery<JM,A>>, CollectionType<A>{
@SuppressWarnings("unchecked")
private QueryWithPublicSelect<JM> query = new QueryWithPublicSelect<JM>();
public SubQuery(Expr<A> select) {
super(null);
query.s(select);
}
public SubQuery(){
super(null);
}
@SuppressWarnings("unchecked")
public SubQuery<JM,A> from(EEntity... o) {query.from(o); return this;}
public SubQuery<JM,A> fullJoin(EEntity<?> o) {query.fullJoin(o); return this;}
public QueryBase<JM,?> getQuery(){ return query;}
public SubQuery<JM,A> groupBy(Expr<?>... o) {query.groupBy(o); return this;}
public SubQuery<JM,A> having(EBoolean... o) {query.having(o); return this;}
public SubQuery<JM,A> innerJoin(EEntity<?> o) {query.innerJoin(o); return this;}
public SubQuery<JM,A> join(EEntity<?> o) {query.join(o); return this;}
public SubQuery<JM,A> leftJoin(EEntity<?> o) {query.leftJoin(o); return this;}
public SubQuery<JM,A> orderBy(OrderSpecifier<?>... o) {query.orderBy(o); return this;}
public SubQuery<JM,A> select(Expr<?>... o) {query.s(o); return this;}
public SubQuery<JM,A> where(EBoolean... o) {query.where(o); return this;}
public SubQuery<JM,A> with(EBoolean o) {query.with(o); return this;}
private static class QueryWithPublicSelect<JM> extends QueryBase<JM,QueryWithPublicSelect<JM>>{
public void s(Expr<?>... expr){
select(expr);
}
}
}

View File

@ -49,7 +49,7 @@ public abstract class BaseSerializer<A extends BaseSerializer<A>> extends Visito
}
return (A)this;
}
@SuppressWarnings("unchecked")
protected final A _append(String sep, List<? extends Expr<?>> expressions) {
boolean first = true;

View File

@ -51,7 +51,7 @@ public abstract class OperationPatterns{
add(Ops.MOD, "%s % %s",10);
add(Ops.MULT,"%s * %s",7);
add(Ops.SUB, "%s - %s",12);
add(Ops.SQRT, "sqrt(%s)");
// add(Ops.SQRT, "sqrt(%s)");
// various
add(Ops.EQ_PRIMITIVE, "%s = %s",18);
@ -72,6 +72,27 @@ public abstract class OperationPatterns{
add(Ops.SUBSTR2ARGS, "substring(%s,%s,%s)");
add(Ops.TRIM, "trim(%s)");
add(Ops.UPPER, "upper(%s)");
// math
add(Ops.OpMath.ABS,"abs(%s)");
add(Ops.OpMath.ACOS,"acos(%s)");
add(Ops.OpMath.ASIN,"asin(%s)");
add(Ops.OpMath.ATAN,"atan(%s)");
add(Ops.OpMath.CEIL,"ceil(%s)");
add(Ops.OpMath.COS,"cos(%s)");
add(Ops.OpMath.TAN,"tan(%s)");
add(Ops.OpMath.SQRT,"sqrt(%s)");
add(Ops.OpMath.SIN,"sin(%s)");
add(Ops.OpMath.ROUND,"round(%s)");
add(Ops.OpMath.RANDOM,"random(%s)");
add(Ops.OpMath.POWER,"%s^%s");
add(Ops.OpMath.MIN,"min(%s,%s)");
add(Ops.OpMath.MAX,"max(%s,%s)");
add(Ops.OpMath.MOD,"mod(%s,%s)");
add(Ops.OpMath.LOG10,"log(%s)");
add(Ops.OpMath.LOG,"log(%s)");
add(Ops.OpMath.FLOOR,"floor(%s)");
add(Ops.OpMath.EXP,"exp(%s)");
// path types
for (PathType type : new PathType[]{PathMetadata.LISTVALUE, PathMetadata.LISTVALUE_CONSTANT, PathMetadata.MAPVALUE, PathMetadata.MAPVALUE_CONSTANT}){