diff --git a/psycopg/connection.h b/psycopg/connection.h index 00430f95..65efcaf0 100644 --- a/psycopg/connection.h +++ b/psycopg/connection.h @@ -166,10 +166,8 @@ HIDDEN void conn_close(connectionObject *self); HIDDEN void conn_close_locked(connectionObject *self); RAISES_NEG HIDDEN int conn_commit(connectionObject *self); RAISES_NEG HIDDEN int conn_rollback(connectionObject *self); -HIDDEN int conn_set_autocommit(connectionObject *self, int value); RAISES_NEG HIDDEN int conn_set_session(connectionObject *self, int autocommit, int isolevel, int readonly, int deferrable); -RAISES_NEG HIDDEN int conn_switch_isolation_level(connectionObject *self, int level); RAISES_NEG HIDDEN int conn_set_client_encoding(connectionObject *self, const char *enc); HIDDEN int conn_poll(connectionObject *self); RAISES_NEG HIDDEN int conn_tpc_begin(connectionObject *self, xidObject *xid); diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index da80b3aa..0cb4cf38 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -1180,68 +1180,36 @@ conn_rollback(connectionObject *self) return res; } -int -conn_set_autocommit(connectionObject *self, int value) -{ - Py_BEGIN_ALLOW_THREADS; - pthread_mutex_lock(&self->lock); - - self->autocommit = value; - - pthread_mutex_unlock(&self->lock); - Py_END_ALLOW_THREADS; - - return 0; -} - - -/* Promote an isolation level to one of the levels supported by the server */ - -static int -_adjust_isolevel(connectionObject *self, int level) { - if (self->server_version < 80000) { - if (level == ISOLATION_LEVEL_READ_UNCOMMITTED) { - level = ISOLATION_LEVEL_READ_COMMITTED; - } - else if (level == ISOLATION_LEVEL_REPEATABLE_READ) { - level = ISOLATION_LEVEL_SERIALIZABLE; - } - } - return level; -} - /* Change the state of the session */ RAISES_NEG int conn_set_session(connectionObject *self, int autocommit, int isolevel, int readonly, int deferrable) { - isolevel = _adjust_isolevel(self, isolevel); + /* Promote an isolation level to one of the levels supported by the server */ + if (self->server_version < 80000) { + if (isolevel == ISOLATION_LEVEL_READ_UNCOMMITTED) { + isolevel = ISOLATION_LEVEL_READ_COMMITTED; + } + else if (isolevel == ISOLATION_LEVEL_REPEATABLE_READ) { + isolevel = ISOLATION_LEVEL_SERIALIZABLE; + } + } + + Py_BEGIN_ALLOW_THREADS; + pthread_mutex_lock(&self->lock); self->isolevel = isolevel; self->readonly = readonly; self->deferrable = deferrable; self->autocommit = autocommit; - return 0; -} + pthread_mutex_unlock(&self->lock); + Py_END_ALLOW_THREADS; - -/* conn_switch_isolation_level - switch isolation level on the connection */ - -RAISES_NEG int -conn_switch_isolation_level(connectionObject *self, int level) -{ - if (level == 0) { - self->autocommit = 1; - } - else { - level = _adjust_isolevel(self, level); - self->isolevel = level; - self->autocommit = 0; - } - - Dprintf("conn_switch_isolation_level: switched to level %d", level); + Dprintf( + "conn_set_session: autocommit %d, isolevel %d, readonly %d, deferrable %d", + autocommit, isolevel, readonly, deferrable); return 0; } diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index f574b090..7b58e3f7 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -531,6 +531,14 @@ exit: return rv; } +#define _set_session_checks(self,what) \ +do { \ + EXC_IF_CONN_CLOSED(self); \ + EXC_IF_CONN_ASYNC(self, what); \ + EXC_IF_IN_TRANSACTION(self, what); \ + EXC_IF_TPC_PREPARED(self, what); \ +} while(0) + /* set_session - set default transaction characteristics */ #define psyco_conn_set_session_doc \ @@ -553,9 +561,7 @@ psyco_conn_set_session(connectionObject *self, PyObject *args, PyObject *kwargs) static char *kwlist[] = {"isolation_level", "readonly", "deferrable", "autocommit", NULL}; - EXC_IF_CONN_CLOSED(self); - EXC_IF_CONN_ASYNC(self, set_session); - EXC_IF_IN_TRANSACTION(self, set_session); + _set_session_checks(self, set_session); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO", kwlist, &isolevel, &readonly, &deferrable, &autocommit)) { @@ -615,9 +621,7 @@ _psyco_conn_autocommit_set_checks(connectionObject *self) { /* wrapper to use the EXC_IF macros. * return NULL in case of error, else whatever */ - EXC_IF_CONN_CLOSED(self); - EXC_IF_CONN_ASYNC(self, autocommit); - EXC_IF_IN_TRANSACTION(self, autocommit); + _set_session_checks(self, autocommit); return Py_None; /* borrowed */ } @@ -628,7 +632,10 @@ psyco_conn_autocommit_set(connectionObject *self, PyObject *pyvalue) if (!_psyco_conn_autocommit_set_checks(self)) { return -1; } if (-1 == (value = PyObject_IsTrue(pyvalue))) { return -1; } - if (0 != conn_set_autocommit(self, value)) { return -1; } + if (0 > conn_set_session(self, value, + self->isolevel, self->readonly, self->deferrable)) { + return -1; + } return 0; } @@ -660,9 +667,7 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args) { int level = 1; - EXC_IF_CONN_CLOSED(self); - EXC_IF_CONN_ASYNC(self, set_isolation_level); - EXC_IF_TPC_PREPARED(self, set_isolation_level); + _set_session_checks(self, set_isolation_level); if (!PyArg_ParseTuple(args, "i", &level)) return NULL; @@ -672,8 +677,17 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args) return NULL; } - if (conn_switch_isolation_level(self, level) < 0) { - return NULL; + if (level == 0) { + if (0 > conn_set_session(self, 1, + ISOLATION_LEVEL_DEFAULT, self->readonly, self->deferrable)) { + return NULL; + } + } + else { + if (0 > conn_set_session(self, 0, + level, self->readonly, self->deferrable)) { + return NULL; + } } Py_RETURN_NONE;