Skip to content

Commit

Permalink
support iteration on cursor
Browse files Browse the repository at this point in the history
as e.g. the django ORM expect this to work
  • Loading branch information
msbt committed Oct 21, 2014
1 parent 410a86e commit 1d7573e
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 12 deletions.
5 changes: 5 additions & 0 deletions CHANGES.txt
Expand Up @@ -2,6 +2,11 @@
Changes for crate
=================

Unreleased
==========

- support iterator protocol on cursor

2014/10/20 0.12.2
=================

Expand Down
33 changes: 21 additions & 12 deletions src/crate/client/cursor.py
Expand Up @@ -21,6 +21,7 @@

from .exceptions import ProgrammingError
from distutils.version import StrictVersion
import warnings

BULK_INSERT_MIN_VERSION = StrictVersion("0.42.0")

Expand All @@ -37,6 +38,7 @@ def __init__(self, connection):
self.connection = connection
self._closed = False
self._result = None
self.rows = None

def execute(self, sql, parameters=None, bulk_parameters=None):
"""
Expand Down Expand Up @@ -89,18 +91,21 @@ def fetchone(self):
more data is available.
Alias for ``next()``.
"""
return self.next()

def next(self):
"""
Fetch the next row of a query result set, returning a single sequence, or None when no
more data is available.
"""
try:
return self._next()
return self.next()
except StopIteration:
return None

def __iter__(self):
"""
support iterator interface: http://legacy.python.org/dev/peps/pep-0249/#iter
This iterator is shared. Advancing this iterator will advance other
iterators created from this cursor.
"""
warnings.warn("DB-API extension cursor.__iter__() used")
return self

def fetchmany(self, count=None):
"""
Fetch the next set of rows of a query result, returning a sequence of sequences
Expand All @@ -113,7 +118,7 @@ def fetchmany(self, count=None):
result = []
for i in range(count):
try:
result.append(self._next())
result.append(self.next())
except StopIteration:
pass
return result
Expand All @@ -128,7 +133,7 @@ def fetchall(self):
iterate = True
while iterate:
try:
result.append(self._next())
result.append(self.next())
except StopIteration:
iterate = False
return result
Expand Down Expand Up @@ -167,15 +172,19 @@ def rowcount(self):
return -1
return self._result.get("rowcount", -1)

def _next(self):
def next(self):
"""
Return the next row of a query result set, respecting if cursor was closed.
"""
if not self._closed:
if self.rows is None:
raise ProgrammingError("No result available. execute() or executemany() must be called first.")
elif not self._closed:
return next(self.rows)
else:
raise ProgrammingError("Cursor closed")

__next__ = next

@property
def description(self):
"""
Expand Down
42 changes: 42 additions & 0 deletions src/crate/client/cursor.txt
Expand Up @@ -51,6 +51,16 @@ A further call to ``fetchone()`` returns an empty result:

>>> cursor.fetchone()

Using ``fetchone()`` on a cursor before issuing a database statement results
in an error::

>>> new_cursor = connection.cursor()
>>> new_cursor.fetchone()
Traceback (most recent call last):
...
ProgrammingError: No result available. execute() or executemany() must be called first.


fetchmany()
===========

Expand Down Expand Up @@ -111,6 +121,38 @@ And each other call returns an empty sequence::
>>> cursor.fetchall()
[]

iteration
=========

The cursor supports the iterator interface and can be iterated upon::

>>> cursor.execute('')
>>> [row for row in cursor]
[['North West Ripple', 1], ['Arkintoofle Minor', 3], ['Alpha Centauri', 3]]

When no other call to execute has been done, it will raise StopIteration on
subsequent iterations::

>>> next(cursor)
Traceback (most recent call last):
...
StopIteration

>>> cursor.execute('')
>>> for row in cursor:
... row
['North West Ripple', 1]
['Arkintoofle Minor', 3]
['Alpha Centauri', 3]

Iterating over a new cursor without results will immediately raise a ProgrammingError::

>>> new_cursor = connection.cursor()
>>> next(new_cursor)
Traceback (most recent call last):
...
ProgrammingError: No result available. execute() or executemany() must be called first.

description
===========

Expand Down

0 comments on commit 1d7573e

Please sign in to comment.