mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-11 19:46:36 +03:00
cursor.callproc now also accepts dict for PostgreSQL 9+ "named notation"
This commit is contained in:
parent
fe4cb0d493
commit
23d279945f
|
@ -1024,6 +1024,7 @@ psyco_curs_callproc(cursorObject *self, PyObject *args)
|
||||||
PyObject *parameters = Py_None;
|
PyObject *parameters = Py_None;
|
||||||
PyObject *operation = NULL;
|
PyObject *operation = NULL;
|
||||||
PyObject *res = NULL;
|
PyObject *res = NULL;
|
||||||
|
PyObject *parameter_names = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#|O",
|
if (!PyArg_ParseTuple(args, "s#|O",
|
||||||
&procname, &procname_len, ¶meters
|
&procname, &procname_len, ¶meters
|
||||||
|
@ -1045,19 +1046,52 @@ psyco_curs_callproc(cursorObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate some memory, build the SQL and create a PyString from it */
|
/* allocate some memory, build the SQL and create a PyString from it */
|
||||||
sl = procname_len + 17 + nparameters*3 - (nparameters ? 1 : 0);
|
|
||||||
sql = (char*)PyMem_Malloc(sl);
|
|
||||||
if (sql == NULL) {
|
|
||||||
PyErr_NoMemory();
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(sql, "SELECT * FROM %s(", procname);
|
if (nparameters > 0 && PyDict_Check(parameters)) {
|
||||||
for(i=0; i<nparameters; i++) {
|
/* for a dict, we put the parameter names into the SQL */
|
||||||
strcat(sql, "%s,");
|
parameter_names = PyDict_Keys(parameters);
|
||||||
|
|
||||||
|
/* first we need to figure out how much space we need for the SQL */
|
||||||
|
sl = procname_len + 17 + nparameters*5 - (nparameters ? 1 : 0);
|
||||||
|
for(i=0; i<nparameters; i++) {
|
||||||
|
sl += strlen(Text_AsUTF8(PyList_GetItem(parameter_names, i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = (char*)PyMem_Malloc(sl);
|
||||||
|
if (sql == NULL) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(sql, "SELECT * FROM %s(", procname);
|
||||||
|
for(i=0; i<nparameters; i++) {
|
||||||
|
/* like procname, param names are not sanitized. don't SQL inject yourself. */
|
||||||
|
strcat(sql, Text_AsUTF8(PyList_GetItem(parameter_names, i)));
|
||||||
|
strcat(sql, ":=%s,");
|
||||||
|
}
|
||||||
|
sql[sl-2] = ')';
|
||||||
|
sql[sl-1] = '\0';
|
||||||
|
Py_DECREF(parameter_names);
|
||||||
|
|
||||||
|
/* now that we have the query string we can discard the keys and proceed normally */
|
||||||
|
parameters = PyDict_Values(parameters);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sl = procname_len + 17 + nparameters*3 - (nparameters ? 1 : 0);
|
||||||
|
|
||||||
|
sql = (char*)PyMem_Malloc(sl);
|
||||||
|
if (sql == NULL) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(sql, "SELECT * FROM %s(", procname);
|
||||||
|
for(i=0; i<nparameters; i++) {
|
||||||
|
strcat(sql, "%s,");
|
||||||
|
}
|
||||||
|
sql[sl-2] = ')';
|
||||||
|
sql[sl-1] = '\0';
|
||||||
}
|
}
|
||||||
sql[sl-2] = ')';
|
|
||||||
sql[sl-1] = '\0';
|
|
||||||
|
|
||||||
if (!(operation = Bytes_FromString(sql))) { goto exit; }
|
if (!(operation = Bytes_FromString(sql))) { goto exit; }
|
||||||
|
|
||||||
|
|
|
@ -71,12 +71,14 @@ typedef unsigned long Py_uhash_t;
|
||||||
#define Text_Format(f,a) PyString_Format(f,a)
|
#define Text_Format(f,a) PyString_Format(f,a)
|
||||||
#define Text_FromUTF8(s) PyString_FromString(s)
|
#define Text_FromUTF8(s) PyString_FromString(s)
|
||||||
#define Text_FromUTF8AndSize(s,n) PyString_FromStringAndSize(s,n)
|
#define Text_FromUTF8AndSize(s,n) PyString_FromStringAndSize(s,n)
|
||||||
|
#define Text_AsUTF8(s) PyString_AsString(s)
|
||||||
#else
|
#else
|
||||||
#define Text_Type PyUnicode_Type
|
#define Text_Type PyUnicode_Type
|
||||||
#define Text_Check(s) PyUnicode_Check(s)
|
#define Text_Check(s) PyUnicode_Check(s)
|
||||||
#define Text_Format(f,a) PyUnicode_Format(f,a)
|
#define Text_Format(f,a) PyUnicode_Format(f,a)
|
||||||
#define Text_FromUTF8(s) PyUnicode_FromString(s)
|
#define Text_FromUTF8(s) PyUnicode_FromString(s)
|
||||||
#define Text_FromUTF8AndSize(s,n) PyUnicode_FromStringAndSize(s,n)
|
#define Text_FromUTF8AndSize(s,n) PyUnicode_FromStringAndSize(s,n)
|
||||||
|
#define Text_AsUTF8(s) PyUnicode_AsUTF8(s)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION > 2
|
#if PY_MAJOR_VERSION > 2
|
||||||
|
|
Loading…
Reference in New Issue
Block a user