diff --git a/querydsl-hibernate/.settings/org.eclipse.jdt.core.prefs b/querydsl-hibernate/.settings/org.eclipse.jdt.core.prefs index d904ea5b5..4aed4b5cd 100644 --- a/querydsl-hibernate/.settings/org.eclipse.jdt.core.prefs +++ b/querydsl-hibernate/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlGrammar.java b/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlGrammar.java index 173bce152..8690cb6b7 100644 --- a/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlGrammar.java +++ b/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlGrammar.java @@ -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 Expr all(CollectionType col){ return new ExprQuantSimple(OpQuant.ALL, col); } @@ -36,36 +39,44 @@ public class HqlGrammar extends Grammar{ return new ExprQuantComparable(OpQuant.ANY, col); } + public static > ExprComparable avg(Expr left){ + return _number(OpNumberAgg.AVG, left); + } + public static > ExprComparable avg(PathCollection left){ + return new ExprQuantComparable(OpQuant.AVG_IN_COL, left); + } + public static ExprComparable count(){ return new CountExpr(null); - } + } + public static ExprComparable count(Expr expr){ return new CountExpr(expr); } - public static ExprComparable current_date(){ return _comparable(OpHql.CURRENT_DATE); - } + } public static ExprComparable current_time(){ return _comparable(OpHql.CURRENT_TIME); } public static ExprComparable current_timestamp(){ return _comparable(OpHql.CURRENT_TIMESTAMP); - } - public static ExprComparable day(Expr date){ - return _comparable(OpHql.DAY, date); } + public static ExprComparable day(Expr date){ + return _comparable(OpHql.DAY, date); + } public static Expr distinct(PathEntity left){ return new DistinctPath(left); - } + } + public static Expr distinct(PathNoEntity left){ return new DistinctPath(left); - } + } public static ExprBoolean exists(CollectionType col){ return new ExprQuantBoolean(OpQuant.EXISTS, col); - } + } public static SubQuery from(ExprEntity select){ return new SubQuery(select).from(select); @@ -73,26 +84,72 @@ public class HqlGrammar extends Grammar{ public static ExprComparable hour(Expr date){ return _comparable(OpHql.HOUR, date); + } + public static PathComponentCollection indices(PathCollection col){ + return new PathComponentCollection(Integer.class, new PathMetadata>(col, null, HqlPathType.LISTINDICES)); } + public static PathComponentCollection indices(PathMap col){ + return new PathComponentCollection(col.getKeyType(), new PathMetadata>(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 maxindex(PathEntityCollection collection) { - return _comparable(OpHql.MAXINDEX, collection); + public static > ExprComparable max(Expr left){ + return _number(OpNumberAgg.MAX, left); + } + public static > ExprComparable max(PathCollection left){ + return new ExprQuantComparable(OpQuant.MAX_IN_COL, left); + } + + public static PathEntity maxelement(PathEntityCollection col) { + return new PathEntity(col.getElementType(), new PathMetadata(col, null, HqlPathType.MINELEMENT)); } - public static ExprComparable minindex(PathEntityCollection collection) { - return _comparable(OpHql.MININDEX, collection); + public static PathComparable maxindex(PathComponentCollection col) { + return new PathComparable(Integer.class, new PathMetadata(col, null, HqlPathType.MAXINDEX)); } - + + public static PathComparable maxindex(PathEntityCollection col) { + return new PathComparable(Integer.class, new PathMetadata(col, null, HqlPathType.MAXINDEX)); + } + public static > ExprComparable min(Expr left){ + return _number(OpNumberAgg.MIN, left); + } + + public static > ExprComparable min(PathCollection left){ + return new ExprQuantComparable(OpQuant.MIN_IN_COL, left); + } + + public static PathEntity minelement(PathEntityCollection col) { + return new PathEntity(col.getElementType(), new PathMetadata(col, null, HqlPathType.MINELEMENT)); + } + + public static PathComparable minindex(PathComponentCollection col) { + return new PathComparable(Integer.class, new PathMetadata(col, null, HqlPathType.MININDEX)); + } + + public static PathComparable minindex(PathEntityCollection col) { + return new PathComparable(Integer.class, new PathMetadata(col, null, HqlPathType.MININDEX)); + } + public static ExprComparable minute(Expr date){ return _comparable(OpHql.MINUTE, date); - } + } public static ExprComparable month(Expr date){ return _comparable(OpHql.MONTH, date); diff --git a/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlOps.java b/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlOps.java index 90d638007..de4c73673 100644 --- a/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlOps.java +++ b/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlOps.java @@ -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{ + + public interface OpHql{ Op CURRENT_DATE = new OpImpl(); Op CURRENT_TIME = new OpImpl(); Op CURRENT_TIMESTAMP = new OpImpl(); @@ -133,8 +155,6 @@ public class HqlOps extends Ops { Op HOUR = new OpImpl(); Op ISEMPTY = new OpImpl(); Op ISNOTEMPTY = new OpImpl(); - Op MAXINDEX = new OpImpl(); - Op MININDEX = new OpImpl(); Op MINUTE = new OpImpl(); Op MONTH = new OpImpl(); Op SECOND = new OpImpl(); @@ -143,16 +163,34 @@ public class HqlOps extends Ops { Op YEAR = new OpImpl(); } - @SuppressWarnings("unchecked") - public interface OpQuant{ + public interface OpNumberAgg{ + Op AVG = new OpImpl(); + Op MAX = new OpImpl(); + Op MIN = new OpImpl(); + } + + public interface OpQuant{ + Op AVG_IN_COL = new OpImpl(); + Op MAX_IN_COL = new OpImpl(); + Op MIN_IN_COL = new OpImpl(); + // 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(); + Op ALL = new OpImpl(); + Op EXISTS = new OpImpl(); + Op NOTEXISTS = new OpImpl(); } + 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(); + } + } diff --git a/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlSerializer.java b/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlSerializer.java index fc17da625..c1a2d9b4a 100644 --- a/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlSerializer.java +++ b/querydsl-hibernate/src/main/java/com/mysema/query/grammar/HqlSerializer.java @@ -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{ 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{ @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 diff --git a/querydsl-hibernate/src/test/java/com/mysema/query/AllTests.java b/querydsl-hibernate/src/test/java/com/mysema/query/AllTests.java index 6e07dfbb9..771110456 100644 --- a/querydsl-hibernate/src/test/java/com/mysema/query/AllTests.java +++ b/querydsl-hibernate/src/test/java/com/mysema/query/AllTests.java @@ -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 { } diff --git a/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/Domain1Instances.java b/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/Domain1Instances.java index de11b0496..ba27337d4 100644 --- a/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/Domain1Instances.java +++ b/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/Domain1Instances.java @@ -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"); diff --git a/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/FeaturesTest.java b/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/FeaturesTest.java index 964c2d301..726e2eb55 100644 --- a/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/FeaturesTest.java +++ b/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/FeaturesTest.java @@ -38,8 +38,7 @@ public class FeaturesTest extends HqlQueryBase{ 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{ @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 diff --git a/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/HqlDomain.java b/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/HqlDomain.java index 2c37abcc9..9e2e3e5d4 100644 --- a/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/HqlDomain.java +++ b/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/HqlDomain.java @@ -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 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 names; - } - @Entity public static class Named { @Id long id; String name; } + @Entity + public static class NameList{ + @Id long id; + @CollectionOfElements Collection 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 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 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 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; diff --git a/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/HqlParserTest.java b/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/HqlParserTest.java index 86dc4845f..e8c9afd4f 100644 --- a/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/HqlParserTest.java +++ b/querydsl-hibernate/src/test/java/com/mysema/query/grammar/hql/HqlParserTest.java @@ -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 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 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 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 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 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 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 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 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 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 }