mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1643 - ENH: Add expression inOrEmpty() ... as a convenience for conditionally added a IN expression
This commit is contained in:
@@ -17,8 +17,16 @@ import java.util.List;
|
||||
|
||||
class InExpression extends AbstractExpression {
|
||||
|
||||
private static final String SQL_TRUE = "1=1";
|
||||
private static final String SQL_FALSE = "1=0";
|
||||
|
||||
private final boolean not;
|
||||
|
||||
/**
|
||||
* Set to true when adding "1=1" predicate (due to null or empty sourceValues).
|
||||
*/
|
||||
private final boolean empty;
|
||||
|
||||
private final Collection<?> sourceValues;
|
||||
|
||||
private List<Object> bindValues;
|
||||
@@ -26,18 +34,27 @@ class InExpression extends AbstractExpression {
|
||||
private boolean multiValueSupported;
|
||||
|
||||
InExpression(String propertyName, Collection<?> sourceValues, boolean not) {
|
||||
this(propertyName, sourceValues, not, false);
|
||||
}
|
||||
|
||||
InExpression(String propertyName, Collection<?> sourceValues, boolean not, boolean orEmpty) {
|
||||
super(propertyName);
|
||||
this.sourceValues = sourceValues;
|
||||
this.not = not;
|
||||
this.empty = orEmpty && (sourceValues == null || sourceValues.isEmpty());
|
||||
}
|
||||
|
||||
InExpression(String propertyName, Object[] array, boolean not) {
|
||||
super(propertyName);
|
||||
this.sourceValues = Arrays.asList(array);
|
||||
this.not = not;
|
||||
this.empty = false;
|
||||
}
|
||||
|
||||
private List<Object> values() {
|
||||
if (empty || sourceValues == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Object> vals = new ArrayList<>(sourceValues.size());
|
||||
for (Object sourceValue : sourceValues) {
|
||||
assert sourceValue != null : "null is not allowed in in-queries";
|
||||
@@ -48,8 +65,8 @@ class InExpression extends AbstractExpression {
|
||||
|
||||
@Override
|
||||
public boolean naturalKey(NaturalKeyQueryData<?> data) {
|
||||
// can't use naturalKey cache for NOT IN
|
||||
if (not) {
|
||||
// can't use naturalKey cache for NOT IN or when "empty"
|
||||
if (not || empty) {
|
||||
return false;
|
||||
}
|
||||
List<Object> copy = data.matchIn(propName, bindValues);
|
||||
@@ -70,11 +87,16 @@ class InExpression extends AbstractExpression {
|
||||
|
||||
@Override
|
||||
public void writeDocQuery(DocQueryContext context) throws IOException {
|
||||
context.writeIn(propName, values().toArray(), not);
|
||||
if (!empty) {
|
||||
context.writeIn(propName, values().toArray(), not);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBindValues(SpiExpressionRequest request) {
|
||||
if (empty) {
|
||||
return;
|
||||
}
|
||||
for (Object value : bindValues) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException("null values in 'in(...)' queries must be handled separately!");
|
||||
@@ -108,10 +130,12 @@ class InExpression extends AbstractExpression {
|
||||
|
||||
@Override
|
||||
public void addSql(SpiExpressionRequest request) {
|
||||
|
||||
if (empty) {
|
||||
request.append(SQL_TRUE);
|
||||
return;
|
||||
}
|
||||
if (bindValues.isEmpty()) {
|
||||
String expr = not ? "1=1" : "1=0";
|
||||
request.append(expr);
|
||||
request.append(not ? SQL_TRUE : SQL_FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -142,10 +166,14 @@ class InExpression extends AbstractExpression {
|
||||
builder.append("In[");
|
||||
}
|
||||
builder.append(propName);
|
||||
builder.append(" ?");
|
||||
if (!multiValueSupported) {
|
||||
// query plan specific to the number of parameters in the IN clause
|
||||
builder.append(bindValues.size());
|
||||
if (empty) {
|
||||
builder.append("empty");
|
||||
} else {
|
||||
builder.append(" ?");
|
||||
if (!multiValueSupported) {
|
||||
// query plan specific to the number of parameters in the IN clause
|
||||
builder.append(bindValues.size());
|
||||
}
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user