2525from neo4j .data import DataDehydrator
2626from neo4j .io import ConnectionErrorHandler
2727from neo4j .work .summary import ResultSummary
28+ from neo4j .exceptions import ResultConsumedError
2829
2930
3031class Result :
@@ -192,20 +193,37 @@ def __iter__(self):
192193 self ._closed = True
193194
194195 def _attach (self ):
195- """Sets the Result object in an attached state by fetching messages from the connection to the buffer.
196+ """Sets the Result object in an attached state by fetching messages from
197+ the connection to the buffer.
196198 """
197199 if self ._closed is False :
198200 while self ._attached is False :
199201 self ._connection .fetch_message ()
200202
201- def _buffer_all (self ):
202- """Sets the Result object in an detached state by fetching all records from the connection to the buffer.
203+ def _buffer (self , n = None ):
204+ """Try to fill `self_record_buffer` with n records.
205+
206+ Might end up with more records in the buffer if the fetch size makes it
207+ overshoot.
208+ Might ent up with fewer records in the buffer if there are not enough
209+ records available.
203210 """
204211 record_buffer = deque ()
205212 for record in self :
206213 record_buffer .append (record )
214+ if n is not None and len (record_buffer ) >= n :
215+ break
207216 self ._closed = False
208- self ._record_buffer = record_buffer
217+ if n is None :
218+ self ._record_buffer = record_buffer
219+ else :
220+ self ._record_buffer .extend (record_buffer )
221+
222+ def _buffer_all (self ):
223+ """Sets the Result object in an detached state by fetching all records
224+ from the connection to the buffer.
225+ """
226+ self ._buffer ()
209227
210228 def _obtain_summary (self ):
211229 """Obtain the summary of this result, buffering any remaining records.
@@ -278,6 +296,13 @@ def single(self):
278296 :returns: the next :class:`neo4j.Record` or :const:`None` if none remain
279297 :warns: if more than one record is available
280298 """
299+ # TODO in 5.0 replace with this code that raises an error if there's not
300+ # exactly one record in the left result stream.
301+ # self._buffer(2).
302+ # if len(self._record_buffer) != 1:
303+ # raise SomeError("Expected exactly 1 record, found %i"
304+ # % len(self._record_buffer))
305+ # return self._record_buffer.popleft()
281306 records = list (self ) # TODO: exhausts the result with self.consume if there are more records.
282307 size = len (records )
283308 if size == 0 :
@@ -292,16 +317,9 @@ def peek(self):
292317
293318 :returns: the next :class:`.Record` or :const:`None` if none remain
294319 """
320+ self ._buffer (1 )
295321 if self ._record_buffer :
296322 return self ._record_buffer [0 ]
297- if not self ._attached :
298- return None
299- while self ._attached :
300- self ._connection .fetch_message ()
301- if self ._record_buffer :
302- return self ._record_buffer [0 ]
303-
304- return None
305323
306324 def graph (self ):
307325 """Return a :class:`neo4j.graph.Graph` instance containing all the graph objects
0 commit comments