Make polling a cursor that's not in an async query raise an exception.

If there is an asynchronous query, polling a cursor that did not
initiate it will raise an exception. Polling while there is no
asynchronous query underway still works, because the user needs to
have a way to get asynchronous NOTIFYs.
This commit is contained in:
Jan Urbański 2010-04-10 18:51:13 +02:00 committed by Federico Di Gregorio
parent a90935930b
commit 4afc1baf35
2 changed files with 34 additions and 1 deletions

View File

@ -1480,6 +1480,12 @@ psyco_curs_poll(cursorObject *self)
{ {
EXC_IF_CURS_CLOSED(self); EXC_IF_CURS_CLOSED(self);
if (self->conn->async_cursor != NULL &&
self->conn->async_cursor != (PyObject *) self) {
PyErr_SetString(ProgrammingError, "poll with wrong cursor");
return NULL;
}
Dprintf("curs_poll: polling with status %d", self->conn->async_status); Dprintf("curs_poll: polling with status %d", self->conn->async_status);
if (self->conn->async_status == ASYNC_WRITE) { if (self->conn->async_status == ASYNC_WRITE) {

View File

@ -299,7 +299,6 @@ class AsyncTests(unittest.TestCase):
self.assert_(not conn.issync()) self.assert_(not conn.issync())
conn.close() conn.close()
def test_flush_on_write(self): def test_flush_on_write(self):
# a very large query requires a flush loop to be sent to the backend # a very large query requires a flush loop to be sent to the backend
curs = self.conn.cursor() curs = self.conn.cursor()
@ -315,6 +314,34 @@ class AsyncTests(unittest.TestCase):
self.fail("sending a large query didn't trigger block on write.") self.fail("sending a large query didn't trigger block on write.")
def test_sync_poll(self):
cur = self.sync_conn.cursor()
# polling a sync cursor works
cur.poll()
def test_async_poll_wrong_cursor(self):
cur1 = self.conn.cursor()
cur2 = self.conn.cursor()
cur1.execute("select 1")
# polling a cursor that's not currently executing is an error
self.assertRaises(psycopg2.ProgrammingError, cur2.poll)
self.wait_for_query(cur1)
self.assertEquals(cur1.fetchone()[0], 1)
def test_async_fetch_wrong_cursor(self):
cur1 = self.conn.cursor()
cur2 = self.conn.cursor()
cur1.execute("select 1")
self.wait_for_query(cur1)
self.assertFalse(self.conn.executing())
# fetching from a cursor with no results is an error
self.assertRaises(psycopg2.ProgrammingError, cur2.fetchone)
# fetching from the correct cursor works
self.assertEquals(cur1.fetchone()[0], 1)
def test_suite(): def test_suite():
return unittest.TestLoader().loadTestsFromName(__name__) return unittest.TestLoader().loadTestsFromName(__name__)