mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-30 21:08:30 +08:00
This commit is contained in:
parent
9cb530a664
commit
6ace0bf0d8
@ -11,7 +11,15 @@ import static com.mysema.query.collections.utils.QueryIteratorUtils.transform;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.collections15.IteratorUtils;
|
||||
import org.apache.commons.collections15.Predicate;
|
||||
@ -23,8 +31,11 @@ import com.mysema.query.JoinExpression;
|
||||
import com.mysema.query.Projectable;
|
||||
import com.mysema.query.QueryBaseWithProjection;
|
||||
import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.QueryModifiers;
|
||||
import com.mysema.query.SearchResults;
|
||||
import com.mysema.query.collections.eval.Evaluator;
|
||||
import com.mysema.query.collections.iterators.FilteringMultiIterator;
|
||||
import com.mysema.query.collections.iterators.LimitingIterator;
|
||||
import com.mysema.query.collections.iterators.MultiIterator;
|
||||
import com.mysema.query.collections.support.DefaultIndexSupport;
|
||||
import com.mysema.query.collections.support.DefaultSourceSortingSupport;
|
||||
@ -57,11 +68,9 @@ import com.mysema.query.util.CloseableIterator;
|
||||
*/
|
||||
// TODO : implement leftJoin, rightJoin and fullJoin
|
||||
// TODO : implement groupBy and having
|
||||
// TODO : remove close handling
|
||||
public class AbstractColQuery<SubType extends AbstractColQuery<SubType>> extends QueryBaseWithProjection<Object, SubType> implements Closeable, Projectable{
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final SubType _this = (SubType) this;
|
||||
|
||||
private boolean arrayProjection = false;
|
||||
|
||||
private boolean closed = false;
|
||||
@ -188,6 +197,11 @@ public class AbstractColQuery<SubType extends AbstractColQuery<SubType>> extends
|
||||
return new DefaultIndexSupport(new SimpleIteratorSource(exprToIt), ops, sources);
|
||||
}
|
||||
|
||||
private <RT> Iterator<RT> createPagedIterator(Expr<RT> projection) throws Exception{
|
||||
Iterator<RT> iterator = createIterator(projection);
|
||||
return LimitingIterator.transform(iterator, getMetadata().getModifiers());
|
||||
}
|
||||
|
||||
private <RT> Iterator<RT> createIterator(Expr<RT> projection) throws Exception {
|
||||
checkClosed();
|
||||
List<Expr<?>> sources = new ArrayList<Expr<?>>();
|
||||
@ -318,7 +332,6 @@ public class AbstractColQuery<SubType extends AbstractColQuery<SubType>> extends
|
||||
return it;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <RT> Iterator<RT> handleSelect(Iterator<?> it, List<Expr<?>> sources, Expr<RT> projection) throws Exception {
|
||||
Iterator<RT> rv = transform(ops, it, sources, projection);
|
||||
if (getMetadata().isDistinct()){
|
||||
@ -335,7 +348,7 @@ public class AbstractColQuery<SubType extends AbstractColQuery<SubType>> extends
|
||||
|
||||
addToProjection(projection);
|
||||
try {
|
||||
return asCloseableIterator(createIterator(projection));
|
||||
return asCloseableIterator(createPagedIterator(projection));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
@ -344,7 +357,7 @@ public class AbstractColQuery<SubType extends AbstractColQuery<SubType>> extends
|
||||
public <RT> CloseableIterator<RT> iterate(Expr<RT> projection) {
|
||||
addToProjection(projection);
|
||||
try {
|
||||
return asCloseableIterator(createIterator(projection));
|
||||
return asCloseableIterator(createPagedIterator(projection));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
@ -402,4 +415,33 @@ public class AbstractColQuery<SubType extends AbstractColQuery<SubType>> extends
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : optimize
|
||||
public <RT> SearchResults<RT> listResults(Expr<RT> projection) {
|
||||
QueryModifiers modifiers = getMetadata().getModifiers();
|
||||
List<RT> list;
|
||||
try {
|
||||
list = IteratorUtils.toList(createIterator(projection));
|
||||
}catch(Exception e){
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
if (list.isEmpty()){
|
||||
return SearchResults.emptyResults();
|
||||
}else if (!modifiers.isRestricting()){
|
||||
return new SearchResults<RT>(list, modifiers, list.size());
|
||||
}else{
|
||||
int start = 0;
|
||||
int end = list.size();
|
||||
if (modifiers.getOffset() != null){
|
||||
if (modifiers.getOffset() < list.size()){
|
||||
start = modifiers.getOffset().intValue();
|
||||
}else{
|
||||
return new SearchResults<RT>(Collections.<RT>emptyList(), modifiers, list.size());
|
||||
}
|
||||
}
|
||||
if (modifiers.getLimit() != null){
|
||||
end = (int)Math.min(start + modifiers.getLimit(), list.size());
|
||||
}
|
||||
return new SearchResults<RT>(list.subList(start, end), modifiers, list.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
package com.mysema.query.collections.iterators;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.mysema.commons.lang.Assert;
|
||||
import com.mysema.query.QueryModifiers;
|
||||
|
||||
/**
|
||||
* PagingIterator provides
|
||||
*
|
||||
* @author tiwe
|
||||
* @version $Id$
|
||||
*/
|
||||
public class LimitingIterator<E> implements Iterator<E> {
|
||||
|
||||
public static <T> Iterator<T> transform(Iterator<T> iterator, QueryModifiers modifiers){
|
||||
if (modifiers.isRestricting()){
|
||||
if (modifiers.getOffset() != null){
|
||||
int counter = 0;
|
||||
while (iterator.hasNext() && counter < modifiers.getOffset()){
|
||||
counter++;
|
||||
iterator.next();
|
||||
}
|
||||
}
|
||||
if (modifiers.getLimit() != null){
|
||||
iterator = new LimitingIterator<T>(iterator, modifiers.getLimit());
|
||||
}
|
||||
}
|
||||
return iterator;
|
||||
}
|
||||
|
||||
private final Iterator<E> original;
|
||||
|
||||
private final long limit;
|
||||
|
||||
private long counter;
|
||||
|
||||
public LimitingIterator(Iterator<E> iterator, long limit) {
|
||||
this.original = Assert.notNull(iterator);
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return original.hasNext() && counter < limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
counter++;
|
||||
return original.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -53,8 +53,8 @@ public class CustomQueryable<SubType extends CustomQueryable<SubType>> extends P
|
||||
}
|
||||
|
||||
|
||||
protected ColQuery getInnerQuery(){
|
||||
return innerQuery;
|
||||
protected QueryMetadata<Object> getMetadata(){
|
||||
return innerQuery.getMetadata();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
package com.mysema.query.collections;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.collections15.IteratorUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mysema.query.QueryModifiers;
|
||||
import com.mysema.query.SearchResults;
|
||||
import com.mysema.query.grammar.GrammarWithAlias;
|
||||
import com.mysema.query.grammar.types.Path.PNumber;
|
||||
|
||||
public class PagingTest extends AbstractQueryTest{
|
||||
|
||||
private List<Integer> ints = Arrays.asList(1,2,3,4,5,6,7,8,9);
|
||||
|
||||
private PNumber<Integer> var = GrammarWithAlias.$(0);
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
assertResultSize(9, 9, null);
|
||||
assertResultSize(9, 2, new QueryModifiers(2l,null));
|
||||
assertResultSize(9, 2, new QueryModifiers(2l,0l));
|
||||
assertResultSize(9, 2, new QueryModifiers(2l,3l));
|
||||
assertResultSize(9, 9, new QueryModifiers(20l,null));
|
||||
assertResultSize(9, 9, new QueryModifiers(20l,0l));
|
||||
assertResultSize(9, 5, new QueryModifiers(20l,4l));
|
||||
assertResultSize(9, 0, new QueryModifiers(10l,9l));
|
||||
}
|
||||
|
||||
private void assertResultSize(int total, int size, QueryModifiers modifiers){
|
||||
// via list
|
||||
assertEquals(size, createQuery(modifiers).list(var).size());
|
||||
|
||||
// via results
|
||||
SearchResults<?> results = createQuery(modifiers).listResults(var);
|
||||
assertEquals(total, results.getTotal());
|
||||
assertEquals(size, results.getResults().size());
|
||||
|
||||
// via count (ignore limit and offset)
|
||||
assertEquals(total, createQuery(modifiers).count());
|
||||
|
||||
// via iterator
|
||||
assertEquals(size, IteratorUtils.toList(createQuery(modifiers).iterate(var)).size());
|
||||
}
|
||||
|
||||
private ColQuery createQuery(QueryModifiers modifiers){
|
||||
ColQuery query = new ColQuery().from(var, ints);
|
||||
if (modifiers != null) query.restrict(modifiers);
|
||||
return query;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.mysema.query.collections.iterators;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.collections15.IteratorUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mysema.query.QueryModifiers;
|
||||
|
||||
public class LimitingIteratorTest {
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
List<Integer> ints = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
|
||||
assertEquals(Arrays.asList(1,2), transform(ints, 2l, null));
|
||||
assertEquals(Arrays.asList(3,4,5), transform(ints, 3l, 2l));
|
||||
assertEquals(Arrays.asList(10), transform(ints, 10l, 9l));
|
||||
}
|
||||
|
||||
private List<Integer> transform(List<Integer> ints, Long limit, Long offset) {
|
||||
QueryModifiers modifiers = new QueryModifiers(limit, offset);
|
||||
return IteratorUtils.toList(LimitingIterator.transform(ints.iterator(), modifiers));
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user