mirror of
https://github.com/querydsl/querydsl.git
synced 2026-07-03 21:07:49 +08:00
#667362 : worked on Collection.any() support
This commit is contained in:
parent
80d96fcdc1
commit
3103dfc715
@ -16,7 +16,6 @@ import com.mysema.query.QueryException;
|
||||
import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.SearchResults;
|
||||
import com.mysema.query.support.ProjectableQuery;
|
||||
import com.mysema.query.support.QueryMixin;
|
||||
import com.mysema.query.types.ArrayConstructorExpression;
|
||||
import com.mysema.query.types.CollectionExpression;
|
||||
import com.mysema.query.types.Expression;
|
||||
@ -48,7 +47,7 @@ public abstract class AbstractColQuery<Q extends AbstractColQuery<Q>> extends P
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public AbstractColQuery(QueryMetadata metadata, QueryEngine queryEngine) {
|
||||
super(new QueryMixin<Q>(metadata));
|
||||
super(new ColQueryMixin<Q>(metadata));
|
||||
this.queryMixin.setSelf((Q) this);
|
||||
this.queryEngine = queryEngine;
|
||||
}
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Mysema Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
package com.mysema.query.collections;
|
||||
|
||||
import com.mysema.query.BooleanBuilder;
|
||||
import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.support.CollectionAnyVisitor;
|
||||
import com.mysema.query.support.QueryMixin;
|
||||
import com.mysema.query.types.CollectionExpression;
|
||||
import com.mysema.query.types.Path;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.types.template.BooleanTemplate;
|
||||
|
||||
/**
|
||||
* ColQueryMixin extends QueryMixin
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public class ColQueryMixin<T> extends QueryMixin<T> {
|
||||
|
||||
public ColQueryMixin() {}
|
||||
|
||||
public ColQueryMixin(QueryMetadata metadata) {
|
||||
super(metadata);
|
||||
}
|
||||
|
||||
public ColQueryMixin(T self, QueryMetadata metadata) {
|
||||
super(self, metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Predicate[] normalize(Predicate[] conditions, boolean where) {
|
||||
for (int i = 0; i < conditions.length; i++){
|
||||
conditions[i] = normalize(conditions[i], where);
|
||||
}
|
||||
return conditions;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Predicate normalize(Predicate predicate, boolean where) {
|
||||
if (predicate instanceof BooleanBuilder && ((BooleanBuilder)predicate).getValue() == null){
|
||||
return predicate;
|
||||
}else{
|
||||
CollectionAnyVisitor.Context context = new CollectionAnyVisitor.Context();
|
||||
Predicate transformed = (Predicate) predicate.accept(CollectionAnyVisitor.DEFAULT, context);
|
||||
for (int i = 0; i < context.anyPaths.size(); i++){
|
||||
innerJoin(
|
||||
(CollectionExpression)context.anyPaths.get(i).getMetadata().getParent(),
|
||||
(Path)context.replacements.get(i));
|
||||
on(BooleanTemplate.create("any"));
|
||||
}
|
||||
return transformed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,6 +63,7 @@ public final class ColQueryTemplates extends JavaTemplates {
|
||||
add(PathType.LISTVALUE_CONSTANT, "{0}.get({1})");
|
||||
add(PathType.ARRAYVALUE, "{0}[{1}]");
|
||||
add(PathType.ARRAYVALUE_CONSTANT, "{0}[{1}]");
|
||||
add(PathType.COLLECTION_ANY, "{0}_any");
|
||||
|
||||
// coalesce
|
||||
add(Ops.COALESCE, functions + ".coalesce({0})");
|
||||
|
||||
@ -34,7 +34,10 @@ import com.mysema.query.types.FactoryExpression;
|
||||
import com.mysema.query.types.Operation;
|
||||
import com.mysema.query.types.ParamExpression;
|
||||
import com.mysema.query.types.ParamNotSetException;
|
||||
import com.mysema.query.types.PathType;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.types.Templates;
|
||||
import com.mysema.query.types.ToStringVisitor;
|
||||
|
||||
/**
|
||||
* DefaultEvaluatorFactory extends the EvaluatorFactory class to provide Java source
|
||||
@ -52,7 +55,7 @@ public class DefaultEvaluatorFactory {
|
||||
|
||||
public DefaultEvaluatorFactory(ColQueryTemplates templates){
|
||||
// TODO : which ClassLoader to pick ?!?
|
||||
this(templates,
|
||||
this(templates,
|
||||
(URLClassLoader)DefaultEvaluatorFactory.class.getClassLoader(),
|
||||
ToolProvider.getSystemJavaCompiler());
|
||||
}
|
||||
@ -148,6 +151,8 @@ public class DefaultEvaluatorFactory {
|
||||
StringBuilder vars = new StringBuilder();
|
||||
ColQuerySerializer ser = new ColQuerySerializer(templates);
|
||||
ser.append("java.util.List<Object[]> rv = new java.util.ArrayList<Object[]>();\n");
|
||||
|
||||
List<String> anyJoinMatchers = new ArrayList<String>();
|
||||
|
||||
// creating context
|
||||
for (JoinExpression join : joins){
|
||||
@ -164,8 +169,12 @@ public class DefaultEvaluatorFactory {
|
||||
sourceClasses.add(Iterable.class);
|
||||
|
||||
}else if (join.getType() == JoinType.INNERJOIN){
|
||||
Operation alias = (Operation)join.getTarget();
|
||||
// TODO : handle join condition
|
||||
Operation alias = (Operation)join.getTarget();
|
||||
if (join.getCondition() != null && join.getCondition().toString().equals("any")){
|
||||
String matcher = alias.getArg(1).toString() + "_matched";
|
||||
ser.append("boolean " + matcher + " = false;\n");
|
||||
anyJoinMatchers.add(matcher);
|
||||
}
|
||||
ser.append("for ( " + typeName + " " + alias.getArg(1) + " : ");
|
||||
ser.handle(alias.getArg(0));
|
||||
if (alias.getArg(0).getType().equals(Map.class)){
|
||||
@ -174,9 +183,6 @@ public class DefaultEvaluatorFactory {
|
||||
ser.append("){\n");
|
||||
vars.append(alias.getArg(1));
|
||||
|
||||
// }else if (join.getType() == JoinType.LEFTJOIN){
|
||||
// // TODO
|
||||
//
|
||||
}else{
|
||||
throw new IllegalArgumentException("Illegal join expression " + join);
|
||||
}
|
||||
@ -184,7 +190,14 @@ public class DefaultEvaluatorFactory {
|
||||
|
||||
// filter
|
||||
if (filter != null){
|
||||
ser.append("if (").handle(filter).append("){\n");
|
||||
ser.append("if (");
|
||||
for (String matcher : anyJoinMatchers){
|
||||
ser.append("!" + matcher + " && ");
|
||||
}
|
||||
ser.handle(filter).append("){\n");
|
||||
for (String matcher : anyJoinMatchers){
|
||||
ser.append(" "+ matcher + " = true;\n");
|
||||
}
|
||||
ser.append(" rv.add(new Object[]{"+vars+"});\n");
|
||||
ser.append("}\n");
|
||||
}else{
|
||||
|
||||
@ -92,7 +92,8 @@ public class ColQueryStandardTest {
|
||||
|
||||
@Test
|
||||
public void TupleProjection(){
|
||||
List<Tuple> tuples = MiniApi.from(cat, data).list(new QTuple(cat.name, cat.birthdate));
|
||||
List<Tuple> tuples = MiniApi.from(cat, data)
|
||||
.list(new QTuple(cat.name, cat.birthdate));
|
||||
for (Tuple tuple : tuples){
|
||||
assertNotNull(tuple.get(cat.name));
|
||||
assertNotNull(tuple.get(cat.birthdate));
|
||||
@ -102,7 +103,8 @@ public class ColQueryStandardTest {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void ArrayProjection(){
|
||||
List<String[]> results = MiniApi.from(cat, data).list(new ArrayConstructorExpression<String>(String[].class, cat.name));
|
||||
List<String[]> results = MiniApi.from(cat, data)
|
||||
.list(new ArrayConstructorExpression<String>(String[].class, cat.name));
|
||||
assertFalse(results.isEmpty());
|
||||
for (String[] result : results){
|
||||
assertNotNull(result[0]);
|
||||
@ -111,7 +113,8 @@ public class ColQueryStandardTest {
|
||||
|
||||
@Test
|
||||
public void ConstructorProjection(){
|
||||
List<Projection> projections = MiniApi.from(cat, data).list(ConstructorExpression.create(Projection.class, cat.name, cat));
|
||||
List<Projection> projections = MiniApi.from(cat, data)
|
||||
.list(ConstructorExpression.create(Projection.class, cat.name, cat));
|
||||
assertFalse(projections.isEmpty());
|
||||
for (Projection projection : projections){
|
||||
assertNotNull(projection);
|
||||
|
||||
@ -52,6 +52,11 @@ public class Cat extends Animal {
|
||||
this.kittensByName = Collections.singletonMap("Kitty", kitten);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Cat(String name, String kittenName){
|
||||
this(name);
|
||||
kittens.get(0).setName(kittenName);
|
||||
}
|
||||
|
||||
@QueryProjection
|
||||
public Cat(String name, int id) {
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
package com.mysema.query.collections;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CollectionTest {
|
||||
|
||||
private final QCat cat = new QCat("cat");
|
||||
|
||||
private final QCat other = new QCat("other");
|
||||
|
||||
private List<Cat> cats;
|
||||
|
||||
@Before
|
||||
public void setUp(){
|
||||
Cat cat1 = new Cat("1");
|
||||
cat1.setKittens(Arrays.asList(cat1));
|
||||
Cat cat2 = new Cat("2");
|
||||
cat2.setKittens(Arrays.asList(cat1, cat2));
|
||||
Cat cat3 = new Cat("3");
|
||||
cat3.setKittens(Arrays.asList(cat1, cat2, cat3));
|
||||
Cat cat4 = new Cat("4");
|
||||
cat4.setKittens(Arrays.asList(cat1, cat2, cat3, cat4));
|
||||
|
||||
cats = Arrays.asList(cat1, cat2, cat3, cat4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Join(){
|
||||
assertEquals("4", MiniApi.from(cat, cats).innerJoin(cat.kittens, other).where(other.name.eq("4")).uniqueResult(cat.name));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Any(){
|
||||
assertEquals("4", MiniApi.from(cat, cats).where(cat.kittens.any().name.eq("4")).uniqueResult(cat.name));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Any2(){
|
||||
assertEquals(4, MiniApi.from(cat, cats).where(cat.kittens.any().name.isNotNull()).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void Any3(){
|
||||
// TODO : support multiple levels of any usage
|
||||
assertEquals(4, MiniApi.from(cat, cats).where(cat.kittens.any().name.isNotNull(), cat.kittens.any().kittens.any().isNotNull()).count());
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user