mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-29 20:23:45 +03:00
Use only the isolation levels available on old PG versions
This commit is contained in:
parent
c2d1f1f2e6
commit
4d3c6865ee
|
@ -1042,6 +1042,13 @@ conn_switch_isolation_level(connectionObject *self, int level)
|
||||||
{
|
{
|
||||||
int curr_level;
|
int curr_level;
|
||||||
|
|
||||||
|
/* use only supported levels on older PG versions */
|
||||||
|
if (self->server_version < 80000) {
|
||||||
|
if (level == 1 || level == 3) {
|
||||||
|
++level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (-1 == (curr_level = conn_get_isolation_level(self))) {
|
if (-1 == (curr_level = conn_get_isolation_level(self))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,10 +384,9 @@ psyco_conn_tpc_recover(connectionObject *self, PyObject *args)
|
||||||
extern const IsolationLevel conn_isolevels[];
|
extern const IsolationLevel conn_isolevels[];
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
_psyco_conn_parse_isolevel(PyObject *pyval)
|
_psyco_conn_parse_isolevel(connectionObject *self, PyObject *pyval)
|
||||||
{
|
{
|
||||||
const char *rv = NULL;
|
const IsolationLevel *isolevel = NULL;
|
||||||
const IsolationLevel *value = NULL;
|
|
||||||
|
|
||||||
Py_INCREF(pyval); /* for ensure_bytes */
|
Py_INCREF(pyval); /* for ensure_bytes */
|
||||||
|
|
||||||
|
@ -400,22 +399,22 @@ _psyco_conn_parse_isolevel(PyObject *pyval)
|
||||||
"isolation_level must be between 1 and 4");
|
"isolation_level must be between 1 and 4");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
rv = conn_isolevels[level].name;
|
|
||||||
|
isolevel = conn_isolevels + level;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse from the string -- this includes "default" */
|
/* parse from the string -- this includes "default" */
|
||||||
else {
|
else {
|
||||||
value = conn_isolevels;
|
isolevel = conn_isolevels;
|
||||||
while ((++value)->name) {
|
while ((++isolevel)->name) {
|
||||||
if (!(pyval = psycopg_ensure_bytes(pyval))) {
|
if (!(pyval = psycopg_ensure_bytes(pyval))) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (0 == strcasecmp(value->name, Bytes_AS_STRING(pyval))) {
|
if (0 == strcasecmp(isolevel->name, Bytes_AS_STRING(pyval))) {
|
||||||
rv = value->name;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!rv) {
|
if (!isolevel->name) {
|
||||||
char msg[256];
|
char msg[256];
|
||||||
snprintf(msg, sizeof(msg),
|
snprintf(msg, sizeof(msg),
|
||||||
"bad value for isolation_level: '%s'", Bytes_AS_STRING(pyval));
|
"bad value for isolation_level: '%s'", Bytes_AS_STRING(pyval));
|
||||||
|
@ -423,9 +422,17 @@ _psyco_conn_parse_isolevel(PyObject *pyval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* use only supported levels on older PG versions */
|
||||||
|
if (isolevel && self->server_version < 80000) {
|
||||||
|
if (isolevel->value == 1 || isolevel->value == 3) {
|
||||||
|
++isolevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(pyval);
|
Py_XDECREF(pyval);
|
||||||
return rv;
|
|
||||||
|
return isolevel ? isolevel->name : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert True/False/"default" into a C string */
|
/* convert True/False/"default" into a C string */
|
||||||
|
@ -477,7 +484,7 @@ psyco_conn_set_transaction(connectionObject *self, PyObject *args, PyObject *kwa
|
||||||
|
|
||||||
if (Py_None != isolation_level) {
|
if (Py_None != isolation_level) {
|
||||||
const char *value = NULL;
|
const char *value = NULL;
|
||||||
if (!(value = _psyco_conn_parse_isolevel(isolation_level))) {
|
if (!(value = _psyco_conn_parse_isolevel(self, isolation_level))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (0 != conn_set(self, "default_transaction_isolation", value)) {
|
if (0 != conn_set(self, "default_transaction_isolation", value)) {
|
||||||
|
|
|
@ -204,14 +204,23 @@ class IsolationLevelsTestCase(unittest.TestCase):
|
||||||
conn = self.connect()
|
conn = self.connect()
|
||||||
curs = conn.cursor()
|
curs = conn.cursor()
|
||||||
|
|
||||||
for name, level in (
|
levels = (
|
||||||
(None, psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT),
|
(None, psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT),
|
||||||
('read uncommitted', psycopg2.extensions.ISOLATION_LEVEL_READ_UNCOMMITTED),
|
('read uncommitted', psycopg2.extensions.ISOLATION_LEVEL_READ_UNCOMMITTED),
|
||||||
('read committed', psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED),
|
('read committed', psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED),
|
||||||
('repeatable read', psycopg2.extensions.ISOLATION_LEVEL_REPEATABLE_READ),
|
('repeatable read', psycopg2.extensions.ISOLATION_LEVEL_REPEATABLE_READ),
|
||||||
('serializable', psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE),
|
('serializable', psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE),
|
||||||
):
|
)
|
||||||
|
for name, level in levels:
|
||||||
conn.set_isolation_level(level)
|
conn.set_isolation_level(level)
|
||||||
|
|
||||||
|
# the only values available on prehistoric PG versions
|
||||||
|
if conn.server_version < 80000:
|
||||||
|
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)
|
self.assertEqual(conn.isolation_level, level)
|
||||||
|
|
||||||
curs.execute('show transaction_isolation;')
|
curs.execute('show transaction_isolation;')
|
||||||
|
|
Loading…
Reference in New Issue
Block a user