Common code in execute() and mogrify() merged.

This commit is contained in:
Daniele Varrazzo 2010-10-05 01:43:23 +01:00
parent 575b2b5f77
commit 5b4d366f4e
2 changed files with 72 additions and 85 deletions

View File

@ -1,3 +1,7 @@
2010-10-05 Daniele Varrazzo <daniele.varrazzo@gmail.com>
* psycopg/cursor_type.c: Common code in execute() and mogrify() merged.
2010-09-23 Daniele Varrazzo <daniele.varrazzo@gmail.com> 2010-09-23 Daniele Varrazzo <daniele.varrazzo@gmail.com>
* lib/errorcodes.py: Added PostgreSQL 9.0 error codes. * lib/errorcodes.py: Added PostgreSQL 9.0 error codes.

View File

@ -305,42 +305,19 @@ static PyObject *_psyco_curs_validate_sql_basic(
return NULL; return NULL;
} }
#define psyco_curs_execute_doc \ /* Merge together a query string and its arguments.
"execute(query, vars=None) -- Execute query with bound vars." *
* The arguments have been already adapted to SQL.
static int *
_psyco_curs_execute(cursorObject *self, * Return a new reference to a string with the merged query,
PyObject *operation, PyObject *vars, long int async) * NULL and set an exception if any happened.
*/
static PyObject *
_psyco_curs_merge_query_args(cursorObject *self,
PyObject *query, PyObject *args)
{ {
int res = 0; PyObject *fquery;
PyObject *fquery, *cvt = NULL;
operation = _psyco_curs_validate_sql_basic(self, operation);
/* Any failure from here forward should 'goto fail' rather than 'return 0'
directly. */
if (operation == NULL) { goto fail; }
IFCLEARPGRES(self->pgres);
if (self->query) {
Py_DECREF(self->query);
self->query = NULL;
}
Dprintf("psyco_curs_execute: starting execution of new query");
/* here we are, and we have a sequence or a dictionary filled with
objects to be substituted (bound variables). we try to be smart and do
the right thing (i.e., what the user expects) */
if (vars && vars != Py_None)
{
if(_mogrify(vars, operation, self->conn, &cvt) == -1) { goto fail; }
}
if (vars && cvt) {
/* if PyString_Format() return NULL an error occured: if the error is /* if PyString_Format() return NULL an error occured: if the error is
a TypeError we need to check the exception.args[0] string for the a TypeError we need to check the exception.args[0] string for the
values: values:
@ -352,7 +329,7 @@ _psyco_curs_execute(cursorObject *self,
the curren exception (we will later restore it if the type or the the curren exception (we will later restore it if the type or the
strings do not match.) */ strings do not match.) */
if (!(fquery = PyString_Format(operation, cvt))) { if (!(fquery = PyString_Format(query, args))) {
PyObject *err, *arg, *trace; PyObject *err, *arg, *trace;
int pe = 0; int pe = 0;
@ -389,6 +366,48 @@ _psyco_curs_execute(cursorObject *self,
else { else {
PyErr_Restore(err, arg, trace); PyErr_Restore(err, arg, trace);
} }
}
return fquery;
}
#define psyco_curs_execute_doc \
"execute(query, vars=None) -- Execute query with bound vars."
static int
_psyco_curs_execute(cursorObject *self,
PyObject *operation, PyObject *vars, long int async)
{
int res = 0;
PyObject *fquery, *cvt = NULL;
operation = _psyco_curs_validate_sql_basic(self, operation);
/* Any failure from here forward should 'goto fail' rather than 'return 0'
directly. */
if (operation == NULL) { goto fail; }
IFCLEARPGRES(self->pgres);
if (self->query) {
Py_DECREF(self->query);
self->query = NULL;
}
Dprintf("psyco_curs_execute: starting execution of new query");
/* here we are, and we have a sequence or a dictionary filled with
objects to be substituted (bound variables). we try to be smart and do
the right thing (i.e., what the user expects) */
if (vars && vars != Py_None)
{
if(_mogrify(vars, operation, self->conn, &cvt) == -1) { goto fail; }
}
if (vars && cvt) {
if (!(fquery = _psyco_curs_merge_query_args(self, operation, cvt))) {
goto fail; goto fail;
} }
@ -582,43 +601,7 @@ psyco_curs_mogrify(cursorObject *self, PyObject *args, PyObject *kwargs)
} }
if (vars && cvt) { if (vars && cvt) {
if (!(fquery = PyString_Format(operation, cvt))) { if (!(fquery = _psyco_curs_merge_query_args(self, operation, cvt))) {
PyObject *err, *arg, *trace;
int pe = 0;
PyErr_Fetch(&err, &arg, &trace);
if (err && PyErr_GivenExceptionMatches(err, PyExc_TypeError)) {
Dprintf("psyco_curs_execute: TypeError exception catched");
PyErr_NormalizeException(&err, &arg, &trace);
if (PyObject_HasAttrString(arg, "args")) {
PyObject *args = PyObject_GetAttrString(arg, "args");
PyObject *str = PySequence_GetItem(args, 0);
const char *s = PyString_AS_STRING(str);
Dprintf("psyco_curs_execute: -> %s", s);
if (!strcmp(s, "not enough arguments for format string")
|| !strcmp(s, "not all arguments converted")) {
Dprintf("psyco_curs_execute: -> got a match");
psyco_set_error(ProgrammingError, (PyObject*)self,
s, NULL, NULL);
pe = 1;
}
Py_DECREF(args);
Py_DECREF(str);
}
}
/* if we did not manage our own exception, restore old one */
if (pe == 1) {
Py_XDECREF(err); Py_XDECREF(arg); Py_XDECREF(trace);
}
else {
PyErr_Restore(err, arg, trace);
}
return NULL; return NULL;
} }