summaryrefslogtreecommitdiff
path: root/psycopg
diff options
context:
space:
mode:
Diffstat (limited to 'psycopg')
-rw-r--r--psycopg/connection.h1
-rw-r--r--psycopg/connection_int.c16
-rw-r--r--psycopg/connection_type.c127
3 files changed, 115 insertions, 29 deletions
diff --git a/psycopg/connection.h b/psycopg/connection.h
index 65efcaf..6b1f244 100644
--- a/psycopg/connection.h
+++ b/psycopg/connection.h
@@ -154,7 +154,6 @@ HIDDEN PyObject *conn_encode(connectionObject *self, PyObject *b);
HIDDEN PyObject *conn_decode(connectionObject *self, const char *str, Py_ssize_t len);
HIDDEN int conn_get_standard_conforming_strings(PGconn *pgconn);
HIDDEN PyObject *conn_pgenc_to_pyenc(const char *encoding, char **clean_encoding);
-RAISES_NEG HIDDEN int conn_get_isolation_level(connectionObject *self);
HIDDEN int conn_get_protocol_version(PGconn *pgconn);
HIDDEN int conn_get_server_version(PGconn *pgconn);
HIDDEN void conn_notice_process(connectionObject *self);
diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c
index e6906eb..49daae5 100644
--- a/psycopg/connection_int.c
+++ b/psycopg/connection_int.c
@@ -568,19 +568,6 @@ exit:
}
-RAISES_NEG int
-conn_get_isolation_level(connectionObject *self)
-{
- /* this may get called by async connections too: here's your result */
- if (self->autocommit) {
- return ISOLATION_LEVEL_AUTOCOMMIT;
- }
- else {
- return self->isolevel;
- }
-}
-
-
int
conn_get_protocol_version(PGconn *pgconn)
{
@@ -697,6 +684,9 @@ conn_setup(connectionObject *self, PGconn *pgconn)
/* for reset */
self->autocommit = 0;
+ self->isolevel = ISOLATION_LEVEL_DEFAULT;
+ self->readonly = STATE_DEFAULT;
+ self->deferrable = STATE_DEFAULT;
/* success */
rv = 0;
diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c
index df67c80..66ff705 100644
--- a/psycopg/connection_type.c
+++ b/psycopg/connection_type.c
@@ -510,7 +510,10 @@ _psyco_conn_parse_onoff(PyObject *pyval)
Py_INCREF(pyval); /* for ensure_bytes */
- if (PyUnicode_CheckExact(pyval) || Bytes_CheckExact(pyval)) {
+ if (pyval == Py_None) {
+ rv = STATE_DEFAULT;
+ }
+ else if (PyUnicode_CheckExact(pyval) || Bytes_CheckExact(pyval)) {
if (!(pyval = psycopg_ensure_bytes(pyval))) {
goto exit;
}
@@ -591,7 +594,7 @@ psyco_conn_set_session(connectionObject *self, PyObject *args, PyObject *kwargs)
" from PostgreSQL 9.1");
return NULL;
}
- if (0 > (c_deferrable = _psyco_conn_parse_onoff(readonly))) {
+ if (0 > (c_deferrable = _psyco_conn_parse_onoff(deferrable))) {
return NULL;
}
}
@@ -609,6 +612,8 @@ psyco_conn_set_session(connectionObject *self, PyObject *args, PyObject *kwargs)
}
+/* autocommit - return or set the current autocommit status */
+
#define psyco_conn_autocommit_doc \
"Set or return the autocommit status."
@@ -646,7 +651,7 @@ psyco_conn_autocommit_set(connectionObject *self, PyObject *pyvalue)
}
-/* isolation_level - return the current isolation level */
+/* isolation_level - return or set the current isolation level */
#define psyco_conn_isolation_level_doc \
"Set or return the connection transaction isolation level."
@@ -654,23 +659,14 @@ psyco_conn_autocommit_set(connectionObject *self, PyObject *pyvalue)
static PyObject *
psyco_conn_isolation_level_get(connectionObject *self)
{
- int rv;
-
- EXC_IF_CONN_CLOSED(self);
- EXC_IF_TPC_PREPARED(self, set_isolation_level);
-
- rv = conn_get_isolation_level(self);
- if (-1 == rv) { return NULL; }
- if (ISOLATION_LEVEL_DEFAULT == rv) {
+ if (self->isolevel == ISOLATION_LEVEL_DEFAULT) {
Py_RETURN_NONE;
} else {
- return PyInt_FromLong((long)rv);
+ return PyInt_FromLong((long)self->isolevel);
}
}
-/* isolation_level - set a new isolation level */
-
static int
psyco_conn_isolation_level_set(connectionObject *self, PyObject *pyvalue)
{
@@ -725,7 +721,7 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
if (level == 0) {
if (0 > conn_set_session(self, 1,
- ISOLATION_LEVEL_DEFAULT, self->readonly, self->deferrable)) {
+ self->isolevel, self->readonly, self->deferrable)) {
return NULL;
}
}
@@ -739,6 +735,99 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
Py_RETURN_NONE;
}
+
+/* readonly - return or set the current read-only status */
+
+#define psyco_conn_readonly_doc \
+"Set or return the connection read-only status."
+
+static PyObject *
+psyco_conn_readonly_get(connectionObject *self)
+{
+ PyObject *rv = NULL;
+
+ switch (self->readonly) {
+ case STATE_OFF:
+ rv = Py_False;
+ break;
+ case STATE_ON:
+ rv = Py_True;
+ break;
+ case STATE_DEFAULT:
+ rv = Py_None;
+ break;
+ default:
+ PyErr_Format(InternalError,
+ "bad internal value for readonly: %d", self->readonly);
+ break;
+ }
+
+ return rv;
+}
+
+
+static int
+psyco_conn_readonly_set(connectionObject *self, PyObject *pyvalue)
+{
+ int value;
+
+ if (!_psyco_set_session_check_setter_wrapper(self)) { return -1; }
+ if (0 > (value = _psyco_conn_parse_onoff(pyvalue))) { return -1; }
+ if (0 > conn_set_session(self, self->autocommit,
+ self->isolevel, value, self->deferrable)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* deferrable - return or set the current deferrable status */
+
+#define psyco_conn_deferrable_doc \
+"Set or return the connection deferrable status."
+
+static PyObject *
+psyco_conn_deferrable_get(connectionObject *self)
+{
+ PyObject *rv = NULL;
+
+ switch (self->deferrable) {
+ case STATE_OFF:
+ rv = Py_False;
+ break;
+ case STATE_ON:
+ rv = Py_True;
+ break;
+ case STATE_DEFAULT:
+ rv = Py_None;
+ break;
+ default:
+ PyErr_Format(InternalError,
+ "bad internal value for deferrable: %d", self->deferrable);
+ break;
+ }
+
+ return rv;
+}
+
+
+static int
+psyco_conn_deferrable_set(connectionObject *self, PyObject *pyvalue)
+{
+ int value;
+
+ if (!_psyco_set_session_check_setter_wrapper(self)) { return -1; }
+ if (0 > (value = _psyco_conn_parse_onoff(pyvalue))) { return -1; }
+ if (0 > conn_set_session(self, self->autocommit,
+ self->isolevel, self->readonly, value)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
/* set_client_encoding method - set client encoding */
#define psyco_conn_set_client_encoding_doc \
@@ -1151,6 +1240,14 @@ static struct PyGetSetDef connectionObject_getsets[] = {
(getter)psyco_conn_isolation_level_get,
(setter)psyco_conn_isolation_level_set,
psyco_conn_isolation_level_doc },
+ { "readonly",
+ (getter)psyco_conn_readonly_get,
+ (setter)psyco_conn_readonly_set,
+ psyco_conn_readonly_doc },
+ { "deferrable",
+ (getter)psyco_conn_deferrable_get,
+ (setter)psyco_conn_deferrable_set,
+ psyco_conn_deferrable_doc },
{NULL}
};
#undef EXCEPTION_GETTER