]> source.dussan.org Git - iciql.git/commitdiff
Revise nested conditions implementation and api
authorJames Moger <james.moger@gitblit.com>
Thu, 23 Oct 2014 01:55:32 +0000 (21:55 -0400)
committerJames Moger <james.moger@gitblit.com>
Thu, 23 Oct 2014 02:29:05 +0000 (22:29 -0400)
src/main/java/com/iciql/Conditions.java [deleted file]
src/main/java/com/iciql/NestedConditions.java [new file with mode: 0644]
src/main/java/com/iciql/Query.java
src/main/java/com/iciql/QueryWhere.java
src/site/usage.mkd
src/test/java/com/iciql/test/NestedConditionsTest.java

diff --git a/src/main/java/com/iciql/Conditions.java b/src/main/java/com/iciql/Conditions.java
deleted file mode 100644 (file)
index 1699641..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2009-2014, Architector Inc., Japan
- * All rights reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.iciql;
-
-public abstract class Conditions<T> {
-
-       public static class And<T> extends Conditions<T> {
-
-               public And(Db db, T alias) {
-                       super(db, alias);
-               }
-
-               protected QueryCondition<T, Boolean> and(boolean x) {
-                       return where.and(x);
-               }
-
-               protected QueryCondition<T, Byte> and(byte x) {
-                       return where.and(x);
-               }
-
-               protected QueryCondition<T, Short> and(short x) {
-                       return where.and(x);
-               }
-
-               protected QueryCondition<T, Integer> and(int x) {
-                       return where.and(x);
-               }
-
-               protected QueryCondition<T, Long> and(long x) {
-                       return where.and(x);
-               }
-
-               protected QueryCondition<T, Float> and(float x) {
-                       return where.and(x);
-               }
-
-               protected QueryCondition<T, Double> and(double x) {
-                       return where.and(x);
-               }
-
-               protected <A> QueryCondition<T, A> and(A x) {
-                       return where.and(x);
-               }
-
-               protected QueryWhere<T> and(And<T> conditions) {
-                       where.andOpenTrue();
-                       where.query.addConditionToken(conditions.where.query);
-                       return where.close();
-               }
-
-               protected QueryWhere<T> and(Or<T> conditions) {
-                       where.andOpenFalse();
-                       where.query.addConditionToken(conditions.where.query);
-                       return where.close();
-               }
-
-       }
-
-       public static class Or<T> extends Conditions<T> {
-
-               public Or(Db db, T alias) {
-                       super(db, alias);
-               }
-
-               protected QueryCondition<T, Boolean> or(boolean x) {
-                       return where.or(x);
-               }
-
-               protected QueryCondition<T, Byte> or(byte x) {
-                       return where.or(x);
-               }
-
-               protected QueryCondition<T, Short> or(short x) {
-                       return where.or(x);
-               }
-
-               protected QueryCondition<T, Integer> or(int x) {
-                       return where.or(x);
-               }
-
-               protected QueryCondition<T, Long> or(long x) {
-                       return where.or(x);
-               }
-
-               protected QueryCondition<T, Float> or(float x) {
-                       return where.or(x);
-               }
-
-               protected QueryCondition<T, Double> or(double x) {
-                       return where.or(x);
-               }
-
-               protected <A> QueryCondition<T, A> or(A x) {
-                       return where.or(x);
-               }
-
-               protected QueryWhere<T> or(And<T> conditions) {
-                       where.orOpenTrue();
-                       where.query.addConditionToken(conditions.where.query);
-                       return where.close();
-               }
-
-               protected QueryWhere<T> or(Or<T> conditions) {
-                       where.orOpenFalse();
-                       where.query.addConditionToken(conditions.where.query);
-                       return where.close();
-               }
-
-       }
-
-       QueryWhere<T> where;
-
-       private Conditions(Db db, T alias) {
-               where = new QueryWhere<T>(Query.rebuild(db, alias));
-       }
-
-}
diff --git a/src/main/java/com/iciql/NestedConditions.java b/src/main/java/com/iciql/NestedConditions.java
new file mode 100644 (file)
index 0000000..5c92a86
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009-2014, Architector Inc., Japan
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.iciql;
+
+public abstract class NestedConditions<T> {
+
+       public static class And<T> extends NestedConditions<T> {
+
+               public And(Db db, T alias) {
+                       super(db, alias);
+               }
+
+               protected QueryCondition<T, Boolean> and(boolean x) {
+                       return where.and(x);
+               }
+
+               protected QueryCondition<T, Byte> and(byte x) {
+                       return where.and(x);
+               }
+
+               protected QueryCondition<T, Short> and(short x) {
+                       return where.and(x);
+               }
+
+               protected QueryCondition<T, Integer> and(int x) {
+                       return where.and(x);
+               }
+
+               protected QueryCondition<T, Long> and(long x) {
+                       return where.and(x);
+               }
+
+               protected QueryCondition<T, Float> and(float x) {
+                       return where.and(x);
+               }
+
+               protected QueryCondition<T, Double> and(double x) {
+                       return where.and(x);
+               }
+
+               protected <A> QueryCondition<T, A> and(A x) {
+                       return where.and(x);
+               }
+
+               protected QueryWhere<T> and(And<T> conditions) {
+                       where.andOpen();
+                       where.query.addConditionToken(conditions.where.query);
+                       return where.close();
+               }
+
+               protected QueryWhere<T> and(Or<T> conditions) {
+                       where.andOpen();
+                       where.query.addConditionToken(conditions.where.query);
+                       return where.close();
+               }
+
+       }
+
+       public static class Or<T> extends NestedConditions<T> {
+
+               public Or(Db db, T alias) {
+                       super(db, alias);
+               }
+
+               protected QueryCondition<T, Boolean> or(boolean x) {
+                       return where.or(x);
+               }
+
+               protected QueryCondition<T, Byte> or(byte x) {
+                       return where.or(x);
+               }
+
+               protected QueryCondition<T, Short> or(short x) {
+                       return where.or(x);
+               }
+
+               protected QueryCondition<T, Integer> or(int x) {
+                       return where.or(x);
+               }
+
+               protected QueryCondition<T, Long> or(long x) {
+                       return where.or(x);
+               }
+
+               protected QueryCondition<T, Float> or(float x) {
+                       return where.or(x);
+               }
+
+               protected QueryCondition<T, Double> or(double x) {
+                       return where.or(x);
+               }
+
+               protected <A> QueryCondition<T, A> or(A x) {
+                       return where.or(x);
+               }
+
+               protected QueryWhere<T> or(And<T> conditions) {
+                       where.orOpen();
+                       where.query.addConditionToken(conditions.where.query);
+                       return where.close();
+               }
+
+               protected QueryWhere<T> or(Or<T> conditions) {
+                       where.orOpen();
+                       where.query.addConditionToken(conditions.where.query);
+                       return where.close();
+               }
+
+       }
+
+       QueryWhere<T> where;
+
+       private NestedConditions(Db db, T alias) {
+               where = new QueryWhere<T>(Query.rebuild(db, alias));
+       }
+
+}
index 7edd8fca294004e11ecafc22ffbf7335117e851c..f22215cebd19362304b227ee351e56d28f05da75 100644 (file)
@@ -27,17 +27,18 @@ import java.util.Arrays;
 import java.util.HashMap;\r
 import java.util.IdentityHashMap;\r
 import java.util.List;\r
-import com.iciql.Conditions.And;\r
-import com.iciql.Conditions.Or;\r
+\r
+import com.iciql.NestedConditions.And;\r
+import com.iciql.NestedConditions.Or;\r
 import com.iciql.Iciql.EnumType;\r
 import com.iciql.bytecode.ClassReader;\r
-import com.iciql.util.JdbcUtils;\r
 import com.iciql.util.IciqlLogger;\r
+import com.iciql.util.JdbcUtils;\r
 import com.iciql.util.Utils;\r
 \r
 /**\r
  * This class represents a query.\r
- * \r
+ *\r
  * @param <T>\r
  *            the return type\r
  */\r
@@ -62,7 +63,7 @@ public class Query<T> {
 \r
        /**\r
         * from() is a static factory method to build a Query object.\r
-        * \r
+        *\r
         * @param db\r
         * @param alias\r
         * @return a query object\r
@@ -119,13 +120,13 @@ public class Query<T> {
                List<X> list = limit(1).select(x);\r
                return list.isEmpty() ? null : list.get(0);\r
        }\r
-       \r
+\r
        public <X> void createView(Class<X> viewClass) {\r
                TableDefinition<X> viewDef = db.define(viewClass);\r
-               \r
+\r
                SQLStatement fromWhere = new SQLStatement(db);\r
                appendFromWhere(fromWhere, false);\r
-               \r
+\r
                SQLStatement stat = new SQLStatement(db);\r
                db.getDialect().prepareCreateView(stat, viewDef, fromWhere.toSQL());\r
                IciqlLogger.create(stat.toSQL());\r
@@ -149,7 +150,7 @@ public class Query<T> {
         * properly encoded. This method is also useful when combined with the where\r
         * clause methods like isParameter() or atLeastParameter() which allows\r
         * iciql to generate re-usable parameterized string statements.\r
-        * \r
+        *\r
         * @return the sql query as plain text\r
         */\r
        public String toSQL() {\r
@@ -161,7 +162,7 @@ public class Query<T> {
         * properly encoded. This method is also useful when combined with the where\r
         * clause methods like isParameter() or atLeastParameter() which allows\r
         * iciql to generate re-usable parameterized string statements.\r
-        * \r
+        *\r
         * @param distinct\r
         *            if true SELECT DISTINCT is used for the query\r
         * @return the sql query as plain text\r
@@ -175,7 +176,7 @@ public class Query<T> {
         * properly encoded. This method is also useful when combined with the where\r
         * clause methods like isParameter() or atLeastParameter() which allows\r
         * iciql to generate re-usable parameterized string statements.\r
-        * \r
+        *\r
         * @param distinct\r
         *            if true SELECT DISTINCT is used for the query\r
         * @param k\r
@@ -228,7 +229,7 @@ public class Query<T> {
                                stat.appendSQL("*");\r
                        }\r
                        appendFromWhere(stat);\r
-               }               \r
+               }\r
                return stat.toSQL().trim();\r
        }\r
 \r
@@ -239,7 +240,7 @@ public class Query<T> {
                stat.appendColumn(columnName);\r
                appendFromWhere(stat);\r
                return stat.toSQL();\r
-       }       \r
+       }\r
 \r
        private List<T> select(boolean distinct) {\r
                List<T> result = Utils.newArrayList();\r
@@ -456,7 +457,7 @@ public class Query<T> {
 \r
        /**\r
         * Begin a primitive boolean field condition clause.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive boolean field to query\r
         * @return a query condition to continue building the condition\r
@@ -468,7 +469,7 @@ public class Query<T> {
 \r
        /**\r
         * Begin a primitive short field condition clause.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive short field to query\r
         * @return a query condition to continue building the condition\r
@@ -479,7 +480,7 @@ public class Query<T> {
 \r
        /**\r
         * Begin a primitive short field condition clause.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive short field to query\r
         * @return a query condition to continue building the condition\r
@@ -490,7 +491,7 @@ public class Query<T> {
 \r
        /**\r
         * Begin a primitive int field condition clause.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive int field to query\r
         * @return a query condition to continue building the condition\r
@@ -501,7 +502,7 @@ public class Query<T> {
 \r
        /**\r
         * Begin a primitive long field condition clause.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive long field to query\r
         * @return a query condition to continue building the condition\r
@@ -512,7 +513,7 @@ public class Query<T> {
 \r
        /**\r
         * Begin a primitive float field condition clause.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive float field to query\r
         * @return a query condition to continue building the condition\r
@@ -523,7 +524,7 @@ public class Query<T> {
 \r
        /**\r
         * Begin a primitive double field condition clause.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive double field to query\r
         * @return a query condition to continue building the condition\r
@@ -534,7 +535,7 @@ public class Query<T> {
 \r
        /**\r
         * Begins a primitive field condition clause.\r
-        * \r
+        *\r
         * @param value\r
         * @return a query condition to continue building the condition\r
         */\r
@@ -549,7 +550,7 @@ public class Query<T> {
 \r
        /**\r
         * Begin an Object field condition clause.\r
-        * \r
+        *\r
         * @param x\r
         *            the mapped object to query\r
         * @return a query condition to continue building the condition\r
@@ -622,7 +623,7 @@ public class Query<T> {
 \r
        /**\r
         * Sets the Limit and Offset of a query.\r
-        * \r
+        *\r
         * @return the query\r
         */\r
 \r
@@ -682,7 +683,7 @@ public class Query<T> {
 \r
        /**\r
         * Order by a number of columns.\r
-        * \r
+        *\r
         * @param expressions\r
         *            the columns\r
         * @return the query\r
@@ -753,7 +754,7 @@ public class Query<T> {
 \r
        /**\r
         * INTERNAL\r
-        * \r
+        *\r
         * @param stat\r
         *            the statement\r
         * @param alias\r
@@ -796,7 +797,7 @@ public class Query<T> {
 \r
        /**\r
         * INTERNAL\r
-        * \r
+        *\r
         * @param stat\r
         *            the statement\r
         * @param alias\r
@@ -879,17 +880,30 @@ public class Query<T> {
                }\r
                if (!conditions.isEmpty()) {\r
                        stat.appendSQL(" WHERE ");\r
+\r
+                       boolean skipNextConjunction = false;\r
+\r
                        for (Token token : conditions) {\r
+\r
+                               if (skipNextConjunction && token instanceof ConditionAndOr) {\r
+                                       skipNextConjunction = false;\r
+                                       continue;\r
+                               }\r
+\r
                                token.appendSQL(stat, this);\r
                                stat.appendSQL(" ");\r
+\r
+                               if (ConditionOpenClose.OPEN == token) {\r
+                                       skipNextConjunction = true;\r
+                               }\r
                        }\r
                }\r
        }\r
-       \r
+\r
        void appendFromWhere(SQLStatement stat) {\r
                appendFromWhere(stat, true);\r
        }\r
-       \r
+\r
        void appendFromWhere(SQLStatement stat, boolean log) {\r
                stat.appendSQL(" FROM ");\r
                from.appendSQL(stat);\r
@@ -927,7 +941,7 @@ public class Query<T> {
 \r
        /**\r
         * Join another table.\r
-        * \r
+        *\r
         * @param alias\r
         *            an alias for the table to join\r
         * @return the joined query\r
@@ -977,7 +991,7 @@ public class Query<T> {
 \r
        /**\r
         * This method returns a mapped Object field by its reference.\r
-        * \r
+        *\r
         * @param obj\r
         * @return\r
         */\r
@@ -988,7 +1002,7 @@ public class Query<T> {
 \r
        /**\r
         * This method returns the alias of a mapped primitive field by its value.\r
-        * \r
+        *\r
         * @param obj\r
         * @return\r
         */\r
index 5ea8bdb481f93261a0cc591c7c8aa156fb1e2af7..731fc0b7f85aa666ae64f1e44d3926eeb7bb65e6 100644 (file)
@@ -19,12 +19,12 @@ package com.iciql;
 \r
 import java.util.List;\r
 \r
-import com.iciql.Conditions.And;\r
-import com.iciql.Conditions.Or;\r
+import com.iciql.NestedConditions.And;\r
+import com.iciql.NestedConditions.Or;\r
 \r
 /**\r
  * This class represents a query with a condition.\r
- * \r
+ *\r
  * @param <T>\r
  *            the return type\r
  */\r
@@ -39,7 +39,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an AND condition with a mapped primitive boolean.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive boolean field to query\r
         * @return a query condition to continue building the condition\r
@@ -51,7 +51,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an AND condition with a mapped primitive byte.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive byte field to query\r
         * @return a query condition to continue building the condition\r
@@ -62,7 +62,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an AND condition with a mapped primitive short.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive short field to query\r
         * @return a query condition to continue building the condition\r
@@ -73,7 +73,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an AND condition with a mapped primitive int.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive int field to query\r
         * @return a query condition to continue building the condition\r
@@ -84,7 +84,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an AND condition with a mapped primitive long.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive long field to query\r
         * @return a query condition to continue building the condition\r
@@ -95,7 +95,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an AND condition with a mapped primitive float.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive float field to query\r
         * @return a query condition to continue building the condition\r
@@ -106,7 +106,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an AND condition with a mapped primitive double.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive double field to query\r
         * @return a query condition to continue building the condition\r
@@ -127,7 +127,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an AND condition with a mapped Object field.\r
-        * \r
+        *\r
         * @param x\r
         *            the Object field to query\r
         * @return a query condition to continue building the condition\r
@@ -139,28 +139,24 @@ public class QueryWhere<T> {
        }\r
 \r
        public QueryWhere<T> and(And<T> conditions) {\r
-               andOpenTrue();\r
+               andOpen();\r
                query.addConditionToken(conditions.where.query);\r
                return close();\r
        }\r
 \r
        public QueryWhere<T> and(Or<T> conditions) {\r
-               andOpenFalse();\r
+               andOpen();\r
                query.addConditionToken(conditions.where.query);\r
                return close();\r
        }\r
 \r
-       public QueryWhere<T> andOpenTrue() {\r
-               return open(ConditionAndOr.AND, true);\r
-       }\r
-\r
-       public QueryWhere<T> andOpenFalse() {\r
-               return open(ConditionAndOr.AND, false);\r
+       public QueryWhere<T> andOpen() {\r
+               return open(ConditionAndOr.AND);\r
        }\r
 \r
        /**\r
         * Specify an OR condition with a mapped primitive boolean.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive boolean field to query\r
         * @return a query condition to continue building the condition\r
@@ -172,7 +168,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an OR condition with a mapped primitive byte.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive byte field to query\r
         * @return a query condition to continue building the condition\r
@@ -183,7 +179,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an OR condition with a mapped primitive short.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive short field to query\r
         * @return a query condition to continue building the condition\r
@@ -194,7 +190,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an OR condition with a mapped primitive int.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive int field to query\r
         * @return a query condition to continue building the condition\r
@@ -205,7 +201,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an OR condition with a mapped primitive long.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive long field to query\r
         * @return a query condition to continue building the condition\r
@@ -216,7 +212,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an OR condition with a mapped primitive float.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive float field to query\r
         * @return a query condition to continue building the condition\r
@@ -227,7 +223,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an OR condition with a mapped primitive double.\r
-        * \r
+        *\r
         * @param x\r
         *            the primitive double field to query\r
         * @return a query condition to continue building the condition\r
@@ -238,7 +234,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Specify an OR condition with a mapped Object field.\r
-        * \r
+        *\r
         * @param x\r
         *            the Object field to query\r
         * @return a query condition to continue building the condition\r
@@ -250,29 +246,24 @@ public class QueryWhere<T> {
        }\r
 \r
        public QueryWhere<T> or(And<T> conditions) {\r
-               orOpenTrue();\r
+               orOpen();\r
                query.addConditionToken(conditions.where.query);\r
                return close();\r
        }\r
 \r
        public QueryWhere<T> or(Or<T> conditions) {\r
-               orOpenFalse();\r
+               orOpen();\r
                query.addConditionToken(conditions.where.query);\r
                return close();\r
        }\r
 \r
-       public QueryWhere<T> orOpenTrue() {\r
-               return open(ConditionAndOr.OR, true);\r
-       }\r
-\r
-       public QueryWhere<T> orOpenFalse() {\r
-               return open(ConditionAndOr.OR, false);\r
+       public QueryWhere<T> orOpen() {\r
+               return open(ConditionAndOr.OR);\r
        }\r
 \r
-       private QueryWhere<T> open(ConditionAndOr andOr, Boolean condition) {\r
+       private QueryWhere<T> open(ConditionAndOr andOr) {\r
                query.addConditionToken(andOr);\r
                query.addConditionToken(ConditionOpenClose.OPEN);\r
-               query.addConditionToken(new Function("", condition));\r
                return this;\r
        }\r
 \r
@@ -303,7 +294,7 @@ public class QueryWhere<T> {
         * properly encoded. This method is also useful when combined with the where\r
         * clause methods like isParameter() or atLeastParameter() which allows\r
         * iciql to generate re-usable parameterized string statements.\r
-        * \r
+        *\r
         * @return the sql query as plain text\r
         */\r
        public String toSQL() {\r
@@ -315,7 +306,7 @@ public class QueryWhere<T> {
         * properly encoded. This method is also useful when combined with the where\r
         * clause methods like isParameter() or atLeastParameter() which allows\r
         * iciql to generate re-usable parameterized string statements.\r
-        * \r
+        *\r
         * @param distinct\r
         *            if true SELECT DISTINCT is used for the query\r
         * @return the sql query as plain text\r
@@ -329,7 +320,7 @@ public class QueryWhere<T> {
         * properly encoded. This method is also useful when combined with the where\r
         * clause methods like isParameter() or atLeastParameter() which allows\r
         * iciql to generate re-usable parameterized string statements.\r
-        * \r
+        *\r
         * @param distinct\r
         *            if true SELECT DISTINCT is used for the query\r
         * @param k\r
@@ -344,12 +335,12 @@ public class QueryWhere<T> {
        public <K> String toSQL(boolean distinct, K k) {\r
                return query.toSQL(distinct, k);\r
        }\r
-       \r
+\r
        public <Z> SubQuery<T, Z> subQuery(Z x) {\r
                return new SubQuery<T, Z>(query, x);\r
        }\r
 \r
-       public SubQuery<T, Boolean> subQuery(boolean x) {               \r
+       public SubQuery<T, Boolean> subQuery(boolean x) {\r
                return subQuery(query.getPrimitiveAliasByValue(x));\r
        }\r
 \r
@@ -376,7 +367,7 @@ public class QueryWhere<T> {
        public SubQuery<T, Double> subQuery(double x) {\r
                return subQuery(query.getPrimitiveAliasByValue(x));\r
        }\r
-       \r
+\r
        public <X, Z> List<X> select(Z x) {\r
                return query.select(x);\r
        }\r
@@ -402,7 +393,7 @@ public class QueryWhere<T> {
        public List<T> selectDistinct() {\r
                return query.selectDistinct();\r
        }\r
-       \r
+\r
        public void createView(Class<?> viewClass) {\r
                query.createView(viewClass);\r
        }\r
@@ -413,7 +404,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Order by primitive boolean field\r
-        * \r
+        *\r
         * @param field\r
         *            a primitive boolean field\r
         * @return the query\r
@@ -425,7 +416,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Order by primitive byte field\r
-        * \r
+        *\r
         * @param field\r
         *            a primitive byte field\r
         * @return the query\r
@@ -436,7 +427,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Order by primitive short field\r
-        * \r
+        *\r
         * @param field\r
         *            a primitive short field\r
         * @return the query\r
@@ -451,7 +442,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Order by primitive long field\r
-        * \r
+        *\r
         * @param field\r
         *            a primitive long field\r
         * @return the query\r
@@ -462,7 +453,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Order by primitive float field\r
-        * \r
+        *\r
         * @param field\r
         *            a primitive float field\r
         * @return the query\r
@@ -473,7 +464,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Order by primitive double field\r
-        * \r
+        *\r
         * @param field\r
         *            a primitive double field\r
         * @return the query\r
@@ -495,7 +486,7 @@ public class QueryWhere<T> {
 \r
        /**\r
         * Order by a number of Object columns.\r
-        * \r
+        *\r
         * @param expressions\r
         *            the order by expressions\r
         * @return the query\r
index 8b54dcea0cd442268b658d982a087065bb152233..b09f91b004c1e6e131a402f4d9b55cc81efbcab4 100644 (file)
@@ -69,28 +69,36 @@ List<Product> allProducts = db.buildObjects(Product.class, rs);
 JdbcUtils.closeSilently(rs, true);\r
 ---JAVA---\r
 \r
-### Compound Conditions\r
+### Compound Nested Conditions\r
 \r
-It is possible to specify type-safe compound where clauses using nested `And` and `Or` statements.\r
+It is possible to specify type-safe compound nested conditions in your WHERE clauses using `And` and `Or` statements.\r
 \r
 ---JAVA---\r
 final Customer model = new Customer();\r
 \r
+// SELECT * FROM CUSTOMERS\r
+//    WHERE customerId IS NOT NULL\r
+//    AND region IS NOT NULL\r
+//    AND (\r
+//      region = 'LA' OR region = 'CA'\r
+//    )\r
 List<Customer> regionals =\r
-    db.from(model).where(model.customerId).isNotNull()\r
-        .and(model.region).isNotNull()\r
-        .and(new Or<Customer>(db, model) {{\r
-                   or(model.region).is("LA");\r
-            or(model.region).is("CA");\r
-        }});\r
+  db.from(model)\r
+    .where(model.customerId).isNotNull()\r
+    .and(model.region).isNotNull()\r
+    .and(new Or<Customer>(db, model) {{\r
+         or(model.region).is("LA");\r
+      or(model.region).is("CA");\r
+    }});\r
 \r
 List<Customer> regionalType1s =\r
-    db.from(model).where(new And<Customer>(db, model) {{\r
-        and(model.type).is(1);\r
-        and(new Or<Customer>(db, model) {{\r
-            or(model.region).is("CA");\r
-            or(model.region).is("LA");\r
-        }});\r
+  db.from(model)\r
+    .where(new And<Customer>(db, model) {{\r
+      and(model.type).is(1);\r
+      and(new Or<Customer>(db, model) {{\r
+        or(model.region).is("CA");\r
+        or(model.region).is("LA");\r
+      }});\r
     }});\r
 \r
 ---JAVA---\r
index 48bcfb3b1ed4dad8f072d965fa3d288f61a9729f..7a20468df3f29fe29ddf1e98dd0b9b837747ab3a 100644 (file)
@@ -28,10 +28,10 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import com.iciql.Conditions.And;
-import com.iciql.Conditions.Or;
 import com.iciql.Db;
 import com.iciql.IciqlException;
+import com.iciql.NestedConditions.And;
+import com.iciql.NestedConditions.Or;
 import com.iciql.QueryWhere;
 import com.iciql.test.models.Customer;
 
@@ -60,13 +60,15 @@ public class NestedConditionsTest {
 
                model = new Customer();
                query = db.from(model).whereTrue();
-               if (customerIds != null) {
-                       query.andOpenFalse();
+
+               if (customerIds != null && customerIds.length > 0) {
+                       query.andOpen();
                        for (String value : customerIds) {
                                query.or(model.customerId).is(value);
                        }
                        query.close();
                }
+
                if (region != null) {
                        query.and(model.region).is(region.name());
                }
@@ -80,37 +82,35 @@ public class NestedConditionsTest {
                String region = db.getDialect().prepareColumnName("region");
 
                assertEquals(
-                               search(null, (String[]) null),
-                               String.format("SELECT * FROM %s WHERE (true)",
-                                               Customer));
+                               String.format("SELECT * FROM %s WHERE (true)", Customer),
+                               search(null, (String[]) null));
                assertEquals(
-                               search(null, new String[0]),
-                               String.format("SELECT * FROM %s WHERE (true) AND ( (false) )",
-                                               Customer));
+                               String.format("SELECT * FROM %s WHERE (true)", Customer),
+                               search(null, new String[0]));
                assertEquals(
-                               search(null, "0001"),
-                               String.format("SELECT * FROM %s WHERE (true) AND ( (false) OR %s = '0001' )",
-                                               Customer, customerId));
+                               String.format("SELECT * FROM %s WHERE (true) AND ( %s = '0001' )",
+                                               Customer, customerId),
+                               search(null, "0001"));
                assertEquals(
-                               search(null, "0001", "0002"),
-                               String.format("SELECT * FROM %s WHERE (true) AND ( (false) OR %s = '0001' OR %s = '0002' )",
-                                               Customer, customerId, customerId));
+                               String.format("SELECT * FROM %s WHERE (true) AND ( %s = '0001' OR %s = '0002' )",
+                                               Customer, customerId, customerId),
+                               search(null, "0001", "0002"));
                assertEquals(
-                               search(Region.JP, (String[]) null),
                                String.format("SELECT * FROM %s WHERE (true) AND %s = 'JP'",
-                                               Customer, region));
+                                               Customer, region),
+                               search(Region.JP, (String[]) null));
                assertEquals(
-                               search(Region.JP, new String[0]),
-                               String.format("SELECT * FROM %s WHERE (true) AND ( (false) ) AND %s = 'JP'",
-                                               Customer, region));
+                               String.format("SELECT * FROM %s WHERE (true) AND %s = 'JP'",
+                                               Customer, region),
+                               search(Region.JP, new String[0]));
                assertEquals(
-                               search(Region.JP, "0001"),
-                               String.format("SELECT * FROM %s WHERE (true) AND ( (false) OR %s = '0001' ) AND %s = 'JP'",
-                                               Customer, customerId, region));
+                               String.format("SELECT * FROM %s WHERE (true) AND ( %s = '0001' ) AND %s = 'JP'",
+                                               Customer, customerId, region),
+                               search(Region.JP, "0001"));
                assertEquals(
-                               search(Region.JP, "0001", "0002"),
-                               String.format("SELECT * FROM %s WHERE (true) AND ( (false) OR %s = '0001' OR %s = '0002' ) AND %s = 'JP'",
-                                               Customer, customerId, customerId, region));
+                               String.format("SELECT * FROM %s WHERE (true) AND ( %s = '0001' OR %s = '0002' ) AND %s = 'JP'",
+                                               Customer, customerId, customerId, region),
+                               search(Region.JP, "0001", "0002"));
        }
 
        @Test
@@ -121,7 +121,7 @@ public class NestedConditionsTest {
                try {
                        db.from(model)
                                        .where(model.customerId).is("0001")
-                                       .andOpenFalse()
+                                       .andOpen()
                                                        .or(model.region).is("FR")
                                                        .or(model.region).is("JP")
                                        .close()
@@ -131,10 +131,11 @@ public class NestedConditionsTest {
                catch (IciqlException error) {
                        assertTrue(false);
                }
+
                try {
                        db.from(model)
                                        .where(model.customerId).is("0001")
-                                       .andOpenFalse()
+                                       .andOpen()
                                                        .or(model.region).is("FR")
                                                        .or(model.region).is("JP")
                                                        .toSQL();
@@ -143,10 +144,11 @@ public class NestedConditionsTest {
                catch (IciqlException error) {
                        assertTrue(true);
                }
+
                try {
                        db.from(model)
                                        .where(model.customerId).is("0001")
-                                       .andOpenFalse()
+                                       .andOpen()
                                                        .or(model.region).is("FR")
                                                        .or(model.region).is("JP")
                                        .close()
@@ -165,37 +167,87 @@ public class NestedConditionsTest {
                String region = db.getDialect().prepareColumnName("region");
 
                final Customer model = new Customer();
+
                assertEquals(
+                               String.format("SELECT * FROM %s WHERE (true) AND %s = '0001' AND ( %s = 'CA' OR %s = 'LA' )",
+                                               Customer, customerId, region, region),
+
                                db.from(model).where(new And<Customer>(db, model) {{
+
                                        and(model.customerId).is("0001");
                                        and(new Or<Customer>(db, model) {{
                                                or(model.region).is("CA");
                                                or(model.region).is("LA");
                                        }});
-                               }}).toSQL(),
-                               String.format("SELECT * FROM %s WHERE (true) AND %s = '0001' AND ( (false) OR %s = 'CA' OR %s = 'LA' )",
-                                               Customer, customerId, region, region));
+
+                               }})
+
+                               .toSQL());
+
                assertEquals(
+                               String.format("SELECT * FROM %s WHERE (false) OR %s = '0001' OR ( %s = '0002' AND %s = 'LA' )",
+                                               Customer, customerId, customerId, region),
+
                                db.from(model).where(new Or<Customer>(db, model) {{
+
                                        or(model.customerId).is("0001");
+
                                        or(new And<Customer>(db, model) {{
                                                and(model.customerId).is("0002");
                                                and(model.region).is("LA");
                                        }});
-                               }}).toSQL(),
-                               String.format("SELECT * FROM %s WHERE (false) OR %s = '0001' OR ( (true) AND %s = '0002' AND %s = 'LA' )",
-                                               Customer, customerId, customerId, region));
+
+                               }})
+
+                               .toSQL());
+
                assertEquals(
+                               String.format("SELECT * FROM %s WHERE (false) OR ( %s = '0001' AND %s = 'WA' ) OR ( %s = '0002' AND %s = 'LA' )",
+                                               Customer, customerId, region, customerId, region),
+
+                               db.from(model).where(new Or<Customer>(db, model) {{
+
+                                       or(new And<Customer>(db, model) {{
+                                               and(model.customerId).is("0001");
+                                               and(model.region).is("WA");
+                                       }});
+
+                                       or(new And<Customer>(db, model) {{
+                                               and(model.customerId).is("0002");
+                                               and(model.region).is("LA");
+                                       }});
+
+                               }})
+
+                               .toSQL());
+
+               assertEquals(
+                               String.format("SELECT * FROM %s WHERE %s = '0001' OR ( %s = '0002' AND %s = 'LA' )",
+                                               Customer, customerId, customerId, region),
+
+                               db.from(model).where(model.customerId).is("0001")
+
+                                       .or(new And<Customer>(db, model) {{
+                                               and(model.customerId).is("0002");
+                                               and(model.region).is("LA");
+                                       }})
+
+                                       .toSQL());
+
+
+               assertEquals(
+                               String.format("SELECT * FROM %s WHERE %s IS NOT NULL AND ( %s = 'LA' OR %s = 'CA' OR %s = 'WA' )",
+                                               Customer, customerId, region, region, region),
                                db.from(model)
                                                .where(model.customerId).isNotNull()
+
                                                .and(new Or<Customer>(db, model) {{
                                                        or(model.region).is("LA");
                                                        or(model.region).is("CA");
+                                                       or(model.region).is("WA");
                                                }})
-                                               .and(model.region).isNotNull()
-                                               .toSQL(),
-                               String.format("SELECT * FROM %s WHERE %s IS NOT NULL AND ( (false) OR %s = 'LA' OR %s = 'CA' ) AND %s IS NOT NULL",
-                                               Customer, customerId, region, region, region));
+
+                                               .toSQL());
        }
 
        @Test