mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-26 02:43:43 +03:00
Add psycopg2.extensions.quote_ident.
This commit is contained in:
parent
c73c1c5771
commit
9295bce154
|
@ -221,6 +221,19 @@ functionalities defined by the |DBAPI|_.
|
||||||
|
|
||||||
.. __: http://www.postgresql.org/docs/current/static/libpq-misc.html#LIBPQ-PQLIBVERSION
|
.. __: http://www.postgresql.org/docs/current/static/libpq-misc.html#LIBPQ-PQLIBVERSION
|
||||||
|
|
||||||
|
.. function:: quote_ident(str, scope)
|
||||||
|
|
||||||
|
Return quoted identifier according to PostgreSQL quoting rules.
|
||||||
|
|
||||||
|
The *scope* must be a `connection` or a `cursor`, the underlying
|
||||||
|
connection encoding is used for any necessary character conversion.
|
||||||
|
|
||||||
|
Requires libpq >= 9.0.
|
||||||
|
|
||||||
|
.. seealso:: libpq docs for `PQescapeIdentifier()`__
|
||||||
|
|
||||||
|
.. __: http://www.postgresql.org/docs/current/static/libpq-exec.html#LIBPQ-PQESCAPEIDENTIFIER
|
||||||
|
|
||||||
.. _sql-adaptation-objects:
|
.. _sql-adaptation-objects:
|
||||||
|
|
||||||
SQL adaptation protocol objects
|
SQL adaptation protocol objects
|
||||||
|
|
|
@ -56,7 +56,7 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
from psycopg2._psycopg import adapt, adapters, encodings, connection, cursor, lobject, Xid, libpq_version, parse_dsn
|
from psycopg2._psycopg import adapt, adapters, encodings, connection, cursor, lobject, Xid, libpq_version, parse_dsn, quote_ident
|
||||||
from psycopg2._psycopg import string_types, binary_types, new_type, new_array_type, register_type
|
from psycopg2._psycopg import string_types, binary_types, new_type, new_array_type, register_type
|
||||||
from psycopg2._psycopg import ISQLQuote, Notify, Diagnostics, Column
|
from psycopg2._psycopg import ISQLQuote, Notify, Diagnostics, Column
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,42 @@ exit:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define psyco_quote_ident_doc "quote_ident(str, conn_or_curs) -> str"
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
psyco_quote_ident(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
const char *str = NULL;
|
||||||
|
char *quoted;
|
||||||
|
PyObject *obj, *result;
|
||||||
|
connectionObject *conn;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "sO", &str, &obj)) return NULL;
|
||||||
|
|
||||||
|
if (PyObject_TypeCheck(obj, &cursorType)) {
|
||||||
|
conn = ((cursorObject*)obj)->conn;
|
||||||
|
}
|
||||||
|
else if (PyObject_TypeCheck(obj, &connectionType)) {
|
||||||
|
conn = (connectionObject*)obj;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"argument 2 must be a connection or a cursor");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
quoted = PQescapeIdentifier(conn->pgconn, str, strlen(str));
|
||||||
|
if (!quoted) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
result = conn_text_from_chars(conn, quoted);
|
||||||
|
PQfreemem(quoted);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/** type registration **/
|
/** type registration **/
|
||||||
#define psyco_register_type_doc \
|
#define psyco_register_type_doc \
|
||||||
"register_type(obj, conn_or_curs) -> None -- register obj with psycopg type system\n\n" \
|
"register_type(obj, conn_or_curs) -> None -- register obj with psycopg type system\n\n" \
|
||||||
|
@ -768,6 +804,8 @@ static PyMethodDef psycopgMethods[] = {
|
||||||
METH_VARARGS|METH_KEYWORDS, psyco_parse_dsn_doc},
|
METH_VARARGS|METH_KEYWORDS, psyco_parse_dsn_doc},
|
||||||
{"adapt", (PyCFunction)psyco_microprotocols_adapt,
|
{"adapt", (PyCFunction)psyco_microprotocols_adapt,
|
||||||
METH_VARARGS, psyco_microprotocols_adapt_doc},
|
METH_VARARGS, psyco_microprotocols_adapt_doc},
|
||||||
|
{"quote_ident", (PyCFunction)psyco_quote_ident,
|
||||||
|
METH_VARARGS, psyco_quote_ident_doc},
|
||||||
|
|
||||||
{"register_type", (PyCFunction)psyco_register_type,
|
{"register_type", (PyCFunction)psyco_register_type,
|
||||||
METH_VARARGS, psyco_register_type_doc},
|
METH_VARARGS, psyco_register_type_doc},
|
||||||
|
|
|
@ -87,7 +87,7 @@ psycopg_escape_string(connectionObject *conn, const char *from, Py_ssize_t len,
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Escape a string to build a valid PostgreSQL identifier
|
/* Escape a string to build a valid PostgreSQL identifier.
|
||||||
*
|
*
|
||||||
* Allocate a new buffer on the Python heap containing the new string.
|
* Allocate a new buffer on the Python heap containing the new string.
|
||||||
* 'len' is optional: if 0 the length is calculated.
|
* 'len' is optional: if 0 the length is calculated.
|
||||||
|
@ -96,7 +96,7 @@ psycopg_escape_string(connectionObject *conn, const char *from, Py_ssize_t len,
|
||||||
*
|
*
|
||||||
* WARNING: this function is not so safe to allow untrusted input: it does no
|
* 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
|
* check for multibyte chars. Such a function should be built on
|
||||||
* PQescapeIndentifier, which is only available from PostgreSQL 9.0.
|
* PQescapeIdentifier, which is only available from PostgreSQL 9.0.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
psycopg_escape_identifier_easy(const char *from, Py_ssize_t len)
|
psycopg_escape_identifier_easy(const char *from, Py_ssize_t len)
|
||||||
|
|
|
@ -165,6 +165,13 @@ class TestQuotedString(ConnectingTestCase):
|
||||||
self.assertEqual(q.encoding, 'utf_8')
|
self.assertEqual(q.encoding, 'utf_8')
|
||||||
|
|
||||||
|
|
||||||
|
class TestQuotedIdentifier(ConnectingTestCase):
|
||||||
|
def test_identifier(self):
|
||||||
|
from psycopg2.extensions import quote_ident
|
||||||
|
self.assertEqual(quote_ident('blah-blah', self.conn), '"blah-blah"')
|
||||||
|
self.assertEqual(quote_ident('quote"inside', self.conn), '"quote""inside"')
|
||||||
|
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user