summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--NEWS-2.34
-rw-r--r--psycopg/connection_int.c29
-rw-r--r--tests/test_connection.py26
4 files changed, 50 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index e5c2922..cc318ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/NEWS-2.3 b/NEWS-2.3
index 4ddfc92..87f03ca 100644
--- a/NEWS-2.3
+++ b/NEWS-2.3
@@ -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)