@@ -165,12 +165,12 @@ public Result run(Query query) {
165165 // Below are all the implementations (methods and classes) as defined by the contracts of Neo4jClient
166166
167167 @ Override
168- public RunnableSpec query (String cypher ) {
168+ public UnboundRunnableSpec query (String cypher ) {
169169 return query (() -> cypher );
170170 }
171171
172172 @ Override
173- public RunnableSpec query (Supplier <String > cypherSupplier ) {
173+ public UnboundRunnableSpec query (Supplier <String > cypherSupplier ) {
174174 return new DefaultRunnableSpec (cypherSupplier );
175175 }
176176
@@ -256,80 +256,63 @@ private UserSelection resolveUser(@Nullable String userName) {
256256 return UserSelectionProvider .getDefaultSelectionProvider ().getUserSelection ();
257257 }
258258
259- class DefaultRunnableSpec implements RunnableSpec {
259+ class DefaultRunnableSpec implements UnboundRunnableSpec , RunnableSpecBoundToDatabaseAndUser {
260260
261261 private final RunnableStatement runnableStatement ;
262262
263263 private DatabaseSelection databaseSelection ;
264264
265- @ Nullable
266- private UserSelection impersonatedUser ;
265+ private UserSelection userSelection ;
267266
268267 DefaultRunnableSpec (Supplier <String > cypherSupplier ) {
268+
269269 this .databaseSelection = resolveTargetDatabaseName (null );
270- this .impersonatedUser = resolveUser (null );
270+ this .userSelection = resolveUser (null );
271271 this .runnableStatement = new RunnableStatement (cypherSupplier );
272272 }
273273
274274 @ Override
275- public RunnableSpecTightToDatabase in (String targetDatabase ) {
275+ public RunnableSpecBoundToDatabase in (String targetDatabase ) {
276276
277277 this .databaseSelection = resolveTargetDatabaseName (targetDatabase );
278- return this ;
278+ return new DefaultRunnableSpecBoundToDatabase () ;
279279 }
280280
281- class DefaultOngoingBindSpec <T > implements OngoingBindSpec <T , RunnableSpecTightToDatabase > {
282-
283- @ Nullable private final T value ;
284-
285- DefaultOngoingBindSpec (@ Nullable T value ) {
286- this .value = value ;
287- }
288-
289- @ Override
290- public RunnableSpecTightToDatabase to (String name ) {
291-
292- DefaultRunnableSpec .this .runnableStatement .parameters .add (name , value );
293- return DefaultRunnableSpec .this ;
294- }
295-
296- @ Override
297- public RunnableSpecTightToDatabase with (Function <T , Map <String , Object >> binder ) {
298-
299- Assert .notNull (binder , "Binder is required." );
281+ @ Override
282+ public RunnableSpecBoundToUser asUser (String asUser ) {
300283
301- return bindAll ( binder . apply ( value ) );
302- }
284+ this . userSelection = resolveUser ( asUser );
285+ return new DefaultRunnableSpecBoundToUser ();
303286 }
304287
305288 @ Override
306- public <T > OngoingBindSpec <T , RunnableSpecTightToDatabase > bind (T value ) {
289+ public <T > OngoingBindSpec <T , RunnableSpec > bind (T value ) {
307290 return new DefaultOngoingBindSpec <>(value );
308291 }
309292
310293 @ Override
311- public RunnableSpecTightToDatabase bindAll (Map <String , Object > newParameters ) {
294+ public RunnableSpec bindAll (Map <String , Object > newParameters ) {
312295 this .runnableStatement .parameters .addAll (newParameters );
313296 return this ;
314297 }
315298
316299 @ Override
317300 public <T > MappingSpec <T > fetchAs (Class <T > targetClass ) {
318301
319- return new DefaultRecordFetchSpec <>(databaseSelection , impersonatedUser , runnableStatement ,
302+ return new DefaultRecordFetchSpec <>(databaseSelection , userSelection , runnableStatement ,
320303 new SingleValueMappingFunction <>(conversionService , targetClass ));
321304 }
322305
323306 @ Override
324307 public RecordFetchSpec <Map <String , Object >> fetch () {
325308
326- return new DefaultRecordFetchSpec <>(databaseSelection , impersonatedUser , runnableStatement , (t , r ) -> r .asMap ());
309+ return new DefaultRecordFetchSpec <>(databaseSelection , userSelection , runnableStatement , (t , r ) -> r .asMap ());
327310 }
328311
329312 @ Override
330313 public ResultSummary run () {
331314
332- try (QueryRunner statementRunner = getQueryRunner (databaseSelection , impersonatedUser )) {
315+ try (QueryRunner statementRunner = getQueryRunner (databaseSelection , userSelection )) {
333316 Result result = runnableStatement .runWith (statementRunner );
334317 return ResultSummaries .process (result .consume ());
335318 } catch (RuntimeException e ) {
@@ -338,6 +321,99 @@ public ResultSummary run() {
338321 throw new RuntimeException (e );
339322 }
340323 }
324+
325+ class DefaultOngoingBindSpec <T > implements OngoingBindSpec <T , RunnableSpec > {
326+
327+ @ Nullable private final T value ;
328+
329+ DefaultOngoingBindSpec (@ Nullable T value ) {
330+ this .value = value ;
331+ }
332+
333+ @ Override
334+ public RunnableSpec to (String name ) {
335+
336+ DefaultRunnableSpec .this .runnableStatement .parameters .add (name , value );
337+ return DefaultRunnableSpec .this ;
338+ }
339+
340+ @ Override
341+ public RunnableSpec with (Function <T , Map <String , Object >> binder ) {
342+
343+ Assert .notNull (binder , "Binder is required." );
344+
345+ return bindAll (binder .apply (value ));
346+ }
347+ }
348+
349+ class DefaultRunnableSpecBoundToDatabase implements RunnableSpecBoundToDatabase {
350+ @ Override
351+ public RunnableSpecBoundToDatabaseAndUser asUser (String aUser ) {
352+
353+ DefaultRunnableSpec .this .userSelection = resolveUser (aUser );
354+ return DefaultRunnableSpec .this ;
355+ }
356+
357+ @ Override
358+ public <T > MappingSpec <T > fetchAs (Class <T > targetClass ) {
359+ return DefaultRunnableSpec .this .fetchAs (targetClass );
360+ }
361+
362+ @ Override
363+ public RecordFetchSpec <Map <String , Object >> fetch () {
364+ return DefaultRunnableSpec .this .fetch ();
365+ }
366+
367+ @ Override
368+ public ResultSummary run () {
369+ return DefaultRunnableSpec .this .run ();
370+ }
371+
372+ @ Override
373+ public <T > OngoingBindSpec <T , RunnableSpec > bind (T value ) {
374+ return DefaultRunnableSpec .this .bind (value );
375+ }
376+
377+ @ Override
378+ public RunnableSpec bindAll (Map <String , Object > parameters ) {
379+ return DefaultRunnableSpec .this .bindAll (parameters );
380+ }
381+ }
382+
383+ class DefaultRunnableSpecBoundToUser implements RunnableSpecBoundToUser {
384+
385+ @ Override
386+ public RunnableSpecBoundToDatabaseAndUser in (String aDatabase ) {
387+
388+ DefaultRunnableSpec .this .databaseSelection = resolveTargetDatabaseName (aDatabase );
389+ return DefaultRunnableSpec .this ;
390+ }
391+
392+ @ Override
393+ public <T > MappingSpec <T > fetchAs (Class <T > targetClass ) {
394+ return DefaultRunnableSpec .this .fetchAs (targetClass );
395+ }
396+
397+ @ Override
398+ public RecordFetchSpec <Map <String , Object >> fetch () {
399+ return DefaultRunnableSpec .this .fetch ();
400+ }
401+
402+ @ Override
403+ public ResultSummary run () {
404+ return DefaultRunnableSpec .this .run ();
405+ }
406+
407+ @ Override
408+ public <T > OngoingBindSpec <T , RunnableSpec > bind (T value ) {
409+ return DefaultRunnableSpec .this .bind (value );
410+ }
411+
412+ @ Override
413+ public RunnableSpec bindAll (Map <String , Object > parameters ) {
414+ return DefaultRunnableSpec .this .bindAll (parameters );
415+ }
416+ }
341417 }
342418
343419 class DefaultRecordFetchSpec <T > implements RecordFetchSpec <T >, MappingSpec <T > {
0 commit comments