#355 - ENH: Add notIn(...) expressions. Just to make life easier in those cases

This commit is contained in:
Robin Bygrave
2015-07-27 20:39:34 +12:00
parent 5a55b5235d
commit 87b485cfa4
9 changed files with 237 additions and 22 deletions
@@ -169,7 +169,22 @@ public interface ExpressionFactory {
* In - property has a value in the collection of values.
*/
Expression in(String propertyName, Collection<?> values);
/**
* Not In - property has a value in the array of values.
*/
Expression notIn(String propertyName, Object[] values);
/**
* Not In - property has a value in the collection of values.
*/
Expression notIn(String propertyName, Collection<?> values);
/**
* Not In - using a subQuery.
*/
Expression notIn(String propertyName, Query<?> subQuery);
/**
* Exists expression
*/
@@ -488,7 +488,22 @@ public interface ExpressionList<T> extends Serializable {
* In - property has a value in the collection of values.
*/
ExpressionList<T> in(String propertyName, Collection<?> values);
/**
* Not In - property has a value in the array of values.
*/
ExpressionList<T> notIn(String propertyName, Object... values);
/**
* Not In - property has a value in the collection of values.
*/
ExpressionList<T> notIn(String propertyName, Collection<?> values);
/**
* Not In - using a subQuery.
*/
ExpressionList<T> notIn(String propertyName, Query<?> subQuery);
/**
* Exists expression
*/
@@ -225,23 +225,44 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
* In - property has a value in the array of values.
*/
public Expression in(String propertyName, Object[] values) {
return new InExpression(propertyName, values);
return new InExpression(propertyName, values, false);
}
/**
* In - using a subQuery.
*/
public Expression in(String propertyName, Query<?> subQuery) {
return new InQueryExpression(propertyName, (SpiQuery<?>) subQuery);
return new InQueryExpression(propertyName, (SpiQuery<?>) subQuery, false);
}
/**
* In - property has a value in the collection of values.
*/
public Expression in(String propertyName, Collection<?> values) {
return new InExpression(propertyName, values);
return new InExpression(propertyName, values, false);
}
/**
* In - property has a value in the array of values.
*/
public Expression notIn(String propertyName, Object[] values) {
return new InExpression(propertyName, values, true);
}
/**
* Not In - property has a value in the collection of values.
*/
public Expression notIn(String propertyName, Collection<?> values) {
return new InExpression(propertyName, values, true);
}
/**
* In - using a subQuery.
*/
public Expression notIn(String propertyName, Query<?> subQuery) {
return new InQueryExpression(propertyName, (SpiQuery<?>) subQuery, true);
}
/**
* Exists subquery
*/
@@ -12,16 +12,20 @@ class InExpression extends AbstractExpression {
private static final long serialVersionUID = 3150665801693551260L;
private final boolean not;
private final Object[] values;
InExpression(String propertyName, Collection<?> coll) {
InExpression(String propertyName, Collection<?> coll, boolean not) {
super(propertyName);
values = coll.toArray(new Object[coll.size()]);
this.values = coll.toArray(new Object[coll.size()]);
this.not = not;
}
InExpression(String propertyName, Object[] array) {
InExpression(String propertyName, Object[] array, boolean not) {
super(propertyName);
this.values = array;
this.not = not;
}
public void addBindValues(SpiExpressionRequest request) {
@@ -50,8 +54,10 @@ class InExpression extends AbstractExpression {
public void addSql(SpiExpressionRequest request) {
if (values.length == 0) {
// 'no match' for in empty collection
request.append("1=0");
if (!not) {
// 'no match' for in empty collection
request.append("1=0");
}
return;
}
@@ -69,6 +75,9 @@ class InExpression extends AbstractExpression {
} else {
request.append(propertyName);
if (not) {
request.append(" not");
}
request.append(" in (?");
for (int i = 1; i < values.length; i++) {
request.append(", ").append("?");
@@ -82,7 +91,7 @@ class InExpression extends AbstractExpression {
* Based on the number of values in the in clause.
*/
public void queryAutoFetchHash(HashQueryPlanBuilder builder) {
builder.add(InExpression.class).add(propName).add(values.length);
builder.add(InExpression.class).add(propName).add(values.length).add(not);
builder.bind(values.length);
}
@@ -18,18 +18,20 @@ class InQueryExpression extends AbstractExpression {
private static final long serialVersionUID = 666990277309851644L;
private final boolean not;
private final SpiQuery<?> subQuery;
private transient CQuery<?> compiledSubQuery;
public InQueryExpression(String propertyName, SpiQuery<?> subQuery) {
public InQueryExpression(String propertyName, SpiQuery<?> subQuery, boolean not) {
super(propertyName);
this.subQuery = subQuery;
this.not = not;
}
public void queryAutoFetchHash(HashQueryPlanBuilder builder) {
builder.add(InQueryExpression.class).add(propName);
builder.add(InQueryExpression.class).add(propName).add(not);
subQuery.queryAutofetchHash(builder);
}
@@ -61,9 +63,11 @@ class InQueryExpression extends AbstractExpression {
subSelect = subSelect.replace('\n', ' ');
String propertyName = getPropertyName();
request.append(" (");
request.append(propertyName);
request.append(") in (");
request.append(" (").append(propertyName).append(")");
if (not) {
request.append(" not");
}
request.append(" in (");
request.append(subSelect);
request.append(") ");
}
@@ -367,7 +367,22 @@ abstract class JunctionExpression<T> implements Junction<T>, SpiExpression, Expr
public ExpressionList<T> in(String propertyName, com.avaje.ebean.Query<?> subQuery) {
return exprList.in(propertyName, subQuery);
}
@Override
public ExpressionList<T> notIn(String propertyName, Collection<?> values) {
return exprList.notIn(propertyName, values);
}
@Override
public ExpressionList<T> notIn(String propertyName, Object... values) {
return exprList.notIn(propertyName, values);
}
@Override
public ExpressionList<T> notIn(String propertyName, com.avaje.ebean.Query<?> subQuery) {
return exprList.notIn(propertyName, subQuery);
}
@Override
public ExpressionList<T> exists(Query<?> subQuery) {
return exprList.exists(subQuery);
@@ -475,6 +475,24 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return this;
}
@Override
public ExpressionList<T> notIn(String propertyName, Object... values) {
add(expr.notIn(propertyName, values));
return this;
}
@Override
public ExpressionList<T> notIn(String propertyName, Collection<?> values) {
add(expr.notIn(propertyName, values));
return this;
}
@Override
public ExpressionList<T> notIn(String propertyName, Query<?> subQuery) {
add(expr.notIn(propertyName, subQuery));
return this;
}
@Override
public ExpressionList<T> exists(Query<?> subQuery) {
add(expr.exists(subQuery));