diff --git a/pynuodb/cursor.py b/pynuodb/cursor.py index e7ecea3..44949e1 100644 --- a/pynuodb/cursor.py +++ b/pynuodb/cursor.py @@ -69,6 +69,8 @@ def close(self): """Closes the cursor into the database.""" self._check_closed() self._statement_cache.shutdown() + if self._result_set: + self._result_set.close(self.session) self.closed = True def _check_closed(self): @@ -79,10 +81,7 @@ def _check_closed(self): raise Error("connection is closed") def _reset(self): - """Resets SQL transaction variables. - - Also closes any open statements and result sets. - """ + """Resets SQL transaction variables.""" self.description = None self.rowcount = -1 self.colcount = -1 diff --git a/pynuodb/encodedsession.py b/pynuodb/encodedsession.py index bb3dfec..41cc0b0 100644 --- a/pynuodb/encodedsession.py +++ b/pynuodb/encodedsession.py @@ -271,6 +271,13 @@ def close_statement(self, statement): self._putMessageId(protocol.CLOSESTATEMENT).putInt(statement.handle) self._exchangeMessages(False) + def close_result_set(self, result_set): + """ + :type result_set: ResultSet + """ + self._putMessageId(protocol.CLOSERESULTSET).putInt(result_set.handle) + self._exchangeMessages(False) + def create_prepared_statement(self, query): """ :type query: str diff --git a/pynuodb/result_set.py b/pynuodb/result_set.py index 70faa89..cde8964 100644 --- a/pynuodb/result_set.py +++ b/pynuodb/result_set.py @@ -35,3 +35,9 @@ def fetchone(self, session): res = self.results[self.results_idx] self.results_idx += 1 return res + + def close(self, session): + """ + :type session EncodedSession + """ + session.close_result_set(self) diff --git a/tests/nuodb_cursor_test.py b/tests/nuodb_cursor_test.py index 2462be7..6d19d3a 100644 --- a/tests/nuodb_cursor_test.py +++ b/tests/nuodb_cursor_test.py @@ -3,7 +3,9 @@ import unittest from .nuodb_base import NuoBase -from pynuodb.exception import DataError, ProgrammingError, BatchError +from pynuodb.exception import DataError, ProgrammingError, BatchError, OperationalError +from distutils.version import LooseVersion +from os import getenv class NuoDBCursorTest(NuoBase): @@ -125,6 +127,29 @@ def test_executemany_somefail(self): cursor.execute("DROP TABLE executemany_table") + def test_result_set_gets_closed(self): + current_version = getenv('NUODB_VERSION', None) # skipif <2.1 + if current_version is not None and not LooseVersion(current_version) < LooseVersion("2.1"): + # Server will throw error after 1000 open result sets + con = self._connect() + for j in [False, True]: + for i in range(2015): + if not j: + cursor = con.cursor() + cursor.execute('select 1 from dual;') + con.commit() + cursor.close() + else: + if i >= 1000: + with self.assertRaises(OperationalError): + cursor = con.cursor() + cursor.execute('select 1 from dual;') + con.commit() + else: + cursor = con.cursor() + cursor.execute('select 1 from dual;') + con.commit() + if __name__ == '__main__': unittest.main()