unified handling of collections and subqueries

This commit is contained in:
Timo Westkämper 2008-03-17 18:00:10 +00:00
parent 0ba83e7ca7
commit 96cdeb7e70
9 changed files with 214 additions and 115 deletions

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query;
import com.mysema.query.grammar.Grammar;

View File

@ -5,11 +5,11 @@
*/
package com.mysema.query;
import com.mysema.query.grammar.Types.ExprBoolean;
import com.mysema.query.grammar.Types.Expr;
import com.mysema.query.grammar.Types.ExprEntity;
public class JoinExpression {
private ExprBoolean[] conditions;
private Expr<Boolean>[] conditions;
private final ExprEntity<?> target;
private final JoinType type;
@ -18,11 +18,11 @@ public class JoinExpression {
this.target = target;
}
public ExprBoolean[] getConditions() {
public Expr<Boolean>[] getConditions() {
return conditions;
}
public void setConditions(ExprBoolean[] conditions) {
public void setConditions(Expr<Boolean>[] conditions) {
this.conditions = conditions;
}

View File

@ -37,6 +37,9 @@ public class QueryBase<A extends QueryBase<A>> implements Query<A> {
select.clear();
where.clear();
}
private final Metadata metadata = new Metadata();
public A from(ExprEntity<?>... o) {
for (ExprEntity<?> expr : o){
joins.add(new JoinExpression(JoinType.DEFAULT,expr));
@ -95,6 +98,30 @@ public class QueryBase<A extends QueryBase<A>> implements Query<A> {
}
return (A) this;
}
public Metadata getMetadata(){
return metadata;
}
public class Metadata{
public List<Expr<?>> getGroupBy() {
return groupBy;
}
public List<ExprBoolean> getHaving() {
return having;
}
public List<JoinExpression> getJoins() {
return joins;
}
public List<OrderSpecifier<?>> getOrderBy() {
return orderBy;
}
public List<Expr<?>> getSelect() {
return select;
}
public List<ExprBoolean> getWhere() {
return where;
}
}
}

View File

@ -187,29 +187,25 @@ public class Grammar {
static <A extends Comparable<A>> ExprBoolean gt(Expr<A> left, A right) {
return _boolean(OpComparable.GT, left, _const(right));
}
static <A extends Comparable<A>> ExprBoolean gt(Expr<A> left,
Expr<A> right) {
return _boolean(OpComparable.GT, left, right);
}
static <A> ExprBoolean in(A left, ExprEntity<Collection<A>> right){
return _boolean(Op.INELEMENTS, _const(left), right);
}
static <A extends Comparable<A>> ExprBoolean in(Expr<A> left,
A... rest) {
return _boolean(Op.INARRAY, left, _const(rest));
return _boolean(Op.IN, left, _const(rest));
}
static <A> ExprBoolean in(ExprEntity<A> left, ExprEntity<Collection<A>> right){
return _boolean(Op.INELEMENTS, left, right);
static <A> ExprBoolean in(Expr<A> left, CollectionType<A> right){
return _boolean(Op.IN, left, (Expr<?>)right);
}
static <A> ExprBoolean isnotnull(Expr<A> left) {
return _boolean(Op.ISNOTNULL, left);
}
static <A> ExprBoolean isnull(Expr<A> left) {
return _boolean(Op.ISNULL, left);
}
@ -244,7 +240,7 @@ public class Grammar {
public static <A extends Comparable<A>> ExprComparable<A> max(Expr<A> left){
return _number(OpNumber.MAX, left);
}
public static <A extends Comparable<A>> ExprComparable<A> min(Expr<A> left){
return _number(OpNumber.MIN, left);
}
@ -252,23 +248,23 @@ public class Grammar {
public static <A extends Comparable<A>> ExprComparable<A> mult(Expr<A> left, A right) {
return _number(OpNumber.MULT, left, _const(right));
}
public static <A extends Comparable<A>> ExprComparable<A> mult(Expr<A> left, Expr<A> right) {
return _number(OpNumber.MULT, left, right);
}
static <A, B extends A> ExprBoolean ne(Expr<A> left, B right) {
return _boolean(Op.NE, left, _const(right));
}
static <A, B extends A> ExprBoolean ne(Expr<A> left, Expr<B> right) {
return _boolean(Op.NE, left, right);
}
}
public static ExprBoolean not(ExprBoolean left) {
return _boolean(OpBoolean.NOT, left);
}
static <A extends Comparable<A>> ExprBoolean notBetween(Expr<A> left,
A start, A end) {
return _boolean(OpComparable.NOTBETWEEN, left, _const(start), _const(end));
@ -278,20 +274,20 @@ public class Grammar {
Expr<A> start, Expr<A> end) {
return _boolean(OpComparable.NOTBETWEEN, left, start, end);
}
static <A extends Comparable<A>> ExprBoolean notIn(Expr<A> left,
A... rest) {
return _boolean(Op.NOTINARRAY, left, _const(rest));
return _boolean(Op.NOTIN, left, _const(rest));
}
static <A> ExprBoolean notIn(Expr<A> left, CollectionType<A> right){
return _boolean(Op.NOTIN, left, (Expr<?>)right);
}
static ExprBoolean or(ExprBoolean left, ExprBoolean right) {
return _boolean(OpBoolean.OR, left, right);
}
public static <A> SubQuery<A> select(Expr<A> select){
return new SubQuery<A>(select);
}
static <A> ExprComparable<Integer> size(Expr<Collection<A>> col){
return _number(Op.SIZE, col);
}

View File

@ -18,15 +18,13 @@ public class Ops {
*/
public interface Op<RT> {
Op<Boolean> EQ = new OpImpl<Boolean>();
Op<Boolean> INARRAY = new OpImpl<Boolean>();
Op<Boolean> INELEMENTS = new OpImpl<Boolean>();
Op<Boolean> IN = new OpImpl<Boolean>();
Op<Boolean> ISNOTNULL = new OpImpl<Boolean>();
Op<Boolean> ISNULL = new OpImpl<Boolean>();
Op<Boolean> ISTYPEOF = new OpImpl<Boolean>();
Op<Boolean> NE = new OpImpl<Boolean>();
Op<Boolean> NOTINARRAY = new OpImpl<Boolean>();
Op<Boolean> NOTIN = new OpImpl<Boolean>();
Op<Integer> SIZE = new OpImpl<Integer>();
Op<?> MAPGET = new OpImpl<Object>();
}
/**

View File

@ -5,61 +5,90 @@
*/
package com.mysema.query.grammar;
import static com.mysema.query.grammar.Grammar.*;
import static com.mysema.query.grammar.Grammar._const;
import com.mysema.query.grammar.Types.Expr;
import com.mysema.query.grammar.Types.Path;
import com.mysema.query.grammar.Types.PathCollection;
import com.mysema.query.grammar.Types.PathMap;
/**
*
* PathMetadata provides
*
*
* @author tiwe
* @version $Id$
*
*
*/
public final class PathMetadata<T>{
public final class PathMetadata<T> {
private final Expr<T> expression;
private final Path<?> parent;
private final Type type;
private PathMetadata(Path<?> parent, Expr<T> expression, Type type){
private final Type type;
private PathMetadata(Path<?> parent, Expr<T> expression, Type type) {
this.parent = parent;
this.expression = expression;
this.type = type;
}
public static PathMetadata<Integer> forListAccess(Path<?> parent, Expr<Integer> index){
return new PathMetadata<Integer>(parent,index,Type.LISTACCESS);
public static PathMetadata<Integer> forListAccess(PathCollection<?> parent,
Expr<Integer> index) {
return new PathMetadata<Integer>(parent, index, Type.LISTACCESS);
}
public static PathMetadata<Integer> forListAccess(PathCollection<?> parent,
int index) {
return new PathMetadata<Integer>(parent, _const(index),
Type.LISTACCESSC);
}
public static PathMetadata<Integer> forMinElement(PathCollection<?> parent) {
return new PathMetadata<Integer>(parent, null, Type.MINELEMENT);
}
public static PathMetadata<Integer> forListAccess(Path<?> parent, int index){
return new PathMetadata<Integer>(parent,_const(index),Type.LISTACCESSC);
public static PathMetadata<Integer> forSize(PathCollection<?> parent) {
return new PathMetadata<Integer>(parent, null, Type.SIZE);
}
public static <KT> PathMetadata<KT> forMapAccess(Path<?> parent, Expr<KT> key){
return new PathMetadata<KT>(parent,key,Type.MAPACCESS);
public static PathMetadata<Integer> forMaxElement(PathCollection<?> parent) {
return new PathMetadata<Integer>(parent, null, Type.MAXELEMENT);
}
public static <KT> PathMetadata<KT> forMapAccess(Path<?> parent, KT key){
return new PathMetadata<KT>(parent,_const(key),Type.MAPACCESSC);
public static <KT> PathMetadata<KT> forMapAccess(PathMap<?, ?> parent,
Expr<KT> key) {
return new PathMetadata<KT>(parent, key, Type.MAPACCESS);
}
public static PathMetadata<String> forProperty(Path<?> parent, String property){
return new PathMetadata<String>(parent,_const(property),Type.PROPERTY);
public static <KT> PathMetadata<KT> forMapAccess(PathMap<?, ?> parent,
KT key) {
return new PathMetadata<KT>(parent, _const(key), Type.MAPACCESSC);
}
public static PathMetadata<String> forVariable(String variable){
return new PathMetadata<String>(null,_const(variable),Type.VARIABLE);
public static PathMetadata<String> forProperty(Path<?> parent,
String property) {
return new PathMetadata<String>(parent, _const(property), Type.PROPERTY);
}
public Expr<T> getExpression() {return expression;}
public Path<?> getParent(){ return parent; }
public Type getType() {return type;}
public enum Type{
LISTACCESS,LISTACCESSC,MAPACCESS,MAPACCESSC,PROPERTY,VARIABLE
}
public static PathMetadata<String> forVariable(String variable) {
return new PathMetadata<String>(null, _const(variable), Type.VARIABLE);
}
public Expr<T> getExpression() {
return expression;
}
public Path<?> getParent() {
return parent;
}
public Type getType() {
return type;
}
public enum Type {
LISTACCESS, LISTACCESSC, MAPACCESS, MAPACCESSC, PROPERTY, VARIABLE, MINELEMENT, MAXELEMENT, SIZE
}
}

View File

@ -6,12 +6,11 @@
package com.mysema.query.grammar;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static com.mysema.query.grammar.PathMetadata.*;
import java.util.Collection;
import java.util.Map;
import com.mysema.query.grammar.Ops.Op;
/**
@ -50,7 +49,7 @@ public class Types {
private final Expr<?> from;
private final String to;
AliasNoEntity(Expr<D> from, String to) {
super(from.type);
super(from.getType());
this.from = from;
this.to = to;
}
@ -87,7 +86,7 @@ public class Types {
Expr(Class<D> type){this.type = type;}
public <B extends D> ExprBoolean eq(B right){return Grammar.eq(this, right);}
public <B extends D> ExprBoolean eq(Expr<B> right){return Grammar.eq(this, right);}
protected Class<D> getType(){ return type;}
public Class<D> getType(){ return type;}
public <B extends D> ExprBoolean ne(B right){return Grammar.ne(this, right);}
public <B extends D> ExprBoolean ne(Expr<B> right){return Grammar.ne(this, right);}
}
@ -113,6 +112,7 @@ public class Types {
public ExprBoolean gt(D right) {return Grammar.gt(this,right);}
public ExprBoolean gt(Expr<D> right) {return Grammar.gt(this,right);}
public ExprBoolean in(D... args) {return Grammar.in(this,args);}
public ExprBoolean in(CollectionType<D> arg) {return Grammar.in(this, arg);}
public ExprBoolean loe(D right) {return Grammar.loe(this,right);}
public ExprBoolean loe(Expr<D> right) {return Grammar.loe(this,right);}
public ExprBoolean lt(D right) {return Grammar.lt(this,right);}
@ -120,8 +120,17 @@ public class Types {
public ExprBoolean notBetween(D first, D second) {return Grammar.notBetween(this, first, second);}
public ExprBoolean notBetween(Expr<D> first, Expr<D> second) {return Grammar.notBetween(this,first,second);}
public ExprBoolean notIn(D...args) {return Grammar.notIn(this, args);}
public ExprBoolean notIn(CollectionType<D> arg) {return Grammar.notIn(this, arg);}
}
// *,
// /,
// DIV,
// %,
// MOD
// -,
// +
public static abstract class ExprEntity<D> extends Expr<D>{
ExprEntity(Class<D> type) {super(type);}
}
@ -204,6 +213,18 @@ public class Types {
public ExprBoolean isnull() {return Grammar.isnull(this);}
}
public interface CollectionType<D>{
}
public interface PathCollection<D> extends Path<Collection<D>>, CollectionType<D>{
Expr<D> get(Expr<Integer> index);
Expr<D> get(int index);
Expr<D> maxelement();
Expr<D> minelement();
ExprComparable<Integer> size();
}
public static class PathComparable<D extends Comparable<D>> extends ExprComparable<D> implements PathNoEntity<D>{
private final PathMetadata<String> metadata;
public PathComparable(Class<D> type, PathMetadata<String> metadata) {
@ -215,7 +236,7 @@ public class Types {
public ExprBoolean isnull() {return Grammar.isnull(this);}
}
public static class PathComponentCollection<D> extends ExprNoEntity<Collection<D>> implements Path<Collection<D>>{
public static class PathComponentCollection<D> extends ExprNoEntity<Collection<D>> implements PathCollection<D>{
private final PathMetadata<String> metadata;
private final Class<D> type;
PathComponentCollection(Class<D> type, PathMetadata<String> metadata) {
@ -223,15 +244,25 @@ public class Types {
this.type = type;
this.metadata = metadata;
}
public ExprNoEntity<D> get(Expr<Integer> index) {
return new PathNoEntitySimple<D>(type, forListAccess(this, index));
}
public ExprNoEntity<D> get(int index) {
return new PathNoEntitySimple<D>(type, forListAccess(this, index));}
return new PathNoEntitySimple<D>(type, forListAccess(this, index));
}
public PathMetadata<String> getMetadata() {return metadata;}
public ExprBoolean isnotnull() {return Grammar.isnotnull(this);}
public ExprBoolean isnull() {return Grammar.isnull(this);}
public ExprEntity<D> maxelement() {
return new PathEntity<D>(type, forMaxElement(this));
}
public ExprEntity<D> minelement() {
return new PathEntity<D>(type, forMinElement(this));
}
public ExprComparable<Integer> size() { return Grammar.size(this);}
}
public static class PathComponentMap<K,V> extends ExprNoEntity<Map<K,V>> implements Path<Map<K,V>>{
public static class PathComponentMap<K,V> extends ExprNoEntity<Map<K,V>> implements PathMap<K,V>{
private final PathMetadata<String> metadata;
private final Class<V> type;
PathComponentMap(Class<V> type, PathMetadata<String> metadata) {
@ -242,6 +273,9 @@ public class Types {
public ExprNoEntity<V> get(Expr<K> key) {
return new PathNoEntitySimple<V>(type, forMapAccess(this, key));
}
public ExprNoEntity<V> get(K key) {
return new PathNoEntitySimple<V>(type, forMapAccess(this, key));
}
public PathMetadata<String> getMetadata() {return metadata;}
public ExprBoolean isnotnull() {return Grammar.isnotnull(this);}
public ExprBoolean isnull() {return Grammar.isnull(this);}
@ -282,13 +316,13 @@ public class Types {
return new PathString(forProperty(this, path));
}
public PathMetadata<?> getMetadata() {return metadata;}
public ExprBoolean in(ExprEntity<Collection<D>> right){return Grammar.in(this, right);}
public ExprBoolean in(CollectionType<D> right){return Grammar.in(this, right);}
public ExprBoolean isnotnull() {return Grammar.isnotnull(this);}
public ExprBoolean isnull() {return Grammar.isnull(this);}
public <B extends D> ExprBoolean typeOf(Class<B> type) {return Grammar.typeOf(this, type);}
}
public static class PathEntityCollection<D> extends ExprEntity<Collection<D>> implements Path<Collection<D>>{
public static class PathEntityCollection<D> extends ExprEntity<Collection<D>> implements PathCollection<D>{
private final PathMetadata<String> metadata;
private final Class<D> type;
PathEntityCollection(Class<D> type, PathMetadata<String> metadata) {
@ -297,15 +331,25 @@ public class Types {
this.metadata = metadata;
}
public AliasEntityCollection<D> as(PathEntity<D> to) {return Grammar.as(this, to);}
public ExprEntity<D> get(Expr<Integer> index) {
return new PathEntity<D>(type, forListAccess(this,index));
}
public ExprEntity<D> get(int index) {
return new PathEntity<D>(type, forListAccess(this,index));}
return new PathEntity<D>(type, forListAccess(this,index));
}
public PathMetadata<String> getMetadata() {return metadata;}
public ExprBoolean isnotnull() {return Grammar.isnotnull(this);}
public ExprBoolean isnull() {return Grammar.isnull(this);}
public ExprComparable<Integer> size() { return Grammar.size(this);}
public ExprEntity<D> maxelement() {
return new PathEntity<D>(type, forMaxElement(this));
}
public ExprEntity<D> minelement() {
return new PathEntity<D>(type, forMinElement(this));
}
public ExprComparable<Integer> size() { return Grammar.size(this); }
}
public static class PathEntityMap<K,V> extends ExprEntity<Map<K,V>> implements Path<Map<K,V>>{
public static class PathEntityMap<K,V> extends ExprEntity<Map<K,V>> implements PathMap<K,V>{
private final PathMetadata<String> metadata;
private final Class<V> type;
PathEntityMap(Class<V> type, PathMetadata<String> metadata) {
@ -313,9 +357,15 @@ public class Types {
this.type = type;
this.metadata = metadata;
}
public PathMetadata<String> getMetadata() {return metadata;}
public ExprEntity<V> get(Expr<K> key) {
return new PathEntity<V>(type, forMapAccess(this, key));
}
public ExprEntity<V> get(K key) {
return new PathEntity<V>(type, forMapAccess(this, key));
}
public PathMetadata<String> getMetadata() {return metadata;}
public ExprBoolean isnotnull() {return Grammar.isnotnull(this);}
public ExprBoolean isnull() {return Grammar.isnull(this);}
public ExprBoolean isnull() {return Grammar.isnull(this);}
}
public static class PathEntityRenamable<D> extends PathEntity<D>{
@ -323,6 +373,11 @@ public class Types {
public AliasEntity<D> as(PathEntity<D> to) {return Grammar.as(this, to);}
}
public interface PathMap<K,V> extends Path<Map<K,V>>{
Expr<V> get(Expr<K> key);
Expr<V> get(K key);
}
public interface PathNoEntity<D> extends Path<D>{
Expr<D> as(String to);
}
@ -347,20 +402,5 @@ public class Types {
public ExprBoolean isnotnull() {return Grammar.isnotnull(this);}
public ExprBoolean isnull() {return Grammar.isnull(this);}
}
public static class SubQuery<A> extends Expr<Collection<A>>{
private List<ExprEntity<?>> from;
private final Expr<A> select;
private List<ExprBoolean> where;
SubQuery(Expr<A> select) {
super(null);
this.select = select;
}
List<ExprEntity<?>> _from() {return from;}
Expr<A> _select() {return select;}
List<ExprBoolean> _where() {return where;}
public SubQuery<A> from(ExprEntity<?>... o){this.from = Arrays.asList(o); return this;}
public SubQuery<A> where(ExprBoolean... o){this.where = Arrays.asList(o); return this;}
}
}

View File

@ -106,6 +106,4 @@ public abstract class Visitor<T extends Visitor<T>> {
protected abstract void visit(PathString expr);
protected abstract void visit(SubQuery<?> subQuery);
}

View File

@ -18,11 +18,11 @@ public abstract class VisitorAdapter<V extends VisitorAdapter<V>> extends
Visitor<V> {
@Override
protected void visit(AliasEntityCollection<?> expr) {
protected void visit(AliasEntity<?> expr) {
visit((AliasToPath) expr);
}
@Override
protected void visit(AliasEntity<?> expr) {
protected void visit(AliasEntityCollection<?> expr) {
visit((AliasToPath) expr);
}
@Override
@ -49,36 +49,38 @@ public abstract class VisitorAdapter<V extends VisitorAdapter<V>> extends
protected void visit(PathBoolean expr) {
visit((Path<?>) expr);
}
protected void visit(PathCollection<?> expr){
visit((Path<?>) expr);
}
@Override
protected void visit(PathComparable<?> expr) {
visit((Path<?>) expr);
}
@Override
protected void visit(PathComponentCollection<?> expr) {
visit((Path<?>) expr);
}
@Override
protected void visit(PathComponentMap<?,?> expr) {
visit((Path<?>) expr);
visit((PathCollection<?>) expr);
}
@Override
protected void visit(PathString expr) {
visit((Path<?>) expr);
protected void visit(PathComponentMap<?,?> expr) {
visit((PathMap<?,?>) expr);
}
@Override
protected void visit(PathEntity<?> expr) {
visit((Path<?>) expr);
}
@Override
protected void visit(PathEntityRenamable<?> expr) {
visit((PathEntity<?>) expr);
}
@Override
protected void visit(PathEntityCollection<?> expr) {
visit((Path<?>) expr);
visit((PathCollection<?>) expr);
}
@Override
protected void visit(PathEntityMap<?,?> expr) {
visit((PathMap<?,?>) expr);
}
@Override
protected void visit(PathEntityRenamable<?> expr) {
visit((PathEntity<?>) expr);
}
protected void visit(PathMap<?,?> expr){
visit((Path<?>) expr);
}
@Override
@ -89,4 +91,8 @@ public abstract class VisitorAdapter<V extends VisitorAdapter<V>> extends
protected void visit(PathNoEntitySimple<?> expr) {
visit((Path<?>) expr);
}
@Override
protected void visit(PathString expr) {
visit((Path<?>) expr);
}
}