diff options
-rw-r--r-- | psycopg/connection.h | 4 | ||||
-rw-r--r-- | psycopg/connection_int.c | 94 | ||||
-rw-r--r-- | psycopg/connection_type.c | 103 |
3 files changed, 110 insertions, 91 deletions
diff --git a/psycopg/connection.h b/psycopg/connection.h index 6c39263..00430f9 100644 --- a/psycopg/connection.h +++ b/psycopg/connection.h @@ -167,8 +167,8 @@ 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_parse_isolevel(connectionObject *self, PyObject *pyval); -RAISES_NEG HIDDEN int conn_parse_onoff(PyObject *pyval); +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); diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index d8d693f..da80b3a 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -1194,9 +1194,11 @@ conn_set_autocommit(connectionObject *self, int value) return 0; } + /* Promote an isolation level to one of the levels supported by the server */ -static int _adjust_isolevel(connectionObject *self, int level) { +static int +_adjust_isolevel(connectionObject *self, int level) { if (self->server_version < 80000) { if (level == ISOLATION_LEVEL_READ_UNCOMMITTED) { level = ISOLATION_LEVEL_READ_COMMITTED; @@ -1209,93 +1211,21 @@ static int _adjust_isolevel(connectionObject *self, int level) { } -/* parse a python object into one of the possible isolation level values */ - +/* Change the state of the session */ RAISES_NEG int -conn_parse_isolevel(connectionObject *self, PyObject *pyval) +conn_set_session(connectionObject *self, int autocommit, + int isolevel, int readonly, int deferrable) { - int rv = -1; - long level; - - Py_INCREF(pyval); /* for ensure_bytes */ - - /* parse from one of the level constants */ - if (PyInt_Check(pyval)) { - level = PyInt_AsLong(pyval); - if (level == -1 && PyErr_Occurred()) { goto exit; } - if (level < 1 || level > 4) { - PyErr_SetString(PyExc_ValueError, - "isolation_level must be between 1 and 4"); - goto exit; - } - - rv = level; - } - - /* parse from the string -- this includes "default" */ - - else { - if (!(pyval = psycopg_ensure_bytes(pyval))) { - goto exit; - } - for (level = 1; level <= 4; level++) { - if (0 == strcasecmp(srv_isolevels[level], Bytes_AS_STRING(pyval))) { - rv = level; - break; - } - } - if (rv < 0 && 0 == strcasecmp("default", Bytes_AS_STRING(pyval))) { - rv = ISOLATION_LEVEL_DEFAULT; - } - if (rv < 0) { - PyErr_Format(PyExc_ValueError, - "bad value for isolation_level: '%s'", Bytes_AS_STRING(pyval)); - goto exit; - } - } - - rv = _adjust_isolevel(self, rv); + isolevel = _adjust_isolevel(self, isolevel); -exit: - Py_XDECREF(pyval); + self->isolevel = isolevel; + self->readonly = readonly; + self->deferrable = deferrable; + self->autocommit = autocommit; - return rv; + return 0; } -/* convert False/True/"default" -> 0/1/2 */ - -RAISES_NEG int -conn_parse_onoff(PyObject *pyval) -{ - int rv = -1; - - Py_INCREF(pyval); /* for ensure_bytes */ - - if (PyUnicode_CheckExact(pyval) || Bytes_CheckExact(pyval)) { - if (!(pyval = psycopg_ensure_bytes(pyval))) { - goto exit; - } - if (0 == strcasecmp("default", Bytes_AS_STRING(pyval))) { - rv = STATE_DEFAULT; - } - else { - PyErr_Format(PyExc_ValueError, - "the only string accepted is 'default'; got %s", - Bytes_AS_STRING(pyval)); - goto exit; - } - } - else { - int istrue; - if (0 > (istrue = PyObject_IsTrue(pyval))) { goto exit; } - rv = istrue ? STATE_ON : STATE_OFF; - } - -exit: - Py_XDECREF(pyval); - - return rv; -} /* conn_switch_isolation_level - switch isolation level on the connection */ diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index 48bebf4..f574b09 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -36,6 +36,9 @@ #include <string.h> #include <ctype.h> +extern HIDDEN const char *srv_isolevels[]; +extern HIDDEN const char *srv_readonly[]; +extern HIDDEN const char *srv_deferrable[]; /** DBAPI methods **/ @@ -442,6 +445,92 @@ exit: } +/* parse a python object into one of the possible isolation level values */ + +RAISES_NEG static int +_psyco_conn_parse_isolevel(PyObject *pyval) +{ + int rv = -1; + long level; + + Py_INCREF(pyval); /* for ensure_bytes */ + + /* parse from one of the level constants */ + if (PyInt_Check(pyval)) { + level = PyInt_AsLong(pyval); + if (level == -1 && PyErr_Occurred()) { goto exit; } + if (level < 1 || level > 4) { + PyErr_SetString(PyExc_ValueError, + "isolation_level must be between 1 and 4"); + goto exit; + } + + rv = level; + } + + /* parse from the string -- this includes "default" */ + + else { + if (!(pyval = psycopg_ensure_bytes(pyval))) { + goto exit; + } + for (level = 1; level <= 4; level++) { + if (0 == strcasecmp(srv_isolevels[level], Bytes_AS_STRING(pyval))) { + rv = level; + break; + } + } + if (rv < 0 && 0 == strcasecmp("default", Bytes_AS_STRING(pyval))) { + rv = ISOLATION_LEVEL_DEFAULT; + } + if (rv < 0) { + PyErr_Format(PyExc_ValueError, + "bad value for isolation_level: '%s'", Bytes_AS_STRING(pyval)); + goto exit; + } + } + +exit: + Py_XDECREF(pyval); + + return rv; +} + +/* convert False/True/"default" -> 0/1/2 */ + +RAISES_NEG static int +_psyco_conn_parse_onoff(PyObject *pyval) +{ + int rv = -1; + + Py_INCREF(pyval); /* for ensure_bytes */ + + if (PyUnicode_CheckExact(pyval) || Bytes_CheckExact(pyval)) { + if (!(pyval = psycopg_ensure_bytes(pyval))) { + goto exit; + } + if (0 == strcasecmp("default", Bytes_AS_STRING(pyval))) { + rv = STATE_DEFAULT; + } + else { + PyErr_Format(PyExc_ValueError, + "the only string accepted is 'default'; got %s", + Bytes_AS_STRING(pyval)); + goto exit; + } + } + else { + int istrue; + if (0 > (istrue = PyObject_IsTrue(pyval))) { goto exit; } + rv = istrue ? STATE_ON : STATE_OFF; + } + +exit: + Py_XDECREF(pyval); + + return rv; +} + /* set_session - set default transaction characteristics */ #define psyco_conn_set_session_doc \ @@ -474,13 +563,13 @@ psyco_conn_set_session(connectionObject *self, PyObject *args, PyObject *kwargs) } if (Py_None != isolevel) { - if (0 > (c_isolevel = conn_parse_isolevel(self, isolevel))) { + if (0 > (c_isolevel = _psyco_conn_parse_isolevel(isolevel))) { return NULL; } } if (Py_None != readonly) { - if (0 > (c_readonly = conn_parse_onoff(readonly))) { + if (0 > (c_readonly = _psyco_conn_parse_onoff(readonly))) { return NULL; } } @@ -491,7 +580,7 @@ psyco_conn_set_session(connectionObject *self, PyObject *args, PyObject *kwargs) " from PostgreSQL 9.1"); return NULL; } - if (0 > (c_deferrable = conn_parse_onoff(readonly))) { + if (0 > (c_deferrable = _psyco_conn_parse_onoff(readonly))) { return NULL; } } @@ -500,10 +589,10 @@ psyco_conn_set_session(connectionObject *self, PyObject *args, PyObject *kwargs) if (-1 == (c_autocommit = PyObject_IsTrue(autocommit))) { return NULL; } } - self->isolevel = c_isolevel; - self->readonly = c_readonly; - self->deferrable = c_deferrable; - self->autocommit = c_autocommit; + if (0 > conn_set_session( + self, c_autocommit, c_isolevel, c_readonly, c_deferrable)) { + return NULL; + } Py_RETURN_NONE; } |