Skip to content

Commit

Permalink
Add stubs for orderBy path expansion #582
Browse files Browse the repository at this point in the history
  • Loading branch information
timowest committed Dec 10, 2013
1 parent d482fd1 commit d2f8020
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 26 deletions.
Expand Up @@ -121,7 +121,7 @@ public BooleanExpression notExists() {
private QueryMetadata projection(Expression<?>... projection) {
QueryMetadata metadata = queryMixin.getMetadata().clone();
for (Expression<?> expr : projection) {
expr = queryMixin.convert(expr);
expr = queryMixin.convert(expr, false);
metadata.addProjection(nullAsTemplate(expr));
}
return metadata;
Expand Down
Expand Up @@ -95,14 +95,14 @@ public T addJoinFlag(JoinFlag flag) {
}

public <E> Expression<E> addProjection(Expression<E> e) {
e = convert(e);
e = convert(e, false);
metadata.addProjection(e);
return e;
}

public T addProjection(Expression<?>... o) {
for (Expression<?> e : o) {
metadata.addProjection(convert(e));
metadata.addProjection(convert(e, false));
}
return self;
}
Expand All @@ -115,7 +115,7 @@ private <P extends Path<?>> P assertRoot(P p) {
}

@SuppressWarnings("rawtypes")
public <RT> Expression<RT> convert(Expression<RT> expr) {
public <RT> Expression<RT> convert(Expression<RT> expr, boolean forOrder) {
if (validateAnyPaths && expr instanceof Path) {
Context context = new Context();
Expression replaced = expr.accept(CollectionAnyVisitor.DEFAULT, context);
Expand All @@ -129,17 +129,17 @@ public <RT> Expression<RT> convert(Expression<RT> expr) {
}
}
if (expr instanceof ProjectionRole<?>) {
return convert(((ProjectionRole) expr).getProjection());
return convert(((ProjectionRole) expr).getProjection(), forOrder);
} else if (expr instanceof FactoryExpression<?> && !(expr instanceof FactoryExpressionAdapter<?>)) {
return FactoryExpressionUtils.wrap((FactoryExpression<RT>)expr);
} else {
return expr;
}
}

protected <D> Expression<D> createAlias(Expression expr, Path alias) {
protected <D> Expression<D> createAlias(Expression<?> expr, Path<?> alias) {
assertRoot(alias);
return ExpressionUtils.as(expr, alias);
return ExpressionUtils.as((Expression)expr, alias);
}

public final T distinct() {
Expand Down Expand Up @@ -178,8 +178,7 @@ public final <P> T fullJoin(MapExpression<?,P> target, Path<P> alias) {
return self;
}

@SuppressWarnings("unchecked")
public final <P> T fullJoin(SubQueryExpression<P> target, Path alias) {
public final <P> T fullJoin(SubQueryExpression<P> target, Path<?> alias) {
metadata.addJoin(JoinType.FULLJOIN, createAlias(target, alias));
return self;
}
Expand Down Expand Up @@ -236,8 +235,7 @@ public final <P> T innerJoin(MapExpression<?,P> target, Path<P> alias) {
return self;
}

@SuppressWarnings("unchecked")
public final <P> T innerJoin(SubQueryExpression<P> target, Path alias) {
public final <P> T innerJoin(SubQueryExpression<P> target, Path<?> alias) {
metadata.addJoin(JoinType.INNERJOIN, createAlias(target, alias));
return self;
}
Expand Down Expand Up @@ -270,8 +268,7 @@ public final <P> T join(MapExpression<?,P> target, Path<P> alias) {
return getSelf();
}

@SuppressWarnings("unchecked")
public final <P> T join(SubQueryExpression<P> target, Path alias) {
public final <P> T join(SubQueryExpression<P> target, Path<?> alias) {
metadata.addJoin(JoinType.JOIN, createAlias(target, alias));
return self;
}
Expand All @@ -296,8 +293,7 @@ public final <P> T leftJoin(MapExpression<?,P> target, Path<P> alias) {
return getSelf();
}

@SuppressWarnings("unchecked")
public final <P> T leftJoin(SubQueryExpression<P> target, Path alias) {
public final <P> T leftJoin(SubQueryExpression<P> target, Path<?> alias) {
metadata.addJoin(JoinType.LEFTJOIN, createAlias(target, alias));
return self;
}
Expand Down Expand Up @@ -325,7 +321,7 @@ public final T on(Predicate... conditions) {
}

public final T orderBy(OrderSpecifier<?> spec) {
Expression<?> e = convert(spec.getTarget());
Expression<?> e = convert(spec.getTarget(), true);
if (!spec.getTarget().equals(e)) {
metadata.addOrderBy(new OrderSpecifier(spec.getOrder(), e));
} else {
Expand Down Expand Up @@ -366,8 +362,7 @@ public final <P> T rightJoin(MapExpression<?,P> target, Path<P> alias) {
return getSelf();
}

@SuppressWarnings("unchecked")
public final <P> T rightJoin(SubQueryExpression<P> target, Path alias) {
public final <P> T rightJoin(SubQueryExpression<P> target, Path<?> alias) {
metadata.addJoin(JoinType.RIGHTJOIN, createAlias(target, alias));
return self;
}
Expand Down
Expand Up @@ -60,8 +60,8 @@ private NativeQueryMixin(QueryMetadata metadata) {
}

@Override
public <RT> Expression<RT> convert(Expression<RT> expr) {
return super.convert(Conversions.convertForNativeQuery(expr));
public <RT> Expression<RT> convert(Expression<RT> expr, boolean forOrder) {
return super.convert(Conversions.convertForNativeQuery(expr), forOrder);
}
}

Expand Down
51 changes: 47 additions & 4 deletions querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryMixin.java
Expand Up @@ -13,9 +13,11 @@
*/
package com.mysema.query.jpa;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.mysema.query.JoinFlag;
import com.mysema.query.QueryMetadata;
import com.mysema.query.support.Context;
Expand All @@ -27,6 +29,9 @@
import com.mysema.query.types.ExpressionUtils;
import com.mysema.query.types.OperationImpl;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathImpl;
import com.mysema.query.types.PathMetadata;
import com.mysema.query.types.PathType;
import com.mysema.query.types.Predicate;

/**
Expand All @@ -38,7 +43,9 @@
*/
public class JPAQueryMixin<T> extends QueryMixin<T> {

private final Set<Path<?>> paths = new HashSet<Path<?>>();
private final Set<Path<?>> paths = Sets.newHashSet();

private final Map<Expression<?>, Path<?>> aliases = Maps.newHashMap();

public static final JoinFlag FETCH = new JoinFlag("fetch ");

Expand All @@ -65,8 +72,44 @@ public T fetchAll() {
}

@Override
public <RT> Expression<RT> convert(Expression<RT> expr) {
return super.convert(Conversions.convert(expr));
protected <D> Expression<D> createAlias(Expression<?> expr, Path<?> alias) {
aliases.put(expr, alias);
return super.createAlias(expr, alias);
}

private <T> Path<T> shorten(Path<T> path) {
PathMetadata<?> metadata = path.getMetadata();
if (metadata.getPathType() != PathType.PROPERTY) {
return path;
} else if (aliases.containsKey(path)) {
return (Path<T>) aliases.get(path);
} else if (metadata.getParent().getMetadata().isRoot()) {
Path<T> newPath = new PathImpl<T>(path.getType(), path.toString().replace('.', '_'));
leftJoin(path, newPath);
return newPath;
} else {
Path<?> parent = shorten(metadata.getParent());
Path<T> oldPath = new PathImpl<T>(path.getType(),
new PathMetadata(parent, metadata.getElement(), metadata.getPathType()));
Path<T> newPath = new PathImpl<T>(path.getType(), oldPath.toString().replace('.', '_'));
leftJoin(oldPath, newPath);
return newPath;
}
}

@Override
public <RT> Expression<RT> convert(Expression<RT> expr, boolean forOrder) {
if (forOrder && expr instanceof Path) {
Path<?> path = (Path<?>)expr;
PathMetadata<?> metadata = path.getMetadata();
// at least three levels
if (metadata.getParent() != null && !metadata.getParent().getMetadata().isRoot()) {
Path<?> shortened = shorten(metadata.getParent());
expr = new PathImpl<RT>((Class)shortened.getType(),
new PathMetadata(shortened, metadata.getElement(), metadata.getPathType()));
}
}
return super.convert(Conversions.convert(expr), forOrder);
}

@Override
Expand Down
@@ -1,17 +1,97 @@
package com.mysema.query.jpa;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;

import org.junit.Test;

import com.mysema.query.JoinExpression;
import com.mysema.query.JoinType;
import com.mysema.query.QueryMetadata;
import com.mysema.query.jpa.domain.QCat;
import com.mysema.query.types.PathMetadataFactory;
import com.mysema.query.types.Predicate;

public class JPAQueryMixinTest {

private JPAQueryMixin mixin = new JPAQueryMixin();

@Test
public void Where_Null() {
mixin.where((Predicate)null);
}


@Test
public void OrderBy() {
QCat cat = QCat.cat;
QCat cat_mate = new QCat("cat_mate");
mixin.from(cat);
mixin.orderBy(cat.mate.name.asc());

QueryMetadata md = mixin.getMetadata();
assertEquals(Arrays.asList(
new JoinExpression(JoinType.DEFAULT, cat),
new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(cat_mate))),
md.getJoins());
assertEquals(Arrays.asList(cat_mate.name.asc()),
md.getOrderBy());
}

@Test
public void OrderBy_Long() {
QCat cat = QCat.cat;
QCat catMate = new QCat(PathMetadataFactory.forProperty(cat, "mate"));
QCat cat_mate = new QCat("cat_mate");
QCat cat_mate_mate = new QCat("cat_mate_mate");
mixin.from(cat);
mixin.orderBy(cat.mate.mate.name.asc());

QueryMetadata md = mixin.getMetadata();
assertEquals(Arrays.asList(
new JoinExpression(JoinType.DEFAULT, cat),
new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(cat_mate)),
new JoinExpression(JoinType.LEFTJOIN, cat_mate.mate.as(cat_mate_mate))),
md.getJoins());
assertEquals(Arrays.asList(cat_mate_mate.name.asc()),
md.getOrderBy());
}

@Test
public void OrderBy_Reuse() {
QCat cat = QCat.cat;
QCat mate = new QCat("mate");
mixin.from(cat);
mixin.leftJoin(cat.mate, mate);
mixin.orderBy(cat.mate.name.asc());

QueryMetadata md = mixin.getMetadata();
assertEquals(Arrays.asList(
new JoinExpression(JoinType.DEFAULT, cat),
new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(mate))),
md.getJoins());
assertEquals(Arrays.asList(mate.name.asc()),
md.getOrderBy());
}

@Test
public void OrderBy_Long_Reuse() {
QCat cat = QCat.cat;
QCat mate = new QCat("mate");
QCat mate_mate = new QCat("mate_mate");
mixin.from(cat);
mixin.leftJoin(cat.mate, mate);
mixin.orderBy(cat.mate.mate.name.asc());

QueryMetadata md = mixin.getMetadata();
assertEquals(Arrays.asList(
new JoinExpression(JoinType.DEFAULT, cat),
new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(mate)),
new JoinExpression(JoinType.LEFTJOIN, mate.mate.as(mate_mate))),
md.getJoins());
assertEquals(Arrays.asList(mate_mate.name.asc()),
md.getOrderBy());
}

// TODO test path.any() behaviour
}

0 comments on commit d2f8020

Please sign in to comment.