2323import io .r2dbc .spi .Parameters ;
2424import io .r2dbc .spi .Result ;
2525import org .junit .jupiter .api .BeforeEach ;
26+ import org .junit .jupiter .api .Nested ;
2627import org .junit .jupiter .api .Test ;
2728import reactor .core .publisher .Flux ;
2829import reactor .core .publisher .Mono ;
3839 * @author Mark Paluch
3940 * @author Mingyuan Wu
4041 * @author Juergen Hoeller
42+ * @author Sam Brannen
4143 */
4244abstract class AbstractDatabaseClientIntegrationTests {
4345
@@ -121,7 +123,8 @@ void executeInsertWithMap() {
121123 DatabaseClient databaseClient = DatabaseClient .create (connectionFactory );
122124
123125 databaseClient .sql ("INSERT INTO legoset (id, name, manual) VALUES(:id, :name, :manual)" )
124- .bindValues (Map .of ("id" , 42055 ,
126+ .bindValues (Map .of (
127+ "id" , 42055 ,
125128 "name" , Parameters .in ("SCHAUFELRADBAGGER" ),
126129 "manual" , Parameters .in (Integer .class )))
127130 .fetch ().rowsUpdated ()
@@ -199,8 +202,7 @@ void executeDeferred() {
199202 void shouldEmitGeneratedKey () {
200203 DatabaseClient databaseClient = DatabaseClient .create (connectionFactory );
201204
202- databaseClient .sql (
203- "INSERT INTO legoset ( name, manual) VALUES(:name, :manual)" )
205+ databaseClient .sql ("INSERT INTO legoset ( name, manual) VALUES(:name, :manual)" )
204206 .bind ("name" ,"SCHAUFELRADBAGGER" )
205207 .bindNull ("manual" , Integer .class )
206208 .filter (statement -> statement .returnGeneratedValues ("id" ))
@@ -211,69 +213,129 @@ void shouldEmitGeneratedKey() {
211213 .verifyComplete ();
212214 }
213215
214- @ Test // gh-34768
215- void executeInsertWithReusedNamedParameter () {
216- DatabaseClient databaseClient = DatabaseClient .create (connectionFactory );
217-
218- Lego lego = new Lego (1 , 42 , "Star Wars" , 42 );
219216
220- databaseClient .sql (() -> "INSERT INTO legoset (id, version, name, manual) VALUES(:id, :number, :name, :number)" )
221- .bind ("id" , lego .id )
222- .bind ("name" , lego .name )
223- .bind ("number" , lego .version )
224- .fetch ().rowsUpdated ()
225- .as (StepVerifier ::create )
226- .expectNext (1L )
227- .verifyComplete ();
217+ @ Nested
218+ class ReusedNamedParameterTests {
219+
220+ @ Test // gh-34768
221+ void executeInsertWithReusedNamedParameter () {
222+ DatabaseClient databaseClient = DatabaseClient .create (connectionFactory );
223+
224+ Lego lego = new Lego (1 , 42 , "Star Wars" , 42 );
225+
226+ // ":number" is reused.
227+ databaseClient .sql ("INSERT INTO legoset (id, version, name, manual) VALUES(:id, :number, :name, :number)" )
228+ .bind ("id" , lego .id )
229+ .bind ("name" , lego .name )
230+ .bind ("number" , lego .version )
231+ .fetch ().rowsUpdated ()
232+ .as (StepVerifier ::create )
233+ .expectNext (1L )
234+ .verifyComplete ();
235+
236+ databaseClient .sql ("SELECT * FROM legoset" )
237+ .mapProperties (Lego .class )
238+ .first ()
239+ .as (StepVerifier ::create )
240+ .assertNext (actual -> assertThat (actual ).isEqualTo (lego ))
241+ .verifyComplete ();
242+ }
243+
244+ @ Test // gh-34768
245+ void executeSelectWithReusedNamedParameterList () {
246+ DatabaseClient databaseClient = DatabaseClient .create (connectionFactory );
247+
248+ String insertSql = "INSERT INTO legoset (id, version, name, manual) VALUES(:id, :version, :name, :manual)" ;
249+ // ":numbers" is reused.
250+ String selectSql = "SELECT * FROM legoset WHERE version IN (:numbers) OR manual IN (:numbers)" ;
251+ Lego lego = new Lego (1 , 42 , "Star Wars" , 99 );
252+
253+ databaseClient .sql (insertSql )
254+ .bind ("id" , lego .id )
255+ .bind ("version" , lego .version )
256+ .bind ("name" , lego .name )
257+ .bind ("manual" , lego .manual )
258+ .fetch ().rowsUpdated ()
259+ .as (StepVerifier ::create )
260+ .expectNext (1L )
261+ .verifyComplete ();
262+
263+ databaseClient .sql (selectSql )
264+ // match version
265+ .bind ("numbers" , List .of (2 , 3 , lego .version , 4 ))
266+ .mapProperties (Lego .class )
267+ .first ()
268+ .as (StepVerifier ::create )
269+ .assertNext (actual -> assertThat (actual ).isEqualTo (lego ))
270+ .verifyComplete ();
271+
272+ databaseClient .sql (selectSql )
273+ // match manual
274+ .bind ("numbers" , List .of (2 , 3 , lego .manual , 4 ))
275+ .mapProperties (Lego .class )
276+ .first ()
277+ .as (StepVerifier ::create )
278+ .assertNext (actual -> assertThat (actual ).isEqualTo (lego ))
279+ .verifyComplete ();
280+ }
281+
282+ @ Test // gh-34768
283+ void executeSelectWithReusedNamedParameterListFromBeanProperties () {
284+ DatabaseClient databaseClient = DatabaseClient .create (connectionFactory );
285+
286+ String insertSql = "INSERT INTO legoset (id, version, name, manual) VALUES(:id, :version, :name, :manual)" ;
287+ // ":numbers" is reused.
288+ String selectSql = "SELECT * FROM legoset WHERE version IN (:numbers) OR manual IN (:numbers)" ;
289+ Lego lego = new Lego (1 , 42 , "Star Wars" , 99 );
290+
291+ databaseClient .sql (insertSql )
292+ .bind ("id" , lego .id )
293+ .bind ("version" , lego .version )
294+ .bind ("name" , lego .name )
295+ .bind ("manual" , lego .manual )
296+ .fetch ().rowsUpdated ()
297+ .as (StepVerifier ::create )
298+ .expectNext (1L )
299+ .verifyComplete ();
300+
301+ databaseClient .sql (selectSql )
302+ // match version
303+ .bindProperties (new LegoRequest (List .of (lego .version )))
304+ .mapProperties (Lego .class )
305+ .first ()
306+ .as (StepVerifier ::create )
307+ .assertNext (actual -> assertThat (actual ).isEqualTo (lego ))
308+ .verifyComplete ();
309+
310+ databaseClient .sql (selectSql )
311+ // match manual
312+ .bindProperties (new LegoRequest (List .of (lego .manual )))
313+ .mapProperties (Lego .class )
314+ .first ()
315+ .as (StepVerifier ::create )
316+ .assertNext (actual -> assertThat (actual ).isEqualTo (lego ))
317+ .verifyComplete ();
318+ }
319+
320+
321+ record Lego (int id , Integer version , String name , Integer manual ) {
322+ }
323+
324+ static class LegoRequest {
325+
326+ private final List <Integer > numbers ;
327+
328+ LegoRequest (List <Integer > numbers ) {
329+ this .numbers = numbers ;
330+ }
331+
332+ public List <Integer > getNumbers () {
333+ return numbers ;
334+ }
335+ }
228336
229- databaseClient .sql ("SELECT * FROM legoset" )
230- .mapProperties (Lego .class )
231- .first ()
232- .as (StepVerifier ::create )
233- .assertNext (actual -> assertThat (actual ).isEqualTo (lego ))
234- .verifyComplete ();
235337 }
236338
237- @ Test // gh-34768
238- void executeSelectWithReusedNamedParameterList () {
239- DatabaseClient databaseClient = DatabaseClient .create (connectionFactory );
240-
241- String insertSql = "INSERT INTO legoset (id, version, name, manual) VALUES(:id, :version, :name, :manual)" ;
242- String selectSql = "SELECT * FROM legoset WHERE version IN (:numbers) OR manual IN (:numbers)" ;
243- Lego lego = new Lego (1 , 42 , "Star Wars" , 99 );
244-
245- databaseClient .sql (insertSql )
246- .bind ("id" , lego .id )
247- .bind ("version" , lego .version )
248- .bind ("name" , lego .name )
249- .bind ("manual" , lego .manual )
250- .fetch ().rowsUpdated ()
251- .as (StepVerifier ::create )
252- .expectNext (1L )
253- .verifyComplete ();
254-
255- databaseClient .sql (selectSql )
256- // match version
257- .bind ("numbers" , List .of (2 , 3 , lego .version , 4 ))
258- .mapProperties (Lego .class )
259- .first ()
260- .as (StepVerifier ::create )
261- .assertNext (actual -> assertThat (actual ).isEqualTo (lego ))
262- .verifyComplete ();
263-
264- databaseClient .sql (selectSql )
265- // match manual
266- .bind ("numbers" , List .of (2 , 3 , lego .manual , 4 ))
267- .mapProperties (Lego .class )
268- .first ()
269- .as (StepVerifier ::create )
270- .assertNext (actual -> assertThat (actual ).isEqualTo (lego ))
271- .verifyComplete ();
272- }
273-
274-
275- record Lego (int id , Integer version , String name , Integer manual ) {
276- }
277339
278340 record ParameterRecord (int id , String name , Integer manual ) {
279341 }
0 commit comments