diff options
| -rw-r--r-- | ChangeLog | 2 | ||||
| -rw-r--r-- | NEWS-2.3 | 4 | ||||
| -rw-r--r-- | psycopg/connection_int.c | 29 | ||||
| -rw-r--r-- | tests/test_connection.py | 26 |
4 files changed, 50 insertions, 11 deletions
@@ -6,6 +6,8 @@ * lib/extras.py: don't change the exception raised when fetching without a result from NamedTupleCursor. + * psycopg/connection_int.c: fixed notices order (ticket #9). + 2010-11-10 Daniele Varrazzo <daniele.varrazzo@gmail.com> * psycopg/green.c: functions unused outside the module marked static. @@ -25,7 +25,9 @@ psycopg 2.3 aims to expose some new features introduced in PostgreSQL 9.0. - Fixed use of `PQfreemem` instead of `free` in binary typecaster. - Fixed access to freed memory in `conn_get_isolation_level()`. - - Fixed crash during Decimal adaptation with a few 2.5.x Python versions. + - Fixed crash during Decimal adaptation with a few 2.5.x Python versions + (ticket #7). + - Fixed notices order (ticket #9). What's new in psycopg 2.2.2 diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index b952788..7f86460 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -71,32 +71,41 @@ void conn_notice_process(connectionObject *self) { struct connectionObject_notice *notice; - PyObject *msg; + Py_ssize_t nnotices; + + if (NULL == self->notice_pending) { + return; + } Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); + Py_BLOCK_THREADS; notice = self->notice_pending; + nnotices = PyList_GET_SIZE(self->notice_list); while (notice != NULL) { - Py_BLOCK_THREADS; - + PyObject *msg; msg = PyString_FromString(notice->message); Dprintf("conn_notice_process: %s", notice->message); - PyList_Append(self->notice_list, msg); + /* Respect the order in which notices were produced, + because in notice_list they are reversed (see ticket #9) */ + PyList_Insert(self->notice_list, nnotices, msg); Py_DECREF(msg); - /* Remove the oldest item if the queue is getting too long. */ - if (PyList_GET_SIZE(self->notice_list) > CONN_NOTICES_LIMIT) - PySequence_DelItem(self->notice_list, 0); - - Py_UNBLOCK_THREADS; - notice = notice->next; } + /* Remove the oldest item if the queue is getting too long. */ + nnotices = PyList_GET_SIZE(self->notice_list); + if (nnotices > CONN_NOTICES_LIMIT) { + PySequence_DelSlice(self->notice_list, + 0, nnotices - CONN_NOTICES_LIMIT); + } + + Py_UNBLOCK_THREADS; pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; diff --git a/tests/test_connection.py b/tests/test_connection.py index 816b636..13b91e8 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -48,6 +48,32 @@ class ConnectionTests(unittest.TestCase): self.assert_(conn.notices) conn.close() + def test_notices_consistent_order(self): + conn = self.connect() + cur = conn.cursor() + cur.execute("create temp table table1 (id serial); create temp table table2 (id serial);") + cur.execute("create temp table table3 (id serial); create temp table table4 (id serial);") + self.assertEqual(4, len(conn.notices)) + self.assert_('table1' in conn.notices[0]) + self.assert_('table2' in conn.notices[1]) + self.assert_('table3' in conn.notices[2]) + self.assert_('table4' in conn.notices[3]) + conn.close() + + def test_notices_limited(self): + conn = self.connect() + cur = conn.cursor() + for i in range(0, 100, 10): + sql = " ".join(["create temp table table%d (id serial);" % j for j in range(i, i+10)]) + cur.execute(sql) + + self.assertEqual(50, len(conn.notices)) + self.assert_('table50' in conn.notices[0], conn.notices[0]) + self.assert_('table51' in conn.notices[1], conn.notices[1]) + self.assert_('table98' in conn.notices[-2], conn.notices[-2]) + self.assert_('table99' in conn.notices[-1], conn.notices[-1]) + conn.close() + def test_server_version(self): conn = self.connect() self.assert_(conn.server_version) |
