mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-13 21:01:01 +08:00
Support for transforming results into something else.
This commit is contained in:
parent
1b0b572b66
commit
4034f5fcef
@ -5,6 +5,7 @@
|
||||
*/
|
||||
package com.mysema.query;
|
||||
|
||||
|
||||
/**
|
||||
* Executes query on a Projectable and transforms results into T. This can be used for example
|
||||
* to group projected columns or to filter out duplicate results.
|
||||
|
||||
@ -29,6 +29,4 @@ public interface Group {
|
||||
|
||||
<K, V> Map<K, V> getMap(Expression<K> key, Expression<V> value);
|
||||
|
||||
<K, V> Map<K, V> getMap(Expression<K> key, Class<V> valueType);
|
||||
|
||||
}
|
||||
@ -14,6 +14,8 @@ import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.collections15.Transformer;
|
||||
|
||||
import com.mysema.commons.lang.CloseableIterator;
|
||||
import com.mysema.commons.lang.Pair;
|
||||
import com.mysema.query.Projectable;
|
||||
@ -33,6 +35,32 @@ import com.mysema.query.types.Expression;
|
||||
@SuppressWarnings("unchecked")
|
||||
public class GroupBy<S> implements ResultTransformer<Map<S, Group>> {
|
||||
|
||||
private static class GList<T> extends AbstractGroupColumnDefinition<T, List<T>>{
|
||||
|
||||
public GList(Expression<T> expr) {
|
||||
super(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupColumn<List<T>> createGroupColumn() {
|
||||
return new GroupColumn<List<T>>() {
|
||||
|
||||
private final List<T> list = new ArrayList<T>();
|
||||
|
||||
@Override
|
||||
public void add(Object o) {
|
||||
list.add((T) o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> get() {
|
||||
return list;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static class GMap<K, V> extends AbstractGroupColumnDefinition<Pair<K, V>, Map<K, V>>{
|
||||
|
||||
public GMap(QPair<K, V> qpair) {
|
||||
@ -60,6 +88,35 @@ public class GroupBy<S> implements ResultTransformer<Map<S, Group>> {
|
||||
}
|
||||
}
|
||||
|
||||
private static class GOne<T> extends AbstractGroupColumnDefinition<T, T>{
|
||||
|
||||
public GOne(Expression<T> expr) {
|
||||
super(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupColumn<T> createGroupColumn() {
|
||||
return new GroupColumn<T>() {
|
||||
private boolean first = true;
|
||||
|
||||
private T val;
|
||||
|
||||
@Override
|
||||
public void add(Object o) {
|
||||
if (first) {
|
||||
val = (T) o;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return val;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static class GSet<T> extends AbstractGroupColumnDefinition<T, Set<T>>{
|
||||
|
||||
public GSet(Expression<T> expr) {
|
||||
@ -85,71 +142,93 @@ public class GroupBy<S> implements ResultTransformer<Map<S, Group>> {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static class GList<T> extends AbstractGroupColumnDefinition<T, List<T>>{
|
||||
|
||||
public GList(Expression<T> expr) {
|
||||
super(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupColumn<List<T>> createGroupColumn() {
|
||||
return new GroupColumn<List<T>>() {
|
||||
|
||||
private final List<T> list = new ArrayList<T>();
|
||||
|
||||
@Override
|
||||
public void add(Object o) {
|
||||
list.add((T) o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> get() {
|
||||
return list;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class GOne<T> extends AbstractGroupColumnDefinition<T, T>{
|
||||
|
||||
public GOne(Expression<T> expr) {
|
||||
super(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupColumn<T> createGroupColumn() {
|
||||
return new GroupColumn<T>() {
|
||||
private T val;
|
||||
|
||||
private boolean first = true;
|
||||
|
||||
@Override
|
||||
public void add(Object o) {
|
||||
if (first) {
|
||||
val = (T) o;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return val;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private final List<GroupColumnDefinition<?, ?>> columnDefinitions = new ArrayList<GroupColumnDefinition<?,?>>();
|
||||
|
||||
private final List<QPair<?, ?>> pairs = new ArrayList<QPair<?,?>>();
|
||||
|
||||
public static <T> GroupBy<T> create(Expression<T> expr) {
|
||||
return new GroupBy<T>(expr);
|
||||
}
|
||||
|
||||
public static <T> GroupBy<T> create(Expression<T> expr, Expression<?> first, Expression<?>... rest) {
|
||||
return new GroupBy<T>(expr, first, rest);
|
||||
}
|
||||
|
||||
private class GroupImpl implements Group {
|
||||
|
||||
private final Map<Expression<?>, GroupColumn<?>> groupColumns = new LinkedHashMap<Expression<?>, GroupColumn<?>>();
|
||||
|
||||
public GroupImpl() {
|
||||
for (int i=0; i < columnDefinitions.size(); i++) {
|
||||
GroupColumnDefinition<?, ?> coldef = columnDefinitions.get(i);
|
||||
groupColumns.put(coldef.getExpression(), coldef.createGroupColumn());
|
||||
}
|
||||
}
|
||||
|
||||
void add(Object[] row) {
|
||||
int i=0;
|
||||
for (GroupColumn<?> groupColumn : groupColumns.values()) {
|
||||
groupColumn.add(row[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private <T, R> R get(Expression<T> expr) {
|
||||
GroupColumn<R> col = (GroupColumn<R>) groupColumns.get(expr);
|
||||
if (col != null) {
|
||||
return col.get();
|
||||
}
|
||||
throw new NoSuchElementException(expr.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, R> R getGroup(GroupColumnDefinition<T, R> definition) {
|
||||
Iterator<GroupColumn<?>> iter = groupColumns.values().iterator();
|
||||
for (GroupColumnDefinition<?, ?> def : columnDefinitions) {
|
||||
GroupColumn<?> groupColumn = iter.next();
|
||||
if (def.equals(definition)) {
|
||||
return (R) groupColumn.get();
|
||||
}
|
||||
}
|
||||
throw new NoSuchElementException(definition.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> getList(Expression<T> expr) {
|
||||
return this.<T, List<T>>get(expr);
|
||||
}
|
||||
|
||||
public <K, V> Map<K, V> getMap(Expression<K> key, Expression<V> value) {
|
||||
for (QPair<?, ?> pair : maps) {
|
||||
if (pair.equals(key, value)) {
|
||||
return (Map<K, V>) groupColumns.get(pair).get();
|
||||
}
|
||||
}
|
||||
throw new NoSuchElementException("GMap(" + key + ", " + value + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getOne(Expression<T> expr) {
|
||||
return this.<T, T>get(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Set<T> getSet(Expression<T> expr) {
|
||||
return this.<T, Set<T>>get(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
List<Object> arr = new ArrayList<Object>(groupColumns.size());
|
||||
for (GroupColumn<?> col : groupColumns.values()) {
|
||||
arr.add(col.get());
|
||||
}
|
||||
return arr.toArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final List<GroupColumnDefinition<?, ?>> columnDefinitions = new ArrayList<GroupColumnDefinition<?,?>>();
|
||||
|
||||
private final List<QPair<?, ?>> maps = new ArrayList<QPair<?,?>>();
|
||||
|
||||
public GroupBy(Expression<S> groupBy) {
|
||||
withGroup(new GOne<S>(groupBy));
|
||||
}
|
||||
@ -170,29 +249,14 @@ public class GroupBy<S> implements ResultTransformer<Map<S, Group>> {
|
||||
}
|
||||
}
|
||||
|
||||
public GroupBy<S> withGroup(GroupColumnDefinition<?, ?> g) {
|
||||
columnDefinitions.add(g);
|
||||
return this;
|
||||
private Expression<?>[] getExpressions() {
|
||||
Expression<?>[] unwrapped = new Expression<?>[columnDefinitions.size()];
|
||||
for (int i=0; i < columnDefinitions.size(); i++) {
|
||||
unwrapped[i] = columnDefinitions.get(i).getExpression();
|
||||
}
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
public <T> GroupBy<S> withSet(Expression<T> expr) {
|
||||
return withGroup(new GSet<T>(expr));
|
||||
}
|
||||
|
||||
public <T> GroupBy<S> withList(Expression<T> expr) {
|
||||
return withGroup(new GList<T>(expr));
|
||||
}
|
||||
|
||||
public <T> GroupBy<S> withOne(Expression<T> expr) {
|
||||
return withGroup(new GOne<T>(expr));
|
||||
}
|
||||
|
||||
public <K, V> GroupBy<S> withMap(Expression<K> key, Expression<V> value) {
|
||||
QPair<K, V> qpair = new QPair<K, V>(key, value);
|
||||
pairs.add(qpair);
|
||||
return withGroup(new GMap<K, V>(qpair));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<S, Group> transform(Projectable projectable) {
|
||||
final Map<S, Group> groups = new LinkedHashMap<S, Group>();
|
||||
@ -215,96 +279,31 @@ public class GroupBy<S> implements ResultTransformer<Map<S, Group>> {
|
||||
return groups;
|
||||
}
|
||||
|
||||
private Expression<?>[] getExpressions() {
|
||||
Expression<?>[] unwrapped = new Expression<?>[columnDefinitions.size()];
|
||||
for (int i=0; i < columnDefinitions.size(); i++) {
|
||||
unwrapped[i] = columnDefinitions.get(i).getExpression();
|
||||
}
|
||||
return unwrapped;
|
||||
public GroupBy<S> withGroup(GroupColumnDefinition<?, ?> g) {
|
||||
columnDefinitions.add(g);
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T> GroupBy<S> withList(Expression<T> expr) {
|
||||
return withGroup(new GList<T>(expr));
|
||||
}
|
||||
|
||||
private class GroupImpl implements Group {
|
||||
|
||||
private final Map<Expression<?>, GroupColumn<?>> groupColumns = new LinkedHashMap<Expression<?>, GroupColumn<?>>();
|
||||
|
||||
public GroupImpl() {
|
||||
for (int i=0; i < columnDefinitions.size(); i++) {
|
||||
GroupColumnDefinition<?, ?> coldef = columnDefinitions.get(i);
|
||||
groupColumns.put(coldef.getExpression(), coldef.createGroupColumn());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, R> R getGroup(GroupColumnDefinition<T, R> definition) {
|
||||
Iterator<GroupColumn<?>> iter = groupColumns.values().iterator();
|
||||
for (GroupColumnDefinition<?, ?> def : columnDefinitions) {
|
||||
GroupColumn<?> groupColumn = iter.next();
|
||||
if (def.equals(definition)) {
|
||||
return (R) groupColumn.get();
|
||||
}
|
||||
}
|
||||
throw new NoSuchElementException(definition.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getOne(Expression<T> expr) {
|
||||
return this.<T, T>get(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Set<T> getSet(Expression<T> expr) {
|
||||
return this.<T, Set<T>>get(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> getList(Expression<T> expr) {
|
||||
return this.<T, List<T>>get(expr);
|
||||
}
|
||||
|
||||
private <T, R> R get(Expression<T> expr) {
|
||||
GroupColumn<R> col = (GroupColumn<R>) groupColumns.get(expr);
|
||||
if (col != null) {
|
||||
return col.get();
|
||||
}
|
||||
throw new NoSuchElementException(expr.toString());
|
||||
}
|
||||
|
||||
public <K, V> Map<K, V> getMap(Expression<K> key, Expression<V> value) {
|
||||
for (QPair<?, ?> pair : pairs) {
|
||||
if (pair.equals(key, value)) {
|
||||
return (Map<K, V>) groupColumns.get(pair).get();
|
||||
}
|
||||
}
|
||||
throw new NoSuchElementException("GMap(" + key + ", " + value + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, V> getMap(Expression<K> key, Class<V> valueType) {
|
||||
for (QPair<?, ?> pair : pairs) {
|
||||
if (pair.equals(key, valueType)) {
|
||||
return (Map<K, V>) groupColumns.get(pair).get();
|
||||
}
|
||||
}
|
||||
throw new NoSuchElementException("GMap(" + key + ", " + valueType + ")");
|
||||
}
|
||||
|
||||
void add(Object[] row) {
|
||||
int i=0;
|
||||
for (GroupColumn<?> groupColumn : groupColumns.values()) {
|
||||
groupColumn.add(row[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
List<Object> arr = new ArrayList<Object>(groupColumns.size());
|
||||
for (GroupColumn<?> col : groupColumns.values()) {
|
||||
arr.add(col.get());
|
||||
}
|
||||
return arr.toArray();
|
||||
}
|
||||
public <K, V> GroupBy<S> withMap(Expression<K> key, Expression<V> value) {
|
||||
QPair<K, V> qpair = new QPair<K, V>(key, value);
|
||||
maps.add(qpair);
|
||||
return withGroup(new GMap<K, V>(qpair));
|
||||
}
|
||||
|
||||
public <T> GroupBy<S> withOne(Expression<T> expr) {
|
||||
return withGroup(new GOne<T>(expr));
|
||||
}
|
||||
|
||||
public <T> GroupBy<S> withSet(Expression<T> expr) {
|
||||
return withGroup(new GSet<T>(expr));
|
||||
}
|
||||
|
||||
public <W> TransformerGroupBy<S, W> withTransformer(Transformer<? super Group, ? extends W> transformer) {
|
||||
return TransformerGroupBy.create(this, transformer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -29,6 +29,10 @@ public final class QPair<K, V> extends ExpressionBase<Pair<K, V>> implements Fac
|
||||
|
||||
private final Expression<V> value;
|
||||
|
||||
public static <K, V> QPair<K, V> create(Expression<K> key, Expression<V> value) {
|
||||
return new QPair<K, V>(key, value);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public QPair(Expression<K> key, Expression<V> value) {
|
||||
super((Class) Pair.class);
|
||||
@ -62,8 +66,7 @@ public final class QPair<K, V> extends ExpressionBase<Pair<K, V>> implements Fac
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = key.hashCode();
|
||||
return 31*hashCode + value.hashCode();
|
||||
return 31*key.hashCode() + value.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
package com.mysema.query.group;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.collections15.Transformer;
|
||||
|
||||
import com.mysema.query.Projectable;
|
||||
import com.mysema.query.ResultTransformer;
|
||||
|
||||
public class TransformerGroupBy<K, V> implements ResultTransformer<Map<K, V>> {
|
||||
|
||||
private final GroupBy<K> groupBy;
|
||||
|
||||
private final Transformer<? super Group, ? extends V> transformer;
|
||||
|
||||
public static <K, V> TransformerGroupBy<K, V> create(GroupBy<K> groupBy, Transformer<? super Group, ? extends V> transformer) {
|
||||
return new TransformerGroupBy<K, V>(groupBy, transformer);
|
||||
}
|
||||
|
||||
public TransformerGroupBy(GroupBy<K> groupBy, Transformer<? super Group, ? extends V> transformer) {
|
||||
this.groupBy = groupBy;
|
||||
this.transformer = transformer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<K, V> transform(Projectable projectable) {
|
||||
return TransformerMap.create(groupBy.transform(projectable), transformer);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
package com.mysema.query.group;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.collections15.Transformer;
|
||||
import org.apache.commons.collections15.collection.TransformedCollection;
|
||||
import org.apache.commons.collections15.set.TransformedSet;
|
||||
|
||||
public class TransformerMap<K, V, T> extends AbstractMap<K, T> {
|
||||
|
||||
private final Map<K, V> map;
|
||||
|
||||
private final Transformer<? super V, ? extends T> transformer;
|
||||
|
||||
public static <K, V, T> Map<K, T> create(Map<K, V> map, Transformer<? super V, ? extends T> transformer) {
|
||||
return new TransformerMap<K, V, T>(map, transformer);
|
||||
}
|
||||
|
||||
public TransformerMap(Map<K, V> map, Transformer<? super V, ? extends T> transformer) {
|
||||
this.map = map;
|
||||
this.transformer = transformer;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean containsValue(Object value) {
|
||||
return map.containsValue(transformer.transform((V) value));
|
||||
}
|
||||
|
||||
public T get(Object key) {
|
||||
return transformer.transform(map.get(key));
|
||||
}
|
||||
|
||||
public T put(K key, T value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public T remove(Object key) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends K, ? extends T> m) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Set<K> keySet() {
|
||||
return map.keySet();
|
||||
}
|
||||
|
||||
public Collection<T> values() {
|
||||
return TransformedCollection.decorate(map.values(), transformer);
|
||||
}
|
||||
|
||||
public Set<java.util.Map.Entry<K, T>> entrySet() {
|
||||
return TransformedSet.decorate(map.entrySet(), new Transformer<Map.Entry<K, V>, Map.Entry<K, T>>() {
|
||||
@Override
|
||||
public java.util.Map.Entry<K, T> transform(final Map.Entry<K, V> input) {
|
||||
return new Map.Entry<K, T>() {
|
||||
|
||||
@Override
|
||||
public K getKey() {
|
||||
return input.getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getValue() {
|
||||
return transformer.transform(input.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setValue(T value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package com.mysema.query.group;
|
||||
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -8,14 +9,15 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.collections15.Transformer;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mysema.commons.lang.CloseableIterator;
|
||||
import com.mysema.commons.lang.IteratorAdapter;
|
||||
import com.mysema.commons.lang.Pair;
|
||||
import com.mysema.query.Projectable;
|
||||
import com.mysema.query.group.GroupBy;
|
||||
import com.mysema.query.support.AbstractProjectable;
|
||||
import com.mysema.query.types.ConstructorExpression;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.expr.NumberExpression;
|
||||
import com.mysema.query.types.expr.StringExpression;
|
||||
@ -24,15 +26,15 @@ import com.mysema.query.types.path.StringPath;
|
||||
|
||||
public class GroupByTest {
|
||||
|
||||
private final NumberExpression<Integer> postId = new NumberPath<Integer>(Integer.class, "postId");
|
||||
private static final NumberExpression<Integer> postId = new NumberPath<Integer>(Integer.class, "postId");
|
||||
|
||||
private final StringExpression postName = new StringPath("postName");
|
||||
private static final StringExpression postName = new StringPath("postName");
|
||||
|
||||
private final NumberExpression<Integer> commentId = new NumberPath<Integer>(Integer.class, "commentId");
|
||||
private static final NumberExpression<Integer> commentId = new NumberPath<Integer>(Integer.class, "commentId");
|
||||
|
||||
private final StringExpression commentText = new StringPath("commentText");
|
||||
private static final StringExpression commentText = new StringPath("commentText");
|
||||
|
||||
private final GroupColumnDefinition<Integer, String> constant = new AbstractGroupColumnDefinition<Integer, String>(commentId) {
|
||||
private static final GroupColumnDefinition<Integer, String> constant = new AbstractGroupColumnDefinition<Integer, String>(commentId) {
|
||||
|
||||
@Override
|
||||
public GroupColumn<String> createGroupColumn() {
|
||||
@ -49,18 +51,51 @@ public class GroupByTest {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
private static final ConstructorExpression<Comment> qComment =
|
||||
new ConstructorExpression<GroupByTest.Comment>(
|
||||
GroupByTest.Comment.class,
|
||||
new Class[] { Integer.class, String.class },
|
||||
commentId, commentText
|
||||
);
|
||||
|
||||
static class PostWithComments {
|
||||
public Integer id;
|
||||
public String name;
|
||||
public Set<Integer> comments;
|
||||
public PostWithComments(Integer id, String name, Set<Integer> comments) {
|
||||
public static class Post {
|
||||
public final Integer id;
|
||||
public final String name;
|
||||
public final Set<Comment> comments;
|
||||
public Post(Integer id, String name, Set<Comment> comments) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.comments = comments;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Comment {
|
||||
public final Integer id;
|
||||
public final String text;
|
||||
public Comment(Integer id, String text) {
|
||||
this.id = id;
|
||||
this.text = text;
|
||||
}
|
||||
public int hashCode() {
|
||||
return 31*id.hashCode() + text.hashCode();
|
||||
}
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
} else if (o instanceof Comment) {
|
||||
Comment other = (Comment) o;
|
||||
return this.id.equals(other.id) && this.text.equals(other.text);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <K, V> Pair<K, V> pair(K key, V value) {
|
||||
return new Pair<K, V>(key, value);
|
||||
}
|
||||
|
||||
private static final Projectable BASIC_RESULTS = projectable(
|
||||
row(1, "post 1", 1, "comment 1"),
|
||||
row(2, "post 2", 4, "comment 4"),
|
||||
@ -71,10 +106,6 @@ public class GroupByTest {
|
||||
row(null, "null post", 8, "comment 8"),
|
||||
row(1, "post 1", 3, "comment 3")
|
||||
);
|
||||
|
||||
private static <K, V> Pair<K, V> pair(K key, V value) {
|
||||
return new Pair<K, V>(key, value);
|
||||
}
|
||||
|
||||
private static final Projectable MAP_RESULTS = projectable(
|
||||
row(1, "post 1", pair(1, "comment 1")),
|
||||
@ -86,10 +117,21 @@ public class GroupByTest {
|
||||
row(1, "post 1", pair(3, "comment 3"))
|
||||
);
|
||||
|
||||
private static final Projectable POST_W_COMMENTS_RESULTS = projectable(
|
||||
row(1, "post 1", comment(1)),
|
||||
row(1, "post 1", comment(2)),
|
||||
row(2, "post 2", comment(5)),
|
||||
row(3, "post 3", comment(6)),
|
||||
row(null, "null post", comment(7)),
|
||||
row(null, "null post", comment(8)),
|
||||
row(1, "post 1", comment(3))
|
||||
);
|
||||
|
||||
@Test
|
||||
public void Group_Order() {
|
||||
Map<Integer, Group> results =
|
||||
GroupBy.create(postId).withOne(postName).withSet(commentId).transform(BASIC_RESULTS);
|
||||
GroupBy.create(postId).withOne(postName).withSet(commentId)
|
||||
.transform(BASIC_RESULTS);
|
||||
|
||||
assertEquals(4, results.size());
|
||||
}
|
||||
@ -97,31 +139,34 @@ public class GroupByTest {
|
||||
@Test
|
||||
public void First_Set_And_List() {
|
||||
Map<Integer, Group> results =
|
||||
GroupBy.create(postId).withOne(postName).withSet(commentId).withList(commentText).transform(BASIC_RESULTS);
|
||||
GroupBy.create(postId).withOne(postName).withSet(commentId).withList(commentText)
|
||||
.transform(BASIC_RESULTS);
|
||||
|
||||
Group group = results.get(1);
|
||||
assertEquals(toInt(1), group.getOne(postId));
|
||||
assertEquals("post 1", group.getOne(postName));
|
||||
assertEquals(toSet(1, 2, 3), group.getSet(commentId));
|
||||
assertEquals(toInt(1), group.getOne(postId));
|
||||
assertEquals("post 1", group.getOne(postName));
|
||||
assertEquals(toSet(1, 2, 3), group.getSet(commentId));
|
||||
assertEquals(Arrays.asList("comment 1", "comment 2", "comment 3"), group.getList(commentText));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Group_By_Null() {
|
||||
Map<Integer, Group> results =
|
||||
GroupBy.create(postId).withOne(postName).withSet(commentId).withList(commentText).transform(BASIC_RESULTS);
|
||||
GroupBy.create(postId).withOne(postName).withSet(commentId).withList(commentText)
|
||||
.transform(BASIC_RESULTS);
|
||||
|
||||
Group group = results.get(null);
|
||||
assertNull(group.getOne(postId));
|
||||
assertEquals("null post", group.getOne(postName));
|
||||
assertEquals(toSet(7, 8), group.getSet(commentId));
|
||||
assertEquals("null post", group.getOne(postName));
|
||||
assertEquals(toSet(7, 8), group.getSet(commentId));
|
||||
assertEquals(Arrays.asList("comment 7", "comment 8"), group.getList(commentText));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void With_Constant_Column() {
|
||||
Map<Integer, Group> results =
|
||||
GroupBy.create(postId).withOne(postName).withGroup(constant).transform(BASIC_RESULTS);
|
||||
GroupBy.create(postId).withOne(postName).withGroup(constant)
|
||||
.transform(BASIC_RESULTS);
|
||||
|
||||
Group group = results.get(1);
|
||||
assertEquals("constant", group.getGroup(constant));
|
||||
@ -130,31 +175,54 @@ public class GroupByTest {
|
||||
@Test
|
||||
public void Map() {
|
||||
Map<Integer, Group> results =
|
||||
GroupBy.create(postId).withOne(postName).withMap(commentId, commentText).transform(MAP_RESULTS);
|
||||
GroupBy.create(postId).withOne(postName).withMap(commentId, commentText)
|
||||
.transform(MAP_RESULTS);
|
||||
|
||||
Group group = results.get(1);
|
||||
|
||||
Map<Integer, String> comments = group.getMap(commentId, commentText);
|
||||
assertEquals(3, comments.size());
|
||||
assertEquals("comment 2", comments.get(2));
|
||||
|
||||
assertEquals(comments, group.getMap(commentId, String.class));
|
||||
assertEquals(comments, group.getMap(commentId, Object.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Array_Access() {
|
||||
Map<Integer, Group> results =
|
||||
GroupBy.create(postId).withOne(postName).withSet(commentId).withList(commentText).transform(BASIC_RESULTS);
|
||||
GroupBy.create(postId).withOne(postName).withSet(commentId).withList(commentText)
|
||||
.transform(BASIC_RESULTS);
|
||||
|
||||
Group group = results.get(1);
|
||||
Object[] array = group.toArray();
|
||||
assertEquals(toInt(1), array[0]);
|
||||
assertEquals("post 1", array[1]);
|
||||
assertEquals(toSet(1, 2, 3), array[2]);
|
||||
assertEquals(toInt(1), array[0]);
|
||||
assertEquals("post 1", array[1]);
|
||||
assertEquals(toSet(1, 2, 3), array[2]);
|
||||
assertEquals(Arrays.asList("comment 1", "comment 2", "comment 3"), array[3]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Transform_Results() {
|
||||
Map<Integer, Post> results =
|
||||
GroupBy.create(postId, postName).withSet(qComment)
|
||||
|
||||
.withTransformer(new Transformer<Group, Post>() {
|
||||
public Post transform(Group group) {
|
||||
return new Post(group.getOne(postId), group.getOne(postName), group.getSet(qComment));
|
||||
}
|
||||
})
|
||||
|
||||
.transform(POST_W_COMMENTS_RESULTS);
|
||||
|
||||
Post post = results.get(1);
|
||||
assertNotNull(post);
|
||||
assertEquals(toInt(1), post.id);
|
||||
assertEquals("post 1", post.name);
|
||||
assertEquals(toSet(comment(1), comment(2), comment(3)), post.comments);
|
||||
}
|
||||
|
||||
private static Comment comment(Integer id) {
|
||||
return new Comment(id, "comment " + id);
|
||||
}
|
||||
|
||||
private static Projectable projectable(final Object[]... rows) {
|
||||
return new AbstractProjectable(){
|
||||
public CloseableIterator<Object[]> iterate(Expression<?>[] args) {
|
||||
|
||||
@ -1032,8 +1032,11 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
.from(employee)
|
||||
.innerJoin(employee._superiorIdKey, employee2);
|
||||
|
||||
Map<Integer, Group> results = new GroupBy<Integer>(employee.id, employee.firstname, employee.lastname)
|
||||
.withMap(employee2.id, new QTuple(employee2.id, employee2.firstname, employee2.lastname))
|
||||
QTuple subordinates = new QTuple(employee2.id, employee2.firstname, employee2.lastname);
|
||||
|
||||
// {id:1, firstname:"Mike", lastname:"Smith", subordinates: [{id:, firstname:, lastname:}, {id:, firstname:, lastname:}...]
|
||||
Map<Integer, Group> results = GroupBy.create(employee.id, employee.firstname, employee.lastname)
|
||||
.withMap(employee2.id, subordinates)
|
||||
.transform(qry);
|
||||
|
||||
assertEquals(2, results.size());
|
||||
@ -1043,7 +1046,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
assertEquals("Mike", group.getOne(employee.firstname));
|
||||
assertEquals("Smith", group.getOne(employee.lastname));
|
||||
|
||||
Map<Integer, Tuple> emps = group.getMap(employee2.id, Tuple.class);
|
||||
Map<Integer, Tuple> emps = group.getMap(employee2.id, subordinates);
|
||||
assertEquals(4, emps.size());
|
||||
assertEquals("Steve", emps.get(12).get(employee2.firstname));
|
||||
|
||||
@ -1052,7 +1055,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
|
||||
assertEquals("Mary", group.getOne(employee.firstname));
|
||||
assertEquals("Smith", group.getOne(employee.lastname));
|
||||
|
||||
emps = group.getMap(employee2.id, Tuple.class);
|
||||
emps = group.getMap(employee2.id, subordinates);
|
||||
assertEquals(4, emps.size());
|
||||
assertEquals("Mason", emps.get(21).get(employee2.lastname));
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user