Files
ebean/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java
T
Roland PramlandRob Bygrave a1f95bf25e Pr/id in as collection2 (#1034)
* ENH: Changed  idIn(List) to idIn(Collection)

* ADD: sanity checks in IdBinder & special case if ID-list is empty
2017-06-19 22:05:56 +12:00

131 lines
3.6 KiB
Java

package io.ebeaninternal.server.expression;
import io.ebeaninternal.api.HashQueryPlanBuilder;
import io.ebeaninternal.api.ManyWhereJoins;
import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.api.SpiExpressionValidation;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.id.IdBinder;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
/**
* Slightly redundant as Query.setId() ultimately also does the same job.
*/
public class IdInExpression extends NonPrepareExpression {
private final Collection<?> idCollection;
public IdInExpression(Collection<?> idCollection) {
this.idCollection = idCollection;
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return null;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeIds(idCollection);
}
@Override
public void validate(SpiExpressionValidation validation) {
// always valid
}
@Override
public void addBindValues(SpiExpressionRequest request) {
// Bind the Id values including EmbeddedId and multiple Id
DefaultExpressionRequest r = (DefaultExpressionRequest) request;
BeanDescriptor<?> descriptor = r.getBeanDescriptor();
IdBinder idBinder = descriptor.getIdBinder();
for (Object id : idCollection) {
idBinder.addIdInBindValue(request, id);
}
}
/**
* For use with deleting non attached detail beans during stateless update.
*/
public void addSqlNoAlias(SpiExpressionRequest request) {
DefaultExpressionRequest r = (DefaultExpressionRequest) request;
BeanDescriptor<?> descriptor = r.getBeanDescriptor();
IdBinder idBinder = descriptor.getIdBinder();
if (idCollection.size() == 0) {
request.append("1=0"); // append false for this stage
} else {
request.append(descriptor.getIdBinder().getBindIdInSql(null));
String inClause = idBinder.getIdInValueExpr(idCollection.size());
request.append(inClause);
}
}
@Override
public void addSql(SpiExpressionRequest request) {
DefaultExpressionRequest r = (DefaultExpressionRequest) request;
BeanDescriptor<?> descriptor = r.getBeanDescriptor();
IdBinder idBinder = descriptor.getIdBinder();
if (idCollection.size() == 0) {
request.append("1=0"); // append false for this stage
} else {
request.append(descriptor.getIdBinderInLHSSql());
String inClause = idBinder.getIdInValueExpr(idCollection.size());
request.append(inClause);
}
}
/**
* Incorporates the number of Id values to bind.
*/
@Override
public void queryPlanHash(HashQueryPlanBuilder builder) {
builder.add(IdInExpression.class).add(idCollection.size());
builder.bind(idCollection.size());
}
@Override
public int queryBindHash() {
return idCollection.hashCode();
}
@Override
public boolean isSameByPlan(SpiExpression other) {
if (!(other instanceof IdInExpression)) {
return false;
}
IdInExpression that = (IdInExpression) other;
return this.idCollection.size() == that.idCollection.size();
}
@Override
public boolean isSameByBind(SpiExpression other) {
IdInExpression that = (IdInExpression) other;
if (this.idCollection.size() != that.idCollection.size()) {
return false;
}
Iterator<?> it = that.idCollection.iterator();
for (Object id1 : idCollection) {
Object id2 = it.next();
if (!id1.equals(id2)) {
return false;
}
}
return true;
}
}