|
23 | 23 | >>> del server['python-tests']
|
24 | 24 | """
|
25 | 25 |
|
| 26 | +import itertools |
26 | 27 | import mimetypes
|
27 | 28 | import os
|
28 | 29 | from types import FunctionType
|
@@ -844,19 +845,30 @@ def iterview(self, name, batch, wrapper=None, **options):
|
844 | 845 | :param options: optional query string parameters
|
845 | 846 | :return: row generator
|
846 | 847 | """
|
| 848 | + # Check sane batch size. |
847 | 849 | if batch <= 0:
|
848 | 850 | raise ValueError('batch must be 1 or more')
|
849 |
| - options['limit'] = batch + 1 # XXX todo: don't overwrite caller's limit |
| 851 | + # Save caller's limit, it must be handled manually. |
| 852 | + limit = options.get('limit') |
| 853 | + if limit is not None and limit <= 0: |
| 854 | + raise ValueError('limit must be 1 or more') |
850 | 855 | startkey, startkey_docid = None, None # XXX todo: honour caller's startkey
|
851 | 856 | while True:
|
852 |
| - options.update(startkey=startkey, startkey_docid=startkey_docid) |
853 |
| - # Get a batch of rows, with one extra for start of next batch. |
| 857 | + loop_limit = min(limit or batch, batch) |
| 858 | + # Get rows in batches, with one extra for start of next batch. |
| 859 | + options.update(limit=loop_limit + 1, startkey=startkey, |
| 860 | + startkey_docid=startkey_docid) |
854 | 861 | rows = list(self.view(name, wrapper, **options))
|
855 |
| - # Yield at most 'batch' rows. |
856 |
| - for row in rows[:batch]: |
| 862 | + # Yield rows from this batch. |
| 863 | + for row in itertools.islice(rows, loop_limit): |
857 | 864 | yield row
|
858 |
| - if len(rows) <= batch: |
| 865 | + # Decrement limit counter. |
| 866 | + if limit is not None: |
| 867 | + limit -= min(len(rows), batch) |
| 868 | + # Check if there is nothing else to yield. |
| 869 | + if len(rows) <= batch or (limit is not None and limit == 0): |
859 | 870 | break
|
| 871 | + # Save start keys for next loop. |
860 | 872 | startkey, startkey_docid = rows[-1]['key'], rows[-1]['id']
|
861 | 873 |
|
862 | 874 | def show(self, name, docid=None, **options):
|
|
0 commit comments