42
42
import org .neo4j .driver .v1 .util .Function ;
43
43
import org .neo4j .driver .v1 .util .Functions ;
44
44
45
- import static java .lang .String .format ;
46
45
import static java .util .Collections .emptyList ;
47
46
48
47
public class InternalStatementResult implements StatementResult
@@ -55,7 +54,6 @@ public class InternalStatementResult implements StatementResult
55
54
private List <String > keys = null ;
56
55
private ResultSummary summary = null ;
57
56
58
- private boolean open = true ;
59
57
private long position = -1 ;
60
58
private boolean done = false ;
61
59
@@ -170,26 +168,17 @@ StreamCollector pullAllResponseCollector()
170
168
@ Override
171
169
public List <String > keys ()
172
170
{
173
- tryFetching ();
171
+ if ( keys == null )
172
+ {
173
+ tryFetchNext ();
174
+ }
174
175
return keys ;
175
176
}
176
177
177
178
@ Override
178
179
public boolean hasNext ()
179
180
{
180
- if (!recordBuffer .isEmpty ())
181
- {
182
- return true ;
183
- }
184
- else if (done )
185
- {
186
- return false ;
187
- }
188
- else
189
- {
190
- tryFetching ();
191
- return hasNext ();
192
- }
181
+ return tryFetchNext ();
193
182
}
194
183
195
184
@ Override
@@ -201,67 +190,52 @@ public Record next()
201
190
// in a way that makes the two equivalent in performance.
202
191
// To get the intended benefit, we need to allocate Record in this method,
203
192
// and have it copy out its fields from some lower level data structure.
204
- assertOpen ();
205
- Record nextRecord = recordBuffer .poll ();
206
- if ( nextRecord != null )
193
+ if ( tryFetchNext () )
207
194
{
208
195
position += 1 ;
209
- return nextRecord ;
210
- }
211
- else if ( done )
212
- {
213
- return null ;
196
+ return recordBuffer .poll ();
214
197
}
215
198
else
216
199
{
217
- tryFetching ();
218
- return next ();
200
+ throw new NoSuchRecordException ( "No more records" );
219
201
}
220
202
}
221
203
222
204
@ Override
223
205
public Record single ()
224
206
{
225
- if ( position > 0 )
207
+ if ( hasNext () )
226
208
{
227
- throw new NoSuchRecordException (
228
- "Cannot retrieve the first record, because other operations have already used the first record. " +
229
- "Please ensure you are not calling `first` multiple times, or are mixing it with calls " +
230
- "to `next`, `single`, `list` or any other method that changes the position of the cursor." );
231
- }
209
+ Record single = next ();
210
+ boolean hasMoreThanOne = hasNext ();
232
211
233
- if ( !hasNext () )
234
- {
235
- throw new NoSuchRecordException ( "Cannot retrieve the first record, because this result is empty." );
236
- }
212
+ consume ();
213
+
214
+ if ( hasMoreThanOne )
215
+ {
216
+ throw new NoSuchRecordException ( "Expected a result with a single record, but this result contains at least one more. " +
217
+ "Ensure your query returns only one record, or use `first` instead of `single` if " +
218
+ "you do not care about the number of records in the result." );
219
+ }
237
220
238
- Record first = next ();
239
- if ( hasNext () )
221
+ return single ;
222
+ }
223
+ else
240
224
{
241
- throw new NoSuchRecordException ( "Expected a result with a single record, but this result contains at least one more. " +
242
- "Ensure your query returns only one record, or use `first` instead of `single` if " +
243
- "you do not care about the number of records in the result." );
225
+ throw new NoSuchRecordException ( "Cannot retrieve a single record, because this result is empty." );
244
226
}
245
- return first ;
246
227
}
247
228
248
229
@ Override
249
230
public Record peek ()
250
231
{
251
- assertOpen ();
252
- Record nextRecord = recordBuffer .peek ();
253
- if ( nextRecord != null )
254
- {
255
- return nextRecord ;
256
- }
257
- else if ( done )
232
+ if ( tryFetchNext () )
258
233
{
259
- return null ;
234
+ return recordBuffer . peek () ;
260
235
}
261
236
else
262
237
{
263
- tryFetching ();
264
- return peek ();
238
+ throw new NoSuchRecordException ( "Cannot peek past the last record" );
265
239
}
266
240
}
267
241
@@ -274,46 +248,41 @@ public List<Record> list()
274
248
@ Override
275
249
public <T > List <T > list ( Function <Record , T > mapFunction )
276
250
{
277
- if ( isEmpty () )
278
- {
279
- assertOpen ();
280
- return emptyList ();
281
- }
282
- else if ( position == -1 && hasNext () )
251
+ if ( hasNext () )
283
252
{
284
253
List <T > result = new ArrayList <>();
254
+
285
255
do
286
256
{
287
257
result .add ( mapFunction .apply ( next () ) );
288
258
}
289
259
while ( hasNext () );
290
260
291
- consume ();
292
261
return result ;
293
262
}
294
263
else
295
264
{
296
- throw new ClientException (
297
- format ( "Can't retain records when cursor is not pointing at the first record (currently at position %d)" , position )
298
- );
265
+ return emptyList ();
299
266
}
300
267
}
301
268
302
- @ SuppressWarnings ("StatementWithEmptyBody" )
303
269
@ Override
304
270
public ResultSummary consume ()
305
271
{
306
- if (! open )
272
+ if ( done )
307
273
{
308
- return summary ;
274
+ recordBuffer . clear () ;
309
275
}
310
-
311
- while ( !done )
276
+ else
312
277
{
313
- connection .receiveOne ();
278
+ do
279
+ {
280
+ connection .receiveOne ();
281
+ recordBuffer .clear ();
282
+ }
283
+ while ( !done );
314
284
}
315
- recordBuffer .clear ();
316
- open = false ;
285
+
317
286
return summary ;
318
287
}
319
288
@@ -323,26 +292,17 @@ public void remove()
323
292
throw new ClientException ( "Removing records from a result is not supported." );
324
293
}
325
294
326
- private void assertOpen ()
295
+ private boolean tryFetchNext ()
327
296
{
328
- if ( !open )
329
- {
330
- throw new ClientException ( "Result has been closed" );
331
- }
332
- }
333
-
334
- private boolean isEmpty ()
335
- {
336
- tryFetching ();
337
- return position == -1 && recordBuffer .isEmpty () && done ;
338
- }
339
-
340
- private void tryFetching ()
341
- {
342
- while ( recordBuffer .isEmpty () && !done )
297
+ while ( recordBuffer .isEmpty () )
343
298
{
299
+ if ( done )
300
+ {
301
+ return false ;
302
+ }
344
303
connection .receiveOne ();
345
304
}
346
- }
347
305
306
+ return true ;
307
+ }
348
308
}
0 commit comments