summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2011-12-15 12:53:48 +0000
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2011-12-15 12:53:48 +0000
commitb5de04d2ff6fd50b7e4fd06516ac396d9c79d8b6 (patch)
treec838c6bf0d56bc6c2cb1f3739746fd2f5ede361d
parentd2d94e203f868d17d4e7ff670078a7df7afbad90 (diff)
downloadpsycopg2-b5de04d2ff6fd50b7e4fd06516ac396d9c79d8b6.tar.gz
Put back a distinct ISOLATION_LEVEL_READ_UNCOMMITTED value
-rw-r--r--lib/extensions.py4
-rw-r--r--psycopg/connection.h7
-rw-r--r--psycopg/connection_int.c23
-rw-r--r--psycopg/connection_type.c7
-rwxr-xr-xtests/test_connection.py13
5 files changed, 34 insertions, 20 deletions
diff --git a/lib/extensions.py b/lib/extensions.py
index bedb246..bb8e3dd 100644
--- a/lib/extensions.py
+++ b/lib/extensions.py
@@ -69,13 +69,11 @@ except ImportError:
"""Isolation level values."""
ISOLATION_LEVEL_AUTOCOMMIT = 0
+ISOLATION_LEVEL_READ_UNCOMMITTED = 4
ISOLATION_LEVEL_READ_COMMITTED = 1
ISOLATION_LEVEL_REPEATABLE_READ = 2
ISOLATION_LEVEL_SERIALIZABLE = 3
-# PostgreSQL internally converts uncommited to commited
-ISOLATION_LEVEL_READ_UNCOMMITTED = ISOLATION_LEVEL_READ_COMMITTED
-
"""psycopg connection status values."""
STATUS_SETUP = 0
STATUS_READY = 1
diff --git a/psycopg/connection.h b/psycopg/connection.h
index 7f512a1..9a9ea42 100644
--- a/psycopg/connection.h
+++ b/psycopg/connection.h
@@ -32,6 +32,13 @@
extern "C" {
#endif
+/* isolation levels */
+#define ISOLATION_LEVEL_AUTOCOMMIT 0
+#define ISOLATION_LEVEL_READ_UNCOMMITTED 4
+#define ISOLATION_LEVEL_READ_COMMITTED 1
+#define ISOLATION_LEVEL_REPEATABLE_READ 2
+#define ISOLATION_LEVEL_SERIALIZABLE 3
+
/* connection status */
#define CONN_STATUS_SETUP 0
#define CONN_STATUS_READY 1
diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c
index 41b73f1..7046513 100644
--- a/psycopg/connection_int.c
+++ b/psycopg/connection_int.c
@@ -35,15 +35,16 @@
#include <string.h>
/* Mapping from isolation level name to value exposed by Python.
- * Only used for backward compatibility by the isolation_level property */
-
+ *
+ * Note: ordering matters: to get a valid pre-PG 8 level from one not valid,
+ * we increase a pointer in this list by one position. */
const IsolationLevel conn_isolevels[] = {
- {"", 0}, /* autocommit */
- {"read committed", 1},
- {"read uncommitted", 1}, /* comes after to report real level */
- {"repeatable read", 2},
- {"serializable", 3},
- {"default", -1},
+ {"", ISOLATION_LEVEL_AUTOCOMMIT},
+ {"read uncommitted", ISOLATION_LEVEL_READ_UNCOMMITTED},
+ {"read committed", ISOLATION_LEVEL_READ_COMMITTED},
+ {"repeatable read", ISOLATION_LEVEL_REPEATABLE_READ},
+ {"serializable", ISOLATION_LEVEL_SERIALIZABLE},
+ {"default", -1}, /* never to be found on the server */
{ NULL }
};
@@ -1041,8 +1042,10 @@ conn_switch_isolation_level(connectionObject *self, int level)
/* use only supported levels on older PG versions */
if (self->server_version < 80000) {
- if (level == 2)
- level = 3;
+ if (level == ISOLATION_LEVEL_READ_UNCOMMITTED)
+ level = ISOLATION_LEVEL_READ_COMMITTED;
+ else if (level == ISOLATION_LEVEL_REPEATABLE_READ)
+ level = ISOLATION_LEVEL_SERIALIZABLE;
}
if (-1 == (curr_level = conn_get_isolation_level(self))) {
diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c
index 02bc4da..693de3c 100644
--- a/psycopg/connection_type.c
+++ b/psycopg/connection_type.c
@@ -405,9 +405,9 @@ _psyco_conn_parse_isolevel(connectionObject *self, PyObject *pyval)
if (PyInt_Check(pyval)) {
long level = PyInt_AsLong(pyval);
if (level == -1 && PyErr_Occurred()) { goto exit; }
- if (level < 1 || level > 3) {
+ if (level < 1 || level > 4) {
PyErr_SetString(PyExc_ValueError,
- "isolation_level must be between 1 and 3");
+ "isolation_level must be between 1 and 4");
goto exit;
}
@@ -437,7 +437,8 @@ _psyco_conn_parse_isolevel(connectionObject *self, PyObject *pyval)
/* use only supported levels on older PG versions */
if (isolevel && self->server_version < 80000) {
- if (isolevel->value == 1 || isolevel->value == 3) {
+ if (isolevel->value == ISOLATION_LEVEL_READ_UNCOMMITTED
+ || isolevel->value == ISOLATION_LEVEL_REPEATABLE_READ) {
++isolevel;
}
}
diff --git a/tests/test_connection.py b/tests/test_connection.py
index 0a79144..a887313 100755
--- a/tests/test_connection.py
+++ b/tests/test_connection.py
@@ -206,6 +206,7 @@ class IsolationLevelsTestCase(unittest.TestCase):
levels = [
(None, psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT),
+ ('read uncommitted', psycopg2.extensions.ISOLATION_LEVEL_READ_UNCOMMITTED),
('read committed', psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED),
('repeatable read', psycopg2.extensions.ISOLATION_LEVEL_REPEATABLE_READ),
('serializable', psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE),
@@ -215,8 +216,10 @@ class IsolationLevelsTestCase(unittest.TestCase):
# the only values available on prehistoric PG versions
if conn.server_version < 80000:
- if level == psycopg2.extensions.ISOLATION_LEVEL_REPEATABLE_READ:
- name, level = ('serializable', psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE)
+ if level in (
+ psycopg2.extensions.ISOLATION_LEVEL_READ_UNCOMMITTED,
+ psycopg2.extensions.ISOLATION_LEVEL_REPEATABLE_READ):
+ name, level = levels[levels.index((name, level)) + 1]
self.assertEqual(conn.isolation_level, level)
@@ -768,11 +771,13 @@ class TransactionControlTests(unittest.TestCase):
self.assertEqual(cur.fetchone()[0], 'read committed')
self.conn.rollback()
- # 'read uncommitted' is internally translated to 'read committed'
self.conn.set_session(
isolation_level=psycopg2.extensions.ISOLATION_LEVEL_READ_UNCOMMITTED)
cur.execute("SHOW default_transaction_isolation;")
- self.assertEqual(cur.fetchone()[0], 'read committed')
+ if self.conn.server_version > 80000:
+ self.assertEqual(cur.fetchone()[0], 'read uncommitted')
+ else:
+ self.assertEqual(cur.fetchone()[0], 'read committed')
self.conn.rollback()
def test_set_isolation_level_str(self):