#634885 : made SubQuery instances reusable by cloning QueryMetadata

This commit is contained in:
Timo Westkämper 2010-09-11 12:34:59 +00:00
parent 64863a4b1f
commit 68d76dcf31
5 changed files with 105 additions and 38 deletions

View File

@ -6,6 +6,7 @@
package com.mysema.query.support;
import com.mysema.commons.lang.Assert;
import com.mysema.query.QueryMetadata;
import com.mysema.query.types.Expr;
import com.mysema.query.types.Ops;
import com.mysema.query.types.expr.EBoolean;
@ -36,8 +37,7 @@ public class DetachableMixin implements Detachable{
@Override
public ObjectSubQuery<Long> count() {
queryMixin.addToProjection(COUNT_ALL_AGG_EXPR);
return new ObjectSubQuery<Long>(Long.class, queryMixin.getMetadata());
return new ObjectSubQuery<Long>(Long.class, projection(COUNT_ALL_AGG_EXPR));
}
@Override
@ -50,22 +50,18 @@ public class DetachableMixin implements Detachable{
@Override
public ListSubQuery<Object[]> list(Expr<?> first, Expr<?> second, Expr<?>... rest) {
queryMixin.addToProjection(first, second);
queryMixin.addToProjection(rest);
return new ListSubQuery<Object[]>(Object[].class, queryMixin.getMetadata());
return new ListSubQuery<Object[]>(Object[].class, projection(first, second, rest));
}
@Override
public ListSubQuery<Object[]> list(Expr<?>[] args) {
queryMixin.addToProjection(args);
return new ListSubQuery<Object[]>(Object[].class, queryMixin.getMetadata());
return new ListSubQuery<Object[]>(Object[].class, projection(args));
}
@SuppressWarnings("unchecked")
@Override
public <RT> ListSubQuery<RT> list(Expr<RT> projection) {
queryMixin.addToProjection(projection);
return new ListSubQuery<RT>((Class)projection.getType(), queryMixin.getMetadata());
return new ListSubQuery<RT>((Class)projection.getType(), projection(projection));
}
@Override
@ -73,77 +69,92 @@ public class DetachableMixin implements Detachable{
return exists().not();
}
private void setUniqueProjection(Expr<?> projection){
queryMixin.addToProjection(projection);
queryMixin.setUnique(true);
}
@Override
public BooleanSubQuery unique(EBoolean projection) {
setUniqueProjection(projection);
return new BooleanSubQuery(queryMixin.getMetadata());
return new BooleanSubQuery(uniqueProjection(projection));
}
@SuppressWarnings("unchecked")
@Override
public <RT extends Comparable<?>> ComparableSubQuery<RT> unique(EComparable<RT> projection) {
setUniqueProjection(projection);
return new ComparableSubQuery<RT>((Class)projection.getType(), queryMixin.getMetadata());
return new ComparableSubQuery<RT>((Class)projection.getType(), uniqueProjection(projection));
}
@SuppressWarnings("unchecked")
@Override
public <RT extends Comparable<?>> DateSubQuery<RT> unique(EDate<RT> projection) {
setUniqueProjection(projection);
return new DateSubQuery<RT>((Class)projection.getType(), queryMixin.getMetadata());
return new DateSubQuery<RT>((Class)projection.getType(), uniqueProjection(projection));
}
@SuppressWarnings("unchecked")
@Override
public <RT extends Comparable<?>> DateTimeSubQuery<RT> unique(EDateTime<RT> projection) {
setUniqueProjection(projection);
return new DateTimeSubQuery<RT>((Class)projection.getType(), queryMixin.getMetadata());
return new DateTimeSubQuery<RT>((Class)projection.getType(), uniqueProjection(projection));
}
@SuppressWarnings("unchecked")
@Override
public <RT extends Number & Comparable<?>> NumberSubQuery<RT> unique(ENumber<RT> projection) {
setUniqueProjection(projection);
return new NumberSubQuery<RT>((Class)projection.getType(), queryMixin.getMetadata());
return new NumberSubQuery<RT>((Class)projection.getType(), uniqueProjection(projection));
}
@Override
public StringSubQuery unique(EString projection) {
setUniqueProjection(projection);
return new StringSubQuery(queryMixin.getMetadata());
return new StringSubQuery(uniqueProjection(projection));
}
@SuppressWarnings("unchecked")
@Override
public <RT extends Comparable<?>> TimeSubQuery<RT> unique(ETime<RT> projection) {
setUniqueProjection(projection);
return new TimeSubQuery<RT>((Class)projection.getType(), queryMixin.getMetadata());
return new TimeSubQuery<RT>((Class)projection.getType(), uniqueProjection(projection));
}
@Override
public ObjectSubQuery<Object[]> unique(Expr<?> first, Expr<?> second, Expr<?>... rest) {
queryMixin.addToProjection(first, second);
queryMixin.addToProjection(rest);
queryMixin.setUnique(true);
return new ObjectSubQuery<Object[]>(Object[].class, queryMixin.getMetadata());
return new ObjectSubQuery<Object[]>(Object[].class, uniqueProjection(first, second, rest));
}
@Override
public ObjectSubQuery<Object[]> unique(Expr<?>[] args) {
queryMixin.addToProjection(args);
queryMixin.setUnique(true);
return new ObjectSubQuery<Object[]>(Object[].class, queryMixin.getMetadata());
return new ObjectSubQuery<Object[]>(Object[].class, uniqueProjection(args));
}
@SuppressWarnings("unchecked")
@Override
public <RT> ObjectSubQuery<RT> unique(Expr<RT> projection) {
setUniqueProjection(projection);
return new ObjectSubQuery<RT>((Class)projection.getType(), queryMixin.getMetadata());
return new ObjectSubQuery<RT>((Class)projection.getType(), uniqueProjection(projection));
}
private QueryMetadata projection(Expr<?>... projection){
QueryMetadata metadata = queryMixin.getMetadata().clone();
for (Expr<?> expr : projection){
metadata.addProjection(expr);
}
return metadata;
}
private QueryMetadata projection(Expr<?> first, Expr<?> second, Expr<?>[] rest) {
QueryMetadata metadata = queryMixin.getMetadata().clone();
metadata.addProjection(first);
metadata.addProjection(second);
for (Expr<?> expr : rest){
metadata.addProjection(expr);
}
return metadata;
}
private QueryMetadata uniqueProjection(Expr<?>... projection){
QueryMetadata metadata = projection(projection);
metadata.setUnique(true);
return metadata;
}
private QueryMetadata uniqueProjection(Expr<?> first, Expr<?> second, Expr<?>[] rest) {
QueryMetadata metadata = projection(first, second, rest);
metadata.setUnique(true);
return metadata;
}
}

View File

@ -142,7 +142,6 @@ public interface Ops {
Operator<Number> COUNT_AGG = new OperatorImpl<Number>("COUNT_AGG",Object.class);
Operator<Number> COUNT_DISTINCT_AGG = new OperatorImpl<Number>("COUNT_DISTINCT_AGG",Object.class);
Operator<Number> COUNT_ALL_AGG = new OperatorImpl<Number>("COUNT_ALL_AGG");
// ENumber<Long> COUNT_ALL_AGG_EXPR = ONumber.create(Long.class, COUNT_ALL_AGG);
}
/**

View File

@ -0,0 +1,19 @@
package com.mysema.query.hql;
import static org.junit.Assert.*;
import org.junit.Test;
import com.mysema.query.hql.domain.QCat;
public class HQLSubQueryTest {
@Test
public void Multiple_Projections(){
HQLSubQuery query = new HQLSubQuery();
query.from(QCat.cat);
assertEquals(1, query.list(QCat.cat).getMetadata().getProjection().size());
assertEquals(1, query.list(QCat.cat).getMetadata().getProjection().size());
}
}

View File

@ -0,0 +1,19 @@
package com.mysema.query.jdoql;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.mysema.query.jdoql.testdomain.QProduct;
public class JDOQLSubQueryTest {
@Test
public void Multiple_Projections(){
JDOQLSubQuery query = new JDOQLSubQuery();
query.from(QProduct.product);
assertEquals(1, query.list(QProduct.product).getMetadata().getProjection().size());
assertEquals(1, query.list(QProduct.product).getMetadata().getProjection().size());
}
}

View File

@ -0,0 +1,19 @@
package com.mysema.query.sql;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.mysema.query.sql.domain.QEmployee;
public class SQLSubQueryTest {
@Test
public void Multiple_Projections(){
SQLSubQuery query = new SQLSubQuery();
query.from(QEmployee.employee);
assertEquals(1, query.list(QEmployee.employee).getMetadata().getProjection().size());
assertEquals(1, query.list(QEmployee.employee).getMetadata().getProjection().size());
}
}