From 6d24ea7c101e952db8fc93d2dba32f50af33d254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Wed, 11 Nov 2009 11:50:47 +0000 Subject: [PATCH] added tests for case statements --- querydsl-apt/pom.xml | 2 +- .../query/collections/ColQueryTemplates.java | 2 +- .../collections/impl/EvaluatorFactory.java | 6 +- .../query/serialization/JavaTemplates.java | 5 ++ .../com/mysema/query/types/CaseBuilder.java | 56 +++++++++++-------- .../com/mysema/query/types/Templates.java | 2 +- .../mysema/query/types/expr/EComparable.java | 41 ++++++++++++++ .../query/types/expr/EComparableBase.java | 44 +-------------- .../com/mysema/query/types/expr/ENumber.java | 42 ++++++++++++++ .../java/com/mysema/query/Projections.java | 38 +++++++++---- .../java/com/mysema/query/StandardTest.java | 8 ++- .../mysema/query/types/CaseBuilderTest.java | 7 ++- querydsl-hql/pom.xml | 56 +++++++++---------- .../com/mysema/query/hql/SubQueryTest.java | 7 --- .../mysema/query/JDOQLQueryStandardTest.java | 1 - 15 files changed, 193 insertions(+), 124 deletions(-) diff --git a/querydsl-apt/pom.xml b/querydsl-apt/pom.xml index b96a895ec..0af85c015 100644 --- a/querydsl-apt/pom.xml +++ b/querydsl-apt/pom.xml @@ -47,7 +47,7 @@ org.hibernate hibernate-annotations - 3.2.1.ga + 3.4.0.GA test diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryTemplates.java b/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryTemplates.java index be95e1fa0..dbd32303d 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryTemplates.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryTemplates.java @@ -63,7 +63,7 @@ public class ColQueryTemplates extends JavaTemplates { // TEMPORARY FIXES - add(Ops.DIV, "((double){0}) / ((double){1})"); + add(Ops.DIV, "(double)({0}/{1})"); } public static boolean like(String str, String like){ diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/impl/EvaluatorFactory.java b/querydsl-collections/src/main/java/com/mysema/query/collections/impl/EvaluatorFactory.java index 04bfa608c..0f0f19a1e 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/impl/EvaluatorFactory.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/impl/EvaluatorFactory.java @@ -94,11 +94,11 @@ public class EvaluatorFactory { }; } catch (CompileException e) { - throw new RuntimeException(e.getMessage(), e); + throw new RuntimeException(e.getMessage() + " with source " + javaSource, e); } catch (ParseException e) { - throw new RuntimeException(e.getMessage(), e); + throw new RuntimeException(e.getMessage() + " with source " + javaSource, e); } catch (ScanException e) { - throw new RuntimeException(e.getMessage(), e); + throw new RuntimeException(e.getMessage() + " with source " + javaSource, e); } } diff --git a/querydsl-core/src/main/java/com/mysema/query/serialization/JavaTemplates.java b/querydsl-core/src/main/java/com/mysema/query/serialization/JavaTemplates.java index 6d631f5ea..572c04fde 100644 --- a/querydsl-core/src/main/java/com/mysema/query/serialization/JavaTemplates.java +++ b/querydsl-core/src/main/java/com/mysema/query/serialization/JavaTemplates.java @@ -71,6 +71,11 @@ public class JavaTemplates extends Templates { add(Ops.DateTimeOps.SECOND, "{0}.getSecond()"); add(Ops.DateTimeOps.WEEK, "{0}.getWeek()"); add(Ops.DateTimeOps.YEAR, "{0}.getYear()"); + + // case + add(Ops.CASE, "({0})"); + add(Ops.CASE_WHEN, "({0}) ? ({1}) : ({2})"); + add(Ops.CASE_ELSE, "{0}"); // Math try { diff --git a/querydsl-core/src/main/java/com/mysema/query/types/CaseBuilder.java b/querydsl-core/src/main/java/com/mysema/query/types/CaseBuilder.java index d0b4ad8a8..515efac88 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/CaseBuilder.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/CaseBuilder.java @@ -3,7 +3,6 @@ package com.mysema.query.types; import java.util.ArrayList; import java.util.List; -import com.mysema.query.types.custom.CSimple; import com.mysema.query.types.expr.EBoolean; import com.mysema.query.types.expr.Expr; import com.mysema.query.types.operation.OSimple; @@ -15,9 +14,21 @@ import com.mysema.query.types.operation.Ops; */ public class CaseBuilder { + private class CaseElement { + + final EBoolean condition; + + final Expr target; + + public CaseElement(EBoolean condition, Expr target){ + this.condition = condition; + this.target = target; + } + } + public class Cases { - private final List> exprs = new ArrayList>(); + private final List> cases = new ArrayList>(); private final Class type; @@ -26,26 +37,29 @@ public class CaseBuilder { } Cases addCase(EBoolean condition, Expr expr) { - exprs.add(OSimple.create(type, Ops.CASE_WHEN, condition, expr)); + cases.add(0, new CaseElement(condition, expr)); return this; } - private Expr createChain(List> exprs) { - StringBuilder builder = new StringBuilder(exprs.size() * 4); - for (int i = 0; i < exprs.size(); i++){ - if (i > 0) builder.append(" "); - builder.append("{").append(i).append("}"); - } - return new CSimple(type, exprs, templateFactory.create(builder.toString())); - } - public Expr otherwise(A constant) { return otherwise(Expr.create(constant)); } public Expr otherwise(Expr expr) { - exprs.add(OSimple.create(type, Ops.CASE_ELSE, expr)); - return OSimple.create(type, Ops.CASE, createChain(exprs)); + cases.add(0, new CaseElement(null, expr)); + Expr last = null; + for (CaseElement element : cases){ + if (last == null){ + last = OSimple.create(type, Ops.CASE_ELSE, + element.target); + }else{ + last = OSimple.create(type, Ops.CASE_WHEN, + element.condition, + element.target, + last); + } + } + return OSimple.create(type, Ops.CASE, last); } public CaseWhen when(EBoolean b) { @@ -66,7 +80,7 @@ public class CaseBuilder { } public Cases then(A constant) { - return cases.addCase(b, Expr.create(constant)); + return then(Expr.create(constant)); } public Cases then(Expr expr) { @@ -76,26 +90,22 @@ public class CaseBuilder { public class Initial { - private final EBoolean b; + private final EBoolean when; public Initial(EBoolean b) { - this.b = b; + this.when = b; } - @SuppressWarnings("unchecked") public Cases then(A constant) { - return new Cases((Class) constant.getClass()).addCase(b, Expr.create(constant)); + return then(Expr.create(constant)); } @SuppressWarnings("unchecked") public Cases then(Expr expr) { - return new Cases((Class)expr.getType()).addCase(b, expr); + return new Cases((Class)expr.getType()).addCase(when, expr); } } - private static final TemplateFactory templateFactory = new TemplateFactory(); - - public Initial when(EBoolean b) { return new Initial(b); } diff --git a/querydsl-core/src/main/java/com/mysema/query/types/Templates.java b/querydsl-core/src/main/java/com/mysema/query/types/Templates.java index 4f031f973..56cf59eab 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/Templates.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/Templates.java @@ -165,7 +165,7 @@ public class Templates { // case add(Ops.CASE, "case {0} end"); - add(Ops.CASE_WHEN, "when {0} then {1}"); + add(Ops.CASE_WHEN, "when {0} then {1} {2}"); add(Ops.CASE_ELSE, "else {0}"); // subquery diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/EComparable.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/EComparable.java index ef6413c13..9c0c5a619 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/expr/EComparable.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/EComparable.java @@ -21,6 +21,47 @@ public abstract class EComparable extends EComparableBase< public EComparable(Class type) { super(type); } + + + /** + * Create a from < this < to expression + * + * @param from + * @param to + * @return + */ + public final EBoolean between(D from, D to) { + return OBoolean.create(Ops.BETWEEN, this, ExprConst.create(from), ExprConst.create(to)); + } + + /** + * Create a first < this < second expression + * + * @param from + * @param to + * @return + */ + public final EBoolean between(Expr from, Expr to) { + return OBoolean.create(Ops.BETWEEN, this, from, to); + } + + /** + * @param from + * @param to + * @return + */ + public final EBoolean notBetween(D from, D to) { + return between(from, to).not(); + } + + /** + * @param from + * @param to + * @return + */ + public final EBoolean notBetween(Expr from, Expr to) { + return between(from, to).not(); + } /** * Create a this > right expression diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/EComparableBase.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/EComparableBase.java index a1d546220..43cab3ddb 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/expr/EComparableBase.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/EComparableBase.java @@ -7,7 +7,6 @@ package com.mysema.query.types.expr; import com.mysema.query.types.Order; import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.operation.OBoolean; import com.mysema.query.types.operation.ONumber; import com.mysema.query.types.operation.OString; import com.mysema.query.types.operation.Ops; @@ -44,30 +43,7 @@ public abstract class EComparableBase extends Expr { } return asc; } - - /** - * Create a first < this < second expression - * - * @param first - * @param second - * @return - */ - public final EBoolean between(D first, D second) { - return OBoolean.create(Ops.BETWEEN, this, ExprConst.create(first), ExprConst.create(second)); - } - - /** - * Create a first < this < second expression - * - * @param first - * @param second - * @return - */ - public final EBoolean between(Expr first, Expr second) { - return OBoolean.create(Ops.BETWEEN, this, first, second); - } - - + /** * Create a cast expression to the given numeric type * @@ -91,24 +67,6 @@ public abstract class EComparableBase extends Expr { return desc; } - /** - * @param first - * @param second - * @return - */ - public final EBoolean notBetween(D first, D second) { - return between(first, second).not(); - } - - /** - * @param first - * @param second - * @return - */ - public final EBoolean notBetween(Expr first, Expr second) { - return between(first, second).not(); - } - /** * Get a cast to String expression * diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumber.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumber.java index 3aaa90b45..056a26cc8 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumber.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumber.java @@ -328,7 +328,49 @@ public abstract class ENumber> extends ECompara public final > EBoolean gt(A right) { return gt(ENumber.create(cast(right))); } + + /** + * Create a from < this < to expression + * + * @param + * @param from + * @param to + * @return + */ + public final > EBoolean between(A from, A to) { + return OBoolean.create(Ops.BETWEEN, this, ExprConst.create(from), ExprConst.create(to)); + } + /** + * Create a from < this < to expression + * + * @param + * @param from + * @param to + * @return + */ + public final > EBoolean between(Expr from, Expr to) { + return OBoolean.create(Ops.BETWEEN, this, from, to); + } + + /** + * @param from + * @param to + * @return + */ + public final > EBoolean notBetween(A from, A to) { + return between(from, to).not(); + } + + /** + * @param from + * @param to + * @return + */ + public final > EBoolean notBetween(Expr from, Expr to) { + return between(from, to).not(); + } + /** * Create a this > right expression * diff --git a/querydsl-core/src/test/java/com/mysema/query/Projections.java b/querydsl-core/src/test/java/com/mysema/query/Projections.java index c64d1988b..f510c4f31 100644 --- a/querydsl-core/src/test/java/com/mysema/query/Projections.java +++ b/querydsl-core/src/test/java/com/mysema/query/Projections.java @@ -9,6 +9,8 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import com.mysema.query.types.CaseBuilder; +import com.mysema.query.types.expr.Constant; import com.mysema.query.types.expr.ECollection; import com.mysema.query.types.expr.EDate; import com.mysema.query.types.expr.EDateTime; @@ -28,12 +30,12 @@ import com.mysema.query.types.expr.Expr; */ public class Projections { -// private final Module module; + private final Module module; private final Target target; public Projections(Module module, Target target) { -// this.module = module; + this.module = module; this.target = target; } @@ -79,6 +81,14 @@ public class Projections { } > Collection> numeric(ENumber expr, ENumber other, A knownValue){ + HashSet> rv = new HashSet>(); + rv.addAll(numeric(expr, other)); + rv.addAll(numeric(expr, ENumber.create(knownValue))); + return rv; + } + + @SuppressWarnings("unchecked") + private > Collection> numeric(ENumber expr, ENumber other){ HashSet> rv = new HashSet>(); rv.add(expr.abs()); rv.add(expr.add(other)); @@ -87,10 +97,14 @@ public class Projections { rv.add(expr.sqrt()); rv.add(expr.subtract(other)); -// CaseBuilder cases = new CaseBuilder(); -// rv.add(ENumber.create(1).add(cases -// .when(expr.gt(0)).then(1) -// .otherwise(0))); + if (!(other instanceof Constant || module == Module.JDOQL)){ + CaseBuilder cases = new CaseBuilder(); + rv.add(ENumber.create(1).add(cases + .when(expr.gt(10)).then(expr) + .when(expr.between(0, 10)).then((ENumber)other) + .otherwise((ENumber)other))); + } + return rv; } @@ -117,6 +131,7 @@ public class Projections { return rv; } + @SuppressWarnings("unchecked") Collection> stringProjections(EString expr, EString other){ HashSet> rv = new HashSet>(); rv.add(expr.append("Hello")); @@ -135,11 +150,12 @@ public class Projections { rv.add(expr.substring(1)); rv.add(expr.substring(0, 1)); -// CaseBuilder cases = new CaseBuilder(); -// rv.add(cases.when(expr.eq("A")).then("a") -// .when(expr.eq("B")).then("b") -// .when(expr.eq("C")).then("c") -// .otherwise("x")); + if (!(other instanceof Constant || module == Module.JDOQL)){ + CaseBuilder cases = new CaseBuilder(); + rv.add(cases.when(expr.eq("A")).then(other) + .when(expr.eq("B")).then(expr) + .otherwise(other)); + } rv.add(expr.trim()); diff --git a/querydsl-core/src/test/java/com/mysema/query/StandardTest.java b/querydsl-core/src/test/java/com/mysema/query/StandardTest.java index d44b77ad9..0ec02cc3c 100644 --- a/querydsl-core/src/test/java/com/mysema/query/StandardTest.java +++ b/querydsl-core/src/test/java/com/mysema/query/StandardTest.java @@ -66,7 +66,9 @@ public abstract class StandardTest { System.err.println(); }catch(Throwable t){ t.printStackTrace(); - errors.add(pr + " failed : " + t.getMessage()); + errors.add(pr + " failed : \n" + + t.getClass().getName() + " : " + + t.getMessage() + "\n"); } } } @@ -85,7 +87,9 @@ public abstract class StandardTest { } }catch(Throwable t){ t.printStackTrace(); - errors.add(f + " failed : " + t.getMessage()); + errors.add(f + " failed : \n" + + t.getClass().getName() + " : " + + t.getMessage() +"\n"); } } } diff --git a/querydsl-core/src/test/java/com/mysema/query/types/CaseBuilderTest.java b/querydsl-core/src/test/java/com/mysema/query/types/CaseBuilderTest.java index 02dfbe1bb..322a21df0 100644 --- a/querydsl-core/src/test/java/com/mysema/query/types/CaseBuilderTest.java +++ b/querydsl-core/src/test/java/com/mysema/query/types/CaseBuilderTest.java @@ -41,7 +41,12 @@ public class CaseBuilderTest { "when customer.annualSpending > 2000 then Silver " + "else Bronze " + "end", cases.toString()); - + + String rv = c.getAnnualSpending() > 10000 ? "Premier" : + c.getAnnualSpending() > 5000 ? "Gold" : + c.getAnnualSpending() > 2000 ? "Silver" : + "Bronze"; + } } diff --git a/querydsl-hql/pom.xml b/querydsl-hql/pom.xml index dcffb8955..dd0a0d85a 100644 --- a/querydsl-hql/pom.xml +++ b/querydsl-hql/pom.xml @@ -14,40 +14,36 @@ Hibernate / HQL support for querydsl jar - - 3.2.1.ga - - - - - org.hibernate - hibernate - 3.2.6.ga - provided - - - - cglib - cglib - - - asm - asm - - - - - org.hibernate - hibernate-annotations - 3.2.1.ga - provided - + + + org.hibernate + hibernate-annotations + 3.4.0.GA + + + cglib + cglib + + + asm + asm + + + provided + org.hibernate hibernate-entitymanager - 3.2.1.ga + 3.4.0.ga provided - + + + org.hibernate + hibernate-validator + 3.1.0.GA + provided + + javax.persistence persistence-api diff --git a/querydsl-hql/src/test/java/com/mysema/query/hql/SubQueryTest.java b/querydsl-hql/src/test/java/com/mysema/query/hql/SubQueryTest.java index 9d7634c71..b99162e39 100644 --- a/querydsl-hql/src/test/java/com/mysema/query/hql/SubQueryTest.java +++ b/querydsl-hql/src/test/java/com/mysema/query/hql/SubQueryTest.java @@ -20,11 +20,4 @@ public class SubQueryTest extends AbstractQueryTest{ toString("exists (select cat from Cat cat where cat.weight < :a1)", sub().from(cat).where(cat.weight.lt(1)).unique(cat).exists()); } -// @Test -// public void stateful(){ -// HQLSubQuery sub = sub(); -// sub.from(cat); -// assertEquals("select cat from cat", sub.toString()); -// } - } diff --git a/querydsl-jdoql/src/test/java/com/mysema/query/JDOQLQueryStandardTest.java b/querydsl-jdoql/src/test/java/com/mysema/query/JDOQLQueryStandardTest.java index b80cfe7cf..02157f4a2 100644 --- a/querydsl-jdoql/src/test/java/com/mysema/query/JDOQLQueryStandardTest.java +++ b/querydsl-jdoql/src/test/java/com/mysema/query/JDOQLQueryStandardTest.java @@ -133,7 +133,6 @@ public class JDOQLQueryStandardTest extends AbstractJDOTest { standardTest.numericCasts(product.price, otherProduct.price, 200.0); standardTest.numericTests(product.amount, otherProduct.amount, 2); standardTest.stringTests(product.name, otherProduct.name, productName); - // timeTests too slow and causes OutOfMemoryError standardTest.timeTests(product.timeField, otherProduct.timeField, time); standardTest.report();