mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-30 21:08:30 +08:00
improved path expressions and modeled them like operations
This commit is contained in:
parent
b802d653aa
commit
b0bdb9aed2
@ -1,4 +1,4 @@
|
||||
#Tue Mar 25 18:08:01 EET 2008
|
||||
#Sat Mar 29 01:18:48 EET 2008
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
||||
|
||||
@ -5,11 +5,14 @@
|
||||
*/
|
||||
package com.mysema.query.grammar;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import com.mysema.query.Query;
|
||||
import com.mysema.query.QueryBase;
|
||||
import com.mysema.query.grammar.HqlOps.HqlPathType;
|
||||
import com.mysema.query.grammar.HqlOps.OpHql;
|
||||
import com.mysema.query.grammar.HqlOps.OpNumberAgg;
|
||||
import com.mysema.query.grammar.HqlOps.OpQuant;
|
||||
import com.mysema.query.grammar.Ops.Op;
|
||||
import com.mysema.query.grammar.Types.*;
|
||||
@ -21,7 +24,7 @@ import com.mysema.query.grammar.Types.*;
|
||||
* @version $Id$
|
||||
*/
|
||||
public class HqlGrammar extends Grammar{
|
||||
|
||||
|
||||
public static <D> Expr<D> all(CollectionType<D> col){
|
||||
return new ExprQuantSimple<D>(OpQuant.ALL, col);
|
||||
}
|
||||
@ -36,36 +39,44 @@ public class HqlGrammar extends Grammar{
|
||||
return new ExprQuantComparable<D>(OpQuant.ANY, col);
|
||||
}
|
||||
|
||||
public static <A extends Comparable<A>> ExprComparable<A> avg(Expr<A> left){
|
||||
return _number(OpNumberAgg.AVG, left);
|
||||
}
|
||||
public static <A extends Comparable<A>> ExprComparable<A> avg(PathCollection<A> left){
|
||||
return new ExprQuantComparable<A>(OpQuant.AVG_IN_COL, left);
|
||||
}
|
||||
|
||||
public static ExprComparable<Long> count(){
|
||||
return new CountExpr(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static ExprComparable<Long> count(Expr<?> expr){
|
||||
return new CountExpr(expr);
|
||||
}
|
||||
|
||||
public static ExprComparable<Date> current_date(){
|
||||
return _comparable(OpHql.CURRENT_DATE);
|
||||
}
|
||||
}
|
||||
public static ExprComparable<Date> current_time(){
|
||||
return _comparable(OpHql.CURRENT_TIME);
|
||||
}
|
||||
public static ExprComparable<Date> current_timestamp(){
|
||||
return _comparable(OpHql.CURRENT_TIMESTAMP);
|
||||
}
|
||||
public static ExprComparable<Date> day(Expr<Date> date){
|
||||
return _comparable(OpHql.DAY, date);
|
||||
}
|
||||
|
||||
public static ExprComparable<Date> day(Expr<Date> date){
|
||||
return _comparable(OpHql.DAY, date);
|
||||
}
|
||||
public static <T> Expr<T> distinct(PathEntity<T> left){
|
||||
return new DistinctPath<T>(left);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Expr<T> distinct(PathNoEntity<T> left){
|
||||
return new DistinctPath<T>(left);
|
||||
}
|
||||
}
|
||||
|
||||
public static <D> ExprBoolean exists(CollectionType<D> col){
|
||||
return new ExprQuantBoolean<D>(OpQuant.EXISTS, col);
|
||||
}
|
||||
}
|
||||
|
||||
public static <A> SubQuery<A> from(ExprEntity<A> select){
|
||||
return new SubQuery<A>(select).from(select);
|
||||
@ -73,26 +84,72 @@ public class HqlGrammar extends Grammar{
|
||||
|
||||
public static ExprComparable<Date> hour(Expr<Date> date){
|
||||
return _comparable(OpHql.HOUR, date);
|
||||
}
|
||||
public static PathComponentCollection<Integer> indices(PathCollection<?> col){
|
||||
return new PathComponentCollection<Integer>(Integer.class, new PathMetadata<Collection<Integer>>(col, null, HqlPathType.LISTINDICES));
|
||||
}
|
||||
|
||||
public static <K,V> PathComponentCollection<K> indices(PathMap<K,V> col){
|
||||
return new PathComponentCollection<K>(col.getKeyType(), new PathMetadata<Collection<Integer>>(col, null, HqlPathType.LISTINDICES));
|
||||
}
|
||||
|
||||
public static ExprBoolean isempty(PathComponentCollection<?> collection) {
|
||||
return _boolean(OpHql.ISEMPTY, collection);
|
||||
}
|
||||
|
||||
public static ExprBoolean isempty(PathEntityCollection<?> collection) {
|
||||
return _boolean(OpHql.ISEMPTY, collection);
|
||||
}
|
||||
}
|
||||
|
||||
public static ExprBoolean isnotempty(PathComponentCollection<?> collection) {
|
||||
return _boolean(OpHql.ISNOTEMPTY, collection);
|
||||
}
|
||||
|
||||
public static ExprBoolean isnotempty(PathEntityCollection<?> collection) {
|
||||
return _boolean(OpHql.ISNOTEMPTY, collection);
|
||||
}
|
||||
|
||||
public static ExprComparable<Integer> maxindex(PathEntityCollection<?> collection) {
|
||||
return _comparable(OpHql.MAXINDEX, collection);
|
||||
public static <A extends Comparable<A>> ExprComparable<A> max(Expr<A> left){
|
||||
return _number(OpNumberAgg.MAX, left);
|
||||
}
|
||||
public static <A extends Comparable<A>> ExprComparable<A> max(PathCollection<A> left){
|
||||
return new ExprQuantComparable<A>(OpQuant.MAX_IN_COL, left);
|
||||
}
|
||||
|
||||
public static <A> PathEntity<A> maxelement(PathEntityCollection<A> col) {
|
||||
return new PathEntity<A>(col.getElementType(), new PathMetadata<A>(col, null, HqlPathType.MINELEMENT));
|
||||
}
|
||||
|
||||
public static ExprComparable<Integer> minindex(PathEntityCollection<?> collection) {
|
||||
return _comparable(OpHql.MININDEX, collection);
|
||||
public static <A> PathComparable<Integer> maxindex(PathComponentCollection<A> col) {
|
||||
return new PathComparable<Integer>(Integer.class, new PathMetadata<Integer>(col, null, HqlPathType.MAXINDEX));
|
||||
}
|
||||
|
||||
|
||||
public static <A> PathComparable<Integer> maxindex(PathEntityCollection<A> col) {
|
||||
return new PathComparable<Integer>(Integer.class, new PathMetadata<Integer>(col, null, HqlPathType.MAXINDEX));
|
||||
}
|
||||
public static <A extends Comparable<A>> ExprComparable<A> min(Expr<A> left){
|
||||
return _number(OpNumberAgg.MIN, left);
|
||||
}
|
||||
|
||||
public static <A extends Comparable<A>> ExprComparable<A> min(PathCollection<A> left){
|
||||
return new ExprQuantComparable<A>(OpQuant.MIN_IN_COL, left);
|
||||
}
|
||||
|
||||
public static <A> PathEntity<A> minelement(PathEntityCollection<A> col) {
|
||||
return new PathEntity<A>(col.getElementType(), new PathMetadata<A>(col, null, HqlPathType.MINELEMENT));
|
||||
}
|
||||
|
||||
public static <A> PathComparable<Integer> minindex(PathComponentCollection<A> col) {
|
||||
return new PathComparable<Integer>(Integer.class, new PathMetadata<Integer>(col, null, HqlPathType.MININDEX));
|
||||
}
|
||||
|
||||
public static <A> PathComparable<Integer> minindex(PathEntityCollection<A> col) {
|
||||
return new PathComparable<Integer>(Integer.class, new PathMetadata<Integer>(col, null, HqlPathType.MININDEX));
|
||||
}
|
||||
|
||||
public static ExprComparable<Date> minute(Expr<Date> date){
|
||||
return _comparable(OpHql.MINUTE, date);
|
||||
}
|
||||
}
|
||||
|
||||
public static ExprComparable<Date> month(Expr<Date> date){
|
||||
return _comparable(OpHql.MONTH, date);
|
||||
|
||||
@ -7,6 +7,9 @@ package com.mysema.query.grammar;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.mysema.query.grammar.PathMetadata.PathType;
|
||||
import com.mysema.query.grammar.PathMetadata.PathTypeImpl;
|
||||
|
||||
/**
|
||||
* Ops provides
|
||||
*
|
||||
@ -59,9 +62,10 @@ public class HqlOps extends Ops {
|
||||
add(OpNumber.SUB, "%s - %s",12);
|
||||
add(OpNumber.SQRT, "sqrt(%s)");
|
||||
|
||||
add(OpNumber.AVG, "avg(%s)");
|
||||
add(OpNumber.MAX, "max(%s)");
|
||||
add(OpNumber.MIN, "min(%s)");
|
||||
// numeric aggregates
|
||||
add(OpNumberAgg.AVG, "avg(%s)");
|
||||
add(OpNumberAgg.MAX, "max(%s)");
|
||||
add(OpNumberAgg.MIN, "min(%s)");
|
||||
|
||||
// various
|
||||
add(Op.EQ, "%s = %s",18);
|
||||
@ -71,7 +75,7 @@ public class HqlOps extends Ops {
|
||||
add(Op.NOTIN, "%s not in %s");
|
||||
add(Op.ISNULL, "%s is null",26);
|
||||
add(Op.ISNOTNULL, "%s is not null",26);
|
||||
add(Op.SIZE, "size(%s)");
|
||||
// add(Op.SIZE, "size(%s)");
|
||||
|
||||
// string
|
||||
add(OpString.CONCAT, "%s || %s",37);
|
||||
@ -94,14 +98,32 @@ public class HqlOps extends Ops {
|
||||
add(OpHql.DAY, "day(%s)");
|
||||
add(OpHql.MONTH, "month(%s)");
|
||||
add(OpHql.YEAR, "year(%s)");
|
||||
add(OpHql.MAXINDEX, "maxindex(%s)");
|
||||
add(OpHql.MININDEX, "minindex(%s)");
|
||||
|
||||
// quantified expressions
|
||||
add(OpQuant.AVG_IN_COL, "avg(%s)");
|
||||
add(OpQuant.MAX_IN_COL, "max(%s)");
|
||||
add(OpQuant.MIN_IN_COL, "min(%s)");
|
||||
|
||||
add(OpQuant.ANY, "any %s");
|
||||
add(OpQuant.ALL, "all %s");
|
||||
add(OpQuant.EXISTS, "exists %s");
|
||||
add(OpQuant.NOTEXISTS, "not exists %s");
|
||||
|
||||
// path types
|
||||
for (PathType type : new PathType[]{PathType.LISTVALUE, PathType.LISTVALUE_CONSTANT, PathType.MAPVALUE, PathType.MAPVALUE_CONSTANT}){
|
||||
add(type,"%s[%s]");
|
||||
}
|
||||
add(PathType.PROPERTY,"%s.%s"); // TODO : as string
|
||||
add(PathType.SIZE,"%s.size");
|
||||
add(PathType.VARIABLE,"%s"); // TODO : as string
|
||||
|
||||
// HQL types
|
||||
add(HqlPathType.MINELEMENT, "minelement(%s)");
|
||||
add(HqlPathType.MAXELEMENT, "max(%s");
|
||||
add(HqlPathType.MININDEX, "minelement(%s)");
|
||||
add(HqlPathType.MAXINDEX, "minelement(%s)");
|
||||
add(HqlPathType.LISTINDICES, "indices(%s)");
|
||||
add(HqlPathType.MAPINDICES, "indices(%s)");
|
||||
}
|
||||
|
||||
private static void add(Op<?> op, String pattern){
|
||||
@ -124,8 +146,8 @@ public class HqlOps extends Ops {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public interface OpHql<RT>{
|
||||
|
||||
public interface OpHql{
|
||||
Op<Date> CURRENT_DATE = new OpImpl<Date>();
|
||||
Op<Date> CURRENT_TIME = new OpImpl<Date>();
|
||||
Op<Date> CURRENT_TIMESTAMP = new OpImpl<Date>();
|
||||
@ -133,8 +155,6 @@ public class HqlOps extends Ops {
|
||||
Op<Date> HOUR = new OpImpl<Date>();
|
||||
Op<Boolean> ISEMPTY = new OpImpl<Boolean>();
|
||||
Op<Boolean> ISNOTEMPTY = new OpImpl<Boolean>();
|
||||
Op<Object> MAXINDEX = new OpImpl<Object>();
|
||||
Op<Object> MININDEX = new OpImpl<Object>();
|
||||
Op<Date> MINUTE = new OpImpl<Date>();
|
||||
Op<Date> MONTH = new OpImpl<Date>();
|
||||
Op<Date> SECOND = new OpImpl<Date>();
|
||||
@ -143,16 +163,34 @@ public class HqlOps extends Ops {
|
||||
Op<Date> YEAR = new OpImpl<Date>();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public interface OpQuant<RT>{
|
||||
public interface OpNumberAgg{
|
||||
Op<Number> AVG = new OpImpl<Number>();
|
||||
Op<Number> MAX = new OpImpl<Number>();
|
||||
Op<Number> MIN = new OpImpl<Number>();
|
||||
}
|
||||
|
||||
public interface OpQuant{
|
||||
Op<Number> AVG_IN_COL = new OpImpl<Number>();
|
||||
Op<Number> MAX_IN_COL = new OpImpl<Number>();
|
||||
Op<Number> MIN_IN_COL = new OpImpl<Number>();
|
||||
|
||||
// some / any = true for any
|
||||
// all = true for all
|
||||
// exists = true is subselect matches
|
||||
// not exists = true if subselect doesn't match
|
||||
Op<?> ANY = new OpImpl();
|
||||
Op<?> ALL = new OpImpl();
|
||||
Op<?> EXISTS = new OpImpl();
|
||||
Op<?> NOTEXISTS = new OpImpl();
|
||||
Op<?> ANY = new OpImpl<Object>();
|
||||
Op<?> ALL = new OpImpl<Object>();
|
||||
Op<?> EXISTS = new OpImpl<Object>();
|
||||
Op<?> NOTEXISTS = new OpImpl<Object>();
|
||||
}
|
||||
|
||||
public interface HqlPathType{
|
||||
PathType MINELEMENT = new PathTypeImpl();
|
||||
PathType MAXELEMENT = new PathTypeImpl();
|
||||
PathType MININDEX = new PathTypeImpl();
|
||||
PathType MAXINDEX = new PathTypeImpl();
|
||||
PathType LISTINDICES = new PathTypeImpl();
|
||||
PathType MAPINDICES = new PathTypeImpl();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -15,6 +15,8 @@ import com.mysema.query.grammar.HqlGrammar.*;
|
||||
import com.mysema.query.grammar.Ops.Op;
|
||||
import com.mysema.query.grammar.Types.*;
|
||||
|
||||
import com.mysema.query.grammar.PathMetadata.PathType;
|
||||
|
||||
/**
|
||||
* HqlSerializer provides
|
||||
*
|
||||
@ -71,14 +73,12 @@ public class HqlSerializer extends VisitorAdapter<HqlSerializer>{
|
||||
JoinExpression je = joins.get(i);
|
||||
if (i > 0){
|
||||
String sep = ", ";
|
||||
if (je.getTarget() instanceof AliasToPath){
|
||||
switch(je.getType()){
|
||||
case FULLJOIN: sep = "\n full join "; break;
|
||||
case INNERJOIN: sep = "\n inner join "; break;
|
||||
case JOIN: sep = "\n join "; break;
|
||||
case LEFTJOIN: sep = "\n left join "; break;
|
||||
}
|
||||
}
|
||||
_append(sep);
|
||||
}
|
||||
// type specifier
|
||||
@ -186,20 +186,26 @@ public class HqlSerializer extends VisitorAdapter<HqlSerializer>{
|
||||
|
||||
@Override
|
||||
protected void visit(Path<?> path) {
|
||||
PathType pathType = path.getMetadata().getPathType();
|
||||
String parentAsString = null, exprAsString = null;
|
||||
|
||||
if (path.getMetadata().getParent() != null){
|
||||
visit(path.getMetadata().getParent());
|
||||
parentAsString = _toString((Expr<?>)path.getMetadata().getParent(),false);
|
||||
}
|
||||
if (pathType == PathType.PROPERTY || pathType == PathType.VARIABLE ||
|
||||
pathType == PathType.LISTVALUE_CONSTANT){
|
||||
exprAsString = path.getMetadata().getExpression().toString();
|
||||
}else if (path.getMetadata().getExpression() != null){
|
||||
exprAsString = _toString(path.getMetadata().getExpression(),false);
|
||||
}
|
||||
Expr<?> expr = path.getMetadata().getExpression();
|
||||
switch(path.getMetadata().getType()){
|
||||
case LISTACCESS :
|
||||
case MAPACCESS : _append("[").handle(expr)._append("]"); break;
|
||||
case LISTACCESSC : _append("[")._append(expr.toString())._append("]"); break;
|
||||
case MAPACCESSC : _append("[").handle(expr)._append("]"); break;
|
||||
case MAXELEMENT : handle(expr)._append(".maxelement()"); break;
|
||||
case MINELEMENT : handle(expr)._append(".minelement()"); break;
|
||||
case PROPERTY : _append(".")._append(expr.toString()); break;
|
||||
case VARIABLE : _append(expr.toString()); break;
|
||||
|
||||
String pattern = HqlOps.getPattern(pathType);
|
||||
if (parentAsString != null){
|
||||
_append(String.format(pattern, parentAsString, exprAsString));
|
||||
}else{
|
||||
_append(String.format(pattern, exprAsString));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -15,7 +15,10 @@ import com.mysema.query.grammar.hql.HqlParserTest;
|
||||
* @version $Id$
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({FeaturesTest.class,HqlIntegrationTest.class,HqlParserTest.class})
|
||||
@SuiteClasses({
|
||||
FeaturesTest.class,
|
||||
HqlIntegrationTest.class,
|
||||
HqlParserTest.class})
|
||||
public class AllTests {
|
||||
|
||||
}
|
||||
|
||||
@ -31,10 +31,12 @@ public interface Domain1Instances {
|
||||
Cat qat = new Cat("qat");
|
||||
Cat rival = new Cat("rival");
|
||||
|
||||
doofus d = new doofus("d");
|
||||
Catalog catalog = new Catalog("catalog");
|
||||
|
||||
Customer cust = new Customer("cust");
|
||||
|
||||
doofus d = new doofus("d");
|
||||
|
||||
Foo foo = new Foo("foo");
|
||||
|
||||
Formula form = new Formula("form");
|
||||
@ -59,7 +61,16 @@ public interface Domain1Instances {
|
||||
|
||||
Player player = new Player("player");
|
||||
|
||||
Price price = new Price("price");
|
||||
|
||||
Product prod = new Product("prod");
|
||||
Product product = new Product("product");
|
||||
|
||||
Show show = new Show("show");
|
||||
|
||||
Status status = new Status("status");
|
||||
|
||||
StatusChange statusChange = new StatusChange("statusChange");
|
||||
|
||||
Store store = new Store("store");
|
||||
|
||||
|
||||
@ -38,8 +38,7 @@ public class FeaturesTest extends HqlQueryBase<FeaturesTest>{
|
||||
public void testBasicStructure(){
|
||||
assertNull(cat.getMetadata().getParent());
|
||||
assertEquals(cat, cat.alive.getMetadata().getParent());
|
||||
assertEquals("cat", cat.getMetadata().getExpression().toString());
|
||||
|
||||
assertEquals("cat", cat.getMetadata().getExpression().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -114,13 +113,15 @@ public class FeaturesTest extends HqlQueryBase<FeaturesTest>{
|
||||
@Test
|
||||
public void testCollectionOperations(){
|
||||
// HQL functions that take collection-valued path expressions: size(), minelement(), maxelement(), minindex(), maxindex(), along with the special elements() and indices functions which may be quantified using some, all, exists, any, in.
|
||||
// size(cat.kittens);
|
||||
// minelement(cat.kittens);
|
||||
// maxelement(cat.kittens);
|
||||
cat.kittens.size();
|
||||
minelement(cat.kittens);
|
||||
maxelement(cat.kittens);
|
||||
minindex(cat.kittens);
|
||||
maxindex(cat.kittens);
|
||||
toString("cat.kittens[0]",cat.kittens(0));
|
||||
toString("cat.kittens[0]",cat.kittens.get(0));
|
||||
toString("cat.kittens[0]",cat.kittens.get(0));
|
||||
|
||||
// some, all, exists, any, in.
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -87,9 +87,9 @@ public class HqlDomain {
|
||||
|
||||
@Entity
|
||||
public static class Customer {
|
||||
@Id int id;
|
||||
@ManyToOne Name name;
|
||||
@ManyToOne Order currentOrder;
|
||||
@Id int id;
|
||||
@ManyToOne Name name;
|
||||
}
|
||||
|
||||
@Entity
|
||||
@ -112,6 +112,12 @@ public class HqlDomain {
|
||||
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class doofus{
|
||||
String gob;
|
||||
@Id long id;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Employee {
|
||||
@ManyToOne Company company;
|
||||
@ -121,11 +127,11 @@ public class HqlDomain {
|
||||
|
||||
@Entity
|
||||
public static class EvilType {
|
||||
@ManyToOne @JoinColumn(name="_asc") EvilType asc;
|
||||
@ManyToOne @JoinColumn(name="_desc") EvilType desc;
|
||||
@Id int id;
|
||||
@ManyToOne EvilType isnull, isnotnull, get, getType, getMetadata;
|
||||
@ManyToOne EvilType toString, hashCode, getClass, notify, notifyAll, wait;
|
||||
@ManyToOne @JoinColumn(name="_asc") EvilType asc;
|
||||
@ManyToOne @JoinColumn(name="_desc") EvilType desc;
|
||||
}
|
||||
|
||||
@DTO
|
||||
@ -140,6 +146,7 @@ public class HqlDomain {
|
||||
public static class Foo {
|
||||
String bar;
|
||||
@Id int id;
|
||||
@CollectionOfElements List<String> names;
|
||||
java.util.Date startDate;
|
||||
public Foo(){}
|
||||
public Foo(long l){}
|
||||
@ -170,18 +177,18 @@ public class HqlDomain {
|
||||
@Id long id;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class NameList{
|
||||
@Id long id;
|
||||
@CollectionOfElements Collection<String> names;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Named {
|
||||
@Id long id;
|
||||
String name;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class NameList{
|
||||
@Id long id;
|
||||
@CollectionOfElements Collection<String> names;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Nationality {
|
||||
@ManyToOne Calendar calendar;
|
||||
@ -204,7 +211,13 @@ public class HqlDomain {
|
||||
|
||||
@Entity
|
||||
public static class Payment extends Item{
|
||||
|
||||
@ManyToOne Status currentStatus, status;
|
||||
PaymentStatus name;
|
||||
@OneToMany Collection<StatusChange> statusChanges;
|
||||
}
|
||||
|
||||
public enum PaymentStatus{
|
||||
AWAITING_APPROVAL
|
||||
}
|
||||
|
||||
@Entity
|
||||
@ -212,8 +225,8 @@ public class HqlDomain {
|
||||
java.util.Date birthDay;
|
||||
@Id long i;
|
||||
@ManyToOne PersonId id;
|
||||
@ManyToOne Nationality nationality;
|
||||
String name;
|
||||
@ManyToOne Nationality nationality;
|
||||
}
|
||||
|
||||
@Entity
|
||||
@ -237,11 +250,29 @@ public class HqlDomain {
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Product {
|
||||
public static class Product extends Item{
|
||||
// @Id long id;
|
||||
String name;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Show {
|
||||
@CollectionOfElements Map<String,String> acts;
|
||||
@Id int id;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Status {
|
||||
@Id long id;
|
||||
String name;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class StatusChange {
|
||||
@Id long id;
|
||||
java.util.Date timeStamp;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Store {
|
||||
@OneToMany List<Customer> customers;
|
||||
@ -249,12 +280,6 @@ public class HqlDomain {
|
||||
@ManyToOne Location location;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class doofus{
|
||||
@Id long id;
|
||||
String gob;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class User {
|
||||
@ManyToOne Company company;
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
package com.mysema.query.grammar.hql;
|
||||
|
||||
import static com.mysema.query.grammar.Grammar.*;
|
||||
import static com.mysema.query.grammar.Grammar.div;
|
||||
import static com.mysema.query.grammar.Grammar.in;
|
||||
import static com.mysema.query.grammar.Grammar.not;
|
||||
import static com.mysema.query.grammar.Grammar.sqrt;
|
||||
import static com.mysema.query.grammar.Grammar.sub;
|
||||
import static com.mysema.query.grammar.HqlGrammar.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@ -14,7 +18,9 @@ import antlr.RecognitionException;
|
||||
import antlr.TokenStreamException;
|
||||
import antlr.collections.AST;
|
||||
|
||||
import com.mysema.query.Domain1;
|
||||
import com.mysema.query.Domain1Dtos;
|
||||
import com.mysema.query.Domain1.Catalog;
|
||||
import com.mysema.query.grammar.HqlGrammar;
|
||||
import com.mysema.query.grammar.HqlQueryBase;
|
||||
import com.mysema.query.grammar.hql.HqlDomain.Color;
|
||||
@ -185,9 +191,10 @@ public class HqlParserTest extends HqlQueryBase<HqlParserTest> implements Domain
|
||||
from(cat).where(cat.kittens.size().gt(0)).parse();
|
||||
// parse( "from Order ord where maxindex(ord.items) > 100" );
|
||||
from(ord).where(maxindex(ord.items).gt(100)).parse();
|
||||
|
||||
// parse( "from Order ord where minelement(ord.items) > 10000" );
|
||||
// from(ord).where(ord.items.minelement().gt(10000)).parse();
|
||||
//
|
||||
// NOTE : Invalid query
|
||||
|
||||
// parse( "select mother from eg.Cat as mother, eg.Cat as kit\n"
|
||||
// + "where kit in elements(foo.kittens)" );
|
||||
select(mother).from(mother, kit).where(kit.in(mother.kittens)).parse();
|
||||
@ -199,7 +206,7 @@ public class HqlParserTest extends HqlQueryBase<HqlParserTest> implements Domain
|
||||
// parse( "from eg.Player p where 3 > all elements(p.scores)" );
|
||||
from(player).where(all(player.scores).lt(3)).parse();
|
||||
// parse( "from eg.Show show where 'fizard' in indices(show.acts)" );
|
||||
// TODO
|
||||
from(show).where(in("fizard",indices(show.acts))).parse();
|
||||
// parse( "from Order ord where ord.items[0].id = 1234" );
|
||||
from(ord).where(ord.items(0).id.eq(1234l)).parse();
|
||||
// parse( "select person from Person person, Calendar calendar\n"
|
||||
@ -227,11 +234,16 @@ public class HqlParserTest extends HqlQueryBase<HqlParserTest> implements Domain
|
||||
// + "where prod.name = 'widget'\n"
|
||||
// + "and store.location.name in ( 'Melbourne', 'Sydney' )\n"
|
||||
// + "and prod = all elements(cust.currentOrder.lineItems)" );
|
||||
// select(cust).from(prod, store).innerJoin(store.customers.as(cust))
|
||||
// .where(prod.name.eq("widget")
|
||||
// .and(store.location().name.in("Melbourne","Sydney"))
|
||||
// .and(prod.eq(all(cust.currentOrder().lineItems)))
|
||||
// ).parse();
|
||||
select(cust).from(prod, store).innerJoin(store.customers.as(cust))
|
||||
.where(prod.name.eq("widget")
|
||||
.and(store.location().name.in("Melbourne","Sydney"))
|
||||
.and(prod.eq(all(cust.currentOrder().lineItems)))
|
||||
).parse();
|
||||
|
||||
prod.eq(new HqlDomain.Product());
|
||||
prod.eq(new Domain1.Product("p"));
|
||||
prod.eq(new Domain1.Item("p"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -248,7 +260,7 @@ public class HqlParserTest extends HqlQueryBase<HqlParserTest> implements Domain
|
||||
select(cat.color, sum(cat.weight), count(cat)).from(cat).groupBy(cat.color).parse();
|
||||
// parse( "select foo.id, avg( elements(foo.names) ), max( indices(foo.names) )\n"
|
||||
// + "from eg.Foo foo group by foo.id" );
|
||||
// TODO
|
||||
select(foo.id, avg(foo.names), max(indices(foo.names))).from(foo).groupBy(foo.id);
|
||||
// parse( "select cat.color, sum(cat.weight), count(cat)\n"
|
||||
// + "from eg.Cat cat group by cat.color\n"
|
||||
// + "having cat.color in (eg.Color.TABBY, eg.Color.BLACK)" );
|
||||
@ -295,7 +307,24 @@ public class HqlParserTest extends HqlQueryBase<HqlParserTest> implements Domain
|
||||
// + "group by ord\n"
|
||||
// + "having sum(price.amount) > :minAmount\n"
|
||||
// + "order by sum(price.amount) desc" );
|
||||
//
|
||||
Catalog cat = new Catalog("cat");
|
||||
select(ord.id, sum(price.amount), count(item))
|
||||
.from(ord).join(ord.lineItems.as(item))
|
||||
.join(item.product.as(product)).from(catalog)
|
||||
.join(catalog.prices.as(price))
|
||||
.where(not(ord.paid)
|
||||
.and(ord.customer.eq(cust))
|
||||
.and(price.product.eq(product))
|
||||
.and(catalog.effectiveDate.lt(sysdate()))
|
||||
.and(catalog.effectiveDate.gt(all(
|
||||
HqlGrammar.select(catalog.effectiveDate).from(catalog)
|
||||
.where(catalog.effectiveDate.lt(sysdate()))
|
||||
))))
|
||||
.groupBy(ord)
|
||||
.having(sum(price.amount).gt(0l))
|
||||
.orderBy(sum(price.amount).desc());
|
||||
|
||||
|
||||
// parse( "select ord.id, sum(price.amount), count(item)\n"
|
||||
// + "from Order as ord join ord.lineItems as item join item.product as product,\n"
|
||||
// + "Catalog as catalog join catalog.prices as price\n"
|
||||
@ -303,7 +332,17 @@ public class HqlParserTest extends HqlQueryBase<HqlParserTest> implements Domain
|
||||
// + "and price.product = product and catalog = :currentCatalog\n"
|
||||
// + "group by ord having sum(price.amount) > :minAmount\n"
|
||||
// + "order by sum(price.amount) desc" );
|
||||
//
|
||||
HqlDomain.Customer c1 = new HqlDomain.Customer();
|
||||
HqlDomain.Catalog c2 = new HqlDomain.Catalog();
|
||||
|
||||
select(ord.id, sum(price.amount), count(item))
|
||||
.from(ord).join(ord.lineItems.as(item)).join(item.product.as(product))
|
||||
.from(catalog).join(catalog.prices.as(price))
|
||||
.where(not(ord.paid).and(ord.customer.eq(c1))
|
||||
.and(price.product.eq(product)).and(catalog.eq(c2)))
|
||||
.groupBy(ord).having(sum(price.amount).gt(0l))
|
||||
.orderBy(sum(price.amount).desc());
|
||||
|
||||
// parse( "select count(payment), status.name \n"
|
||||
// + "from Payment as payment \n"
|
||||
// + " join payment.currentStatus as status\n"
|
||||
@ -319,6 +358,17 @@ public class HqlParserTest extends HqlQueryBase<HqlParserTest> implements Domain
|
||||
// + " )\n"
|
||||
// + "group by status.name, status.sortOrder\n"
|
||||
// + "order by status.sortOrder" );
|
||||
// select(count(payment), status.name)
|
||||
// .from(payment).join(payment.currentStatus.as(status))
|
||||
// .join(payment.statusChanges.as(statusChange))
|
||||
// .where(payment.status().name.ne(PaymentStatus.AWAITING_APPROVAL)
|
||||
// .or(
|
||||
// statusChange.timeStamp.eq(select(max(change.timestamp))
|
||||
// .from(change).where(change.payment.eq(null)
|
||||
// )))
|
||||
// .groupBy(status.name.asc(), status.sortOrder.asc())
|
||||
// .orderBy(status.sortOrder);
|
||||
|
||||
// parse( "select count(payment), status.name \n"
|
||||
// + "from Payment as payment\n"
|
||||
// + " join payment.currentStatus as status\n"
|
||||
@ -326,12 +376,25 @@ public class HqlParserTest extends HqlQueryBase<HqlParserTest> implements Domain
|
||||
// + " or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser\n"
|
||||
// + "group by status.name, status.sortOrder\n"
|
||||
// + "order by status.sortOrder" );
|
||||
HqlDomain.User currentUser = new HqlDomain.User();
|
||||
|
||||
// select(count(payment), status.name)
|
||||
// .from(payment).join(payment.currentStatus.as(status))
|
||||
// .where(payment.status().name.ne(PaymentStatus.AWAITING_APPROVAL)
|
||||
// .or(payment.statusChanges(maxindex(payment.statusChanges)).user.ne(currentUser)))
|
||||
// .groupBy(status.name, status.sortOrder)
|
||||
// .orderBy(status.sortOrder);
|
||||
|
||||
// parse( "select account, payment\n"
|
||||
// + "from Account as account\n"
|
||||
// + " left outer join account.payments as payment\n"
|
||||
// + "where :currentUser in elements(account.holder.users)\n"
|
||||
// + " and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)\n"
|
||||
// + "order by account.type.sortOrder, account.accountNumber, payment.dueDate" );
|
||||
// select(account, payment).from(account)
|
||||
// .leftJoin(account.payments.as(payment))
|
||||
// .where(in(currentUser, account.holder().users).and())
|
||||
|
||||
// parse( "select account, payment\n"
|
||||
// + "from Account as account\n"
|
||||
// + " join account.holder.users as user\n"
|
||||
@ -357,7 +420,7 @@ public class HqlParserTest extends HqlQueryBase<HqlParserTest> implements Domain
|
||||
@Test
|
||||
public void testFromWithJoin() throws Exception {
|
||||
// parse( "FROM eg.mypackage.Cat qat, com.toadstool.Foo f join net.sf.blurb.Blurb" );
|
||||
from(qat,foo).join(cust).parse();
|
||||
// NOTE : invalid query!
|
||||
// parse( "FROM eg.mypackage.Cat qat left join com.multijoin.JoinORama , com.toadstool.Foo f join net.sf.blurb.Blurb" );
|
||||
// TODO
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user