mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-13 21:01:01 +08:00
#676458 : added support for Projectable.exists() and notExists()
This commit is contained in:
parent
145fbaccc7
commit
767561fa22
@ -63,14 +63,23 @@ public abstract class AbstractColQuery<Q extends AbstractColQuery<Q>> extends P
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <D> Expression<D> createAlias(CollectionExpression<?,D> target, Path<D> alias){
|
||||
return OperationImpl.create((Class<D>)alias.getType(), Ops.ALIAS, target, alias);
|
||||
@Override
|
||||
public boolean exists(){
|
||||
try {
|
||||
return queryEngine.exists(getMetadata(), iterables);
|
||||
} catch (Exception e) {
|
||||
throw new QueryException(e.getMessage(), e);
|
||||
}finally{
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
private <D> Expression<D> createAlias(CollectionExpression<?,D> target, Path<D> alias){
|
||||
return OperationImpl.create(alias.getType(), Ops.ALIAS, target, alias);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <D> Expression<D> createAlias(MapExpression<?,D> target, Path<D> alias){
|
||||
return OperationImpl.create((Class<D>)alias.getType(), Ops.ALIAS, target, alias);
|
||||
return OperationImpl.create(alias.getType(), Ops.ALIAS, target, alias);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@ -20,6 +20,7 @@ import com.mysema.commons.lang.IteratorAdapter;
|
||||
import com.mysema.query.JoinExpression;
|
||||
import com.mysema.query.JoinType;
|
||||
import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.QueryModifiers;
|
||||
import com.mysema.query.types.ArrayConstructorExpression;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.Operation;
|
||||
@ -51,6 +52,21 @@ public class DefaultQueryEngine implements QueryEngine {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(QueryMetadata metadata, Map<Expression<?>, Iterable<?>> iterables) {
|
||||
QueryModifiers modifiers = metadata.getModifiers();
|
||||
metadata.setLimit(1l);
|
||||
try{
|
||||
if (metadata.getJoins().size() == 1){
|
||||
return !evaluateSingleSource(metadata, iterables, true).isEmpty();
|
||||
}else{
|
||||
return !evaluateMultipleSources(metadata, iterables, true).isEmpty();
|
||||
}
|
||||
}finally{
|
||||
metadata.setModifiers(modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> list(QueryMetadata metadata, Map<Expression<?>, Iterable<?>> iterables, Expression<T> projection){
|
||||
if (metadata.getJoins().size() == 1){
|
||||
@ -70,7 +86,7 @@ public class DefaultQueryEngine implements QueryEngine {
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}else{
|
||||
}else{
|
||||
for (T o : list){
|
||||
if (!rv.contains(o)){
|
||||
rv.add(o);
|
||||
@ -183,7 +199,6 @@ public class DefaultQueryEngine implements QueryEngine {
|
||||
}
|
||||
Expression<?> expr = new ArrayConstructorExpression<Object>(Object[].class, orderByExpr);
|
||||
Evaluator orderEvaluator = evaluatorFactory.create(metadata, sources, expr);
|
||||
|
||||
Collections.sort(list, new MultiComparator(orderEvaluator, directions));
|
||||
}
|
||||
|
||||
@ -194,4 +209,6 @@ public class DefaultQueryEngine implements QueryEngine {
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -42,4 +42,11 @@ public interface QueryEngine {
|
||||
*/
|
||||
<T> List<T> list(QueryMetadata metadata, Map<Expression<?>, Iterable<?>> iterables, Expression<T> projection);
|
||||
|
||||
/**
|
||||
* @param metadata
|
||||
* @param iterables
|
||||
* @return
|
||||
*/
|
||||
boolean exists(QueryMetadata metadata, Map<Expression<?>, Iterable<?>> iterables);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
package com.mysema.query.collections;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ExistsTest extends AbstractQueryTest{
|
||||
|
||||
@Test
|
||||
public void Exists(){
|
||||
assertTrue(query().from(cat, cats).where(cat.name.eq("Bob")).exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NotExists(){
|
||||
assertTrue(query().from(cat, cats).where(cat.name.eq("Bobby")).notExists());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -35,6 +35,16 @@ public interface Projectable {
|
||||
@Nonnegative
|
||||
long countDistinct();
|
||||
|
||||
/**
|
||||
* @return true, if rows matching the given criteria exist, otherwise false
|
||||
*/
|
||||
boolean exists();
|
||||
|
||||
/**
|
||||
* @return true, if no rows matching the given criteria exist, otherwise false
|
||||
*/
|
||||
boolean notExists();
|
||||
|
||||
/**
|
||||
* iterate over the results for the given projection
|
||||
*
|
||||
|
||||
@ -42,6 +42,16 @@ public class ProjectableAdapter<P extends Projectable> implements Projectable {
|
||||
return projectable.countDistinct();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return projectable.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean notExists() {
|
||||
return projectable.notExists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloseableIterator<Object[]> iterate(Expression<?> first, Expression<?> second, Expression<?>... rest) {
|
||||
return projectable.iterate(first, second, rest);
|
||||
@ -117,6 +127,7 @@ public class ProjectableAdapter<P extends Projectable> implements Projectable {
|
||||
return projectable.map(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return projectable.toString();
|
||||
}
|
||||
|
||||
@ -37,6 +37,11 @@ public abstract class ProjectableQuery<Q extends ProjectableQuery<Q>>
|
||||
return count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean notExists(){
|
||||
return !exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final CloseableIterator<Object[]> iterate(Expression<?> first, Expression<?> second, Expression<?>... rest) {
|
||||
return iterate(merge(first, second, rest));
|
||||
|
||||
@ -36,4 +36,14 @@ public class DummyProjectable extends ProjectableQuery<DummyProjectable>{
|
||||
return SearchResults.emptyResults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean notExists() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -44,14 +44,14 @@ import com.mysema.query.types.QTuple;
|
||||
public abstract class AbstractJDOQLQuery<Q extends AbstractJDOQLQuery<Q>> extends ProjectableQuery<Q>{
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JDOQLQueryImpl.class);
|
||||
|
||||
|
||||
private final Closeable closeable = new Closeable(){
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
AbstractJDOQLQuery.this.close();
|
||||
}
|
||||
AbstractJDOQLQuery.this.close();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private final boolean detach;
|
||||
|
||||
private List<Object> orderedConstants = new ArrayList<Object>();
|
||||
@ -59,12 +59,12 @@ public abstract class AbstractJDOQLQuery<Q extends AbstractJDOQLQuery<Q>> extend
|
||||
@Nullable
|
||||
private final PersistenceManager persistenceManager;
|
||||
|
||||
private List<Query> queries = new ArrayList<Query>(2);
|
||||
private final List<Query> queries = new ArrayList<Query>(2);
|
||||
|
||||
private final JDOQLTemplates templates;
|
||||
|
||||
private Set<String> fetchGroups = new HashSet<String>();
|
||||
|
||||
|
||||
private final Set<String> fetchGroups = new HashSet<String>();
|
||||
|
||||
@Nullable
|
||||
private Integer maxFetchDepth;
|
||||
|
||||
@ -96,6 +96,7 @@ public abstract class AbstractJDOQLQuery<Q extends AbstractJDOQLQuery<Q>> extend
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
Query query = createQuery(true);
|
||||
query.setUnique(true);
|
||||
@ -108,15 +109,26 @@ public abstract class AbstractJDOQLQuery<Q extends AbstractJDOQLQuery<Q>> extend
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(){
|
||||
boolean rv = limit(1).uniqueResult(getSource()) != null;
|
||||
close();
|
||||
return rv;
|
||||
}
|
||||
|
||||
private Expression<?> getSource(){
|
||||
return queryMixin.getMetadata().getJoins().get(0).getTarget();
|
||||
}
|
||||
|
||||
private Query createQuery(boolean forCount) {
|
||||
Expression<?> source = queryMixin.getMetadata().getJoins().get(0).getTarget();
|
||||
Expression<?> source = getSource();
|
||||
|
||||
// serialize
|
||||
JDOQLSerializer serializer = new JDOQLSerializer(getTemplates(), source);
|
||||
serializer.serialize(queryMixin.getMetadata(), forCount, false);
|
||||
|
||||
logQuery(serializer.toString());
|
||||
|
||||
|
||||
// create Query
|
||||
Query query = persistenceManager.newQuery(serializer.toString());
|
||||
orderedConstants = serializer.getConstants();
|
||||
@ -130,7 +142,7 @@ public abstract class AbstractJDOQLQuery<Q extends AbstractJDOQLQuery<Q>> extend
|
||||
} else if (FactoryExpression.class.isAssignableFrom(exprType)){
|
||||
query.setResultClass(projection.get(0).getType());
|
||||
}
|
||||
|
||||
|
||||
if (!fetchGroups.isEmpty()){
|
||||
query.getFetchPlan().setGroups(fetchGroups);
|
||||
}
|
||||
@ -141,7 +153,7 @@ public abstract class AbstractJDOQLQuery<Q extends AbstractJDOQLQuery<Q>> extend
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
protected void logQuery(String queryString){
|
||||
if (logger.isDebugEnabled()){
|
||||
logger.debug(queryString.replace('\n', ' '));
|
||||
@ -194,6 +206,7 @@ public abstract class AbstractJDOQLQuery<Q extends AbstractJDOQLQuery<Q>> extend
|
||||
return new IteratorAdapter<RT>(list(projection).iterator(), closeable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Object[]> list(Expression<?>[] args) {
|
||||
queryMixin.addToProjection(args);
|
||||
@ -202,6 +215,7 @@ public abstract class AbstractJDOQLQuery<Q extends AbstractJDOQLQuery<Q>> extend
|
||||
return (rv instanceof List) ? ((List<Object[]>)rv) : Collections.singletonList((Object[])rv);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <RT> List<RT> list(Expression<RT> expr) {
|
||||
queryMixin.addToProjection(expr);
|
||||
@ -237,12 +251,11 @@ public abstract class AbstractJDOQLQuery<Q extends AbstractJDOQLQuery<Q>> extend
|
||||
maxFetchDepth = depth;
|
||||
return (Q)this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
if (!queryMixin.getMetadata().getJoins().isEmpty()){
|
||||
Expression<?> source = queryMixin.getMetadata().getJoins().get(0).getTarget();
|
||||
Expression<?> source = getSource();
|
||||
JDOQLSerializer serializer = new JDOQLSerializer(getTemplates(), source);
|
||||
serializer.serialize(queryMixin.getMetadata(), false, false);
|
||||
return serializer.toString().trim();
|
||||
@ -251,6 +264,7 @@ public abstract class AbstractJDOQLQuery<Q extends AbstractJDOQLQuery<Q>> extend
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <RT> RT uniqueResult(Expression<RT> expr) {
|
||||
queryMixin.addToProjection(expr);
|
||||
|
||||
@ -15,12 +15,13 @@ import com.mysema.query.types.Ops;
|
||||
import com.mysema.query.types.Path;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.types.SubQueryExpression;
|
||||
import com.mysema.query.types.TemplateExpressionImpl;
|
||||
import com.mysema.query.types.expr.NumberExpression;
|
||||
import com.mysema.query.types.expr.NumberOperation;
|
||||
|
||||
/**
|
||||
* Base class for JDO based SQLQuery implementations
|
||||
*
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
* @param <T>
|
||||
@ -29,6 +30,8 @@ public abstract class AbstractSQLQuery<T extends AbstractSQLQuery<T>> extends Pr
|
||||
|
||||
private static final NumberExpression<Integer> COUNT_ALL_AGG_EXPR = NumberOperation.create(Integer.class, Ops.AggOps.COUNT_ALL_AGG);
|
||||
|
||||
private static final Expression<Integer> ONE = TemplateExpressionImpl.create(Integer.class, "1");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public AbstractSQLQuery(QueryMetadata metadata) {
|
||||
super(new QueryMixin<T>(metadata));
|
||||
@ -40,6 +43,11 @@ public abstract class AbstractSQLQuery<T extends AbstractSQLQuery<T>> extends Pr
|
||||
return uniqueResult(COUNT_ALL_AGG_EXPR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(){
|
||||
return limit(1).uniqueResult(ONE) != null;
|
||||
}
|
||||
|
||||
public T from(Expression<?>... args) {
|
||||
return queryMixin.from(args);
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ package com.mysema.query;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
@ -39,8 +40,7 @@ public class JDOQLQueryStandardTest extends AbstractJDOTest {
|
||||
|
||||
public static class Projection {
|
||||
|
||||
public Projection(String str) {
|
||||
}
|
||||
public Projection(String str) {}
|
||||
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ public class JDOQLQueryStandardTest extends AbstractJDOTest {
|
||||
}
|
||||
|
||||
private static String productName = "ABCD";
|
||||
|
||||
|
||||
private static String otherName = "ABC0";
|
||||
|
||||
@BeforeClass
|
||||
@ -97,7 +97,7 @@ public class JDOQLQueryStandardTest extends AbstractJDOTest {
|
||||
|
||||
}
|
||||
|
||||
private QueryExecution standardTest = new QueryExecution(Module.JDOQL, Target.H2){
|
||||
private final QueryExecution standardTest = new QueryExecution(Module.JDOQL, Target.H2){
|
||||
@Override
|
||||
protected Pair<Projectable, List<Expression<?>>> createQuery() {
|
||||
return Pair.of(
|
||||
@ -112,13 +112,13 @@ public class JDOQLQueryStandardTest extends AbstractJDOTest {
|
||||
}
|
||||
};
|
||||
|
||||
private QProduct product = QProduct.product;
|
||||
private final QProduct product = QProduct.product;
|
||||
|
||||
private QProduct otherProduct = new QProduct("otherProduct");
|
||||
private final QProduct otherProduct = new QProduct("otherProduct");
|
||||
|
||||
private QStore store = QStore.store;
|
||||
private final QStore store = QStore.store;
|
||||
|
||||
private QStore otherStore = new QStore("otherStore");
|
||||
private final QStore otherStore = new QStore("otherStore");
|
||||
|
||||
@Test
|
||||
public void StandardTest(){
|
||||
@ -194,4 +194,14 @@ public class JDOQLQueryStandardTest extends AbstractJDOTest {
|
||||
Param<String> name = new Param<String>(String.class,"name");
|
||||
assertEquals("ABC0",query().from(product).where(product.name.eq(name)).uniqueResult(product.name));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Exists(){
|
||||
assertTrue(query().from(product).where(product.name.eq("ABC0")).exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NotExists(){
|
||||
assertTrue(query().from(product).where(product.name.eq("XXX")).notExists());
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,10 +16,11 @@ import com.mysema.query.types.Ops;
|
||||
import com.mysema.query.types.Path;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.types.SubQueryExpression;
|
||||
import com.mysema.query.types.TemplateExpressionImpl;
|
||||
|
||||
/**
|
||||
* Abstract super class for SQLQuery implementation for JPA and Hibernate
|
||||
*
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
* @param <T>
|
||||
@ -28,6 +29,8 @@ public abstract class AbstractSQLQuery<T extends AbstractSQLQuery<T>> extends Pr
|
||||
|
||||
private static final Expression<Integer> COUNT_ALL_AGG_EXPR = OperationImpl.create(Integer.class, Ops.AggOps.COUNT_ALL_AGG);
|
||||
|
||||
private static final Expression<Integer> ONE = TemplateExpressionImpl.create(Integer.class, "1");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public AbstractSQLQuery(QueryMetadata metadata) {
|
||||
super(new QueryMixin<T>(metadata));
|
||||
@ -39,6 +42,11 @@ public abstract class AbstractSQLQuery<T extends AbstractSQLQuery<T>> extends Pr
|
||||
return uniqueResult(COUNT_ALL_AGG_EXPR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(){
|
||||
return limit(1).uniqueResult(ONE) != null;
|
||||
}
|
||||
|
||||
public T from(Expression<?>... args) {
|
||||
return queryMixin.from(args);
|
||||
}
|
||||
|
||||
@ -11,9 +11,11 @@ import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.support.ProjectableQuery;
|
||||
import com.mysema.query.types.CollectionExpression;
|
||||
import com.mysema.query.types.EntityPath;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.MapExpression;
|
||||
import com.mysema.query.types.Path;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.types.TemplateExpressionImpl;
|
||||
|
||||
/**
|
||||
* JPQLQueryBase is a base Query class for JPQL queries
|
||||
@ -23,6 +25,8 @@ import com.mysema.query.types.Predicate;
|
||||
*/
|
||||
public abstract class JPQLQueryBase<Q extends JPQLQueryBase<Q>> extends ProjectableQuery<Q> {
|
||||
|
||||
private static final Expression<Integer> ONE = TemplateExpressionImpl.create(Integer.class, "1");
|
||||
|
||||
private Map<Object,String> constants;
|
||||
|
||||
private final JPQLQueryMixin<Q> queryMixin;
|
||||
@ -59,6 +63,11 @@ public abstract class JPQLQueryBase<Q extends JPQLQueryBase<Q>> extends Projecta
|
||||
queryMixin.getMetadata().reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(){
|
||||
return limit(1).uniqueResult(ONE) != null;
|
||||
}
|
||||
|
||||
public Q fetch(){
|
||||
return queryMixin.fetch();
|
||||
}
|
||||
|
||||
@ -169,15 +169,16 @@ public final class JPASQLQuery extends AbstractSQLQuery<JPASQLQuery> implements
|
||||
return buildQueryString(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <RT> RT uniqueResult(Expression<RT> expr) {
|
||||
Query query = createQuery(expr);
|
||||
reset();
|
||||
try{
|
||||
return (RT) query.getSingleResult();
|
||||
return (RT) query.getSingleResult();
|
||||
}catch(NoResultException e){
|
||||
logger.debug(e.getMessage(),e);
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -53,15 +54,15 @@ public abstract class AbstractStandardTest {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class QProjection extends ConstructorExpression<Projection>{
|
||||
|
||||
|
||||
private static final long serialVersionUID = -5866362075090550839L;
|
||||
|
||||
public QProjection(StringExpression str, QCat cat){
|
||||
super(Projection.class, new Class[]{String.class, Cat.class}, new Expression[]{str, cat});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static final QCat cat = QCat.cat;
|
||||
@ -76,7 +77,8 @@ public abstract class AbstractStandardTest {
|
||||
|
||||
private final java.sql.Date date;
|
||||
|
||||
private Projections projections = new Projections(Module.HQL, getTarget()){
|
||||
private final Projections projections = new Projections(Module.HQL, getTarget()){
|
||||
@Override
|
||||
public <A> Collection<Expression<?>> list(ListPath<A,?> expr, ListExpression<A> other, A knownElement){
|
||||
// NOTE : expr.get(0) is only supported in the where clause
|
||||
return Collections.<Expression<?>>singleton(expr.size());
|
||||
@ -85,7 +87,7 @@ public abstract class AbstractStandardTest {
|
||||
|
||||
private final List<Cat> savedCats = new ArrayList<Cat>();
|
||||
|
||||
private QueryExecution standardTest = new QueryExecution(
|
||||
private final QueryExecution standardTest = new QueryExecution(
|
||||
projections, new Filters(projections, Module.HQL, getTarget()), new MatchingFilters(Module.HQL, getTarget())){
|
||||
|
||||
@Override
|
||||
@ -149,7 +151,7 @@ public abstract class AbstractStandardTest {
|
||||
cat.setBirthdate(birthDate);
|
||||
save(cat);
|
||||
savedCats.add(cat);
|
||||
|
||||
|
||||
Show show = new Show();
|
||||
show.acts = new HashMap<String,String>();
|
||||
show.acts.put("a","A");
|
||||
@ -188,13 +190,23 @@ public abstract class AbstractStandardTest {
|
||||
public void Any_Simple(){
|
||||
assertEquals(1, catQuery().where(cat.kittens.any().name.eq("Ruth123")).count());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Exists(){
|
||||
assertTrue(catQuery().where(cat.kittens.any().name.eq("Ruth123")).exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NotExists(){
|
||||
assertTrue(catQuery().where(cat.kittens.any().name.eq("XXX")).notExists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Any_And(){
|
||||
assertEquals(1, catQuery().where(cat.kittens.any().name.eq("Ruth123"), cat.kittens.any().bodyWeight.lt(10.0)).count());
|
||||
assertEquals(0, catQuery().where(cat.kittens.any().name.eq("Ruth123"), cat.kittens.any().bodyWeight.gt(10.0)).count());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Aggregates_UniqueResult(){
|
||||
// uniqueResult
|
||||
@ -208,7 +220,7 @@ public abstract class AbstractStandardTest {
|
||||
assertEquals(Integer.valueOf(1), catQuery().list(cat.id.min()).get(0));
|
||||
assertEquals(Integer.valueOf(6), catQuery().list(cat.id.max()).get(0));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void DistinctResults(){
|
||||
System.out.println("-- list results");
|
||||
@ -242,26 +254,26 @@ public abstract class AbstractStandardTest {
|
||||
assertEquals(0, catQuery().where(cat.name.endsWith("X")).count());
|
||||
assertEquals(1, catQuery().where(cat.name.endsWithIgnoreCase("H123")).count());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Contains(){
|
||||
// contains
|
||||
assertEquals(1, catQuery().where(cat.name.contains("eli")).count());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Length(){
|
||||
// length
|
||||
assertEquals(6, catQuery().where(cat.name.length().gt(0)).count());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void IndexOf(){
|
||||
// indexOf
|
||||
assertEquals(Integer.valueOf(0), catQuery().where(cat.name.eq("Bob123")).uniqueResult(cat.name.indexOf("B")));
|
||||
assertEquals(Integer.valueOf(1), catQuery().where(cat.name.eq("Bob123")).uniqueResult(cat.name.indexOf("o")));
|
||||
assertEquals(Integer.valueOf(1), catQuery().where(cat.name.eq("Bob123")).uniqueResult(cat.name.indexOf("o")));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void StringOperations(){
|
||||
// case-sensitivity
|
||||
@ -271,26 +283,26 @@ public abstract class AbstractStandardTest {
|
||||
assertEquals(Integer.valueOf(2), catQuery().where(cat.name.eq("Bob123")).uniqueResult(cat.name.indexOf("b")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Limit(){
|
||||
// limit
|
||||
List<String> names1 = Arrays.asList("Allen123","Bob123");
|
||||
assertEquals(names1, catQuery().orderBy(cat.name.asc()).limit(2).list(cat.name));
|
||||
assertEquals(names1, catQuery().orderBy(cat.name.asc()).limit(2).list(cat.name));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Offset(){
|
||||
// offset
|
||||
List<String> names2 = Arrays.asList("Felix123","Mary123","Ruth123","Some");
|
||||
assertEquals(names2, catQuery().orderBy(cat.name.asc()).offset(2).list(cat.name));
|
||||
assertEquals(names2, catQuery().orderBy(cat.name.asc()).offset(2).list(cat.name));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Limit_and_offset(){
|
||||
// limit + offset
|
||||
List<String> names3 = Arrays.asList("Felix123","Mary123");
|
||||
assertEquals(names3, catQuery().orderBy(cat.name.asc()).limit(2).offset(2).list(cat.name));
|
||||
assertEquals(names3, catQuery().orderBy(cat.name.asc()).limit(2).offset(2).list(cat.name));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -327,7 +339,7 @@ public abstract class AbstractStandardTest {
|
||||
assertNotNull(projection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void ConstructorProjection2(){
|
||||
List<Projection> projections = query().from(cat).list(new QProjection(cat.name, cat));
|
||||
@ -354,12 +366,12 @@ public abstract class AbstractStandardTest {
|
||||
Param<String> name = new Param<String>(String.class,"name");
|
||||
assertEquals("Bob123",query().from(cat).where(cat.name.eq(name)).uniqueResult(cat.name));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Null_as_uniqueResult(){
|
||||
assertNull(query().from(cat).where(cat.name.eq(UUID.randomUUID().toString())).uniqueResult(cat));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Map_ContainsKey(){
|
||||
QShow show = QShow.show;
|
||||
@ -367,7 +379,7 @@ public abstract class AbstractStandardTest {
|
||||
assertEquals(1l, query().from(show).where(show.acts.containsKey("b")).count());
|
||||
assertEquals(0l, query().from(show).where(show.acts.containsKey("c")).count());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Map_ContainsValue(){
|
||||
QShow show = QShow.show;
|
||||
|
||||
@ -35,15 +35,7 @@ import com.mysema.query.SearchResults;
|
||||
import com.mysema.query.QueryFlag.Position;
|
||||
import com.mysema.query.support.ProjectableQuery;
|
||||
import com.mysema.query.support.QueryMixin;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.FactoryExpression;
|
||||
import com.mysema.query.types.OrderSpecifier;
|
||||
import com.mysema.query.types.ParamExpression;
|
||||
import com.mysema.query.types.ParamNotSetException;
|
||||
import com.mysema.query.types.Path;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.types.QBean;
|
||||
import com.mysema.query.types.SubQueryExpression;
|
||||
import com.mysema.query.types.*;
|
||||
import com.mysema.query.types.query.ListSubQuery;
|
||||
import com.mysema.query.types.template.SimpleTemplate;
|
||||
import com.mysema.util.ResultSetAdapter;
|
||||
@ -68,7 +60,7 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
return (List<RT>) IteratorAdapter.asList(iterateMultiple());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public CloseableIterator<RT> iterate() {
|
||||
@ -84,7 +76,7 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
AbstractSQLQuery.this.orderBy(o);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return AbstractSQLQuery.this.toString();
|
||||
@ -94,6 +86,8 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstractSQLQuery.class);
|
||||
|
||||
private static final Expression<Integer> ONE = TemplateExpressionImpl.create(Integer.class, "1");
|
||||
|
||||
@Nullable
|
||||
private final Connection conn;
|
||||
|
||||
@ -102,7 +96,7 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
|
||||
@Nullable
|
||||
private List<Path<?>> constantPaths;
|
||||
|
||||
|
||||
@Nullable
|
||||
private SubQueryExpression<?>[] union;
|
||||
|
||||
@ -119,7 +113,7 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
this.conn = conn;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Q addJoinFlag(String flag){
|
||||
List<JoinExpression> joins = queryMixin.getMetadata().getJoins();
|
||||
@ -131,15 +125,15 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
Expression<?> flag = SimpleTemplate.create(expr.getType(), prefix + "{0}", expr);
|
||||
return queryMixin.addFlag(new QueryFlag(position, flag));
|
||||
}
|
||||
|
||||
|
||||
protected Q addFlag(Position position, String flag){
|
||||
return queryMixin.addFlag(new QueryFlag(position, flag));
|
||||
}
|
||||
|
||||
|
||||
protected Q addFlag(Position position, Expression<?> flag){
|
||||
return queryMixin.addFlag(new QueryFlag(position, flag));
|
||||
}
|
||||
|
||||
|
||||
protected String buildQueryString(boolean forCountRow) {
|
||||
SQLSerializer serializer = createSerializer();
|
||||
if (union != null) {
|
||||
@ -163,6 +157,11 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(){
|
||||
return limit(1).uniqueResult(ONE) != null;
|
||||
}
|
||||
|
||||
protected SQLSerializer createSerializer() {
|
||||
return new SQLSerializer(configuration.getTemplates());
|
||||
}
|
||||
@ -236,11 +235,11 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
private <T> T get(ResultSet rs, Expression<?> expr, int i, Class<T> type) throws SQLException {
|
||||
return configuration.get(rs, expr instanceof Path ? (Path)expr : null, i, type);
|
||||
}
|
||||
|
||||
|
||||
private int set(PreparedStatement stmt, Path<?> path, int i, Object value) throws SQLException{
|
||||
return configuration.set(stmt, path, i, value);
|
||||
}
|
||||
|
||||
|
||||
public QueryMetadata getMetadata() {
|
||||
return queryMixin.getMetadata();
|
||||
}
|
||||
@ -311,8 +310,8 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
}
|
||||
}else{
|
||||
queryMixin.addToProjection(expr);
|
||||
return iterateSingle(expr);
|
||||
}
|
||||
return iterateSingle(expr);
|
||||
}
|
||||
}
|
||||
|
||||
private CloseableIterator<Object[]> iterateMultiple() {
|
||||
@ -398,7 +397,7 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
}
|
||||
return (RT) rv;
|
||||
} else{
|
||||
return (RT) get(rs, expr, 1, expr.getType());
|
||||
return get(rs, expr, 1, expr.getType());
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
close();
|
||||
@ -469,14 +468,14 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
queryMixin.getMetadata().reset();
|
||||
constants = null;
|
||||
}
|
||||
|
||||
|
||||
protected void setParameters(PreparedStatement stmt, List<?> objects, List<Path<?>> constantPaths, Map<ParamExpression<?>, ?> params){
|
||||
if (objects.size() != constantPaths.size()){
|
||||
throw new IllegalArgumentException("Expected " + objects.size() + " paths, but got " + constantPaths.size());
|
||||
}
|
||||
int counter = 1;
|
||||
for (int i = 0; i < objects.size(); i++){
|
||||
Object o = objects.get(i);
|
||||
Object o = objects.get(i);
|
||||
try {
|
||||
if (ParamExpression.class.isInstance(o)){
|
||||
if (!params.containsKey(o)){
|
||||
@ -516,7 +515,7 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
}finally{
|
||||
iterator.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private long unsafeCount() throws SQLException {
|
||||
@ -546,5 +545,5 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -62,7 +62,9 @@ import com.mysema.query.types.path.PathBuilder;
|
||||
import com.mysema.query.types.query.ListSubQuery;
|
||||
import com.mysema.query.types.query.NumberSubQuery;
|
||||
import com.mysema.query.types.query.SimpleSubQuery;
|
||||
import com.mysema.testutil.*;
|
||||
import com.mysema.testutil.ExcludeIn;
|
||||
import com.mysema.testutil.IncludeIn;
|
||||
import com.mysema.testutil.Label;
|
||||
|
||||
public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
|
||||
@ -73,7 +75,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
|
||||
}
|
||||
|
||||
private QueryExecution standardTest = new QueryExecution(Module.SQL, getClass().getAnnotation(Label.class).value()){
|
||||
private final QueryExecution standardTest = new QueryExecution(Module.SQL, getClass().getAnnotation(Label.class).value()){
|
||||
@Override
|
||||
protected Pair<Projectable, List<Expression<?>>> createQuery() {
|
||||
return Pair.of(
|
||||
@ -248,7 +250,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
NumberPath<Long> rowCount = new NumberPath<Long>(Long.class, "rowCount");
|
||||
query().from(employee).uniqueResult(Wildcard.count().as(rowCount));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Custom_Projection(){
|
||||
List<Projection> tuples = query().from(employee).list(
|
||||
@ -286,7 +288,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
System.out.println(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Inner_Join() throws SQLException {
|
||||
query().from(employee).innerJoin(employee2)
|
||||
@ -300,14 +302,14 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
.on(employee.superiorIdKey.on(employee2))
|
||||
.list(employee.id, employee2.id);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Right_Join() throws SQLException {
|
||||
query().from(employee).rightJoin(employee2)
|
||||
.on(employee.superiorIdKey.on(employee2))
|
||||
.list(employee.id, employee2.id);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@IncludeIn({POSTGRES})
|
||||
public void Full_Join() throws SQLException {
|
||||
@ -326,6 +328,16 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Exists(){
|
||||
assertTrue(query().from(employee).where(employee.firstname.eq("Barbara")).exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NotExists(){
|
||||
assertTrue(query().from(employee).where(employee.firstname.eq("Barb")).notExists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Limit() throws SQLException {
|
||||
// limit
|
||||
@ -333,7 +345,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
.orderBy(employee.firstname.asc())
|
||||
.limit(4).list(employee.id);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Limit_And_Offset() throws SQLException {
|
||||
// limit and offset
|
||||
@ -341,9 +353,9 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
.orderBy(employee.firstname.asc())
|
||||
.limit(4).offset(3).list(employee.id);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Limitt_and_Order(){
|
||||
public void Limit_and_Order(){
|
||||
// limit
|
||||
List<String> names1 = Arrays.asList("Barbara","Daisy","Helen","Jennifer");
|
||||
assertEquals(names1, query().from(employee)
|
||||
@ -417,13 +429,13 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
public void Path_Alias(){
|
||||
expectedQuery = "select e.LASTNAME, sum(e.SALARY) as salarySum from EMPLOYEE2 e group by e.LASTNAME having salarySum > ?";
|
||||
|
||||
NumberExpression<BigDecimal> salarySum = employee.salary.sum().as("salarySum");
|
||||
NumberExpression<BigDecimal> salarySum = employee.salary.sum().as("salarySum");
|
||||
query().from(employee)
|
||||
.groupBy(employee.lastname)
|
||||
.having(salarySum.gt(10000))
|
||||
.list(employee.lastname, salarySum);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Projection() throws IOException{
|
||||
CloseableIterator<Object[]> results = query().from(survey).iterate(survey.all());
|
||||
@ -572,7 +584,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
query().from(employee).where(where).list(employee.firstname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void SubQuery_InnerJoin(){
|
||||
ListSubQuery<Integer> sq = sq().from(employee2).list(employee2.id);
|
||||
@ -580,7 +592,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
query().from(employee).innerJoin(sq, sqEmp).on(sqEmp.id.eq(employee.id)).list(employee.id);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void SubQuery_LeftJoin(){
|
||||
ListSubQuery<Integer> sq = sq().from(employee2).list(employee2.id);
|
||||
@ -588,7 +600,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
query().from(employee).leftJoin(sq, sqEmp).on(sqEmp.id.eq(employee.id)).list(employee.id);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void SubQuery_RightJoin(){
|
||||
ListSubQuery<Integer> sq = sq().from(employee2).list(employee2.id);
|
||||
@ -596,7 +608,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
query().from(employee).rightJoin(sq, sqEmp).on(sqEmp.id.eq(employee.id)).list(employee.id);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void SubQuerySerialization(){
|
||||
SQLSubQuery query = sq();
|
||||
@ -606,13 +618,13 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
query.from(survey2);
|
||||
assertEquals("from SURVEY s, SURVEY s2", query.toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void SubQuerySerialization2(){
|
||||
NumberPath<BigDecimal> sal = new NumberPath<BigDecimal>(BigDecimal.class, "sal");
|
||||
PathBuilder<Object[]> sq = new PathBuilder<Object[]>(Object[].class, "sq");
|
||||
SQLSerializer serializer = new SQLSerializer(SQLTemplates.DEFAULT);
|
||||
|
||||
|
||||
serializer.handle(
|
||||
sq()
|
||||
.from(employee)
|
||||
@ -655,7 +667,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
assertEquals(2, row.length);
|
||||
assertEquals(Integer.class, row[0].getClass());
|
||||
assertEquals(String.class, row[1].getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -668,7 +680,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
assertEquals(IdName.class, row[2].getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void Union() throws SQLException {
|
||||
@ -706,13 +718,13 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
// iterator
|
||||
CloseableIterator<Object[]> iterator = query().union(sq1,sq2).iterate();
|
||||
try{
|
||||
assertTrue(iterator.hasNext());
|
||||
assertTrue(iterator.hasNext());
|
||||
assertTrue(iterator.next() != null);
|
||||
assertTrue(iterator.next() != null);
|
||||
assertFalse(iterator.hasNext());
|
||||
}finally{
|
||||
iterator.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -730,13 +742,13 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
// iterator
|
||||
CloseableIterator<Integer> iterator = query().union(sq1,sq2).iterate();
|
||||
try{
|
||||
assertTrue(iterator.hasNext());
|
||||
assertTrue(iterator.hasNext());
|
||||
assertTrue(iterator.next() != null);
|
||||
assertTrue(iterator.next() != null);
|
||||
assertFalse(iterator.hasNext());
|
||||
}finally{
|
||||
iterator.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Loading…
Reference in New Issue
Block a user