Get rid of RowSelection, QueryParameters and related deprecated functionality
This commit is contained in:
parent
1246a22c83
commit
f416b728a9
|
@ -8,7 +8,6 @@ package org.hibernate.community.dialect.pagination;
|
|||
|
||||
import org.hibernate.dialect.pagination.AbstractLimitHandler;
|
||||
import org.hibernate.dialect.pagination.LimitHandler;
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
/**
|
||||
|
@ -25,40 +24,6 @@ public class SkipFirstLimitHandler extends AbstractLimitHandler {
|
|||
this.variableLimit = variableLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
|
||||
boolean hasFirstRow = hasFirstRow( selection );
|
||||
boolean hasMaxRows = hasMaxRows( selection );
|
||||
|
||||
if ( !hasFirstRow && !hasMaxRows ) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
StringBuilder skipFirst = new StringBuilder();
|
||||
|
||||
if ( supportsVariableLimit() ) {
|
||||
if ( hasFirstRow ) {
|
||||
skipFirst.append( " skip ?" );
|
||||
}
|
||||
if ( hasMaxRows ) {
|
||||
skipFirst.append( " first ?" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( hasFirstRow ) {
|
||||
skipFirst.append( " skip " )
|
||||
.append( selection.getFirstRow() );
|
||||
}
|
||||
if ( hasMaxRows ) {
|
||||
skipFirst.append( " first " )
|
||||
.append( getMaxOrLimit( selection ) );
|
||||
}
|
||||
}
|
||||
|
||||
return insertAfterSelect( sql, skipFirst.toString() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit) {
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ import java.sql.SQLException;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||
|
@ -121,7 +120,7 @@ public abstract class AbstractLimitHandler implements LimitHandler {
|
|||
* specified in the offset clause?
|
||||
* <p/>
|
||||
* NOTE: what gets passed into
|
||||
* {@link AbstractLimitHandler#processSql(String, RowSelection)}
|
||||
* {@link AbstractLimitHandler#processSql(String, Limit)}
|
||||
* is the zero-based offset. Handlers which do not {@link #supportsVariableLimit}
|
||||
* should take care to perform any needed first-row-conversion calls prior
|
||||
* to injecting the limit values into the SQL string.
|
||||
|
@ -134,142 +133,6 @@ public abstract class AbstractLimitHandler implements LimitHandler {
|
|||
return zeroBasedFirstResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
throw new UnsupportedOperationException( "Paged queries not supported by " + getClass().getName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bindLimitParametersAtStartOfQuery(RowSelection selection, PreparedStatement statement, int index)
|
||||
throws SQLException {
|
||||
return bindLimitParametersFirst()
|
||||
? bindLimitParameters( selection, statement, index )
|
||||
: 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bindLimitParametersAtEndOfQuery(RowSelection selection, PreparedStatement statement, int index)
|
||||
throws SQLException {
|
||||
return !bindLimitParametersFirst()
|
||||
? bindLimitParameters( selection, statement, index )
|
||||
: 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxRows(RowSelection selection, PreparedStatement statement) throws SQLException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of binding parameter values needed by the LIMIT clause.
|
||||
*
|
||||
* @param selection the selection criteria for rows.
|
||||
* @param statement Statement to which to bind limit parameter values.
|
||||
* @param index Index from which to start binding.
|
||||
* @return The number of parameter values bound.
|
||||
* @throws SQLException Indicates problems binding parameter values.
|
||||
*/
|
||||
protected final int bindLimitParameters(RowSelection selection, PreparedStatement statement, int index)
|
||||
throws SQLException {
|
||||
|
||||
if ( !supportsVariableLimit() ) {
|
||||
//never any parameters to bind
|
||||
return 0;
|
||||
}
|
||||
|
||||
final boolean hasMaxRows = hasMaxRows( selection );
|
||||
final boolean hasFirstRow = hasFirstRow( selection );
|
||||
|
||||
final boolean bindLimit
|
||||
= hasMaxRows && supportsLimit()
|
||||
|| forceLimitUsage();
|
||||
final boolean bindOffset
|
||||
= hasFirstRow && supportsOffset()
|
||||
|| hasFirstRow && hasMaxRows && supportsLimitOffset();
|
||||
|
||||
if ( !bindLimit && !bindOffset ) {
|
||||
//no parameters to bind this time
|
||||
return 0;
|
||||
}
|
||||
|
||||
final boolean reverse = bindLimitParametersInReverseOrder();
|
||||
|
||||
if ( bindOffset ) {
|
||||
statement.setInt(
|
||||
index + ( reverse || !bindLimit ? 1 : 0 ),
|
||||
getFirstRow( selection )
|
||||
);
|
||||
}
|
||||
if ( bindLimit ) {
|
||||
statement.setInt(
|
||||
index + ( reverse || !bindOffset ? 0 : 1 ),
|
||||
getMaxOrLimit( selection )
|
||||
);
|
||||
}
|
||||
|
||||
return bindOffset && bindLimit ? 2 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a max row limit indicated?
|
||||
*
|
||||
* @param selection The row selection options
|
||||
*
|
||||
* @return Whether a max row limit was indicated
|
||||
*/
|
||||
public static boolean hasMaxRows(RowSelection selection) {
|
||||
return selection != null
|
||||
&& selection.getMaxRows() != null
|
||||
&& selection.getMaxRows() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a first row limit indicated?
|
||||
*
|
||||
* @param selection The row selection options
|
||||
*
|
||||
* @return Whether a first row limit was indicated
|
||||
*/
|
||||
public static boolean hasFirstRow(RowSelection selection) {
|
||||
return selection != null
|
||||
&& selection.getFirstRow() != null
|
||||
&& selection.getFirstRow() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some dialect-specific LIMIT clauses require the maximum last row number
|
||||
* (aka, first_row_number + total_row_count), while others require the maximum
|
||||
* returned row count (the total maximum number of rows to return).
|
||||
*
|
||||
* @param selection the selection criteria for rows.
|
||||
*
|
||||
* @return The appropriate value to bind into the limit clause.
|
||||
*/
|
||||
protected final int getMaxOrLimit(RowSelection selection) {
|
||||
if ( selection == null || selection.getMaxRows() == null ) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
final int firstRow = getFirstRow( selection );
|
||||
final int maxRows = selection.getMaxRows();
|
||||
final int maxOrLimit = useMaxForLimit()
|
||||
? maxRows + firstRow //TODO: maxRows + firstRow - 1, surely?
|
||||
: maxRows;
|
||||
// Use Integer.MAX_VALUE on overflow
|
||||
return maxOrLimit < 0 ? Integer.MAX_VALUE : maxOrLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the indicated first row for pagination
|
||||
*
|
||||
* @param selection The row selection options
|
||||
*
|
||||
* @return The first row
|
||||
*/
|
||||
protected final int getFirstRow(RowSelection selection) {
|
||||
if ( selection == null || selection.getFirstRow() == null ) {
|
||||
return 0;
|
||||
}
|
||||
return convertToFirstRowValue( selection.getFirstRow() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit) {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect.pagination;
|
||||
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
import static java.lang.String.valueOf;
|
||||
|
@ -33,19 +32,6 @@ public abstract class AbstractNoOffsetLimitHandler extends AbstractLimitHandler
|
|||
|
||||
protected abstract String insert(String limitClause, String sql);
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
if ( !hasMaxRows( selection ) ) {
|
||||
return sql;
|
||||
}
|
||||
String limitClause = limitClause();
|
||||
if ( !supportsVariableLimit() ) {
|
||||
String limitLiteral = valueOf( getMaxOrLimit(selection) );
|
||||
limitClause = limitClause.replace( "?", limitLiteral );
|
||||
}
|
||||
return insert( limitClause, sql );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit) {
|
||||
if ( !hasMaxRows( limit ) ) {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect.pagination;
|
||||
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
/**
|
||||
|
@ -19,14 +18,6 @@ public abstract class AbstractSimpleLimitHandler extends AbstractLimitHandler {
|
|||
|
||||
protected abstract String limitClause(boolean hasFirstRow);
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
if ( !hasMaxRows( selection ) ) {
|
||||
return sql;
|
||||
}
|
||||
return insert( limitClause( hasFirstRow( selection ) ), sql );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit) {
|
||||
if ( !hasMaxRows( limit ) ) {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect.pagination;
|
||||
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
/**
|
||||
|
@ -18,27 +17,6 @@ public class LegacyDB2LimitHandler extends AbstractLimitHandler {
|
|||
|
||||
public static final LegacyDB2LimitHandler INSTANCE = new LegacyDB2LimitHandler();
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
if ( hasFirstRow( selection ) ) {
|
||||
//nest the main query in an outer select
|
||||
return "select * from (select row_.*,rownumber() over(order by order of row_) as rownumber_ from ("
|
||||
+ sql + fetchFirstRows( selection )
|
||||
+ ") as row_) as query_ where rownumber_>"
|
||||
+ selection.getFirstRow()
|
||||
+ " order by rownumber_";
|
||||
}
|
||||
else {
|
||||
//on DB2, offset/fetch comes after all the
|
||||
//various "for update"ish clauses
|
||||
return insertAtEnd( fetchFirstRows( selection ), sql );
|
||||
}
|
||||
}
|
||||
|
||||
private String fetchFirstRows(RowSelection limit) {
|
||||
return " fetch first " + getMaxOrLimit( limit ) + " rows only";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit) {
|
||||
if ( hasFirstRow( limit ) ) {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
package org.hibernate.dialect.pagination;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
/**
|
||||
|
@ -67,22 +66,6 @@ public class LegacyLimitHandler extends AbstractLimitHandler {
|
|||
return dialect.convertToFirstRowValue( zeroBasedFirstResult );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
final boolean useLimitOffset
|
||||
= supportsOffset()
|
||||
&& hasFirstRow( selection )
|
||||
|| supportsLimit()
|
||||
&& supportsLimitOffset()
|
||||
&& hasFirstRow( selection )
|
||||
&& hasMaxRows( selection );
|
||||
return dialect.getLimitString(
|
||||
sql,
|
||||
useLimitOffset ? getFirstRow( selection ) : 0,
|
||||
getMaxOrLimit( selection )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit) {
|
||||
final boolean useLimitOffset
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect.pagination;
|
||||
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -22,41 +21,6 @@ public class LegacyOracleLimitHandler extends AbstractLimitHandler {
|
|||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
final boolean hasOffset = hasFirstRow( selection );
|
||||
sql = sql.trim();
|
||||
|
||||
String forUpdateClause = null;
|
||||
Matcher forUpdateMatcher = getForUpdatePattern().matcher( sql );
|
||||
if ( forUpdateMatcher.find() ) {
|
||||
int forUpdateIndex = forUpdateMatcher.start();
|
||||
// save 'for update ...' and then remove it
|
||||
forUpdateClause = sql.substring( forUpdateIndex );
|
||||
sql = sql.substring( 0, forUpdateIndex );
|
||||
}
|
||||
|
||||
final StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 );
|
||||
if ( hasOffset ) {
|
||||
pagingSelect.append( "select * from (select row_.*,rownum rownum_ from (" ).append( sql );
|
||||
if ( version < 900 ) {
|
||||
pagingSelect.append( ") row_) where rownum_<=? and rownum_>?" );
|
||||
}
|
||||
else {
|
||||
pagingSelect.append( ") row_ where rownum<=?) where rownum_>?" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
pagingSelect.append( "select * from (" ).append( sql ).append( ") where rownum<=?" );
|
||||
}
|
||||
|
||||
if ( forUpdateClause != null ) {
|
||||
pagingSelect.append( forUpdateClause );
|
||||
}
|
||||
|
||||
return pagingSelect.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit) {
|
||||
final boolean hasOffset = hasFirstRow( limit );
|
||||
|
|
|
@ -9,8 +9,6 @@ package org.hibernate.dialect.pagination;
|
|||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
|
||||
|
@ -43,139 +41,16 @@ public interface LimitHandler {
|
|||
*/
|
||||
boolean supportsLimitOffset();
|
||||
|
||||
default String processSql(String sql, Limit limit) {
|
||||
return processSql(
|
||||
sql,
|
||||
limit == null ? null : new RowSelection(
|
||||
limit.getFirstRow(),
|
||||
limit.getMaxRows(),
|
||||
null,
|
||||
null
|
||||
)
|
||||
);
|
||||
}
|
||||
String processSql(String sql, Limit limit);
|
||||
|
||||
default String processSql(String sql, Limit limit, QueryOptions queryOptions) {
|
||||
return processSql(
|
||||
sql,
|
||||
limit == null ? null : new RowSelection(
|
||||
limit.getFirstRow(),
|
||||
limit.getMaxRows(),
|
||||
null,
|
||||
null
|
||||
)
|
||||
);
|
||||
return processSql( sql, limit );
|
||||
}
|
||||
|
||||
default int bindLimitParametersAtStartOfQuery(Limit limit, PreparedStatement statement, int index)
|
||||
throws SQLException {
|
||||
return bindLimitParametersAtStartOfQuery(
|
||||
limit == null ? null : new RowSelection(
|
||||
limit.getFirstRow(),
|
||||
limit.getMaxRows(),
|
||||
null,
|
||||
null
|
||||
),
|
||||
statement,
|
||||
index
|
||||
);
|
||||
}
|
||||
int bindLimitParametersAtStartOfQuery(Limit limit, PreparedStatement statement, int index) throws SQLException;
|
||||
|
||||
default int bindLimitParametersAtEndOfQuery(Limit limit, PreparedStatement statement, int index)
|
||||
throws SQLException {
|
||||
return bindLimitParametersAtEndOfQuery(
|
||||
limit == null ? null : new RowSelection(
|
||||
limit.getFirstRow(),
|
||||
limit.getMaxRows(),
|
||||
null,
|
||||
null
|
||||
),
|
||||
statement,
|
||||
index
|
||||
);
|
||||
}
|
||||
int bindLimitParametersAtEndOfQuery(Limit limit, PreparedStatement statement, int index) throws SQLException;
|
||||
|
||||
default void setMaxRows(Limit limit, PreparedStatement statement) throws SQLException {
|
||||
setMaxRows(
|
||||
limit == null ? null : new RowSelection(
|
||||
limit.getFirstRow(),
|
||||
limit.getMaxRows(),
|
||||
null,
|
||||
null
|
||||
),
|
||||
statement
|
||||
);
|
||||
}
|
||||
void setMaxRows(Limit limit, PreparedStatement statement) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return processed SQL query.
|
||||
*
|
||||
* @param sql the SQL query to process.
|
||||
* @param selection the selection criteria for rows.
|
||||
*
|
||||
* @return Query statement with LIMIT clause applied.
|
||||
* @deprecated todo (6.0): remove in favor of Limit version?
|
||||
*/
|
||||
@Deprecated
|
||||
String processSql(String sql, RowSelection selection);
|
||||
|
||||
/**
|
||||
* Return processed SQL query.
|
||||
*
|
||||
* @param sql the SQL query to process.
|
||||
* @param queryParameters the queryParameters.
|
||||
*
|
||||
* @return Query statement with LIMIT clause applied.
|
||||
* @deprecated Use {@link #processSql(String, Limit, QueryOptions)}
|
||||
* todo (6.0): remove in favor of Limit version?
|
||||
*/
|
||||
@Deprecated
|
||||
default String processSql(String sql, QueryParameters queryParameters ){
|
||||
return processSql( sql, queryParameters.getRowSelection() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind parameter values needed by the limit and offset clauses
|
||||
* right at the start of the original query statement, before all
|
||||
* the other query parameters.
|
||||
*
|
||||
* @param selection the selection criteria for rows.
|
||||
* @param statement Statement to which to bind limit parameter values.
|
||||
* @param index Index from which to start binding.
|
||||
* @return The number of parameter values bound.
|
||||
* @throws SQLException Indicates problems binding parameter values.
|
||||
* @deprecated todo (6.0): remove in favor of Limit version?
|
||||
*/
|
||||
@Deprecated
|
||||
int bindLimitParametersAtStartOfQuery(RowSelection selection, PreparedStatement statement, int index)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Bind parameter values needed by the limit and offset clauses
|
||||
* right at the end of the original query statement, after all
|
||||
* the other query parameters.
|
||||
*
|
||||
* @param selection the selection criteria for rows.
|
||||
* @param statement Statement to which to bind limit parameter values.
|
||||
* @param index Index from which to start binding.
|
||||
* @return The number of parameter values bound.
|
||||
* @throws SQLException Indicates problems binding parameter values.
|
||||
* @deprecated todo (6.0): remove in favor of Limit version?
|
||||
*/
|
||||
@Deprecated
|
||||
int bindLimitParametersAtEndOfQuery(RowSelection selection, PreparedStatement statement, int index)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Use JDBC APIs to limit the number of rows returned by the SQL query.
|
||||
* Handlers that do not support a SQL limit clause should implement this
|
||||
* method.
|
||||
*
|
||||
* @param selection the selection criteria for rows.
|
||||
* @param statement Statement which number of returned rows shall be limited.
|
||||
* @throws SQLException Indicates problems while limiting maximum rows returned.
|
||||
* @deprecated todo (6.0): remove in favor of Limit version?
|
||||
*/
|
||||
@Deprecated
|
||||
void setMaxRows(RowSelection selection, PreparedStatement statement) throws SQLException;
|
||||
}
|
||||
|
|
|
@ -8,12 +8,9 @@ package org.hibernate.dialect.pagination;
|
|||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||
import static java.util.regex.Pattern.compile;
|
||||
|
||||
/**
|
||||
|
@ -25,37 +22,6 @@ public class NoopLimitHandler extends AbstractLimitHandler {
|
|||
|
||||
public static final NoopLimitHandler INSTANCE = new NoopLimitHandler();
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bindLimitParametersAtStartOfQuery(RowSelection selection, PreparedStatement statement, int index) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bindLimitParametersAtEndOfQuery(RowSelection selection, PreparedStatement statement, int index) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxRows(RowSelection selection, PreparedStatement statement) throws SQLException {
|
||||
if ( selection != null && selection.getMaxRows() != null && selection.getMaxRows() > 0 ) {
|
||||
final int maxRows = selection.getMaxRows() + convertToFirstRowValue(
|
||||
selection.getFirstRow() == null ? 0 : selection.getFirstRow()
|
||||
);
|
||||
// Use Integer.MAX_VALUE on overflow
|
||||
if ( maxRows < 0 ) {
|
||||
statement.setMaxRows( Integer.MAX_VALUE );
|
||||
}
|
||||
else {
|
||||
statement.setMaxRows( maxRows );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit) {
|
||||
return sql;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect.pagination;
|
||||
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
/**
|
||||
|
@ -26,52 +25,6 @@ public class OffsetFetchLimitHandler extends AbstractLimitHandler {
|
|||
this.variableLimit = variableLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
|
||||
boolean hasFirstRow = hasFirstRow(selection);
|
||||
boolean hasMaxRows = hasMaxRows(selection);
|
||||
|
||||
if ( !hasFirstRow && !hasMaxRows ) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
StringBuilder offsetFetch = new StringBuilder();
|
||||
|
||||
begin(sql, offsetFetch, hasFirstRow, hasMaxRows);
|
||||
|
||||
if ( hasFirstRow ) {
|
||||
offsetFetch.append( " offset " );
|
||||
if ( supportsVariableLimit() ) {
|
||||
offsetFetch.append( "?" );
|
||||
}
|
||||
else {
|
||||
offsetFetch.append( selection.getFirstRow() );
|
||||
}
|
||||
if ( renderOffsetRowsKeyword() ) {
|
||||
offsetFetch.append( " rows" );
|
||||
}
|
||||
|
||||
}
|
||||
if ( hasMaxRows ) {
|
||||
if ( hasFirstRow ) {
|
||||
offsetFetch.append( " fetch next " );
|
||||
}
|
||||
else {
|
||||
offsetFetch.append( " fetch first " );
|
||||
}
|
||||
if ( supportsVariableLimit() ) {
|
||||
offsetFetch.append( "?" );
|
||||
}
|
||||
else {
|
||||
offsetFetch.append( getMaxOrLimit( selection ) );
|
||||
}
|
||||
offsetFetch.append( " rows only" );
|
||||
}
|
||||
|
||||
return insert( offsetFetch.toString(), sql );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit) {
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@ import java.util.Locale;
|
|||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
|
||||
|
@ -33,18 +31,6 @@ public class Oracle12LimitHandler extends AbstractLimitHandler {
|
|||
Oracle12LimitHandler() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
final boolean hasFirstRow = hasFirstRow( selection );
|
||||
final boolean hasMaxRows = hasMaxRows( selection );
|
||||
|
||||
if ( !hasMaxRows ) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
return processSql( sql, getForUpdateIndex( sql ), hasFirstRow );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit, QueryOptions queryOptions) {
|
||||
final boolean hasMaxRows = hasMaxRows( limit );
|
||||
|
@ -58,24 +44,6 @@ public class Oracle12LimitHandler extends AbstractLimitHandler {
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, QueryParameters queryParameters) {
|
||||
final RowSelection selection = queryParameters.getRowSelection();
|
||||
|
||||
final boolean hasMaxRows = hasMaxRows( selection );
|
||||
|
||||
if ( !hasMaxRows ) {
|
||||
return sql;
|
||||
}
|
||||
sql = sql.trim();
|
||||
|
||||
return processSql(
|
||||
sql,
|
||||
hasFirstRow( selection ),
|
||||
queryParameters.getLockOptions()
|
||||
);
|
||||
}
|
||||
|
||||
protected String processSql(String sql, boolean hasFirstRow, LockOptions lockOptions) {
|
||||
if ( lockOptions != null ) {
|
||||
final LockMode lockMode = lockOptions.getLockMode();
|
||||
|
|
|
@ -13,7 +13,6 @@ import java.util.List;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
|
@ -55,84 +54,6 @@ public class SQLServer2005LimitHandler extends AbstractLimitHandler {
|
|||
return zeroBasedFirstResult + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the offset of the given {@link RowSelection} is {@literal 0},
|
||||
* add a {@code top(?)} clause to the given SQL query. When the offset
|
||||
* is non-zero, wrap the given query in an outer query that limits the
|
||||
* results using the {@code row_number()} window function.
|
||||
*
|
||||
* <pre>
|
||||
* with query_ as (
|
||||
* select row_.*, row_number()
|
||||
* over (order by current_timestamp) AS rownumber_
|
||||
* from ( [original-query] ) row_
|
||||
* )
|
||||
* select [alias-list] from query_
|
||||
* where rownumber_ >= ? and rownumber_ < ?
|
||||
* </pre>
|
||||
*
|
||||
* Where {@code [original-query]} is the original SQL query, with a
|
||||
* {@code top()} clause added iff the query has an {@code order by}
|
||||
* clause, and with generated aliases added to any elements of the
|
||||
* projection list that don't already have aliases, and
|
||||
* {@code [alias-list]} is a list of aliases in the projection list.
|
||||
*
|
||||
* @return A new SQL statement
|
||||
*/
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
sql = sql.trim();
|
||||
if ( sql.endsWith(";") ) {
|
||||
sql = sql.substring( 0, sql.length()-1 );
|
||||
}
|
||||
|
||||
final int selectOffset = Keyword.SELECT.rootOffset( sql );
|
||||
final int afterSelectOffset = Keyword.SELECT.endOffset( sql, selectOffset );
|
||||
final int fromOffset = Keyword.FROM.rootOffset( sql ); //TODO: what if there is no 'from' clause?!
|
||||
|
||||
boolean hasCommonTables = Keyword.WITH.occursAt( sql, 0 );
|
||||
boolean hasOrderBy = Keyword.ORDER_BY.rootOffset( sql ) > 0;
|
||||
boolean hasFirstRow = hasFirstRow( selection );
|
||||
|
||||
final StringBuilder result = new StringBuilder( sql );
|
||||
|
||||
if ( !hasFirstRow || hasOrderBy ) {
|
||||
result.insert( afterSelectOffset, " top(?)" );
|
||||
topAdded = true;
|
||||
}
|
||||
|
||||
if ( hasFirstRow ) {
|
||||
|
||||
// enclose original SQL statement with outer query
|
||||
// that provides the rownumber_ column
|
||||
|
||||
String aliases = selectAliases( sql, afterSelectOffset, fromOffset, result ); //warning: changes result by side-effect
|
||||
result.insert( selectOffset, ( hasCommonTables ? "," : "with" )
|
||||
+ " query_ as (select row_.*,row_number() over (order by current_timestamp) as rownumber_ from (" )
|
||||
.append( ") row_) select " ).append( aliases )
|
||||
.append( " from query_ where rownumber_>=? and rownumber_<?" );
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bindLimitParametersAtStartOfQuery(RowSelection selection, PreparedStatement statement, int index) throws SQLException {
|
||||
if ( topAdded ) {
|
||||
// bind parameter to top(?)
|
||||
statement.setInt( index, getMaxOrLimit( selection ) - 1 );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bindLimitParametersAtEndOfQuery(RowSelection selection, PreparedStatement statement, int index) throws SQLException {
|
||||
return hasFirstRow( selection )
|
||||
? super.bindLimitParametersAtEndOfQuery( selection, statement, index )
|
||||
: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the offset of the given {@link RowSelection} is {@literal 0},
|
||||
* add a {@code top(?)} clause to the given SQL query. When the offset
|
||||
|
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.engine.internal;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.engine.spi.TypedValue;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Centralizes the commonality regarding binding of parameter values into PreparedStatements as this logic is
|
||||
* used in many places.
|
||||
* <p/>
|
||||
* Ideally would like to move to the parameter handling as it is done in the hql.ast package.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ParameterBinder {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
ParameterBinder.class.getName()
|
||||
);
|
||||
|
||||
/**
|
||||
* Helper contract for dealing with named parameters and resolving their locations
|
||||
*/
|
||||
public static interface NamedParameterSource {
|
||||
/**
|
||||
* Retrieve the locations for the given parameter name
|
||||
*
|
||||
* @param name The parameter name
|
||||
*
|
||||
* @return The locations
|
||||
*/
|
||||
public int[] getNamedParameterLocations(String name);
|
||||
}
|
||||
|
||||
private ParameterBinder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform parameter binding
|
||||
*
|
||||
* @param st The statement to bind parameters to
|
||||
* @param queryParameters The parameters
|
||||
* @param start The initial bind position
|
||||
* @param source The named parameter source, for resolving the locations of named parameters
|
||||
* @param session The session
|
||||
*
|
||||
* @return The next bind position after the last position we bound here.
|
||||
*
|
||||
* @throws SQLException Indicates a problem calling JDBC bind methods
|
||||
* @throws HibernateException Indicates a problem access bind values.
|
||||
*/
|
||||
public static int bindQueryParameters(
|
||||
final PreparedStatement st,
|
||||
final QueryParameters queryParameters,
|
||||
final int start,
|
||||
final NamedParameterSource source,
|
||||
SessionImplementor session) throws SQLException, HibernateException {
|
||||
int col = start;
|
||||
col += bindPositionalParameters( st, queryParameters, col, session );
|
||||
col += bindNamedParameters( st, queryParameters, col, source, session );
|
||||
return col;
|
||||
}
|
||||
|
||||
private static int bindPositionalParameters(
|
||||
final PreparedStatement st,
|
||||
final QueryParameters queryParameters,
|
||||
final int start,
|
||||
final SessionImplementor session) throws SQLException, HibernateException {
|
||||
return bindPositionalParameters(
|
||||
st,
|
||||
queryParameters.getPositionalParameterValues(),
|
||||
queryParameters.getPositionalParameterTypes(),
|
||||
start,
|
||||
session
|
||||
);
|
||||
}
|
||||
|
||||
private static int bindPositionalParameters(
|
||||
final PreparedStatement st,
|
||||
final Object[] values,
|
||||
final Type[] types,
|
||||
final int start,
|
||||
final SessionImplementor session) throws SQLException, HibernateException {
|
||||
int span = 0;
|
||||
for ( int i = 0; i < values.length; i++ ) {
|
||||
types[i].nullSafeSet( st, values[i], start + span, session );
|
||||
span += types[i].getColumnSpan( session.getFactory() );
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
private static int bindNamedParameters(
|
||||
final PreparedStatement ps,
|
||||
final QueryParameters queryParameters,
|
||||
final int start,
|
||||
final NamedParameterSource source,
|
||||
final SessionImplementor session) throws SQLException, HibernateException {
|
||||
return bindNamedParameters( ps, queryParameters.getNamedParameters(), start, source, session );
|
||||
}
|
||||
|
||||
private static int bindNamedParameters(
|
||||
final PreparedStatement ps,
|
||||
final Map namedParams,
|
||||
final int start,
|
||||
final NamedParameterSource source,
|
||||
final SessionImplementor session) throws SQLException, HibernateException {
|
||||
if ( namedParams != null ) {
|
||||
// assumes that types are all of span 1
|
||||
final Iterator iter = namedParams.entrySet().iterator();
|
||||
int result = 0;
|
||||
while ( iter.hasNext() ) {
|
||||
final Map.Entry e = (Map.Entry) iter.next();
|
||||
final String name = (String) e.getKey();
|
||||
final TypedValue typedVal = (TypedValue) e.getValue();
|
||||
final int[] locations = source.getNamedParameterLocations( name );
|
||||
for ( int location : locations ) {
|
||||
if ( LOG.isDebugEnabled() ) {
|
||||
LOG.debugf(
|
||||
"bindNamedParameters() %s -> %s [%s]",
|
||||
typedVal.getValue(),
|
||||
name,
|
||||
location + start
|
||||
);
|
||||
}
|
||||
typedVal.getType().nullSafeSet( ps, typedVal.getValue(), location + start, session );
|
||||
}
|
||||
result += locations.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -1,597 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.engine.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.util.EntityPrinter;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
import org.hibernate.transform.ResultTransformer;
|
||||
import org.hibernate.type.ComponentType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public final class QueryParameters {
|
||||
private static final Logger LOG = CoreLogging.logger( QueryParameters.class );
|
||||
public static final String HQL_VARIABLE_PREFIX = ":";
|
||||
|
||||
|
||||
private Type[] positionalParameterTypes;
|
||||
private Object[] positionalParameterValues;
|
||||
private Map<String, TypedValue> namedParameters;
|
||||
|
||||
private LockOptions lockOptions;
|
||||
private RowSelection rowSelection;
|
||||
private boolean cacheable;
|
||||
private String cacheRegion;
|
||||
private String comment;
|
||||
private List<String> queryHints;
|
||||
private ScrollMode scrollMode;
|
||||
private Serializable[] collectionKeys;
|
||||
private Object optionalObject;
|
||||
private String optionalEntityName;
|
||||
private Serializable optionalId;
|
||||
private boolean isReadOnlyInitialized;
|
||||
private boolean readOnly;
|
||||
private boolean callable;
|
||||
private boolean autodiscovertypes;
|
||||
private boolean isNaturalKeyLookup;
|
||||
private boolean passDistinctThrough = true;
|
||||
|
||||
private final ResultTransformer resultTransformer; // why is all others non final ?
|
||||
|
||||
private String processedSQL;
|
||||
private Type[] processedPositionalParameterTypes;
|
||||
private Object[] processedPositionalParameterValues;
|
||||
|
||||
public QueryParameters() {
|
||||
this( ArrayHelper.EMPTY_TYPE_ARRAY, ArrayHelper.EMPTY_OBJECT_ARRAY );
|
||||
}
|
||||
|
||||
public QueryParameters(Type type, Object value) {
|
||||
this( new Type[] { type }, new Object[] { value } );
|
||||
}
|
||||
|
||||
public QueryParameters(
|
||||
final Type[] positionalParameterTypes,
|
||||
final Object[] positionalParameterValues,
|
||||
final Object optionalObject,
|
||||
final String optionalEntityName,
|
||||
final Serializable optionalObjectId) {
|
||||
this( positionalParameterTypes, positionalParameterValues );
|
||||
this.optionalObject = optionalObject;
|
||||
this.optionalId = optionalObjectId;
|
||||
this.optionalEntityName = optionalEntityName;
|
||||
}
|
||||
|
||||
public QueryParameters(
|
||||
final Type[] positionalParameterTypes,
|
||||
final Object[] positionalParameterValues) {
|
||||
this( positionalParameterTypes, positionalParameterValues, null, null, false, false, false, null, null, null, false, null );
|
||||
}
|
||||
|
||||
public QueryParameters(
|
||||
final Type[] positionalParameterTypes,
|
||||
final Object[] positionalParameterValues,
|
||||
final Object[] collectionKeys) {
|
||||
this( positionalParameterTypes, positionalParameterValues, null, (Serializable[]) collectionKeys );
|
||||
}
|
||||
|
||||
public QueryParameters(
|
||||
final Type[] positionalParameterTypes,
|
||||
final Object[] positionalParameterValues,
|
||||
final Serializable[] collectionKeys) {
|
||||
this( positionalParameterTypes, positionalParameterValues, null, collectionKeys );
|
||||
}
|
||||
|
||||
public QueryParameters(
|
||||
final Type[] positionalParameterTypes,
|
||||
final Object[] positionalParameterValues,
|
||||
final Map<String, TypedValue> namedParameters,
|
||||
final Serializable[] collectionKeys) {
|
||||
this(
|
||||
positionalParameterTypes,
|
||||
positionalParameterValues,
|
||||
namedParameters,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
collectionKeys,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
public QueryParameters(
|
||||
final Type[] positionalParameterTypes,
|
||||
final Object[] positionalParameterValues,
|
||||
final LockOptions lockOptions,
|
||||
final RowSelection rowSelection,
|
||||
final boolean isReadOnlyInitialized,
|
||||
final boolean readOnly,
|
||||
final boolean cacheable,
|
||||
final String cacheRegion,
|
||||
//final boolean forceCacheRefresh,
|
||||
final String comment,
|
||||
final List<String> queryHints,
|
||||
final boolean isLookupByNaturalKey,
|
||||
final ResultTransformer transformer) {
|
||||
this(
|
||||
positionalParameterTypes,
|
||||
positionalParameterValues,
|
||||
null,
|
||||
lockOptions,
|
||||
rowSelection,
|
||||
isReadOnlyInitialized,
|
||||
readOnly,
|
||||
cacheable,
|
||||
cacheRegion,
|
||||
comment,
|
||||
queryHints,
|
||||
null,
|
||||
transformer
|
||||
);
|
||||
isNaturalKeyLookup = isLookupByNaturalKey;
|
||||
}
|
||||
|
||||
public QueryParameters(
|
||||
final Type[] positionalParameterTypes,
|
||||
final Object[] positionalParameterValues,
|
||||
final Map<String, TypedValue> namedParameters,
|
||||
final LockOptions lockOptions,
|
||||
final RowSelection rowSelection,
|
||||
final boolean isReadOnlyInitialized,
|
||||
final boolean readOnly,
|
||||
final boolean cacheable,
|
||||
final String cacheRegion,
|
||||
//final boolean forceCacheRefresh,
|
||||
final String comment,
|
||||
final List<String> queryHints,
|
||||
final Serializable[] collectionKeys,
|
||||
ResultTransformer transformer) {
|
||||
this.positionalParameterTypes = positionalParameterTypes;
|
||||
this.positionalParameterValues = positionalParameterValues;
|
||||
this.namedParameters = namedParameters;
|
||||
this.lockOptions = lockOptions;
|
||||
this.rowSelection = rowSelection;
|
||||
this.cacheable = cacheable;
|
||||
this.cacheRegion = cacheRegion;
|
||||
//this.forceCacheRefresh = forceCacheRefresh;
|
||||
this.comment = comment;
|
||||
this.queryHints = queryHints;
|
||||
this.collectionKeys = collectionKeys;
|
||||
this.isReadOnlyInitialized = isReadOnlyInitialized;
|
||||
this.readOnly = readOnly;
|
||||
this.resultTransformer = transformer;
|
||||
}
|
||||
|
||||
public QueryParameters(
|
||||
final Type[] positionalParameterTypes,
|
||||
final Object[] positionalParameterValues,
|
||||
final Map<String, TypedValue> namedParameters,
|
||||
final LockOptions lockOptions,
|
||||
final RowSelection rowSelection,
|
||||
final boolean isReadOnlyInitialized,
|
||||
final boolean readOnly,
|
||||
final boolean cacheable,
|
||||
final String cacheRegion,
|
||||
//final boolean forceCacheRefresh,
|
||||
final String comment,
|
||||
final List<String> queryHints,
|
||||
final Serializable[] collectionKeys,
|
||||
final Object optionalObject,
|
||||
final String optionalEntityName,
|
||||
final Serializable optionalId,
|
||||
final ResultTransformer transformer) {
|
||||
this(
|
||||
positionalParameterTypes,
|
||||
positionalParameterValues,
|
||||
namedParameters,
|
||||
lockOptions,
|
||||
rowSelection,
|
||||
isReadOnlyInitialized,
|
||||
readOnly,
|
||||
cacheable,
|
||||
cacheRegion,
|
||||
comment,
|
||||
queryHints,
|
||||
collectionKeys,
|
||||
transformer
|
||||
);
|
||||
this.optionalEntityName = optionalEntityName;
|
||||
this.optionalId = optionalId;
|
||||
this.optionalObject = optionalObject;
|
||||
}
|
||||
|
||||
public QueryParameters(
|
||||
QueryParameterBindings queryParameterBindings,
|
||||
LockOptions lockOptions,
|
||||
QueryOptions queryOptions,
|
||||
final Serializable[] collectionKeys,
|
||||
final Object optionalObject,
|
||||
final String optionalEntityName,
|
||||
final Serializable optionalId,
|
||||
ResultTransformer resultTransformer) {
|
||||
this(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
lockOptions,
|
||||
new RowSelection(
|
||||
queryOptions.getFirstRow(),
|
||||
queryOptions.getMaxRows(),
|
||||
queryOptions.getTimeout(),
|
||||
queryOptions.getFetchSize()
|
||||
),
|
||||
queryOptions.isReadOnly() != null,
|
||||
queryOptions.isReadOnly(),
|
||||
queryOptions.isResultCachingEnabled(),
|
||||
queryOptions.getResultCacheRegionName(),
|
||||
queryOptions.getComment(),
|
||||
queryOptions.getDatabaseHints(),
|
||||
collectionKeys,
|
||||
optionalObject,
|
||||
optionalEntityName,
|
||||
optionalId,
|
||||
resultTransformer
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public boolean hasRowSelection() {
|
||||
return rowSelection != null;
|
||||
}
|
||||
|
||||
public Map<String, TypedValue> getNamedParameters() {
|
||||
return namedParameters;
|
||||
}
|
||||
|
||||
public Type[] getPositionalParameterTypes() {
|
||||
return positionalParameterTypes;
|
||||
}
|
||||
|
||||
public Object[] getPositionalParameterValues() {
|
||||
return positionalParameterValues;
|
||||
}
|
||||
|
||||
public RowSelection getRowSelection() {
|
||||
return rowSelection;
|
||||
}
|
||||
|
||||
public ResultTransformer getResultTransformer() {
|
||||
return resultTransformer;
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public void setNamedParameters(Map<String, TypedValue> map) {
|
||||
namedParameters = map;
|
||||
}
|
||||
|
||||
public void setPositionalParameterTypes(Type[] types) {
|
||||
positionalParameterTypes = types;
|
||||
}
|
||||
|
||||
public void setPositionalParameterValues(Object[] objects) {
|
||||
positionalParameterValues = objects;
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public void setRowSelection(RowSelection selection) {
|
||||
rowSelection = selection;
|
||||
}
|
||||
|
||||
public LockOptions getLockOptions() {
|
||||
return lockOptions;
|
||||
}
|
||||
|
||||
public void setLockOptions(LockOptions lockOptions) {
|
||||
this.lockOptions = lockOptions;
|
||||
}
|
||||
|
||||
public void traceParameters(SessionFactoryImplementor factory) throws HibernateException {
|
||||
EntityPrinter print = new EntityPrinter( factory );
|
||||
if ( positionalParameterValues.length != 0 ) {
|
||||
LOG.tracev( "Parameters: {0}", print.toString( positionalParameterTypes, positionalParameterValues ) );
|
||||
}
|
||||
if ( namedParameters != null ) {
|
||||
LOG.tracev( "Named parameters: {0}", print.toString( namedParameters ) );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCacheable() {
|
||||
return cacheable;
|
||||
}
|
||||
|
||||
public void setCacheable(boolean b) {
|
||||
cacheable = b;
|
||||
}
|
||||
|
||||
public String getCacheRegion() {
|
||||
return cacheRegion;
|
||||
}
|
||||
|
||||
public void setCacheRegion(String cacheRegion) {
|
||||
this.cacheRegion = cacheRegion;
|
||||
}
|
||||
|
||||
public void validateParameters() throws QueryException {
|
||||
final int types = positionalParameterTypes == null ? 0 : positionalParameterTypes.length;
|
||||
final int values = positionalParameterValues == null ? 0 : positionalParameterValues.length;
|
||||
if ( types != values ) {
|
||||
throw new QueryException(
|
||||
"Number of positional parameter types [" + types +
|
||||
"] does not match number of positional parameters [" + values + "]"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public List<String> getQueryHints() {
|
||||
return queryHints;
|
||||
}
|
||||
|
||||
public void setQueryHints(List<String> queryHints) {
|
||||
this.queryHints = queryHints;
|
||||
}
|
||||
|
||||
public ScrollMode getScrollMode() {
|
||||
return scrollMode;
|
||||
}
|
||||
|
||||
public void setScrollMode(ScrollMode scrollMode) {
|
||||
this.scrollMode = scrollMode;
|
||||
}
|
||||
|
||||
public Serializable[] getCollectionKeys() {
|
||||
return collectionKeys;
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public void setCollectionKeys(Serializable[] collectionKeys) {
|
||||
this.collectionKeys = collectionKeys;
|
||||
}
|
||||
|
||||
public String getOptionalEntityName() {
|
||||
return optionalEntityName;
|
||||
}
|
||||
|
||||
public void setOptionalEntityName(String optionalEntityName) {
|
||||
this.optionalEntityName = optionalEntityName;
|
||||
}
|
||||
|
||||
public Serializable getOptionalId() {
|
||||
return optionalId;
|
||||
}
|
||||
|
||||
public void setOptionalId(Serializable optionalId) {
|
||||
this.optionalId = optionalId;
|
||||
}
|
||||
|
||||
public Object getOptionalObject() {
|
||||
return optionalObject;
|
||||
}
|
||||
|
||||
public void setOptionalObject(Object optionalObject) {
|
||||
this.optionalObject = optionalObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the read-only/modifiable mode been explicitly set?
|
||||
* @see QueryParameters#setReadOnly(boolean)
|
||||
* @see QueryParameters#isReadOnly(SharedSessionContractImplementor)
|
||||
*
|
||||
* @return true, the read-only/modifiable mode was explicitly set
|
||||
* false, the read-only/modifiable mode was not explicitly set
|
||||
*/
|
||||
public boolean isReadOnlyInitialized() {
|
||||
return isReadOnlyInitialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should entities and proxies loaded by the Query be put in read-only mode? The
|
||||
* read-only/modifiable setting must be initialized via QueryParameters#setReadOnly(boolean)
|
||||
* before calling this method.
|
||||
*
|
||||
* @see QueryParameters#isReadOnlyInitialized()
|
||||
* @see QueryParameters#isReadOnly(SharedSessionContractImplementor)
|
||||
* @see QueryParameters#setReadOnly(boolean)
|
||||
*
|
||||
* The read-only/modifiable setting has no impact on entities/proxies returned by the
|
||||
* query that existed in the session before the query was executed.
|
||||
*
|
||||
* @return true, entities and proxies loaded by the Query will be put in read-only mode
|
||||
* false, entities and proxies loaded by the Query will be put in modifiable mode
|
||||
* @throws IllegalStateException if the read-only/modifiable setting has not been
|
||||
* initialized (i.e., isReadOnlyInitialized() == false).
|
||||
*/
|
||||
public boolean isReadOnly() {
|
||||
if ( !isReadOnlyInitialized() ) {
|
||||
throw new IllegalStateException( "cannot call isReadOnly() when isReadOnlyInitialized() returns false" );
|
||||
}
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should entities and proxies loaded by the Query be put in read-only mode? If the
|
||||
* read-only/modifiable setting was not initialized (i.e., QueryParameters#isReadOnlyInitialized() == false),
|
||||
* then the default read-only/modifiable setting for the persistence context is returned instead.
|
||||
* <p/>
|
||||
* The read-only/modifiable setting has no impact on entities/proxies returned by the
|
||||
* query that existed in the session before the query was executed.
|
||||
*
|
||||
* @param session The originating session
|
||||
*
|
||||
* @return {@code true} indicates that entities and proxies loaded by the query will be put in read-only mode;
|
||||
* {@code false} indicates that entities and proxies loaded by the query will be put in modifiable mode
|
||||
*
|
||||
* @see QueryParameters#isReadOnlyInitialized()
|
||||
* @see QueryParameters#setReadOnly(boolean)
|
||||
* @see PersistenceContext#isDefaultReadOnly()
|
||||
*
|
||||
* The read-only/modifiable setting has no impact on entities/proxies returned by the
|
||||
* query that existed in the session before the query was executed.
|
||||
*
|
||||
*/
|
||||
public boolean isReadOnly(SharedSessionContractImplementor session) {
|
||||
return isReadOnlyInitialized
|
||||
? isReadOnly()
|
||||
: session.getPersistenceContextInternal().isDefaultReadOnly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the read-only/modifiable mode for entities and proxies loaded by the query.
|
||||
* <p/>
|
||||
* The read-only/modifiable setting has no impact on entities/proxies returned by the
|
||||
* query that existed in the session before the query was executed.
|
||||
*
|
||||
* @param readOnly if {@code true}, entities and proxies loaded by the query will be put in read-only mode; if
|
||||
* {@code false}, entities and proxies loaded by the query will be put in modifiable mode
|
||||
*
|
||||
* @see QueryParameters#isReadOnlyInitialized()
|
||||
* @see QueryParameters#isReadOnly(SharedSessionContractImplementor)
|
||||
* @see QueryParameters#setReadOnly(boolean)
|
||||
* @see PersistenceContext#isDefaultReadOnly()
|
||||
*/
|
||||
public void setReadOnly(boolean readOnly) {
|
||||
this.readOnly = readOnly;
|
||||
this.isReadOnlyInitialized = true;
|
||||
}
|
||||
|
||||
public void setCallable(boolean callable) {
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
public boolean isCallable() {
|
||||
return callable;
|
||||
}
|
||||
|
||||
public boolean hasAutoDiscoverScalarTypes() {
|
||||
return autodiscovertypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this query should pass the {@code distinct} to the database.
|
||||
* @return the query passes {@code distinct} to the database
|
||||
*/
|
||||
public boolean isPassDistinctThrough() {
|
||||
return passDistinctThrough;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if this query should pass the {@code distinct} to the database.
|
||||
* @param passDistinctThrough the query passes {@code distinct} to the database
|
||||
*/
|
||||
public void setPassDistinctThrough(boolean passDistinctThrough) {
|
||||
this.passDistinctThrough = passDistinctThrough;
|
||||
}
|
||||
|
||||
private int getNumberOfParametersCoveredBy(Type[] subtypes) {
|
||||
int numberOfParameters = 0;
|
||||
for ( Type type : subtypes ) {
|
||||
if ( type.isComponentType() ) {
|
||||
numberOfParameters = numberOfParameters + getNumberOfParametersCoveredBy( ((ComponentType) type).getSubtypes() );
|
||||
}
|
||||
else {
|
||||
numberOfParameters++;
|
||||
}
|
||||
}
|
||||
return numberOfParameters;
|
||||
}
|
||||
|
||||
public String getFilteredSQL() {
|
||||
return processedSQL;
|
||||
}
|
||||
|
||||
public Object[] getFilteredPositionalParameterValues() {
|
||||
return processedPositionalParameterValues;
|
||||
}
|
||||
|
||||
public Type[] getFilteredPositionalParameterTypes() {
|
||||
return processedPositionalParameterTypes;
|
||||
}
|
||||
|
||||
public boolean isNaturalKeyLookup() {
|
||||
return isNaturalKeyLookup;
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public void setNaturalKeyLookup(boolean isNaturalKeyLookup) {
|
||||
this.isNaturalKeyLookup = isNaturalKeyLookup;
|
||||
}
|
||||
|
||||
public void setAutoDiscoverScalarTypes(boolean autodiscovertypes) {
|
||||
this.autodiscovertypes = autodiscovertypes;
|
||||
}
|
||||
|
||||
public QueryParameters createCopyUsing(RowSelection selection) {
|
||||
QueryParameters copy = new QueryParameters(
|
||||
this.positionalParameterTypes,
|
||||
this.positionalParameterValues,
|
||||
this.namedParameters,
|
||||
this.lockOptions,
|
||||
selection,
|
||||
this.isReadOnlyInitialized,
|
||||
this.readOnly,
|
||||
this.cacheable,
|
||||
this.cacheRegion,
|
||||
this.comment,
|
||||
this.queryHints,
|
||||
this.collectionKeys,
|
||||
this.optionalObject,
|
||||
this.optionalEntityName,
|
||||
this.optionalId,
|
||||
this.resultTransformer
|
||||
);
|
||||
copy.processedSQL = this.processedSQL;
|
||||
copy.processedPositionalParameterTypes = this.processedPositionalParameterTypes;
|
||||
copy.processedPositionalParameterValues = this.processedPositionalParameterValues;
|
||||
copy.passDistinctThrough = this.passDistinctThrough;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public void bindDynamicParameter(Type paramType, Object paramValue) {
|
||||
if(processedPositionalParameterTypes != null) {
|
||||
int length = processedPositionalParameterTypes.length;
|
||||
Type[] types = new Type[length + 1];
|
||||
Object[] values = new Object[length + 1];
|
||||
for ( int i = 0; i < length; i++ ) {
|
||||
types[i] = processedPositionalParameterTypes[i];
|
||||
values[i] = processedPositionalParameterValues[i];
|
||||
}
|
||||
types[length] = paramType;
|
||||
values[length] = paramValue;
|
||||
processedPositionalParameterTypes = types;
|
||||
processedPositionalParameterValues = values;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.engine.spi;
|
||||
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
|
||||
/**
|
||||
* Encapsulates details related to the creation and execution of
|
||||
* a JDBC statement
|
||||
*
|
||||
* Differs from {@link QueryOptions} in that this contract describes options
|
||||
*
|
||||
* Represents a selection criteria for rows in a JDBC {@link java.sql.ResultSet}
|
||||
*
|
||||
*
|
||||
*
|
||||
* @author Gavin King
|
||||
* @deprecated todo (6.0): remove in favor of Limit within QueryOptions?
|
||||
*/
|
||||
@Deprecated
|
||||
public final class RowSelection {
|
||||
private Integer firstRow;
|
||||
private Integer maxRows;
|
||||
private Integer timeout;
|
||||
private Integer fetchSize;
|
||||
|
||||
public RowSelection() {
|
||||
}
|
||||
|
||||
public RowSelection(Integer firstRow, Integer maxRows, Integer timeout, Integer fetchSize) {
|
||||
this.firstRow = firstRow;
|
||||
this.maxRows = maxRows;
|
||||
this.timeout = timeout;
|
||||
this.fetchSize = fetchSize;
|
||||
}
|
||||
|
||||
public void setFirstRow(Integer firstRow) {
|
||||
if ( firstRow != null && firstRow < 0 ) {
|
||||
throw new IllegalArgumentException( "first-row value cannot be negative : " + firstRow );
|
||||
}
|
||||
this.firstRow = firstRow;
|
||||
}
|
||||
|
||||
public void setFirstRow(int firstRow) {
|
||||
this.firstRow = firstRow;
|
||||
}
|
||||
|
||||
public Integer getFirstRow() {
|
||||
return firstRow;
|
||||
}
|
||||
|
||||
public void setMaxRows(Integer maxRows) {
|
||||
this.maxRows = maxRows;
|
||||
}
|
||||
|
||||
public void setMaxRows(int maxRows) {
|
||||
this.maxRows = maxRows;
|
||||
}
|
||||
|
||||
public Integer getMaxRows() {
|
||||
return maxRows;
|
||||
}
|
||||
|
||||
public void setTimeout(Integer timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public Integer getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public Integer getFetchSize() {
|
||||
return fetchSize;
|
||||
}
|
||||
|
||||
public void setFetchSize(Integer fetchSize) {
|
||||
this.fetchSize = fetchSize;
|
||||
}
|
||||
|
||||
public void setFetchSize(int fetchSize) {
|
||||
this.fetchSize = fetchSize;
|
||||
}
|
||||
|
||||
public boolean definesLimits() {
|
||||
return maxRows != null || (firstRow != null && firstRow <= 0);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.param;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Convenience base class for explicitly defined query parameters.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractExplicitParameterSpecification implements ExplicitParameterSpecification {
|
||||
private final int sourceLine;
|
||||
private final int sourceColumn;
|
||||
private Type expectedType;
|
||||
|
||||
/**
|
||||
* Constructs an AbstractExplicitParameterSpecification.
|
||||
*
|
||||
* @param sourceLine See {@link #getSourceLine()}
|
||||
* @param sourceColumn See {@link #getSourceColumn()}
|
||||
*/
|
||||
protected AbstractExplicitParameterSpecification(int sourceLine, int sourceColumn) {
|
||||
this.sourceLine = sourceLine;
|
||||
this.sourceColumn = sourceColumn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourceLine() {
|
||||
return sourceLine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourceColumn() {
|
||||
return sourceColumn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getExpectedType() {
|
||||
return expectedType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpectedType(Type expectedType) {
|
||||
this.expectedType = expectedType;
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.param;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* A specialized ParameterSpecification impl for dealing with a collection-key as part of a collection filter
|
||||
* compilation.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CollectionFilterKeyParameterSpecification implements ParameterSpecification {
|
||||
public static final String PARAM_KEY = "{collection_key}";
|
||||
|
||||
private final String collectionRole;
|
||||
private final Type keyType;
|
||||
|
||||
/**
|
||||
* Creates a specialized collection-filter collection-key parameter spec.
|
||||
*
|
||||
* @param collectionRole The collection role being filtered.
|
||||
* @param keyType The mapped collection-key type.
|
||||
*/
|
||||
public CollectionFilterKeyParameterSpecification(String collectionRole, Type keyType) {
|
||||
this.collectionRole = collectionRole;
|
||||
this.keyType = keyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bind(
|
||||
PreparedStatement statement,
|
||||
QueryParameters qp,
|
||||
SharedSessionContractImplementor session,
|
||||
int position) throws SQLException {
|
||||
final Object value = qp.getNamedParameters().get( PARAM_KEY ).getValue();
|
||||
keyType.nullSafeSet( statement, value, position, session );
|
||||
return keyType.getColumnSpan( session.getFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getExpectedType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpectedType(Type expectedType) {
|
||||
// todo : throw exception?
|
||||
}
|
||||
|
||||
@Override
|
||||
public String renderDisplayInfo() {
|
||||
return "collection-filter-key=" + collectionRole;
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.param;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* A specialized ParameterSpecification impl for dealing with a dynamic filter parameters.
|
||||
*
|
||||
* @see org.hibernate.Session#enableFilter(String)
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DynamicFilterParameterSpecification implements ParameterSpecification {
|
||||
private final String filterName;
|
||||
private final String parameterName;
|
||||
private final Type definedParameterType;
|
||||
|
||||
/**
|
||||
* Constructs a parameter specification for a particular filter parameter.
|
||||
*
|
||||
* @param filterName The name of the filter
|
||||
* @param parameterName The name of the parameter
|
||||
* @param definedParameterType The parameter type specified on the filter metadata
|
||||
*/
|
||||
public DynamicFilterParameterSpecification(
|
||||
String filterName,
|
||||
String parameterName,
|
||||
Type definedParameterType) {
|
||||
this.filterName = filterName;
|
||||
this.parameterName = parameterName;
|
||||
this.definedParameterType = definedParameterType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bind(
|
||||
PreparedStatement statement,
|
||||
QueryParameters qp,
|
||||
SharedSessionContractImplementor session,
|
||||
int start) throws SQLException {
|
||||
final int columnSpan = definedParameterType.getColumnSpan( session.getFactory() );
|
||||
final String fullParamName = filterName + '.' + parameterName;
|
||||
final Object value = session.getLoadQueryInfluencers().getFilterParameterValue(fullParamName);
|
||||
final Type type = session.getLoadQueryInfluencers().getFilterParameterType(fullParamName);
|
||||
if ( Collection.class.isInstance( value ) ) {
|
||||
int positions = 0;
|
||||
Iterator itr = ( ( Collection ) value ).iterator();
|
||||
while ( itr.hasNext() ) {
|
||||
Object next = itr.next();
|
||||
qp.bindDynamicParameter( type, next );
|
||||
definedParameterType.nullSafeSet( statement, next, start + positions, session );
|
||||
positions += columnSpan;
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
else {
|
||||
qp.bindDynamicParameter(type, value);
|
||||
definedParameterType.nullSafeSet( statement, value, start, session );
|
||||
return columnSpan;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getExpectedType() {
|
||||
return definedParameterType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpectedType(Type expectedType) {
|
||||
// todo : throw exception? maybe warn if not the same?
|
||||
}
|
||||
|
||||
@Override
|
||||
public String renderDisplayInfo() {
|
||||
return "dynamic-filter={filterName=" + filterName + ",paramName=" + parameterName + "}";
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.param;
|
||||
|
||||
|
||||
/**
|
||||
* An additional contract for parameters which originate from parameters explicitly encountered in the source statement
|
||||
* (HQL or native-SQL).
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ExplicitParameterSpecification extends ParameterSpecification {
|
||||
/**
|
||||
* Retrieves the line number on which this parameter occurs in the source query.
|
||||
*
|
||||
* @return The line number.
|
||||
*/
|
||||
int getSourceLine();
|
||||
|
||||
/**
|
||||
* Retrieves the column number (within the {@link #getSourceLine()}) where this parameter occurs.
|
||||
*
|
||||
* @return The column number.
|
||||
*/
|
||||
int getSourceColumn();
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.param;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.engine.spi.TypedValue;
|
||||
|
||||
/**
|
||||
* Parameter bind specification for an explicit named parameter.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NamedParameterSpecification extends AbstractExplicitParameterSpecification {
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Constructs a named parameter bind specification.
|
||||
*
|
||||
* @param sourceLine See {@link #getSourceLine()}
|
||||
* @param sourceColumn See {@link #getSourceColumn()}
|
||||
* @param name The named parameter name.
|
||||
*/
|
||||
public NamedParameterSpecification(int sourceLine, int sourceColumn, String name) {
|
||||
super( sourceLine, sourceColumn );
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind the appropriate value into the given statement at the specified position.
|
||||
*
|
||||
* @param statement The statement into which the value should be bound.
|
||||
* @param qp The defined values for the current query execution.
|
||||
* @param session The session against which the current execution is occuring.
|
||||
* @param position The position from which to start binding value(s).
|
||||
*
|
||||
* @return The number of sql bind positions "eaten" by this bind operation.
|
||||
*/
|
||||
@Override
|
||||
public int bind(
|
||||
PreparedStatement statement,
|
||||
QueryParameters qp,
|
||||
SharedSessionContractImplementor session,
|
||||
int position) throws SQLException {
|
||||
TypedValue typedValue = qp.getNamedParameters().get( name );
|
||||
typedValue.getType().nullSafeSet( statement, typedValue.getValue(), position, session );
|
||||
return typedValue.getType().getColumnSpan( session.getFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String renderDisplayInfo() {
|
||||
return "name=" + name + ", expectedType=" + getExpectedType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for property 'name'.
|
||||
*
|
||||
* @return Value for property 'name'.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.param;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ParameterBinder {
|
||||
/**
|
||||
* Bind the appropriate value into the given statement at the specified position.
|
||||
*
|
||||
* @param statement The statement into which the value should be bound.
|
||||
* @param qp The defined values for the current query execution.
|
||||
* @param session The session against which the current execution is occuring.
|
||||
* @param position The position from which to start binding value(s).
|
||||
*
|
||||
* @return The number of sql bind positions "eaten" by this bind operation.
|
||||
* @throws SQLException Indicates problems performing the JDBC bind operation.
|
||||
*/
|
||||
int bind(PreparedStatement statement, QueryParameters qp, SharedSessionContractImplementor session, int position) throws SQLException;
|
||||
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.param;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Maintains information relating to parameters which need to get bound into a
|
||||
* JDBC {@link PreparedStatement}.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ParameterSpecification extends ParameterBinder {
|
||||
/**
|
||||
* Get the type which we are expecting for a bind into this parameter based
|
||||
* on translated contextual information.
|
||||
*
|
||||
* @return The expected type.
|
||||
*/
|
||||
Type getExpectedType();
|
||||
|
||||
/**
|
||||
* Injects the expected type. Called during translation.
|
||||
*
|
||||
* @param expectedType The type to expect.
|
||||
*/
|
||||
void setExpectedType(Type expectedType);
|
||||
|
||||
/**
|
||||
* Render this parameter into displayable info (for logging, etc).
|
||||
*
|
||||
* @return The displayable info.
|
||||
*/
|
||||
String renderDisplayInfo();
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.param;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.engine.spi.TypedValue;
|
||||
|
||||
/**
|
||||
* Parameter bind specification for an explicit positional (or ordinal) parameter.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PositionalParameterSpecification extends AbstractExplicitParameterSpecification {
|
||||
private final int label;
|
||||
private final int bindingPosition;
|
||||
|
||||
/**
|
||||
* Constructs a position/ordinal parameter bind specification.
|
||||
*
|
||||
* @param sourceLine See {@link #getSourceLine()}
|
||||
* @param sourceColumn See {@link #getSourceColumn()}
|
||||
* @param label The position in the source query, relative to the other source positional parameters.
|
||||
*/
|
||||
public PositionalParameterSpecification(
|
||||
int sourceLine,
|
||||
int sourceColumn,
|
||||
int label,
|
||||
int bindingPosition) {
|
||||
super( sourceLine, sourceColumn );
|
||||
this.label = label;
|
||||
this.bindingPosition = bindingPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind the appropriate value into the given statement at the specified position.
|
||||
*
|
||||
* @param statement The statement into which the value should be bound.
|
||||
* @param qp The defined values for the current query execution.
|
||||
* @param session The session against which the current execution is occurring.
|
||||
* @param position The position from which to start binding value(s).
|
||||
*
|
||||
* @return The number of sql bind positions "eaten" by this bind operation.
|
||||
*/
|
||||
@Override
|
||||
public int bind(PreparedStatement statement, QueryParameters qp, SharedSessionContractImplementor session, int position) throws SQLException {
|
||||
final TypedValue typedValue = qp.getNamedParameters().get( Integer.toString( label ) );
|
||||
typedValue.getType().nullSafeSet( statement, typedValue.getValue(), position, session );
|
||||
return typedValue.getType().getColumnSpan( session.getFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String renderDisplayInfo() {
|
||||
return "label=" + label + ", expectedType=" + getExpectedType();
|
||||
}
|
||||
|
||||
public int getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
|
@ -79,7 +79,7 @@ import org.hibernate.metamodel.model.domain.BasicDomainType;
|
|||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.internal.CompositeSqmPathSource;
|
||||
import org.hibernate.param.VersionTypeSeedParameterSpecification;
|
||||
import org.hibernate.sql.exec.internal.VersionTypeSeedParameterSpecification;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Joinable;
|
||||
|
|
|
@ -4,18 +4,14 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.param;
|
||||
package org.hibernate.sql.exec.internal;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
|
||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.VersionType;
|
||||
|
||||
/**
|
|
@ -11,7 +11,6 @@ import java.util.Locale;
|
|||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.dialect.SQLServer2005Dialect;
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.orm.test.dialect;
|
|||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.dialect.SQLServer2012Dialect;
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.query.Limit;
|
||||
|
||||
import org.junit.After;
|
||||
|
|
Loading…
Reference in New Issue