mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-06-28 00:33:07 +03:00
Better separation between interface and state change code
The state change function has a C callable signature.
This commit is contained in:
parent
ca59fd8b3f
commit
8527144173
|
@ -167,8 +167,8 @@ HIDDEN void conn_close_locked(connectionObject *self);
|
||||||
RAISES_NEG HIDDEN int conn_commit(connectionObject *self);
|
RAISES_NEG HIDDEN int conn_commit(connectionObject *self);
|
||||||
RAISES_NEG HIDDEN int conn_rollback(connectionObject *self);
|
RAISES_NEG HIDDEN int conn_rollback(connectionObject *self);
|
||||||
HIDDEN int conn_set_autocommit(connectionObject *self, int value);
|
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_set_session(connectionObject *self, int autocommit,
|
||||||
RAISES_NEG HIDDEN int conn_parse_onoff(PyObject *pyval);
|
int isolevel, int readonly, int deferrable);
|
||||||
RAISES_NEG HIDDEN int conn_switch_isolation_level(connectionObject *self, int level);
|
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);
|
RAISES_NEG HIDDEN int conn_set_client_encoding(connectionObject *self, const char *enc);
|
||||||
HIDDEN int conn_poll(connectionObject *self);
|
HIDDEN int conn_poll(connectionObject *self);
|
||||||
|
|
|
@ -1194,9 +1194,11 @@ conn_set_autocommit(connectionObject *self, int value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Promote an isolation level to one of the levels supported by the server */
|
/* 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 (self->server_version < 80000) {
|
||||||
if (level == ISOLATION_LEVEL_READ_UNCOMMITTED) {
|
if (level == ISOLATION_LEVEL_READ_UNCOMMITTED) {
|
||||||
level = ISOLATION_LEVEL_READ_COMMITTED;
|
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
|
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;
|
isolevel = _adjust_isolevel(self, isolevel);
|
||||||
long level;
|
|
||||||
|
|
||||||
Py_INCREF(pyval); /* for ensure_bytes */
|
self->isolevel = isolevel;
|
||||||
|
self->readonly = readonly;
|
||||||
|
self->deferrable = deferrable;
|
||||||
|
self->autocommit = autocommit;
|
||||||
|
|
||||||
/* parse from one of the level constants */
|
return 0;
|
||||||
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);
|
|
||||||
|
|
||||||
exit:
|
|
||||||
Py_XDECREF(pyval);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 */
|
/* conn_switch_isolation_level - switch isolation level on the connection */
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
extern HIDDEN const char *srv_isolevels[];
|
||||||
|
extern HIDDEN const char *srv_readonly[];
|
||||||
|
extern HIDDEN const char *srv_deferrable[];
|
||||||
|
|
||||||
/** DBAPI methods **/
|
/** 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 */
|
/* set_session - set default transaction characteristics */
|
||||||
|
|
||||||
#define psyco_conn_set_session_doc \
|
#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 (Py_None != isolevel) {
|
||||||
if (0 > (c_isolevel = conn_parse_isolevel(self, isolevel))) {
|
if (0 > (c_isolevel = _psyco_conn_parse_isolevel(isolevel))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Py_None != readonly) {
|
if (Py_None != readonly) {
|
||||||
if (0 > (c_readonly = conn_parse_onoff(readonly))) {
|
if (0 > (c_readonly = _psyco_conn_parse_onoff(readonly))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,7 +580,7 @@ psyco_conn_set_session(connectionObject *self, PyObject *args, PyObject *kwargs)
|
||||||
" from PostgreSQL 9.1");
|
" from PostgreSQL 9.1");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (0 > (c_deferrable = conn_parse_onoff(readonly))) {
|
if (0 > (c_deferrable = _psyco_conn_parse_onoff(readonly))) {
|
||||||
return NULL;
|
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; }
|
if (-1 == (c_autocommit = PyObject_IsTrue(autocommit))) { return NULL; }
|
||||||
}
|
}
|
||||||
|
|
||||||
self->isolevel = c_isolevel;
|
if (0 > conn_set_session(
|
||||||
self->readonly = c_readonly;
|
self, c_autocommit, c_isolevel, c_readonly, c_deferrable)) {
|
||||||
self->deferrable = c_deferrable;
|
return NULL;
|
||||||
self->autocommit = c_autocommit;
|
}
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user