Return input tuple in cur.callproc, factor code to use PQescapeIdentifier in single place

This commit is contained in:
mrmilosz 2015-12-13 01:10:03 -05:00
parent 92109e4bba
commit 0772d187e9
4 changed files with 42 additions and 44 deletions

View File

@ -1015,35 +1015,6 @@ exit:
#define psyco_curs_callproc_doc \
"callproc(procname, parameters=None) -- Execute stored procedure."
/* Call PQescapeIdentifier.
*
* In case of error set a Python exception.
*
* TODO: this function can become more generic and go into utils
*/
static char *
_escape_identifier(PGconn *pgconn, const char *str, size_t length)
{
char *rv = NULL;
#if PG_VERSION_NUM >= 90000
rv = PQescapeIdentifier(pgconn, str, length);
if (!rv) {
char *msg;
msg = PQerrorMessage(pgconn);
if (!msg || !msg[0]) {
msg = "no message provided";
}
PyErr_Format(InterfaceError, "failed to escape identifier: %s", msg);
}
#else
PyErr_Format(PyExc_NotImplementedError,
"named parameters require psycopg2 compiled against libpq 9.0+");
#endif
return rv;
}
static PyObject *
psyco_curs_callproc(cursorObject *self, PyObject *args)
{
@ -1107,7 +1078,7 @@ psyco_curs_callproc(cursorObject *self, PyObject *args)
if (!(pname = psycopg_ensure_bytes(pname))) { goto exit; }
if (!(cpname = Bytes_AsString(pname))) { goto exit; }
if (!(scpnames[i] = _escape_identifier(
if (!(scpnames[i] = psycopg_escape_identifier(
self->conn->pgconn, cpname, strlen(cpname)))) {
goto exit;
}
@ -1158,10 +1129,14 @@ psyco_curs_callproc(cursorObject *self, PyObject *args)
if (0 <= _psyco_curs_execute(
self, operation, pvals, self->conn->async, 0)) {
/* return None from this until it's DBAPI compliant... */
Py_INCREF(Py_None);
res = Py_None;
/* The dict case is outside DBAPI scope anyway, so simply return None */
if (using_dict) {
Py_INCREF(Py_None);
res = Py_None;
}
else {
res = pvals;
}
}
exit:

View File

@ -124,6 +124,7 @@ RAISES HIDDEN PyObject *psyco_set_error(PyObject *exc, cursorObject *curs, const
HIDDEN char *psycopg_escape_string(connectionObject *conn,
const char *from, Py_ssize_t len, char *to, Py_ssize_t *tolen);
HIDDEN char *psycopg_escape_identifier_easy(const char *from, Py_ssize_t len);
HIDDEN char *psycopg_escape_identifier(PGconn *pgconn, const char *str, size_t length);
HIDDEN int psycopg_strdup(char **to, const char *from, Py_ssize_t len);
HIDDEN int psycopg_is_text_file(PyObject *f);

View File

@ -59,7 +59,6 @@
HIDDEN PyObject *pyDateTimeModuleP = NULL;
HIDDEN PyObject *psycoEncodings = NULL;
#ifdef PSYCOPG_DEBUG
HIDDEN int psycopg_debug_enabled = 0;
#endif
@ -175,7 +174,6 @@ exit:
static PyObject *
psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs)
{
#if PG_VERSION_NUM >= 90000
PyObject *ident = NULL, *obj = NULL, *result = NULL;
connectionObject *conn;
const char *str;
@ -203,9 +201,8 @@ psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs)
str = Bytes_AS_STRING(ident);
quoted = PQescapeIdentifier(conn->pgconn, str, strlen(str));
quoted = psycopg_escape_identifier(conn->pgconn, str, strlen(str));
if (!quoted) {
PyErr_NoMemory();
goto exit;
}
result = conn_text_from_chars(conn, quoted);
@ -215,10 +212,6 @@ exit:
Py_XDECREF(ident);
return result;
#else
PyErr_SetString(NotSupportedError, "PQescapeIdentifier not available in libpq < 9.0");
return NULL;
#endif
}
/** type registration **/

View File

@ -95,8 +95,8 @@ psycopg_escape_string(connectionObject *conn, const char *from, Py_ssize_t len,
* The returned string doesn't include quotes.
*
* WARNING: this function is not so safe to allow untrusted input: it does no
* check for multibyte chars. Such a function should be built on
* PQescapeIdentifier, which is only available from PostgreSQL 9.0.
* check for multibyte chars. Functions otherwise reliant on PostgreSQL 9.0
* and above should use the below function psycopg_escape_identifier instead.
*/
char *
psycopg_escape_identifier_easy(const char *from, Py_ssize_t len)
@ -124,6 +124,35 @@ psycopg_escape_identifier_easy(const char *from, Py_ssize_t len)
return rv;
}
/* Call PostgreSQL 9.0+ function PQescapeIdentifier.
*
* In case of error set a Python exception.
*/
char *
psycopg_escape_identifier(PGconn *pgconn, const char *str, size_t length)
{
char *rv = NULL;
#if PG_VERSION_NUM >= 90000
rv = PQescapeIdentifier(pgconn, str, length);
if (!rv) {
char *msg;
msg = PQerrorMessage(pgconn);
if (!msg || !msg[0]) {
msg = "no message provided";
}
PyErr_Format(InterfaceError, "failed to escape identifier: %s", msg);
}
#else
PyErr_Format(PyExc_NotImplementedError,
"PQescapeIdentifier requires psycopg2 compiled against libpq 9.0+");
#endif
return rv;
}
/* Duplicate a string.
*
* Allocate a new buffer on the Python heap containing the new string.