mirror of
https://github.com/querydsl/querydsl.git
synced 2026-07-03 21:07:49 +08:00
Merge pull request #1203 from querydsl/i1198
Transform containsKey and containsValue via JPAMapAccessVisitor
This commit is contained in:
commit
bf1c36e7cb
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2015, Timo Westkämper
|
||||
*
|
||||
* 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.querydsl.core.types;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public class ParameterizedPathImpl<T> extends PathImpl<T> implements ParameterizedExpression<T> {
|
||||
|
||||
private static final long serialVersionUID = -498707460985111265L;
|
||||
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
public ParameterizedPathImpl(Class<? extends T> type, PathMetadata metadata, Class<?>... parameterTypes) {
|
||||
super(type, metadata);
|
||||
this.parameterTypes = parameterTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getParameter(int index) {
|
||||
return parameterTypes[index];
|
||||
}
|
||||
|
||||
}
|
||||
@ -18,11 +18,7 @@ import java.util.Collection;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.querydsl.core.types.Path;
|
||||
import com.querydsl.core.types.PathImpl;
|
||||
import com.querydsl.core.types.PathMetadata;
|
||||
import com.querydsl.core.types.PathMetadataFactory;
|
||||
import com.querydsl.core.types.Visitor;
|
||||
import com.querydsl.core.types.*;
|
||||
import com.querydsl.core.types.expr.SimpleExpression;
|
||||
|
||||
/**
|
||||
@ -60,7 +56,7 @@ public class CollectionPath<E, Q extends SimpleExpression<? super E>> extends Co
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public CollectionPath(Class<? super E> type, Class<Q> queryType, PathMetadata metadata, PathInits inits) {
|
||||
super(new PathImpl<Collection<E>>((Class)Collection.class, metadata), inits);
|
||||
super(new ParameterizedPathImpl<Collection<E>>((Class)Collection.class, metadata, type), inits);
|
||||
this.elementType = (Class<E>)type;
|
||||
this.queryType = queryType;
|
||||
this.pathMixin = (PathImpl<Collection<E>>)mixin;
|
||||
|
||||
@ -20,12 +20,7 @@ import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.querydsl.core.types.Expression;
|
||||
import com.querydsl.core.types.Path;
|
||||
import com.querydsl.core.types.PathImpl;
|
||||
import com.querydsl.core.types.PathMetadata;
|
||||
import com.querydsl.core.types.PathMetadataFactory;
|
||||
import com.querydsl.core.types.Visitor;
|
||||
import com.querydsl.core.types.*;
|
||||
import com.querydsl.core.types.expr.ListExpression;
|
||||
import com.querydsl.core.types.expr.SimpleExpression;
|
||||
|
||||
@ -66,7 +61,7 @@ public class ListPath<E, Q extends SimpleExpression<? super E>> extends Collecti
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ListPath(Class<? super E> elementType, Class<Q> queryType, PathMetadata metadata, PathInits inits) {
|
||||
super(new PathImpl<List<E>>((Class)List.class, metadata), inits);
|
||||
super(new ParameterizedPathImpl<List<E>>((Class)List.class, metadata, elementType), inits);
|
||||
this.elementType = (Class<E>)elementType;
|
||||
this.queryType = queryType;
|
||||
this.pathMixin = (PathImpl<List<E>>)mixin;
|
||||
|
||||
@ -20,13 +20,7 @@ import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.querydsl.core.types.Expression;
|
||||
import com.querydsl.core.types.ExpressionException;
|
||||
import com.querydsl.core.types.Path;
|
||||
import com.querydsl.core.types.PathImpl;
|
||||
import com.querydsl.core.types.PathMetadata;
|
||||
import com.querydsl.core.types.PathMetadataFactory;
|
||||
import com.querydsl.core.types.Visitor;
|
||||
import com.querydsl.core.types.*;
|
||||
import com.querydsl.core.types.expr.MapExpressionBase;
|
||||
import com.querydsl.core.types.expr.SimpleExpression;
|
||||
|
||||
@ -63,7 +57,7 @@ public class MapPath<K, V, E extends SimpleExpression<? super V>> extends MapExp
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public MapPath(Class<? super K> keyType, Class<? super V> valueType, Class<E> queryType, PathMetadata metadata) {
|
||||
super(new PathImpl<Map<K,V>>((Class)Map.class, metadata));
|
||||
super(new ParameterizedPathImpl<Map<K,V>>((Class)Map.class, metadata, keyType, valueType));
|
||||
this.keyType = (Class<K>) keyType;
|
||||
this.valueType = (Class<V>) valueType;
|
||||
this.queryType = queryType;
|
||||
|
||||
@ -18,11 +18,7 @@ import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.querydsl.core.types.Path;
|
||||
import com.querydsl.core.types.PathImpl;
|
||||
import com.querydsl.core.types.PathMetadata;
|
||||
import com.querydsl.core.types.PathMetadataFactory;
|
||||
import com.querydsl.core.types.Visitor;
|
||||
import com.querydsl.core.types.*;
|
||||
import com.querydsl.core.types.expr.SimpleExpression;
|
||||
|
||||
/**
|
||||
@ -60,7 +56,7 @@ public class SetPath<E, Q extends SimpleExpression<? super E>> extends Collectio
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public SetPath(Class<? super E> type, Class<Q> queryType, PathMetadata metadata, PathInits inits) {
|
||||
super(new PathImpl<Set<E>>((Class)Set.class, metadata), inits);
|
||||
super(new ParameterizedPathImpl<Set<E>>((Class)Set.class, metadata, type), inits);
|
||||
this.elementType = (Class<E>)type;
|
||||
this.queryType = queryType;
|
||||
this.pathMixin = (PathImpl<Set<E>>)mixin;
|
||||
|
||||
@ -23,7 +23,6 @@ import java.util.Map;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.querydsl.core.types.Operator;
|
||||
import com.querydsl.core.types.Ops;
|
||||
import com.querydsl.core.types.PathType;
|
||||
|
||||
/**
|
||||
* HQLTemplates extends JPQLTemplates with Hibernate specific extensions
|
||||
@ -75,23 +74,6 @@ public class HQLTemplates extends JPQLTemplates {
|
||||
builder.put(BigDecimal.class, "big_decimal");
|
||||
typeNames = builder.build();
|
||||
|
||||
// TODO : remove this when Hibernate supports member of properly
|
||||
add(JPQLOps.MEMBER_OF, "{0} in elements({1})");
|
||||
add(JPQLOps.NOT_MEMBER_OF, "{0} not in elements({1})");
|
||||
|
||||
// path types
|
||||
for (PathType type : new PathType[] {
|
||||
PathType.LISTVALUE,
|
||||
PathType.MAPVALUE,
|
||||
PathType.MAPVALUE_CONSTANT }) {
|
||||
add(type, "{0}[{1}]");
|
||||
}
|
||||
add(PathType.LISTVALUE_CONSTANT, "{0}[{1s}]");
|
||||
add(PathType.COLLECTION_ANY, "any elements({0})");
|
||||
|
||||
add(Ops.CONTAINS_KEY, "{1} in indices({0})");
|
||||
add(Ops.CONTAINS_VALUE, "{1} in elements({0})");
|
||||
|
||||
// add Hibernate Spatial mappings, if on classpath
|
||||
try {
|
||||
Class cl = Class.forName("com.querydsl.spatial.hibernate.HibernateSpatialSupport");
|
||||
|
||||
@ -21,6 +21,28 @@ class JPAMapAccessVisitor extends ReplaceVisitor<Void> {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression<?> visit(Operation<?> expr, @Nullable Void context) {
|
||||
if (expr.getOperator() == Ops.CONTAINS_KEY) {
|
||||
ParameterizedExpression map = (ParameterizedExpression<?>) expr.getArg(0);
|
||||
Expression key = expr.getArg(1);
|
||||
Path replacement = new PathImpl<Object>(map.getParameter(1),
|
||||
ExpressionUtils.createRootVariable((Path<?>)map));
|
||||
metadata.addJoin(JoinType.LEFTJOIN, ExpressionUtils.as(map, replacement));
|
||||
metadata.addJoinCondition(ExpressionUtils.eq(
|
||||
Expressions.operation(map.getParameter(0), JPQLOps.KEY, replacement),
|
||||
key));
|
||||
return ExpressionUtils.isNotNull(replacement);
|
||||
} else if (expr.getOperator() == Ops.CONTAINS_VALUE) {
|
||||
ParameterizedExpression<?> map = (ParameterizedExpression<?>) expr.getArg(0);
|
||||
Expression<?> value = expr.getArg(1);
|
||||
return Expressions.predicate(JPQLOps.MEMBER_OF, value, map);
|
||||
} else {
|
||||
return super.visit(expr, context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression<?> visit(Path<?> expr, @Nullable Void context) {
|
||||
expr = (Path<?>) super.visit(expr, null);
|
||||
PathMetadata pathMetadata = expr.getMetadata();
|
||||
@ -33,7 +55,7 @@ class JPAMapAccessVisitor extends ReplaceVisitor<Void> {
|
||||
ParameterizedExpression parExpr = (ParameterizedExpression) parent;
|
||||
replacement = new PathImpl(parExpr.getParameter(1),
|
||||
ExpressionUtils.createRootVariable(parent));
|
||||
metadata.addJoin(JoinType.JOIN, ExpressionUtils.as(parent, replacement));
|
||||
metadata.addJoin(JoinType.LEFTJOIN, ExpressionUtils.as(parent, replacement));
|
||||
metadata.addJoinCondition(ExpressionUtils.eq(
|
||||
Expressions.operation(parExpr.getParameter(0), JPQLOps.KEY, replacement),
|
||||
ExpressionUtils.toExpression(pathMetadata.getElement())));
|
||||
|
||||
@ -907,42 +907,36 @@ public abstract class AbstractJPATest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@NoEclipseLink @NoOpenJPA @NoBatooJPA
|
||||
public void Map_ContainsKey() {
|
||||
QShow show = QShow.show;
|
||||
assertEquals(1l, query().from(show).where(show.acts.containsKey("a")).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
@NoEclipseLink @NoOpenJPA @NoBatooJPA
|
||||
public void Map_ContainsKey2() {
|
||||
QShow show = QShow.show;
|
||||
assertEquals(1l, query().from(show).where(show.acts.containsKey("b")).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
@NoEclipseLink @NoOpenJPA @NoBatooJPA
|
||||
public void Map_ContainsKey3() {
|
||||
QShow show = QShow.show;
|
||||
assertEquals(0l, query().from(show).where(show.acts.containsKey("c")).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
@NoEclipseLink @NoOpenJPA @NoBatooJPA
|
||||
public void Map_ContainsValue() {
|
||||
QShow show = QShow.show;
|
||||
assertEquals(1l, query().from(show).where(show.acts.containsValue("A")).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
@NoEclipseLink @NoOpenJPA @NoBatooJPA
|
||||
public void Map_ContainsValue2() {
|
||||
QShow show = QShow.show;
|
||||
assertEquals(1l, query().from(show).where(show.acts.containsValue("B")).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
@NoEclipseLink @NoOpenJPA @NoBatooJPA
|
||||
public void Map_ContainsValue3() {
|
||||
QShow show = QShow.show;
|
||||
assertEquals(0l, query().from(show).where(show.acts.containsValue("C")).count());
|
||||
|
||||
@ -21,39 +21,22 @@ public class CollectionTest extends AbstractQueryTest{
|
||||
|
||||
@Test
|
||||
public void Constant_InElements_Set() {
|
||||
assertToString("?1 in elements(cat.kittensSet)", cat.kittensSet.contains(new Cat()));
|
||||
assertToString("?1 member of cat.kittensSet", cat.kittensSet.contains(new Cat()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Constant_InElements_List() {
|
||||
assertToString("?1 in elements(cat.kittens)", cat.kittens.contains(new Cat()));
|
||||
assertToString("?1 member of cat.kittens", cat.kittens.contains(new Cat()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Path_InElements_List() {
|
||||
assertToString("cat in elements(cat1.kittens)", cat.in(cat1.kittens));
|
||||
assertToString("cat member of cat1.kittens", cat.in(cat1.kittens));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Path_InElements_Set() {
|
||||
assertToString("cat in elements(cat1.kittensSet)", cat.in(cat1.kittensSet));
|
||||
assertToString("cat member of cat1.kittensSet", cat.in(cat1.kittensSet));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void CollectionOperations() {
|
||||
// HQL functions that take collection-valued path expressions: size(),
|
||||
// minelement(), maxelement(), minindex(), maxindex(), along with the
|
||||
// special elements() and indices functions which may be quantified
|
||||
// using some, all, exists, any, in.
|
||||
cat.kittens.size();
|
||||
// minelement(cat.kittens);
|
||||
// maxelement(cat.kittens);
|
||||
// minindex(cat.kittens);
|
||||
// maxindex(cat.kittens);
|
||||
assertToString("cat.kittens[0]", cat.kittens(0));
|
||||
assertToString("cat.kittens[0]", cat.kittens.get(0));
|
||||
|
||||
// some, all, exists, any, in.
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ public class FeaturesTest extends AbstractQueryTest {
|
||||
|
||||
// toString("cat.bodyWeight as bw", cat.bodyWeight.as("bw"));
|
||||
|
||||
assertToString("kitten in elements(cat.kittens)", kitten.in(cat.kittens));
|
||||
assertToString("kitten member of cat.kittens", kitten.in(cat.kittens));
|
||||
|
||||
// toString("distinct cat.bodyWeight", distinct(cat.bodyWeight));
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ public class JPQLSerializerTest {
|
||||
serializer.serializeForDelete(md);
|
||||
assertEquals("delete from Cat kitten\n" +
|
||||
"where kitten.id = ?1 and exists (select 1\n" +
|
||||
"from Cat cat\nwhere cat.id = ?2 and kitten in elements(cat.kittens))", serializer.toString());
|
||||
"from Cat cat\nwhere cat.id = ?2 and kitten member of cat.kittens)", serializer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011, Mysema Ltd
|
||||
*
|
||||
* 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.querydsl.jpa;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.querydsl.jpa.domain.QShow;
|
||||
|
||||
public class MapTest extends AbstractQueryTest {
|
||||
|
||||
private QShow show = QShow.show;
|
||||
|
||||
@Test
|
||||
public void Contains() {
|
||||
assertToString("show.acts[?1] = ?2", show.acts.contains("x", "y"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Contains_Key() {
|
||||
assertToString("?1 in indices(show.acts)", show.acts.containsKey("x"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Contains_Value() {
|
||||
assertToString("?1 in elements(show.acts)", show.acts.containsValue("y"));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user