Refactored AbstractSQLQuery subtypes to support generic return types, to facilitate subtyping.

This commit is contained in:
Reuben D'Netto 2018-02-12 11:40:26 +11:00
parent ad35e9d946
commit 2b746f75ee
10 changed files with 622 additions and 392 deletions

View File

@ -0,0 +1,54 @@
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.querydsl.sql.mssql;
import com.querydsl.core.JoinFlag;
import com.querydsl.core.QueryMetadata;
import com.querydsl.sql.AbstractSQLQuery;
import com.querydsl.sql.Configuration;
import javax.inject.Provider;
import java.sql.Connection;
/**
* {@code AbstractSQLServerQuery} provides SQL Server related extensions to SQLQuery
*
* @param <T> result type
* @param <C> the concrete subtype
*
* @author tiwe
*/
public abstract class AbstractSQLServerQuery<T, C extends AbstractSQLQuery<T,C>> extends AbstractSQLQuery<T, C> {
public AbstractSQLServerQuery(Connection conn, Configuration configuration, QueryMetadata metadata) {
super(conn, configuration, metadata);
}
public AbstractSQLServerQuery(Provider<Connection> connProvider, Configuration configuration, QueryMetadata metadata) {
super(connProvider, configuration, metadata);
}
/**
* Set the table hints
*
* @param tableHints table hints
* @return the current object
*/
public C tableHints(SQLServerTableHints... tableHints) {
if (tableHints.length > 0) {
String hints = SQLServerGrammar.tableHints(tableHints);
addJoinFlag(hints, JoinFlag.Position.END);
}
return (C) this;
}
}

View File

@ -13,28 +13,27 @@
*/
package com.querydsl.sql.mssql;
import java.sql.Connection;
import javax.inject.Provider;
import com.querydsl.core.DefaultQueryMetadata;
import com.querydsl.core.JoinFlag;
import com.querydsl.core.QueryMetadata;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Expression;
import com.querydsl.sql.AbstractSQLQuery;
import com.querydsl.sql.Configuration;
import com.querydsl.sql.SQLServerTemplates;
import com.querydsl.sql.SQLTemplates;
import javax.inject.Provider;
import java.sql.Connection;
/**
* {@code SQLServerQuery} provides SQL Server related extensions to SQLQuery
*
* If you need to subtype this, use the base class instead.
*
* @param <T> result type
*
* @author tiwe
*/
public class SQLServerQuery<T> extends AbstractSQLQuery<T, SQLServerQuery<T>> {
public class SQLServerQuery<T> extends AbstractSQLServerQuery<T, SQLServerQuery<T>> {
public SQLServerQuery(Connection conn) {
this(conn, SQLServerTemplates.DEFAULT, new DefaultQueryMetadata());
@ -53,7 +52,7 @@ public class SQLServerQuery<T> extends AbstractSQLQuery<T, SQLServerQuery<T>> {
}
public SQLServerQuery(Connection conn, Configuration configuration) {
super(conn, configuration);
super(conn, configuration, new DefaultQueryMetadata());
}
public SQLServerQuery(Provider<Connection> connProvider, Configuration configuration, QueryMetadata metadata) {
@ -61,21 +60,7 @@ public class SQLServerQuery<T> extends AbstractSQLQuery<T, SQLServerQuery<T>> {
}
public SQLServerQuery(Provider<Connection> connProvider, Configuration configuration) {
super(connProvider, configuration);
}
/**
* Set the table hints
*
* @param tableHints table hints
* @return the current object
*/
public SQLServerQuery<T> tableHints(SQLServerTableHints... tableHints) {
if (tableHints.length > 0) {
String hints = SQLServerGrammar.tableHints(tableHints);
addJoinFlag(hints, JoinFlag.Position.END);
}
return this;
super(connProvider, configuration, new DefaultQueryMetadata());
}
@Override

View File

@ -0,0 +1,238 @@
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.querydsl.sql.mysql;
import com.google.common.base.Joiner;
import com.querydsl.core.JoinFlag;
import com.querydsl.core.QueryFlag.Position;
import com.querydsl.core.QueryMetadata;
import com.querydsl.sql.AbstractSQLQuery;
import com.querydsl.sql.Configuration;
import com.querydsl.sql.SQLQuery;
import javax.inject.Provider;
import java.io.File;
import java.sql.Connection;
/**
* {@code MySQLQuery} provides MySQL related extensions to SQLQuery.
*
* @author tiwe
* @see SQLQuery
* @param <T> result type
* @param <C> the concrete subtype
*/
public abstract class AbstractMySQLQuery<T, C extends AbstractSQLQuery<T, C>> extends AbstractSQLQuery<T, C> {
protected static final String WITH_ROLLUP = "\nwith rollup ";
protected static final String STRAIGHT_JOIN = "straight_join ";
protected static final String SQL_SMALL_RESULT = "sql_small_result ";
protected static final String SQL_NO_CACHE = "sql_no_cache ";
protected static final String LOCK_IN_SHARE_MODE = "\nlock in share mode ";
protected static final String HIGH_PRIORITY = "high_priority ";
protected static final String SQL_CALC_FOUND_ROWS = "sql_calc_found_rows ";
protected static final String SQL_CACHE = "sql_cache ";
protected static final String SQL_BUFFER_RESULT = "sql_buffer_result ";
protected static final String SQL_BIG_RESULT = "sql_big_result ";
protected static final Joiner JOINER = Joiner.on(", ");
public AbstractMySQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) {
super(conn, configuration, metadata);
}
public AbstractMySQLQuery(Provider<Connection> connProvider, Configuration configuration, QueryMetadata metadata) {
super(connProvider, configuration, metadata);
}
/**
* For SQL_BIG_RESULT, MySQL directly uses disk-based temporary tables if needed, and prefers
* sorting to using a temporary table with a key on the GROUP BY elements.
*
* @return the current object
*/
public C bigResult() {
return addFlag(Position.AFTER_SELECT, SQL_BIG_RESULT);
}
/**
* SQL_BUFFER_RESULT forces the result to be put into a temporary table. This helps MySQL free
* the table locks early and helps in cases where it takes a long time to send the result set
* to the client. This option can be used only for top-level SELECT statements, not for
* subqueries or following UNION.
*
* @return the current object
*/
public C bufferResult() {
return addFlag(Position.AFTER_SELECT, SQL_BUFFER_RESULT);
}
/**
* SQL_CACHE tells MySQL to store the result in the query cache if it is cacheable and the value
* of the query_cache_type system variable is 2 or DEMAND.
*
* @return the current object
*/
public C cache() {
return addFlag(Position.AFTER_SELECT, SQL_CACHE);
}
/**
* SQL_CALC_FOUND_ROWS tells MySQL to calculate how many rows there would be in the result set,
* disregarding any LIMIT clause. The number of rows can then be retrieved with SELECT FOUND_ROWS().
*
* @return the current object
*/
public C calcFoundRows() {
return addFlag(Position.AFTER_SELECT, SQL_CALC_FOUND_ROWS);
}
/**
* HIGH_PRIORITY gives the SELECT higher priority than a statement that updates a table.
* You should use this only for queries that are very fast and must be done at once.
*
* @return the current object
*/
public C highPriority() {
return addFlag(Position.AFTER_SELECT, HIGH_PRIORITY);
}
/**
* SELECT ... INTO var_list selects column values and stores them into variables.
*
* @param var variable name
* @return the current object
*/
public C into(String var) {
return addFlag(Position.END, "\ninto " + var);
}
/**
* SELECT ... INTO DUMPFILE writes a single row to a file without any formatting.
*
* @param file file to write to
* @return the current object
*/
public C intoDumpfile(File file) {
return addFlag(Position.END, "\ninto dumpfile '" + file.getPath() + "'");
}
/**
* SELECT ... INTO OUTFILE writes the selected rows to a file. Column and line terminators c
* an be specified to produce a specific output format.
*
* @param file file to write to
* @return the current object
*/
public C intoOutfile(File file) {
return addFlag(Position.END, "\ninto outfile '" + file.getPath() + "'");
}
/**
* Using LOCK IN SHARE MODE sets a shared lock that permits other transactions to read the examined
* rows but not to update or delete them.
*
* @return the current object
*/
public C lockInShareMode() {
return addFlag(Position.END, LOCK_IN_SHARE_MODE);
}
/**
* With SQL_NO_CACHE, the server does not use the query cache. It neither checks the query cache
* to see whether the result is already cached, nor does it cache the query result.
*
* @return the current object
*/
public C noCache() {
return addFlag(Position.AFTER_SELECT, SQL_NO_CACHE);
}
/**
* For SQL_SMALL_RESULT, MySQL uses fast temporary tables to store the resulting table instead
* of using sorting. This should not normally be needed.
*
* @return the current object
*/
public C smallResult() {
return addFlag(Position.AFTER_SELECT, SQL_SMALL_RESULT);
}
/**
* STRAIGHT_JOIN forces the optimizer to join the tables in the order in which they are listed
* in the FROM clause. You can use this to speed up a query if the optimizer joins the tables
* in nonoptimal order. STRAIGHT_JOIN also can be used in the table_references list.
*
* @return the current object
*/
public C straightJoin() {
return addFlag(Position.AFTER_SELECT, STRAIGHT_JOIN);
}
/**
* You can use FORCE INDEX, which acts like USE INDEX (index_list) but with the addition that a
* table scan is assumed to be very expensive. In other words, a table scan is used only if there
* is no way to use one of the given indexes to find rows in the table.
*
* @param indexes index names
* @return the current object
*/
public C forceIndex(String... indexes) {
return addJoinFlag(" force index (" + JOINER.join(indexes) + ")", JoinFlag.Position.END);
}
/**
* The alternative syntax IGNORE INDEX (index_list) can be used to tell MySQL to not use some
* particular index or indexes.
*
* @param indexes index names
* @return the current object
*/
public C ignoreIndex(String... indexes) {
return addJoinFlag(" ignore index (" + JOINER.join(indexes) + ")", JoinFlag.Position.END);
}
/**
* By specifying USE INDEX (index_list), you can tell MySQL to use only one of the named indexes
* to find rows in the table.
*
* @param indexes index names
* @return the current object
*/
public C useIndex(String... indexes) {
return addJoinFlag(" use index (" + JOINER.join(indexes) + ")", JoinFlag.Position.END);
}
/**
* The GROUP BY clause permits a WITH ROLLUP modifier that causes extra rows to be added to the
* summary output. These rows represent higher-level (or super-aggregate) summary operations.
* ROLLUP thus enables you to answer questions at multiple levels of analysis with a single query.
* It can be used, for example, to provide support for OLAP (Online Analytical Processing) operations.
*
* @return the current object
*/
public C withRollup() {
return addFlag(Position.AFTER_GROUP_BY, WITH_ROLLUP);
}
}

View File

@ -13,51 +13,25 @@
*/
package com.querydsl.sql.mysql;
import java.io.File;
import java.sql.Connection;
import javax.inject.Provider;
import com.google.common.base.Joiner;
import com.querydsl.core.DefaultQueryMetadata;
import com.querydsl.core.JoinFlag;
import com.querydsl.core.QueryFlag.Position;
import com.querydsl.core.QueryMetadata;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Expression;
import com.querydsl.sql.*;
import com.querydsl.sql.Configuration;
import com.querydsl.sql.MySQLTemplates;
import com.querydsl.sql.SQLTemplates;
import javax.inject.Provider;
import java.sql.Connection;
/**
* {@code MySQLQuery} provides MySQL related extensions to SQLQuery
* {@code MySQLQuery} provides MySQL related extensions to SQLQuery.
*
* @author tiwe
* @see SQLQuery
* @param <T> result type
* If you need to subtype this, use the base class instead.
*
* @param <T> the result type
*/
public class MySQLQuery<T> extends AbstractSQLQuery<T, MySQLQuery<T>> {
private static final String WITH_ROLLUP = "\nwith rollup ";
private static final String STRAIGHT_JOIN = "straight_join ";
private static final String SQL_SMALL_RESULT = "sql_small_result ";
private static final String SQL_NO_CACHE = "sql_no_cache ";
private static final String LOCK_IN_SHARE_MODE = "\nlock in share mode ";
private static final String HIGH_PRIORITY = "high_priority ";
private static final String SQL_CALC_FOUND_ROWS = "sql_calc_found_rows ";
private static final String SQL_CACHE = "sql_cache ";
private static final String SQL_BUFFER_RESULT = "sql_buffer_result ";
private static final String SQL_BIG_RESULT = "sql_big_result ";
private static final Joiner JOINER = Joiner.on(", ");
public class MySQLQuery<T> extends AbstractMySQLQuery<T, MySQLQuery<T>> {
public MySQLQuery(Connection conn) {
this(conn, new Configuration(MySQLTemplates.DEFAULT), new DefaultQueryMetadata());
}
@ -79,177 +53,7 @@ public class MySQLQuery<T> extends AbstractSQLQuery<T, MySQLQuery<T>> {
}
public MySQLQuery(Provider<Connection> connProvider, Configuration configuration) {
super(connProvider, configuration);
}
/**
* For SQL_BIG_RESULT, MySQL directly uses disk-based temporary tables if needed, and prefers
* sorting to using a temporary table with a key on the GROUP BY elements.
*
* @return the current object
*/
public MySQLQuery<T> bigResult() {
return addFlag(Position.AFTER_SELECT, SQL_BIG_RESULT);
}
/**
* SQL_BUFFER_RESULT forces the result to be put into a temporary table. This helps MySQL free
* the table locks early and helps in cases where it takes a long time to send the result set
* to the client. This option can be used only for top-level SELECT statements, not for
* subqueries or following UNION.
*
* @return the current object
*/
public MySQLQuery<T> bufferResult() {
return addFlag(Position.AFTER_SELECT, SQL_BUFFER_RESULT);
}
/**
* SQL_CACHE tells MySQL to store the result in the query cache if it is cacheable and the value
* of the query_cache_type system variable is 2 or DEMAND.
*
* @return the current object
*/
public MySQLQuery<T> cache() {
return addFlag(Position.AFTER_SELECT, SQL_CACHE);
}
/**
* SQL_CALC_FOUND_ROWS tells MySQL to calculate how many rows there would be in the result set,
* disregarding any LIMIT clause. The number of rows can then be retrieved with SELECT FOUND_ROWS().
*
* @return the current object
*/
public MySQLQuery<T> calcFoundRows() {
return addFlag(Position.AFTER_SELECT, SQL_CALC_FOUND_ROWS);
}
/**
* HIGH_PRIORITY gives the SELECT higher priority than a statement that updates a table.
* You should use this only for queries that are very fast and must be done at once.
*
* @return the current object
*/
public MySQLQuery<T> highPriority() {
return addFlag(Position.AFTER_SELECT, HIGH_PRIORITY);
}
/**
* SELECT ... INTO var_list selects column values and stores them into variables.
*
* @param var variable name
* @return the current object
*/
public MySQLQuery<T> into(String var) {
return addFlag(Position.END, "\ninto " + var);
}
/**
* SELECT ... INTO DUMPFILE writes a single row to a file without any formatting.
*
* @param file file to write to
* @return the current object
*/
public MySQLQuery<T> intoDumpfile(File file) {
return addFlag(Position.END, "\ninto dumpfile '" + file.getPath() + "'");
}
/**
* SELECT ... INTO OUTFILE writes the selected rows to a file. Column and line terminators c
* an be specified to produce a specific output format.
*
* @param file file to write to
* @return the current object
*/
public MySQLQuery<T> intoOutfile(File file) {
return addFlag(Position.END, "\ninto outfile '" + file.getPath() + "'");
}
/**
* Using LOCK IN SHARE MODE sets a shared lock that permits other transactions to read the examined
* rows but not to update or delete them.
*
* @return the current object
*/
public MySQLQuery<T> lockInShareMode() {
return addFlag(Position.END, LOCK_IN_SHARE_MODE);
}
/**
* With SQL_NO_CACHE, the server does not use the query cache. It neither checks the query cache
* to see whether the result is already cached, nor does it cache the query result.
*
* @return the current object
*/
public MySQLQuery<T> noCache() {
return addFlag(Position.AFTER_SELECT, SQL_NO_CACHE);
}
/**
* For SQL_SMALL_RESULT, MySQL uses fast temporary tables to store the resulting table instead
* of using sorting. This should not normally be needed.
*
* @return the current object
*/
public MySQLQuery<T> smallResult() {
return addFlag(Position.AFTER_SELECT, SQL_SMALL_RESULT);
}
/**
* STRAIGHT_JOIN forces the optimizer to join the tables in the order in which they are listed
* in the FROM clause. You can use this to speed up a query if the optimizer joins the tables
* in nonoptimal order. STRAIGHT_JOIN also can be used in the table_references list.
*
* @return the current object
*/
public MySQLQuery<T> straightJoin() {
return addFlag(Position.AFTER_SELECT, STRAIGHT_JOIN);
}
/**
* You can use FORCE INDEX, which acts like USE INDEX (index_list) but with the addition that a
* table scan is assumed to be very expensive. In other words, a table scan is used only if there
* is no way to use one of the given indexes to find rows in the table.
*
* @param indexes index names
* @return the current object
*/
public MySQLQuery<T> forceIndex(String... indexes) {
return addJoinFlag(" force index (" + JOINER.join(indexes) + ")", JoinFlag.Position.END);
}
/**
* The alternative syntax IGNORE INDEX (index_list) can be used to tell MySQL to not use some
* particular index or indexes.
*
* @param indexes index names
* @return the current object
*/
public MySQLQuery<T> ignoreIndex(String... indexes) {
return addJoinFlag(" ignore index (" + JOINER.join(indexes) + ")", JoinFlag.Position.END);
}
/**
* By specifying USE INDEX (index_list), you can tell MySQL to use only one of the named indexes
* to find rows in the table.
*
* @param indexes index names
* @return the current object
*/
public MySQLQuery<T> useIndex(String... indexes) {
return addJoinFlag(" use index (" + JOINER.join(indexes) + ")", JoinFlag.Position.END);
}
/**
* The GROUP BY clause permits a WITH ROLLUP modifier that causes extra rows to be added to the
* summary output. These rows represent higher-level (or super-aggregate) summary operations.
* ROLLUP thus enables you to answer questions at multiple levels of analysis with a single query.
* It can be used, for example, to provide support for OLAP (Online Analytical Processing) operations.
*
* @return the current object
*/
public MySQLQuery<T> withRollup() {
return addFlag(Position.AFTER_GROUP_BY, WITH_ROLLUP);
super(connProvider, configuration, new DefaultQueryMetadata());
}
@Override
@ -262,17 +66,19 @@ public class MySQLQuery<T> extends AbstractSQLQuery<T, MySQLQuery<T>> {
@Override
public <U> MySQLQuery<U> select(Expression<U> expr) {
queryMixin.setProjection(expr);
@SuppressWarnings("unchecked") // This is the new type
MySQLQuery<U> newType = (MySQLQuery<U>) this;
return newType;
@SuppressWarnings("unchecked")
MySQLQuery<U> res = (MySQLQuery<U>) this;
return res;
}
@Override
public MySQLQuery<Tuple> select(Expression<?>... exprs) {
queryMixin.setProjection(exprs);
@SuppressWarnings("unchecked") // This is the new type
MySQLQuery<Tuple> newType = (MySQLQuery<Tuple>) this;
return newType;
@SuppressWarnings("unchecked")
MySQLQuery<Tuple> res = (MySQLQuery<Tuple>) this;
return res;
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.querydsl.sql.oracle;
import com.querydsl.core.QueryFlag.Position;
import com.querydsl.core.QueryMetadata;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.Predicate;
import com.querydsl.sql.AbstractSQLQuery;
import com.querydsl.sql.Configuration;
import javax.inject.Provider;
import java.sql.Connection;
/**
* {@code OracleQuery} provides Oracle specific extensions to the base SQL query type
*
* @author tiwe
* @param <T> result type
* @param <C> the concrete subtype
*/
public abstract class AbstractOracleQuery<T, C extends AbstractSQLQuery<T, C>> extends AbstractSQLQuery<T, C> {
protected static final String CONNECT_BY = "\nconnect by ";
protected static final String CONNECT_BY_NOCYCLE_PRIOR = "\nconnect by nocycle prior ";
protected static final String CONNECT_BY_PRIOR = "\nconnect by prior ";
protected static final String ORDER_SIBLINGS_BY = "\norder siblings by ";
protected static final String START_WITH = "\nstart with ";
public AbstractOracleQuery(Connection conn, Configuration configuration, QueryMetadata metadata) {
super(conn, configuration, metadata);
}
public AbstractOracleQuery(Provider<Connection> connProvider, Configuration configuration, QueryMetadata metadata) {
super(connProvider, configuration, metadata);
}
/**
* CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy.
*
* @param cond condition
* @return the current object
*/
public C connectByPrior(Predicate cond) {
return addFlag(Position.BEFORE_ORDER, CONNECT_BY_PRIOR, cond);
}
/**
* CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy.
*
* @param cond condition
* @return the current object
*/
public C connectBy(Predicate cond) {
return addFlag(Position.BEFORE_ORDER, CONNECT_BY, cond);
}
/**
* CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy.
*
* @param cond condition
* @return the current object
*/
public C connectByNocyclePrior(Predicate cond) {
return addFlag(Position.BEFORE_ORDER, CONNECT_BY_NOCYCLE_PRIOR, cond);
}
/**
* START WITH specifies the root row(s) of the hierarchy.
*
* @param cond condition
* @return the current object
*/
public <A> C startWith(Predicate cond) {
return addFlag(Position.BEFORE_ORDER, START_WITH, cond);
}
/**
* ORDER SIBLINGS BY preserves any ordering specified in the hierarchical query clause and then
* applies the order_by_clause to the siblings of the hierarchy.
*
* @param path path
* @return the current object
*/
public C orderSiblingsBy(Expression<?> path) {
return addFlag(Position.BEFORE_ORDER, ORDER_SIBLINGS_BY, path);
}
// TODO : connect by root
// TODO : connect by iscycle
// TODO : connect by isleaf (pseudocolumn)
// TODO : sys connect path
}

View File

@ -13,39 +13,26 @@
*/
package com.querydsl.sql.oracle;
import java.sql.Connection;
import javax.inject.Provider;
import com.querydsl.core.DefaultQueryMetadata;
import com.querydsl.core.QueryFlag.Position;
import com.querydsl.core.QueryMetadata;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.Predicate;
import com.querydsl.sql.AbstractSQLQuery;
import com.querydsl.sql.Configuration;
import com.querydsl.sql.OracleTemplates;
import com.querydsl.sql.SQLTemplates;
import javax.inject.Provider;
import java.sql.Connection;
/**
* {@code OracleQuery} provides Oracle specific extensions to the base SQL query type
*
* If you need to subtype this, use the base class instead.
*
* @author tiwe
* @param <T> result type
*/
public class OracleQuery<T> extends AbstractSQLQuery<T, OracleQuery<T>> {
private static final String CONNECT_BY = "\nconnect by ";
private static final String CONNECT_BY_NOCYCLE_PRIOR = "\nconnect by nocycle prior ";
private static final String CONNECT_BY_PRIOR = "\nconnect by prior ";
private static final String ORDER_SIBLINGS_BY = "\norder siblings by ";
private static final String START_WITH = "\nstart with ";
public class OracleQuery<T> extends AbstractOracleQuery<T, OracleQuery<T>> {
public OracleQuery(Connection conn) {
this(conn, OracleTemplates.DEFAULT, new DefaultQueryMetadata());
}
@ -71,59 +58,9 @@ public class OracleQuery<T> extends AbstractSQLQuery<T, OracleQuery<T>> {
}
public OracleQuery(Provider<Connection> connProvider, Configuration configuration) {
super(connProvider, configuration);
super(connProvider, configuration, new DefaultQueryMetadata());
}
/**
* CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy.
*
* @param cond condition
* @return the current object
*/
public OracleQuery<T> connectByPrior(Predicate cond) {
return addFlag(Position.BEFORE_ORDER, CONNECT_BY_PRIOR, cond);
}
/**
* CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy.
*
* @param cond condition
* @return the current object
*/
public OracleQuery<T> connectBy(Predicate cond) {
return addFlag(Position.BEFORE_ORDER, CONNECT_BY, cond);
}
/**
* CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy.
*
* @param cond condition
* @return the current object
*/
public OracleQuery<T> connectByNocyclePrior(Predicate cond) {
return addFlag(Position.BEFORE_ORDER, CONNECT_BY_NOCYCLE_PRIOR, cond);
}
/**
* START WITH specifies the root row(s) of the hierarchy.
*
* @param cond condition
* @return the current object
*/
public <A> OracleQuery<T> startWith(Predicate cond) {
return addFlag(Position.BEFORE_ORDER, START_WITH, cond);
}
/**
* ORDER SIBLINGS BY preserves any ordering specified in the hierarchical query clause and then
* applies the order_by_clause to the siblings of the hierarchy.
*
* @param path path
* @return the current object
*/
public OracleQuery<T> orderSiblingsBy(Expression<?> path) {
return addFlag(Position.BEFORE_ORDER, ORDER_SIBLINGS_BY, path);
}
@Override
public OracleQuery<T> clone(Connection conn) {
@ -132,19 +69,11 @@ public class OracleQuery<T> extends AbstractSQLQuery<T, OracleQuery<T>> {
return q;
}
// TODO : connect by root
// TODO : connect by iscycle
// TODO : connect by isleaf (pseudocolumn)
// TODO : sys connect path
@Override
public <U> OracleQuery<U> select(Expression<U> expr) {
queryMixin.setProjection(expr);
@SuppressWarnings("unchecked") // This is the new type
OracleQuery<U> newType = (OracleQuery<U>) this;
OracleQuery<U> newType = (OracleQuery<U>) this;
return newType;
}
@ -152,9 +81,7 @@ public class OracleQuery<T> extends AbstractSQLQuery<T, OracleQuery<T>> {
public OracleQuery<Tuple> select(Expression<?>... exprs) {
queryMixin.setProjection(exprs);
@SuppressWarnings("unchecked") // This is the new type
OracleQuery<Tuple> newType = (OracleQuery<Tuple>) this;
OracleQuery<Tuple> newType = (OracleQuery<Tuple>) this;
return newType;
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.querydsl.sql.postgresql;
import com.querydsl.core.QueryFlag;
import com.querydsl.core.QueryFlag.Position;
import com.querydsl.core.QueryMetadata;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.sql.AbstractSQLQuery;
import com.querydsl.sql.Configuration;
import com.querydsl.sql.RelationalPath;
import com.querydsl.sql.SQLQuery;
import javax.inject.Provider;
import java.sql.Connection;
/**
* {@code PostgreSQLQuery} provides PostgreSQL related extensions to SQLQuery
*
* @param <T> result type
* @param <C> the concrete subtype
*
* @see SQLQuery
* @author tiwe
*/
public abstract class AbstractPostgreSQLQuery<T, C extends AbstractSQLQuery<T, C>> extends AbstractSQLQuery<T, C> {
public AbstractPostgreSQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) {
super(conn, configuration, metadata);
}
public AbstractPostgreSQLQuery(Provider<Connection> connProvider, Configuration configuration, QueryMetadata metadata) {
super(connProvider, configuration, metadata);
}
/**
* FOR SHARE causes the rows retrieved by the SELECT statement to be locked as though for update.
*
* @return the current object
*/
public C forShare() {
// global forShare support was added later, delegating to super implementation
return super.forShare();
}
/**
* With NOWAIT, the statement reports an error, rather than waiting, if a selected row cannot
* be locked immediately.
*
* @return the current object
*/
public C noWait() {
QueryFlag noWaitFlag = configuration.getTemplates().getNoWaitFlag();
return addFlag(noWaitFlag);
}
/**
* FOR UPDATE / FOR SHARE OF tables
*
* @param paths tables
* @return the current object
*/
public C of(RelationalPath<?>... paths) {
StringBuilder builder = new StringBuilder(" of ");
for (RelationalPath<?> path : paths) {
if (builder.length() > 4) {
builder.append(", ");
}
builder.append(getConfiguration().getTemplates().quoteIdentifier(path.getTableName()));
}
return addFlag(Position.END, builder.toString());
}
/**
* adds a DISTINCT ON clause
*
* @param exprs
* @return
*/
public C distinctOn(Expression<?>... exprs) {
return addFlag(Position.AFTER_SELECT,
Expressions.template(Object.class, "distinct on({0}) ",
ExpressionUtils.list(Object.class, exprs)));
}
}

View File

@ -13,29 +13,25 @@
*/
package com.querydsl.sql.postgresql;
import java.sql.Connection;
import javax.inject.Provider;
import com.querydsl.core.DefaultQueryMetadata;
import com.querydsl.core.QueryFlag;
import com.querydsl.core.QueryFlag.Position;
import com.querydsl.core.QueryMetadata;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.sql.*;
import com.querydsl.sql.Configuration;
import com.querydsl.sql.PostgreSQLTemplates;
import com.querydsl.sql.SQLTemplates;
import javax.inject.Provider;
import java.sql.Connection;
/**
* {@code PostgreSQLQuery} provides PostgreSQL related extensions to SQLQuery
* {@code PostgreSQLQuery} provides Postgres related extensions to SQLQuery.
*
* @param <T> result type
* If you need to subtype this, use the base class instead.
*
* @see SQLQuery
* @author tiwe
* @param <T> the result type
*/
public class PostgreSQLQuery<T> extends AbstractSQLQuery<T, PostgreSQLQuery<T>> {
public class PostgreSQLQuery<T> extends AbstractPostgreSQLQuery<T, PostgreSQLQuery<T>> {
public PostgreSQLQuery(Connection conn) {
this(conn, new Configuration(PostgreSQLTemplates.DEFAULT), new DefaultQueryMetadata());
@ -58,57 +54,7 @@ public class PostgreSQLQuery<T> extends AbstractSQLQuery<T, PostgreSQLQuery<T>>
}
public PostgreSQLQuery(Provider<Connection> connProvider, Configuration configuration) {
super(connProvider, configuration);
}
/**
* FOR SHARE causes the rows retrieved by the SELECT statement to be locked as though for update.
*
* @return the current object
*/
public PostgreSQLQuery<T> forShare() {
// global forShare support was added later, delegating to super implementation
return super.forShare();
}
/**
* With NOWAIT, the statement reports an error, rather than waiting, if a selected row cannot
* be locked immediately.
*
* @return the current object
*/
public PostgreSQLQuery<T> noWait() {
QueryFlag noWaitFlag = configuration.getTemplates().getNoWaitFlag();
return addFlag(noWaitFlag);
}
/**
* FOR UPDATE / FOR SHARE OF tables
*
* @param paths tables
* @return the current object
*/
public PostgreSQLQuery<T> of(RelationalPath<?>... paths) {
StringBuilder builder = new StringBuilder(" of ");
for (RelationalPath<?> path : paths) {
if (builder.length() > 4) {
builder.append(", ");
}
builder.append(getConfiguration().getTemplates().quoteIdentifier(path.getTableName()));
}
return addFlag(Position.END, builder.toString());
}
/**
* adds a DISTINCT ON clause
*
* @param exprs
* @return
*/
public PostgreSQLQuery<T> distinctOn(Expression<?>... exprs) {
return addFlag(Position.AFTER_SELECT,
Expressions.template(Object.class, "distinct on({0}) ",
ExpressionUtils.list(Object.class, exprs)));
super(connProvider, configuration, new DefaultQueryMetadata());
}
@ -123,7 +69,7 @@ public class PostgreSQLQuery<T> extends AbstractSQLQuery<T, PostgreSQLQuery<T>>
public <U> PostgreSQLQuery<U> select(Expression<U> expr) {
queryMixin.setProjection(expr);
@SuppressWarnings("unchecked") // This is the new type
PostgreSQLQuery<U> newType = (PostgreSQLQuery<U>) this;
PostgreSQLQuery<U> newType = (PostgreSQLQuery<U>) this;
return newType;
}
@ -131,7 +77,7 @@ public class PostgreSQLQuery<T> extends AbstractSQLQuery<T, PostgreSQLQuery<T>>
public PostgreSQLQuery<Tuple> select(Expression<?>... exprs) {
queryMixin.setProjection(exprs);
@SuppressWarnings("unchecked") // This is the new type
PostgreSQLQuery<Tuple> newType = (PostgreSQLQuery<Tuple>) this;
PostgreSQLQuery<Tuple> newType = (PostgreSQLQuery<Tuple>) this;
return newType;
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.querydsl.sql.teradata;
import com.querydsl.core.DefaultQueryMetadata;
import com.querydsl.core.QueryMetadata;
import com.querydsl.sql.AbstractSQLQuery;
import com.querydsl.sql.Configuration;
import com.querydsl.sql.SQLTemplates;
import com.querydsl.sql.TeradataTemplates;
import javax.inject.Provider;
import java.sql.Connection;
/**
* {@code AbstractTeradataQuery} provides Teradata related extensions to SQLQuery
*
* @param <T> result type
* @param <C> the concrete subtype.
*
* @author tiwe
*/
public abstract class AbstractTeradataQuery<T, C extends AbstractSQLQuery<T, C>> extends AbstractSQLQuery<T, C> {
public AbstractTeradataQuery(Connection conn) {
this(conn, new Configuration(TeradataTemplates.DEFAULT), new DefaultQueryMetadata());
}
public AbstractTeradataQuery(Connection conn, SQLTemplates templates) {
this(conn, new Configuration(templates), new DefaultQueryMetadata());
}
public AbstractTeradataQuery(Connection conn, Configuration configuration) {
this(conn, configuration, new DefaultQueryMetadata());
}
public AbstractTeradataQuery(Connection conn, Configuration configuration, QueryMetadata metadata) {
super(conn, configuration, metadata);
}
public AbstractTeradataQuery(Provider<Connection> connProvider, Configuration configuration, QueryMetadata metadata) {
super(connProvider, configuration, metadata);
}
public AbstractTeradataQuery(Provider<Connection> connProvider, Configuration configuration) {
super(connProvider, configuration);
}
}

View File

@ -13,10 +13,6 @@
*/
package com.querydsl.sql.teradata;
import java.sql.Connection;
import javax.inject.Provider;
import com.querydsl.core.DefaultQueryMetadata;
import com.querydsl.core.QueryFlag;
import com.querydsl.core.QueryMetadata;
@ -24,16 +20,24 @@ import com.querydsl.core.Tuple;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.sql.*;
import com.querydsl.sql.Configuration;
import com.querydsl.sql.SQLOps;
import com.querydsl.sql.SQLTemplates;
import com.querydsl.sql.TeradataTemplates;
import javax.inject.Provider;
import java.sql.Connection;
/**
* {@code TeradataQuery} provides Teradata related extensions to SQLQuery
*
* If you need to subtype this, use the base class instead.
*
* @param <T> result type
*
* @author tiwe
*/
public class TeradataQuery<T> extends AbstractSQLQuery<T, TeradataQuery<T>> {
public class TeradataQuery<T> extends AbstractTeradataQuery<T, TeradataQuery<T>> {
public TeradataQuery(Connection conn) {
this(conn, new Configuration(TeradataTemplates.DEFAULT), new DefaultQueryMetadata());