1
1
/*
2
- * Copyright 2002-2024 the original author or authors.
2
+ * Copyright 2002-2025 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
16
16
17
17
package org .springframework .r2dbc .core ;
18
18
19
- import java .util .Arrays ;
20
- import java .util .Collections ;
21
19
import java .util .HashMap ;
22
- import java .util .LinkedHashMap ;
20
+ import java .util .List ;
23
21
import java .util .Map ;
24
22
25
23
import io .r2dbc .spi .Parameters ;
42
40
* @author Mark Paluch
43
41
* @author Jens Schauder
44
42
* @author Anton Naydenov
43
+ * @author Sam Brannen
45
44
*/
46
45
class NamedParameterUtilsTests {
47
46
48
- private final BindMarkersFactory BIND_MARKERS = BindMarkersFactory .indexed ("$" , 1 );
47
+ private static final BindMarkersFactory INDEXED_MARKERS = BindMarkersFactory .indexed ("$" , 1 );
48
+
49
+ private static final BindMarkersFactory ANONYMOUS_MARKERS = BindMarkersFactory .anonymous ("?" );
49
50
50
51
51
52
@ Test
@@ -73,7 +74,7 @@ void substituteNamedParameters() {
73
74
namedParams .addValue ("a" , "a" ).addValue ("b" , "b" ).addValue ("c" , "c" );
74
75
75
76
PreparedOperation <?> operation = NamedParameterUtils .substituteNamedParameters (
76
- "xxx :a :b :c" , BIND_MARKERS , namedParams );
77
+ "xxx :a :b :c" , INDEXED_MARKERS , namedParams );
77
78
78
79
assertThat (operation .toQuery ()).isEqualTo ("xxx $1 $2 $3" );
79
80
@@ -87,11 +88,11 @@ void substituteNamedParameters() {
87
88
void substituteObjectArray () {
88
89
MapBindParameterSource namedParams = new MapBindParameterSource (new HashMap <>());
89
90
namedParams .addValue ("a" ,
90
- Arrays . asList (new Object [] {"Walter" , "Heisenberg" },
91
- new Object [] {"Walt Jr." , "Flynn" }));
91
+ List . of (new Object [] {"Walter" , "Heisenberg" },
92
+ new Object [] {"Walt Jr." , "Flynn" }));
92
93
93
94
PreparedOperation <?> operation = NamedParameterUtils .substituteNamedParameters (
94
- "xxx :a" , BIND_MARKERS , namedParams );
95
+ "xxx :a" , INDEXED_MARKERS , namedParams );
95
96
96
97
assertThat (operation .toQuery ()).isEqualTo ("xxx ($1, $2), ($3, $4)" );
97
98
}
@@ -100,13 +101,13 @@ void substituteObjectArray() {
100
101
void shouldBindObjectArray () {
101
102
MapBindParameterSource namedParams = new MapBindParameterSource (new HashMap <>());
102
103
namedParams .addValue ("a" ,
103
- Arrays . asList (new Object [] {"Walter" , "Heisenberg" },
104
- new Object [] {"Walt Jr." , "Flynn" }));
104
+ List . of (new Object [] {"Walter" , "Heisenberg" },
105
+ new Object [] {"Walt Jr." , "Flynn" }));
105
106
106
107
BindTarget bindTarget = mock ();
107
108
108
109
PreparedOperation <?> operation = NamedParameterUtils .substituteNamedParameters (
109
- "xxx :a" , BIND_MARKERS , namedParams );
110
+ "xxx :a" , INDEXED_MARKERS , namedParams );
110
111
operation .bindTo (bindTarget );
111
112
112
113
verify (bindTarget ).bind (0 , "Walter" );
@@ -141,7 +142,7 @@ void parseSqlStatementWithPostgresCasting() {
141
142
142
143
ParsedSql parsedSql = NamedParameterUtils .parseSqlStatement (sql );
143
144
PreparedOperation <?> operation = NamedParameterUtils .substituteNamedParameters (
144
- parsedSql , BIND_MARKERS , new MapBindParameterSource ());
145
+ parsedSql , INDEXED_MARKERS , new MapBindParameterSource ());
145
146
146
147
assertThat (operation .toQuery ()).isEqualTo (expectedSql );
147
148
}
@@ -312,14 +313,13 @@ void shouldAllowParsingMultipleUseOfParameter() {
312
313
void multipleEqualParameterReferencesBindsValueOnce () {
313
314
String sql = "SELECT * FROM person where name = :id or lastname = :id" ;
314
315
315
- BindMarkersFactory factory = BindMarkersFactory .indexed ("$" , 0 );
316
+ MapBindParameterSource source = new MapBindParameterSource (Map .of ("id" , Parameters .in ("foo" )));
317
+ PreparedOperation <String > operation = NamedParameterUtils .substituteNamedParameters (sql , INDEXED_MARKERS , source );
316
318
317
- PreparedOperation <String > operation = NamedParameterUtils .substituteNamedParameters (
318
- sql , factory , new MapBindParameterSource (
319
- Collections .singletonMap ("id" , Parameters .in ("foo" ))));
319
+ assertThat (operation .toQuery ())
320
+ .isEqualTo ("SELECT * FROM person where name = $1 or lastname = $1" );
320
321
321
- assertThat (operation .toQuery ()).isEqualTo (
322
- "SELECT * FROM person where name = $0 or lastname = $0" );
322
+ Map <Integer , Object > bindings = new HashMap <>();
323
323
324
324
operation .bindTo (new BindTarget () {
325
325
@ Override
@@ -328,8 +328,7 @@ public void bind(String identifier, Object value) {
328
328
}
329
329
@ Override
330
330
public void bind (int index , Object value ) {
331
- assertThat (index ).isEqualTo (0 );
332
- assertThat (value ).isEqualTo (Parameters .in ("foo" ));
331
+ bindings .put (index , value );
333
332
}
334
333
@ Override
335
334
public void bindNull (String identifier , Class <?> type ) {
@@ -340,22 +339,24 @@ public void bindNull(int index, Class<?> type) {
340
339
throw new UnsupportedOperationException ();
341
340
}
342
341
});
342
+
343
+ assertThat (bindings )
344
+ .hasSize (1 )
345
+ .containsEntry (0 , Parameters .in ("foo" ));
343
346
}
344
347
345
348
@ Test
346
- void multipleEqualCollectionParameterReferencesBindsValueOnce () {
349
+ void multipleEqualCollectionParameterReferencesForIndexedMarkersBindsValueOnce () {
347
350
String sql = "SELECT * FROM person where name IN (:ids) or lastname IN (:ids)" ;
348
351
349
- BindMarkersFactory factory = BindMarkersFactory . indexed ( "$" , 0 );
350
-
351
- MultiValueMap < Integer , Object > bindings = new LinkedMultiValueMap <>( );
352
+ MapBindParameterSource source = new MapBindParameterSource ( Map . of ( "ids" ,
353
+ Parameters . in ( List . of ( "foo" , "bar" , "baz" ))));
354
+ PreparedOperation < String > operation = NamedParameterUtils . substituteNamedParameters ( sql , INDEXED_MARKERS , source );
352
355
353
- PreparedOperation <String > operation = NamedParameterUtils .substituteNamedParameters (
354
- sql , factory , new MapBindParameterSource (Collections .singletonMap ("ids" ,
355
- Parameters .in (Arrays .asList ("foo" , "bar" , "baz" )))));
356
+ assertThat (operation .toQuery ())
357
+ .isEqualTo ("SELECT * FROM person where name IN ($1, $2, $3) or lastname IN ($1, $2, $3)" );
356
358
357
- assertThat (operation .toQuery ()).isEqualTo (
358
- "SELECT * FROM person where name IN ($0, $1, $2) or lastname IN ($0, $1, $2)" );
359
+ MultiValueMap <Integer , Object > bindings = new LinkedMultiValueMap <>();
359
360
360
361
operation .bindTo (new BindTarget () {
361
362
@ Override
@@ -364,8 +365,6 @@ public void bind(String identifier, Object value) {
364
365
}
365
366
@ Override
366
367
public void bind (int index , Object value ) {
367
- assertThat (index ).isIn (0 , 1 , 2 );
368
- assertThat (value ).isIn ("foo" , "bar" , "baz" );
369
368
bindings .add (index , value );
370
369
}
371
370
@ Override
@@ -378,25 +377,24 @@ public void bindNull(int index, Class<?> type) {
378
377
}
379
378
});
380
379
381
- assertThat (bindings ).containsEntry (0 , Collections .singletonList ("foo" )) //
382
- .containsEntry (1 , Collections .singletonList ("bar" )) //
383
- .containsEntry (2 , Collections .singletonList ("baz" ));
380
+ assertThat (bindings )
381
+ .hasSize (3 )
382
+ .containsEntry (0 , List .of ("foo" ))
383
+ .containsEntry (1 , List .of ("bar" ))
384
+ .containsEntry (2 , List .of ("baz" ));
384
385
}
385
386
386
387
@ Test
387
- void multipleEqualParameterReferencesForAnonymousMarkersBindsValueMultipleTimes () {
388
+ void multipleEqualParameterReferencesForAnonymousMarkersBindsValueTwice () {
388
389
String sql = "SELECT * FROM person where name = :id or lastname = :id" ;
389
390
390
- BindMarkersFactory factory = BindMarkersFactory .anonymous ("?" );
391
-
392
- PreparedOperation <String > operation = NamedParameterUtils .substituteNamedParameters (
393
- sql , factory , new MapBindParameterSource (
394
- Collections .singletonMap ("id" , Parameters .in ("foo" ))));
391
+ MapBindParameterSource source = new MapBindParameterSource (Map .of ("id" , Parameters .in ("foo" )));
392
+ PreparedOperation <String > operation = NamedParameterUtils .substituteNamedParameters (sql , ANONYMOUS_MARKERS , source );
395
393
396
- assertThat (operation .toQuery ()). isEqualTo (
397
- "SELECT * FROM person where name = ? or lastname = ?" );
394
+ assertThat (operation .toQuery ())
395
+ . isEqualTo ( "SELECT * FROM person where name = ? or lastname = ?" );
398
396
399
- Map <Integer , Object > bindValues = new LinkedHashMap <>();
397
+ Map <Integer , Object > bindings = new HashMap <>();
400
398
401
399
operation .bindTo (new BindTarget () {
402
400
@ Override
@@ -405,7 +403,7 @@ public void bind(String identifier, Object value) {
405
403
}
406
404
@ Override
407
405
public void bind (int index , Object value ) {
408
- bindValues .put (index , value );
406
+ bindings .put (index , value );
409
407
}
410
408
@ Override
411
409
public void bindNull (String identifier , Class <?> type ) {
@@ -417,21 +415,23 @@ public void bindNull(int index, Class<?> type) {
417
415
}
418
416
});
419
417
420
- assertThat (bindValues ).hasSize (2 ).containsEntry (0 , Parameters .in ("foo" )).containsEntry (1 , Parameters .in ("foo" ));
418
+ assertThat (bindings )
419
+ .hasSize (2 )
420
+ .containsEntry (0 , Parameters .in ("foo" ))
421
+ .containsEntry (1 , Parameters .in ("foo" ));
421
422
}
422
423
423
424
@ Test
424
425
void multipleEqualParameterReferencesBindsNullOnce () {
425
426
String sql = "SELECT * FROM person where name = :id or lastname = :id" ;
426
427
427
- BindMarkersFactory factory = BindMarkersFactory .indexed ("$" , 0 );
428
+ MapBindParameterSource source = new MapBindParameterSource (Map .of ("id" , Parameters .in (String .class )));
429
+ PreparedOperation <String > operation = NamedParameterUtils .substituteNamedParameters (sql , INDEXED_MARKERS , source );
428
430
429
- PreparedOperation <String > operation = NamedParameterUtils .substituteNamedParameters (
430
- sql , factory , new MapBindParameterSource (
431
- Collections .singletonMap ("id" , Parameters .in (String .class ))));
431
+ assertThat (operation .toQuery ())
432
+ .isEqualTo ("SELECT * FROM person where name = $1 or lastname = $1" );
432
433
433
- assertThat (operation .toQuery ()).isEqualTo (
434
- "SELECT * FROM person where name = $0 or lastname = $0" );
434
+ Map <Integer , Object > bindings = new HashMap <>();
435
435
436
436
operation .bindTo (new BindTarget () {
437
437
@ Override
@@ -440,8 +440,7 @@ public void bind(String identifier, Object value) {
440
440
}
441
441
@ Override
442
442
public void bind (int index , Object value ) {
443
- assertThat (index ).isEqualTo (0 );
444
- assertThat (value ).isEqualTo (Parameters .in (String .class ));
443
+ bindings .put (index , value );
445
444
}
446
445
@ Override
447
446
public void bindNull (String identifier , Class <?> type ) {
@@ -452,16 +451,20 @@ public void bindNull(int index, Class<?> type) {
452
451
throw new UnsupportedOperationException ();
453
452
}
454
453
});
454
+
455
+ assertThat (bindings )
456
+ .hasSize (1 )
457
+ .containsEntry (0 , Parameters .in (String .class ));
455
458
}
456
459
457
460
458
- private String expand (ParsedSql sql ) {
459
- return NamedParameterUtils .substituteNamedParameters (sql , BIND_MARKERS ,
461
+ private static String expand (ParsedSql sql ) {
462
+ return NamedParameterUtils .substituteNamedParameters (sql , INDEXED_MARKERS ,
460
463
new MapBindParameterSource ()).toQuery ();
461
464
}
462
465
463
- private String expand (String sql ) {
464
- return NamedParameterUtils .substituteNamedParameters (sql , BIND_MARKERS ,
466
+ private static String expand (String sql ) {
467
+ return NamedParameterUtils .substituteNamedParameters (sql , INDEXED_MARKERS ,
465
468
new MapBindParameterSource ()).toQuery ();
466
469
}
467
470
0 commit comments