@ -87,10 +87,9 @@ abstract class NamedParameterUtils {
@@ -87,10 +87,9 @@ abstract class NamedParameterUtils {
/ * *
* Parse the SQL statement and locate any placeholders or named parameters .
* Namedparameters are substituted for a R2DBC placeholder .
*
* Named parameters are substituted for a R2DBC placeholder .
* @param sql the SQL statement
* @return the parsed statement , represented as { @link ParsedSql } instance .
* @return the parsed statement , represented as { @link ParsedSql } instance
* /
public static ParsedSql parseSqlStatement ( String sql ) {
Assert . notNull ( sql , "SQL must not be null" ) ;
@ -134,20 +133,22 @@ abstract class NamedParameterUtils {
@@ -134,20 +133,22 @@ abstract class NamedParameterUtils {
while ( statement [ j ] ! = '}' ) {
j + + ;
if ( j > = statement . length ) {
throw new InvalidDataAccessApiUsageException ( "Non-terminated named parameter declaration " +
"at position " + i + " in statement: " + sql ) ;
throw new InvalidDataAccessApiUsageException (
"Non-terminated named parameter declaration at position " + i +
" in statement: " + sql ) ;
}
if ( statement [ j ] = = ':' | | statement [ j ] = = '{' ) {
throw new InvalidDataAccessApiUsageException ( "Parameter name contains invalid character '" +
statement [ j ] + "' at position " + i + " in statement: " + sql ) ;
throw new InvalidDataAccessApiUsageException (
"Parameter name contains invalid character '" + statement [ j ] +
"' at position " + i + " in statement: " + sql ) ;
}
}
if ( j - i > 2 ) {
parameter = sql . substring ( i + 2 , j ) ;
namedParameterCount = addNewNamedParameter ( namedParameters ,
namedParameterCount , parameter ) ;
totalParameterCount = addNamedParameter ( parameterList ,
totalParameterCount , escapes , i , j + 1 , parameter ) ;
namedParameterCount = addNewNamedParameter (
namedParameters , namedParameter Count , parameter ) ;
totalParameterCount = addNamedParameter (
parameterList , totalParameterCount , escapes , i , j + 1 , parameter ) ;
}
j + + ;
}
@ -157,10 +158,10 @@ abstract class NamedParameterUtils {
@@ -157,10 +158,10 @@ abstract class NamedParameterUtils {
}
if ( j - i > 1 ) {
parameter = sql . substring ( i + 1 , j ) ;
namedParameterCount = addNewNamedParameter ( namedParameters ,
namedParameterCount , parameter ) ;
totalParameterCount = addNamedParameter ( parameterList ,
totalParameterCount , escapes , i , j , parameter ) ;
namedParameterCount = addNewNamedParameter (
namedParameters , namedParameter Count , parameter ) ;
totalParameterCount = addNamedParameter (
parameterList , totalParameterCount , escapes , i , j , parameter ) ;
}
}
i = j - 1 ;
@ -190,8 +191,8 @@ abstract class NamedParameterUtils {
@@ -190,8 +191,8 @@ abstract class NamedParameterUtils {
return parsedSql ;
}
private static int addNamedParameter (
List < ParameterHolder > parameterList , int totalParameterCount , int escapes , int i , int j , String parameter ) {
private static int addNamedParameter ( List < ParameterHolder > parameterList ,
int totalParameterCount , int escapes , int i , int j , String parameter ) {
parameterList . add ( new ParameterHolder ( parameter , i - escapes , j - escapes ) ) ;
totalParameterCount + + ;
@ -256,10 +257,9 @@ abstract class NamedParameterUtils {
@@ -256,10 +257,9 @@ abstract class NamedParameterUtils {
/ * *
* Parse the SQL statement and locate any placeholders or named parameters . Named
* parameters are substituted for a R2DBC placeholder , and any select list is expanded
* to the required number of placeholders . Select lists may contain an array of
* objects , and in that case the placeholders will be grouped and enclosed with
* parentheses . This allows for the use of "expression lists" in the SQL statement
* like : < br / > < br / >
* to the required number of placeholders . Select lists may contain an array of objects ,
* and in that case the placeholders will be grouped and enclosed with parentheses .
* This allows for the use of "expression lists" in the SQL statement like :
* { @code select id , name , state from table where ( name , age ) in ( ( ' John ' , 35 ) , ( ' Ann ' , 50 ) ) }
* < p > The parameter values passed in are used to determine the number of placeholders to
* be used for a select list . Select lists should be limited to 100 or fewer elements .
@ -269,17 +269,19 @@ abstract class NamedParameterUtils {
@@ -269,17 +269,19 @@ abstract class NamedParameterUtils {
* @param bindMarkersFactory the bind marker factory .
* @param paramSource the source for named parameters
* @return the expanded query that accepts bind parameters and allows for execution
* without further translation
* without further translation
* @see # parseSqlStatement
* /
public static PreparedOperation < String > substituteNamedParameters ( ParsedSql parsedSql ,
BindMarkersFactory bindMarkersFactory , BindParameterSource paramSource ) {
NamedParameters markerHolder = new NamedParameters ( bindMarkersFactory ) ;
String originalSql = parsedSql . getOriginalSql ( ) ;
List < String > paramNames = parsedSql . getParameterNames ( ) ;
if ( paramNames . isEmpty ( ) ) {
return new ExpandedQuery ( originalSql , markerHolder , paramSource ) ;
}
StringBuilder actualSql = new StringBuilder ( originalSql . length ( ) ) ;
int lastIndex = 0 ;
for ( int i = 0 ; i < paramNames . size ( ) ; i + + ) {
@ -318,7 +320,6 @@ abstract class NamedParameterUtils {
@@ -318,7 +320,6 @@ abstract class NamedParameterUtils {
actualSql . append ( marker . getPlaceholder ( counter ) ) ;
counter + + ;
}
}
}
else {
@ -343,6 +344,7 @@ abstract class NamedParameterUtils {
@@ -343,6 +344,7 @@ abstract class NamedParameterUtils {
return ( c < 128 & & separatorIndex [ c ] ) | | Character . isWhitespace ( c ) ;
}
// -------------------------------------------------------------------------
// Convenience methods operating on a plain SQL String
// -------------------------------------------------------------------------
@ -359,6 +361,7 @@ abstract class NamedParameterUtils {
@@ -359,6 +361,7 @@ abstract class NamedParameterUtils {
* /
public static PreparedOperation < String > substituteNamedParameters ( String sql ,
BindMarkersFactory bindMarkersFactory , BindParameterSource paramSource ) {
ParsedSql parsedSql = parseSqlStatement ( sql ) ;
return substituteNamedParameters ( parsedSql , bindMarkersFactory , paramSource ) ;
}
@ -407,9 +410,9 @@ abstract class NamedParameterUtils {
@@ -407,9 +410,9 @@ abstract class NamedParameterUtils {
public int hashCode ( ) {
return Objects . hash ( this . parameterName , this . startIndex , this . endIndex ) ;
}
}
/ * *
* Holder for bind markers progress .
* /
@ -426,7 +429,6 @@ abstract class NamedParameterUtils {
@@ -426,7 +429,6 @@ abstract class NamedParameterUtils {
this . identifiable = factory . identifiablePlaceholders ( ) ;
}
/ * *
* Get the { @link NamedParameter } identified by { @code namedParameter } .
* Parameter objects get created if they do not yet exist .
@ -434,20 +436,16 @@ abstract class NamedParameterUtils {
@@ -434,20 +436,16 @@ abstract class NamedParameterUtils {
* @return the named parameter
* /
NamedParameter getOrCreate ( String namedParameter ) {
List < NamedParameter > reference = this . references . computeIfAbsent (
namedParameter , ignore - > new ArrayList < > ( ) ) ;
namedParameter , key - > new ArrayList < > ( ) ) ;
if ( reference . isEmpty ( ) ) {
NamedParameter param = new NamedParameter ( namedParameter ) ;
reference . add ( param ) ;
return param ;
}
if ( this . identifiable ) {
return reference . get ( 0 ) ;
}
NamedParameter param = new NamedParameter ( namedParameter ) ;
reference . add ( param ) ;
return param ;
@ -458,13 +456,13 @@ abstract class NamedParameterUtils {
@@ -458,13 +456,13 @@ abstract class NamedParameterUtils {
return this . references . get ( name ) ;
}
class NamedParameter {
private final String namedParameter ;
private final List < BindMarker > placeholders = new ArrayList < > ( ) ;
NamedParameter ( String namedParameter ) {
this . namedParameter = namedParameter ;
}
@ -475,9 +473,7 @@ abstract class NamedParameterUtils {
@@ -475,9 +473,7 @@ abstract class NamedParameterUtils {
* @return the placeholder to be used in the SQL statement
* /
String addPlaceholder ( ) {
BindMarker bindMarker = NamedParameters . this . bindMarkers . next (
this . namedParameter ) ;
BindMarker bindMarker = NamedParameters . this . bindMarkers . next ( this . namedParameter ) ;
this . placeholders . add ( bindMarker ) ;
return bindMarker . getPlaceholder ( ) ;
}
@ -487,17 +483,15 @@ abstract class NamedParameterUtils {
@@ -487,17 +483,15 @@ abstract class NamedParameterUtils {
}
String getPlaceholder ( int counter ) {
while ( counter + 1 > this . placeholders . size ( ) ) {
addPlaceholder ( ) ;
}
return this . placeholders . get ( counter ) . getPlaceholder ( ) ;
}
}
}
/ * *
* Expanded query that allows binding of parameters using parameter names that were
* used to expand the query . Binding unrolls { @link Collection } s and nested arrays .
@ -510,35 +504,25 @@ abstract class NamedParameterUtils {
@@ -510,35 +504,25 @@ abstract class NamedParameterUtils {
private final BindParameterSource parameterSource ;
ExpandedQuery ( String expandedSql , NamedParameters parameters ,
BindParameterSource parameterSource ) {
ExpandedQuery ( String expandedSql , NamedParameters parameters , BindParameterSource parameterSource ) {
this . expandedSql = expandedSql ;
this . parameters = parameters ;
this . parameterSource = parameterSource ;
}
@SuppressWarnings ( "unchecked" )
public void bind ( BindTarget target , String identifier , Object value ) {
List < BindMarker > bindMarkers = getBindMarkers ( identifier ) ;
if ( bindMarkers = = null ) {
target . bind ( identifier , value ) ;
return ;
}
if ( value instanceof Collection ) {
Collection < Object > collection = ( Collection < Object > ) value ;
Iterator < Object > iterator = collection . iterator ( ) ;
Iterator < BindMarker > markers = bindMarkers . iterator ( ) ;
while ( iterator . hasNext ( ) ) {
Object valueToBind = iterator . next ( ) ;
if ( valueToBind instanceof Object [ ] ) {
Object [ ] objects = ( Object [ ] ) valueToBind ;
for ( Object object : objects ) {
@ -557,24 +541,19 @@ abstract class NamedParameterUtils {
@@ -557,24 +541,19 @@ abstract class NamedParameterUtils {
}
}
private void bind ( BindTarget target , Iterator < BindMarker > markers ,
Object valueToBind ) {
private void bind ( BindTarget target , Iterator < BindMarker > markers , Object valueToBind ) {
Assert . isTrue ( markers . hasNext ( ) , ( ) - > String . format (
"No bind marker for value [%s] in SQL [%s]. Check that the query was expanded using the same arguments." ,
valueToBind , toQuery ( ) ) ) ;
markers . next ( ) . bind ( target , valueToBind ) ;
}
public void bindNull ( BindTarget target , String identifier , Class < ? > valueType ) {
List < BindMarker > bindMarkers = getBindMarkers ( identifier ) ;
if ( bindMarkers = = null ) {
target . bindNull ( identifier , valueType ) ;
return ;
}
for ( BindMarker bindMarker : bindMarkers ) {
bindMarker . bindNull ( target , valueType ) ;
}
@ -582,19 +561,14 @@ abstract class NamedParameterUtils {
@@ -582,19 +561,14 @@ abstract class NamedParameterUtils {
@Nullable
List < BindMarker > getBindMarkers ( String identifier ) {
List < NamedParameters . NamedParameter > parameters = this . parameters . getMarker (
identifier ) ;
List < NamedParameters . NamedParameter > parameters = this . parameters . getMarker ( identifier ) ;
if ( parameters = = null ) {
return null ;
}
List < BindMarker > markers = new ArrayList < > ( ) ;
for ( NamedParameters . NamedParameter parameter : parameters ) {
markers . addAll ( parameter . placeholders ) ;
}
return markers ;
}
@ -605,14 +579,10 @@ abstract class NamedParameterUtils {
@@ -605,14 +579,10 @@ abstract class NamedParameterUtils {
@Override
public void bindTo ( BindTarget target ) {
for ( String namedParameter : this . parameterSource . getParameterNames ( ) ) {
Object value = this . parameterSource . getValue ( namedParameter ) ;
if ( value = = null ) {
bindNull ( target , namedParameter ,
this . parameterSource . getType ( namedParameter ) ) ;
bindNull ( target , namedParameter , this . parameterSource . getType ( namedParameter ) ) ;
}
else {
bind ( target , namedParameter , value ) ;
@ -624,7 +594,6 @@ abstract class NamedParameterUtils {
@@ -624,7 +594,6 @@ abstract class NamedParameterUtils {
public String toQuery ( ) {
return this . expandedSql ;
}
}
}