From 8d9beece5cd01eb524e3c540950fc380cc217e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Fri, 12 Mar 2010 15:36:03 +0000 Subject: [PATCH] extended SQLQuery interface added MSSQL paging tests --- .../com/mysema/query/support/QueryMixin.java | 2 +- .../mysema/query/sql/AbstractSQLQuery.java | 154 ++++++++++-------- .../java/com/mysema/query/sql/SQLQuery.java | 18 +- .../com/mysema/query/sql/SQLQueryImpl.java | 3 + .../com/mysema/query/sql/SQLSubQuery.java | 2 +- .../mysema/query/mssql/SelectMSSQLTest.java | 51 ++++-- 6 files changed, 146 insertions(+), 84 deletions(-) diff --git a/querydsl-core/src/main/java/com/mysema/query/support/QueryMixin.java b/querydsl-core/src/main/java/com/mysema/query/support/QueryMixin.java index c3a0fc900..c3edadcf4 100644 --- a/querydsl-core/src/main/java/com/mysema/query/support/QueryMixin.java +++ b/querydsl-core/src/main/java/com/mysema/query/support/QueryMixin.java @@ -54,7 +54,7 @@ public class QueryMixin{ return metadata; } - public T from(PEntity... args) { + public T from(Expr... args) { metadata.addFrom(args); return self; } diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLQuery.java index c7662e620..2cd6a0195 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLQuery.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLQuery.java @@ -31,7 +31,10 @@ import com.mysema.query.types.OrderSpecifier; import com.mysema.query.types.expr.EBoolean; import com.mysema.query.types.expr.EConstructor; import com.mysema.query.types.expr.Expr; +import com.mysema.query.types.operation.OSimple; +import com.mysema.query.types.operation.Ops; import com.mysema.query.types.path.PEntity; +import com.mysema.query.types.path.Path; import com.mysema.query.types.query.ListSubQuery; import com.mysema.query.types.query.SubQuery; import com.mysema.util.JDBCUtil; @@ -116,13 +119,26 @@ public abstract class AbstractSQLQuery> extends } } + @SuppressWarnings("unchecked") + private Expr createAlias(Expr target, Expr alias){ + return OSimple.create((Class)alias.getType(), Ops.ALIAS, target.asExpr(), alias.asExpr()); + } + protected SQLSerializer createSerializer() { return new SQLSerializer(templates); } - public Q from(PEntity... args) { + public Q from(Expr... args) { return queryMixin.from(args); } + + public Q from(SubQuery source, Expr alias) { + return queryMixin.from(createAlias(source.asExpr(), alias)); + } + + public Q from(ListSubQuery source, Expr alias) { + return queryMixin.from(createAlias(source.asExpr(), alias)); + } public Q fullJoin(PEntity target) { return queryMixin.fullJoin(target); @@ -152,57 +168,6 @@ public abstract class AbstractSQLQuery> extends return queryMixin.getMetadata(); } - protected SQLTemplates getTemplates() { - return templates; - } - - public Q innerJoin(PEntity target) { - return queryMixin.innerJoin(target); - } - - private UnionBuilder innerUnion(SubQuery... sq) { - if (!queryMixin.getMetadata().getJoins().isEmpty()) { - throw new IllegalArgumentException("Don't mix union and from"); - } - this.sq = sq; - return new UnionBuilder(); - } - - public Q join(PEntity target) { - return queryMixin.join(target); - } - - public Q leftJoin(PEntity target) { - return queryMixin.leftJoin(target); - } - - @Override - public List list(Expr[] args) { - return IteratorAdapter.asList(iterate(args)); - } - - @Override - public List list(Expr expr) { - return IteratorAdapter.asList(iterate(expr)); - } - - @Override - public CloseableIterator iterate(Expr[] args) { - queryMixin.addToProjection(args); - return iterateMultiple(); - } - - @SuppressWarnings("unchecked") - @Override - public CloseableIterator iterate(Expr expr) { - queryMixin.addToProjection(expr); - if (expr.getType().isArray()) { - return (CloseableIterator) iterateMultiple(); - } else { - return iterateSingle(expr); - } - } - public ResultSet getResults(Expr... exprs) { queryMixin.addToProjection(exprs); String queryString = buildQueryString(false); @@ -230,6 +195,39 @@ public abstract class AbstractSQLQuery> extends } } + protected SQLTemplates getTemplates() { + return templates; + } + + public Q innerJoin(PEntity target) { + return queryMixin.innerJoin(target); + } + + private UnionBuilder innerUnion(SubQuery... sq) { + if (!queryMixin.getMetadata().getJoins().isEmpty()) { + throw new IllegalArgumentException("Don't mix union and from"); + } + this.sq = sq; + return new UnionBuilder(); + } + + @Override + public CloseableIterator iterate(Expr[] args) { + queryMixin.addToProjection(args); + return iterateMultiple(); + } + + @SuppressWarnings("unchecked") + @Override + public CloseableIterator iterate(Expr expr) { + queryMixin.addToProjection(expr); + if (expr.getType().isArray()) { + return (CloseableIterator) iterateMultiple(); + } else { + return iterateSingle(expr); + } + } + private CloseableIterator iterateMultiple() { String queryString = buildQueryString(false); logger.debug("query : {}", queryString); @@ -265,23 +263,6 @@ public abstract class AbstractSQLQuery> extends } - @Override - public SearchResults listResults(Expr expr) { - queryMixin.addToProjection(expr); - long total = count(); - try { - if (total > 0) { - QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); - return new SearchResults(list(expr), modifiers, total); - } else { - return SearchResults.emptyResults(); - } - - } finally { - reset(); - } - } - @SuppressWarnings("unchecked") private CloseableIterator iterateSingle(@Nullable final Expr expr) { String queryString = buildQueryString(false); @@ -337,6 +318,41 @@ public abstract class AbstractSQLQuery> extends } } + public Q join(PEntity target) { + return queryMixin.join(target); + } + + public Q leftJoin(PEntity target) { + return queryMixin.leftJoin(target); + } + + @Override + public List list(Expr[] args) { + return IteratorAdapter.asList(iterate(args)); + } + + @Override + public List list(Expr expr) { + return IteratorAdapter.asList(iterate(expr)); + } + + @Override + public SearchResults listResults(Expr expr) { + queryMixin.addToProjection(expr); + long total = count(); + try { + if (total > 0) { + QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); + return new SearchResults(list(expr), modifiers, total); + } else { + return SearchResults.emptyResults(); + } + + } finally { + reset(); + } + } + public Q on(EBoolean... conditions) { return queryMixin.on(conditions); } diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQuery.java index 0e803a5cc..10340218c 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQuery.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQuery.java @@ -30,7 +30,23 @@ public interface SQLQuery extends Query, Projectable { * @param o * @return */ - SQLQuery from(PEntity... o); + SQLQuery from(Expr... o); + + /** + * @param + * @param source + * @param alias + * @return + */ + SQLQuery from(ListSubQuery source, Expr alias); + + /** + * @param + * @param source + * @param alias + * @return + */ + SQLQuery from(SubQuery source, Expr alias); /** * Adds a full join to the given target diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQueryImpl.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQueryImpl.java index da9638283..1880a9f91 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQueryImpl.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQueryImpl.java @@ -9,6 +9,8 @@ import java.sql.Connection; import com.mysema.query.DefaultQueryMetadata; import com.mysema.query.QueryMetadata; +import com.mysema.query.types.expr.Expr; +import com.mysema.query.types.query.SubQuery; /** * SQLQueryImpl is a JDBC based implementation of the Querydsl SQLQuery interface @@ -59,5 +61,6 @@ public class SQLQueryImpl extends AbstractSQLQuery implements SQLQ public SQLQueryImpl clone(Connection conn){ return new SQLQueryImpl(conn, getTemplates(), getMetadata().clone()); } + } diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSubQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSubQuery.java index b879f0773..56981c859 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSubQuery.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSubQuery.java @@ -19,7 +19,7 @@ import com.mysema.query.types.path.PEntity; * */ public class SQLSubQuery extends DetachableQuery{ - + public SQLSubQuery() { this(new DefaultQueryMetadata()); } diff --git a/querydsl-sql/src/test/java/com/mysema/query/mssql/SelectMSSQLTest.java b/querydsl-sql/src/test/java/com/mysema/query/mssql/SelectMSSQLTest.java index c22a282af..9a6aecff4 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/mssql/SelectMSSQLTest.java +++ b/querydsl-sql/src/test/java/com/mysema/query/mssql/SelectMSSQLTest.java @@ -5,14 +5,27 @@ */ package com.mysema.query.mssql; +import static com.mysema.query.Constants.employee; +import static com.mysema.query.sql.mssql.SQLServerGrammar.rn; +import static com.mysema.query.sql.mssql.SQLServerGrammar.rowNumber; + +import java.util.Arrays; + import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Test; import org.junit.runner.RunWith; import com.mysema.query.Connections; import com.mysema.query.SelectBaseTest; import com.mysema.query.Target; import com.mysema.query.sql.SQLServerTemplates; +import com.mysema.query.sql.mssql.RowNumber; +import com.mysema.query.types.custom.CSimple; +import com.mysema.query.types.expr.Expr; +import com.mysema.query.types.path.PSimple; +import com.mysema.query.types.query.ListSubQuery; +import com.mysema.query.types.query.SubQuery; import com.mysema.testutil.FilteringTestRunner; import com.mysema.testutil.Label; import com.mysema.testutil.ResourceCheck; @@ -32,16 +45,30 @@ public class SelectMSSQLTest extends SelectBaseTest { dialect = new SQLServerTemplates().newLineToSingleSpace(); } - /* - * - SELECT - FROM ( - SELECT , ROW_NUMBER() OVER ([PARTITION BY ... ] ORDER BY ...) AS rowNum - FROM table1 - ) AS table2 - WHERE table2.rowNum BETWEEN ? and ? - * - */ - - + @Test + public void testPaging(){ + RowNumber rowNumber = rowNumber().orderBy(employee.lastname.asc()).as(rn); + // TODO : create a short cut for wild card + Expr all = CSimple.create(Object[].class, "*"); + + // simple + for (Object[] row : query().from(employee).list(employee.firstname, employee.lastname, rowNumber)){ + System.out.println(Arrays.asList(row)); + } + + // with subquery + ListSubQuery sub = s().from(employee).list(employee.firstname, employee.lastname, rowNumber); + PSimple subAlias = new PSimple(Object[].class, "s"); + for (Object[] row : query().from(sub, subAlias).list(all)){ + System.out.println(Arrays.asList(row)); + } + + // with subquery, only row number + SubQuery sub2 = s().from(employee).unique(rowNumber); + PSimple subAlias2 = new PSimple(Long.class, "s"); + for (Object[] row : query().from(sub2, subAlias2).list(all)){ + System.out.println(Arrays.asList(row)); + } + } + }