Add parse_dsn module function

Calls PQconninfoParse to parse the dsn into a list of keyword and value
structs, then constructs a dictionary from that.  Can be useful when one
needs to alter some part of the the connection string reliably, but
doesn't want to get into all the details of parsing a dsn string:
quoting, URL format, etc.
This commit is contained in:
Oleksandr Shulgin 2015-06-01 10:16:07 +02:00
parent d66165232e
commit 6c57e4a648
3 changed files with 53 additions and 1 deletions

View File

@ -78,6 +78,7 @@ The module interface respects the standard defined in the |DBAPI|_.
.. seealso:: .. seealso::
- `parse_dsn`
- libpq `connection string syntax`__ - libpq `connection string syntax`__
- libpq supported `connection parameters`__ - libpq supported `connection parameters`__
- libpq supported `environment variables`__ - libpq supported `environment variables`__
@ -91,6 +92,17 @@ The module interface respects the standard defined in the |DBAPI|_.
The parameters *connection_factory* and *async* are Psycopg extensions The parameters *connection_factory* and *async* are Psycopg extensions
to the |DBAPI|. to the |DBAPI|.
.. function:: parse_dsn(dsn)
Parse connection string into a dictionary of keywords and values.
Uses libpq's ``PQconninfoParse`` to parse the string according to
accepted format(s) and check for supported keywords.
Example::
>>> psycopg2.parse_dsn('dbname=test user=postgres password=secret')
{'password': 'secret', 'user': 'postgres', 'dbname': 'test'}
.. data:: apilevel .. data:: apilevel

View File

@ -56,7 +56,7 @@ from psycopg2._psycopg import Error, Warning, DataError, DatabaseError, Programm
from psycopg2._psycopg import IntegrityError, InterfaceError, InternalError from psycopg2._psycopg import IntegrityError, InterfaceError, InternalError
from psycopg2._psycopg import NotSupportedError, OperationalError from psycopg2._psycopg import NotSupportedError, OperationalError
from psycopg2._psycopg import _connect, apilevel, threadsafety, paramstyle from psycopg2._psycopg import _connect, parse_dsn, apilevel, threadsafety, paramstyle
from psycopg2._psycopg import __version__ from psycopg2._psycopg import __version__
from psycopg2 import tz from psycopg2 import tz

View File

@ -112,6 +112,44 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
return conn; return conn;
} }
#define psyco_parse_dsn_doc \
"parse_dsn(dsn) -- Parse database connection string.\n\n"
static PyObject *
psyco_parse_dsn(PyObject *self, PyObject *args)
{
char *dsn, *err;
PQconninfoOption *options = NULL, *o;
PyObject *res = NULL, *value;
if (!PyArg_ParseTuple(args, "s", &dsn)) {
return NULL;
}
options = PQconninfoParse(dsn, &err);
if (!options) {
PyErr_Format(PyExc_RuntimeError, "PQconninfoParse: %s: %s", dsn, err);
PQfreemem(err);
return NULL;
}
res = PyDict_New();
for (o = options; o->keyword != NULL; o++) {
if (o->val != NULL) {
value = PyString_FromString(o->val);
if (value == NULL || PyDict_SetItemString(res, o->keyword, value) != 0) {
Py_DECREF(res);
res = NULL;
break;
}
}
}
PQconninfoFree(options);
return res;
}
/** 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" \
@ -695,6 +733,8 @@ error:
static PyMethodDef psycopgMethods[] = { static PyMethodDef psycopgMethods[] = {
{"_connect", (PyCFunction)psyco_connect, {"_connect", (PyCFunction)psyco_connect,
METH_VARARGS|METH_KEYWORDS, psyco_connect_doc}, METH_VARARGS|METH_KEYWORDS, psyco_connect_doc},
{"parse_dsn", (PyCFunction)psyco_parse_dsn,
METH_VARARGS, 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},