diff options
author | Sotaro SUZUKI <sotaro.suzuki@architector.jp> | 2014-10-01 16:17:34 +0900 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2014-10-06 10:22:39 -0400 |
commit | 48da60f625b53dccbc4a34737eba55eb0eda181b (patch) | |
tree | 0b048e6247ce0ec196df7015c8fa77bf36e062a0 /src/main/java | |
parent | 8ba3b92816e65acc0d1d71ba23259deed616eefe (diff) | |
download | iciql-48da60f625b53dccbc4a34737eba55eb0eda181b.tar.gz iciql-48da60f625b53dccbc4a34737eba55eb0eda181b.zip |
add support stackable condition: ex. X and (Y or Z)
see samples in
src/test/java/com/iciql/test/StackableConditionsTest.java
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/com/iciql/ConditionOpenClose.java | 33 | ||||
-rw-r--r-- | src/main/java/com/iciql/Conditions.java | 132 | ||||
-rw-r--r-- | src/main/java/com/iciql/Query.java | 54 | ||||
-rw-r--r-- | src/main/java/com/iciql/QueryWhere.java | 55 | ||||
-rw-r--r-- | src/main/java/com/iciql/TableDefinition.java | 11 |
5 files changed, 279 insertions, 6 deletions
diff --git a/src/main/java/com/iciql/ConditionOpenClose.java b/src/main/java/com/iciql/ConditionOpenClose.java new file mode 100644 index 0000000..5284abd --- /dev/null +++ b/src/main/java/com/iciql/ConditionOpenClose.java @@ -0,0 +1,33 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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; + +enum ConditionOpenClose implements Token { + OPEN("("), CLOSE(")"); + + private String text; + + ConditionOpenClose(String text) { + this.text = text; + } + + public <T> void appendSQL(SQLStatement stat, Query<T> query) { + stat.appendSQL(text); + } + +} diff --git a/src/main/java/com/iciql/Conditions.java b/src/main/java/com/iciql/Conditions.java new file mode 100644 index 0000000..1699641 --- /dev/null +++ b/src/main/java/com/iciql/Conditions.java @@ -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 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/Query.java b/src/main/java/com/iciql/Query.java index 5f29edf..7edd8fc 100644 --- a/src/main/java/com/iciql/Query.java +++ b/src/main/java/com/iciql/Query.java @@ -27,7 +27,8 @@ import java.util.Arrays; import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
-
+import com.iciql.Conditions.And;
+import com.iciql.Conditions.Or;
import com.iciql.Iciql.EnumType;
import com.iciql.bytecode.ClassReader;
import com.iciql.util.JdbcUtils;
@@ -47,6 +48,7 @@ public class Query<T> { private SelectTable<T> from;
private ArrayList<Token> conditions = Utils.newArrayList();
private ArrayList<UpdateColumn> updateColumnDeclarations = Utils.newArrayList();
+ private int conditionDepth = 0;
private ArrayList<SelectTable<T>> joins = Utils.newArrayList();
private final IdentityHashMap<Object, SelectColumn<T>> aliasMap = Utils.newIdentityHashMap();
private ArrayList<OrderExpression<T>> orderByList = Utils.newArrayList();
@@ -70,7 +72,16 @@ public class Query<T> { Query<T> query = new Query<T>(db);
TableDefinition<T> def = (TableDefinition<T>) db.define(alias.getClass());
query.from = new SelectTable<T>(db, query, alias, false);
- def.initSelectObject(query.from, alias, query.aliasMap);
+ def.initSelectObject(query.from, alias, query.aliasMap, false);
+ return query;
+ }
+
+ @SuppressWarnings("unchecked")
+ static <T> Query<T> rebuild(Db db, T alias) {
+ Query<T> query = new Query<T>(db);
+ TableDefinition<T> def = (TableDefinition<T>) db.define(alias.getClass());
+ query.from = new SelectTable<T>(db, query, alias, false);
+ def.initSelectObject(query.from, alias, query.aliasMap, true);
return query;
}
@@ -583,6 +594,26 @@ public class Query<T> { return new QueryWhere<T>(this);
}
+ public Query<T> where(And<T> conditions) {
+ whereTrue();
+ addConditionToken(conditions.where.query);
+ return this;
+ }
+
+ public Query<T> where(Or<T> conditions) {
+ whereFalse();
+ addConditionToken(conditions.where.query);
+ return this;
+ }
+
+ public QueryWhere<T> whereTrue() {
+ return whereTrue(true);
+ }
+
+ public QueryWhere<T> whereFalse() {
+ return whereTrue(false);
+ }
+
public QueryWhere<T> whereTrue(Boolean condition) {
Token token = new Function("", condition);
addConditionToken(token);
@@ -821,14 +852,31 @@ public class Query<T> { }
void addConditionToken(Token condition) {
+ if (condition == ConditionOpenClose.OPEN) {
+ conditionDepth ++;
+ } else if (condition == ConditionOpenClose.CLOSE) {
+ conditionDepth --;
+ if (conditionDepth < 0) {
+ throw new IciqlException("unmatch condition open-close count");
+ }
+ }
conditions.add(condition);
}
+ void addConditionToken(Query<T> other) {
+ for (Token condition : other.conditions) {
+ addConditionToken(condition);
+ }
+ }
+
void addUpdateColumnDeclaration(UpdateColumn declaration) {
updateColumnDeclarations.add(declaration);
}
void appendWhere(SQLStatement stat) {
+ if (conditionDepth != 0) {
+ throw new IciqlException("unmatch condition open-close count");
+ }
if (!conditions.isEmpty()) {
stat.appendSQL(" WHERE ");
for (Token token : conditions) {
@@ -897,7 +945,7 @@ public class Query<T> { private <A> QueryJoin<T> join(A alias, boolean outerJoin) {
TableDefinition<T> def = (TableDefinition<T>) db.define(alias.getClass());
SelectTable<T> join = new SelectTable(db, this, alias, outerJoin);
- def.initSelectObject(join, alias, aliasMap);
+ def.initSelectObject(join, alias, aliasMap, false);
joins.add(join);
return new QueryJoin(this, join);
}
diff --git a/src/main/java/com/iciql/QueryWhere.java b/src/main/java/com/iciql/QueryWhere.java index 5baa5ab..5ea8bdb 100644 --- a/src/main/java/com/iciql/QueryWhere.java +++ b/src/main/java/com/iciql/QueryWhere.java @@ -19,6 +19,9 @@ package com.iciql; import java.util.List;
+import com.iciql.Conditions.And;
+import com.iciql.Conditions.Or;
+
/**
* This class represents a query with a condition.
*
@@ -135,6 +138,26 @@ public class QueryWhere<T> { return new QueryCondition<T, A>(query, x);
}
+ public QueryWhere<T> and(And<T> conditions) {
+ andOpenTrue();
+ query.addConditionToken(conditions.where.query);
+ return close();
+ }
+
+ public QueryWhere<T> and(Or<T> conditions) {
+ andOpenFalse();
+ query.addConditionToken(conditions.where.query);
+ return close();
+ }
+
+ public QueryWhere<T> andOpenTrue() {
+ return open(ConditionAndOr.AND, true);
+ }
+
+ public QueryWhere<T> andOpenFalse() {
+ return open(ConditionAndOr.AND, false);
+ }
+
/**
* Specify an OR condition with a mapped primitive boolean.
*
@@ -226,6 +249,38 @@ public class QueryWhere<T> { return new QueryCondition<T, A>(query, x);
}
+ public QueryWhere<T> or(And<T> conditions) {
+ orOpenTrue();
+ query.addConditionToken(conditions.where.query);
+ return close();
+ }
+
+ public QueryWhere<T> or(Or<T> conditions) {
+ orOpenFalse();
+ query.addConditionToken(conditions.where.query);
+ return close();
+ }
+
+ public QueryWhere<T> orOpenTrue() {
+ return open(ConditionAndOr.OR, true);
+ }
+
+ public QueryWhere<T> orOpenFalse() {
+ return open(ConditionAndOr.OR, false);
+ }
+
+ private QueryWhere<T> open(ConditionAndOr andOr, Boolean condition) {
+ query.addConditionToken(andOr);
+ query.addConditionToken(ConditionOpenClose.OPEN);
+ query.addConditionToken(new Function("", condition));
+ return this;
+ }
+
+ public QueryWhere<T> close() {
+ query.addConditionToken(ConditionOpenClose.CLOSE);
+ return this;
+ }
+
public QueryWhere<T> limit(long limit) {
query.limit(limit);
return this;
diff --git a/src/main/java/com/iciql/TableDefinition.java b/src/main/java/com/iciql/TableDefinition.java index 6d8cb6e..e0cc169 100644 --- a/src/main/java/com/iciql/TableDefinition.java +++ b/src/main/java/com/iciql/TableDefinition.java @@ -1131,11 +1131,16 @@ public class TableDefinition<T> { }
}
- void initSelectObject(SelectTable<T> table, Object obj, Map<Object, SelectColumn<T>> map) {
+ void initSelectObject(SelectTable<T> table, Object obj, Map<Object, SelectColumn<T>> map, boolean reuse) {
for (FieldDefinition def : fields) {
- Object newValue = def.initWithNewObject(obj);
+ Object value;
+ if (!reuse) {
+ value = def.initWithNewObject(obj);
+ } else {
+ value = def.getValue(obj);
+ }
SelectColumn<T> column = new SelectColumn<T>(table, def);
- map.put(newValue, column);
+ map.put(value, column);
}
}
|