diff --git a/pynuodb/cursor.py b/pynuodb/cursor.py index 4e515f5..f944518 100644 --- a/pynuodb/cursor.py +++ b/pynuodb/cursor.py @@ -184,7 +184,11 @@ def executemany(self, operation, seq_of_parameters): def fetchone(self): # type: () -> Optional[result_set.Row] """Return the next row of results from the previous SQL operation.""" - self._check_closed() + # Inline _check_closed to avoid per-row function-call overhead. + if self.closed: + raise Error("cursor is closed") + if self.session.closed: + raise Error("connection is closed") if self._result_set is None: raise Error("Previous execute did not produce any results or no call was issued yet") self.rownumber += 1 @@ -218,14 +222,22 @@ def fetchall(self): # type: () -> List[result_set.Row] """Return all rows generated by the previous SQL operation.""" self._check_closed() + if self._result_set is None: + raise Error("Previous execute did not produce any results or no call was issued yet") - fetched_rows = [] + fetched_rows = [] # type: List[result_set.Row] while True: - row = self.fetchone() - if row is None: + # Drain the current in-memory batch in one shot instead of calling + # fetchone() per row. + idx = self._result_set.results_idx + batch = self._result_set.results + if idx < len(batch): + fetched_rows.extend(batch[idx:]) + self._result_set.results_idx = len(batch) + if self._result_set.complete: break - else: - fetched_rows.append(row) + self.session.fetch_result_set_next(self._result_set) + self.rownumber += len(fetched_rows) return fetched_rows def nextset(self): # pylint: disable=no-self-use