31
31
import io .r2dbc .postgresql .util .GeneratedValuesUtils ;
32
32
import io .r2dbc .postgresql .util .Operators ;
33
33
import io .r2dbc .postgresql .util .sql .BasicPostgresqlSqlLexer ;
34
- import io .r2dbc .postgresql .util .sql .TokenType ;
35
34
import io .r2dbc .postgresql .util .sql .TokenizedSql ;
36
35
import io .r2dbc .spi .Statement ;
37
36
import reactor .core .publisher .Flux ;
52
51
import static io .r2dbc .postgresql .util .PredicateUtils .or ;
53
52
54
53
/**
55
- * {@link Statement} using the <a href="https://www.postgresql.org/docs/current/static/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY">Extended Query Flow</a> .
54
+ * {@link Statement}.
56
55
*/
57
56
final class PostgresqlStatement implements io .r2dbc .postgresql .api .PostgresqlStatement {
58
57
@@ -85,6 +84,10 @@ final class PostgresqlStatement implements io.r2dbc.postgresql.api.PostgresqlSta
85
84
86
85
@ Override
87
86
public PostgresqlStatement add () {
87
+ Binding binding = bindings .peekLast ();
88
+ if (binding != null ) {
89
+ binding .validate ();
90
+ }
88
91
this .bindings .add (new Binding (tokenizedSql .getParameterCount ()));
89
92
return this ;
90
93
}
@@ -99,7 +102,7 @@ public PostgresqlStatement bind(int index, Object value) {
99
102
Assert .requireNonNull (value , "value must not be null" );
100
103
101
104
BindingLogger .logBind (this .connectionContext , index , value );
102
- getCurrentOrNewBinding ().add (index , this .resources .getCodecs ().encode (value ));
105
+ getCurrentOrFirstBinding ().add (index , this .resources .getCodecs ().encode (value ));
103
106
return this ;
104
107
}
105
108
@@ -112,17 +115,17 @@ public PostgresqlStatement bindNull(String identifier, Class<?> type) {
112
115
public PostgresqlStatement bindNull (int index , Class <?> type ) {
113
116
Assert .requireNonNull (type , "type must not be null" );
114
117
115
- if (index >= tokenizedSql .getParameterCount ()){
118
+ if (index >= tokenizedSql .getParameterCount ()) {
116
119
throw new UnsupportedOperationException (String .format ("Cannot bind parameter %d, statement has %d parameters" , index , this .tokenizedSql .getParameterCount ()));
117
120
}
118
121
119
122
BindingLogger .logBindNull (this .connectionContext , index , type );
120
- getCurrentOrNewBinding ().add (index , this .resources .getCodecs ().encodeNull (type ));
123
+ getCurrentOrFirstBinding ().add (index , this .resources .getCodecs ().encodeNull (type ));
121
124
return this ;
122
125
}
123
126
124
127
@ Nonnull
125
- private Binding getCurrentOrNewBinding () {
128
+ private Binding getCurrentOrFirstBinding () {
126
129
Binding binding = bindings .peekLast ();
127
130
if (binding == null ) {
128
131
Binding newBinding = new Binding (tokenizedSql .getParameterCount ());
@@ -145,20 +148,12 @@ public Flux<io.r2dbc.postgresql.api.PostgresqlResult> execute() {
145
148
public PostgresqlStatement returnGeneratedValues (String ... columns ) {
146
149
Assert .requireNonNull (columns , "columns must not be null" );
147
150
148
- boolean hasReturning = this .tokenizedSql .getStatements ().stream ()
149
- .flatMap (s -> s .getTokens ().stream ())
150
- .anyMatch (token -> (token .getType () == TokenType .DEFAULT )
151
- && (token .getValue ().equalsIgnoreCase ("RETURNING" )));
151
+ boolean hasReturning = this .tokenizedSql .hasDefaultTokenValue ("RETURNING" );
152
152
if (hasReturning ) {
153
153
throw new IllegalStateException ("Statement already includes RETURNING clause" );
154
154
}
155
- boolean isSupporting = this .tokenizedSql .getStatements ().stream ()
156
- .flatMap (s -> s .getTokens ().stream ())
157
- .anyMatch (e -> e .getType () == TokenType .DEFAULT
158
- && (e .getValue ().equalsIgnoreCase ("DELETE" )
159
- || e .getValue ().equalsIgnoreCase ("INSERT" )
160
- || e .getValue ().equalsIgnoreCase ("UPDATE" )));
161
155
156
+ boolean isSupporting = this .tokenizedSql .hasDefaultTokenValue ("DELETE" , "INSERT" , "UPDATE" );
162
157
if (!isSupporting ) {
163
158
throw new IllegalStateException ("Statement is not a DELETE, INSERT, or UPDATE command" );
164
159
}
@@ -185,13 +180,13 @@ public String toString() {
185
180
}
186
181
187
182
Binding getCurrentBinding () {
188
- return getCurrentOrNewBinding ();
183
+ return getCurrentOrFirstBinding ();
189
184
}
190
185
191
186
private int getIdentifierIndex (String identifier ) {
192
187
Assert .requireNonNull (identifier , "identifier must not be null" );
193
188
Assert .requireType (identifier , String .class , "identifier must be a String" );
194
- if (!identifier .startsWith ("$" )){
189
+ if (!identifier .startsWith ("$" )) {
195
190
throw new NoSuchElementException (String .format ("\" %s\" is not a valid identifier" , identifier ));
196
191
}
197
192
try {
0 commit comments