diff --git a/doc/src/connection.rst b/doc/src/connection.rst index 95b858d3..b31c2d29 100644 --- a/doc/src/connection.rst +++ b/doc/src/connection.rst @@ -613,29 +613,6 @@ The ``connection`` class .. versionadded:: 2.8 - .. index:: - pair: Connection; Parameters - - .. method:: get_dsn_parameters() - - Get the effective dsn parameters for the connection as a dictionary. - - The *password* parameter is removed from the result. - - Example:: - - >>> conn.get_dsn_parameters() - {'dbname': 'test', 'user': 'postgres', 'port': '5432', 'sslmode': 'prefer'} - - Requires libpq >= 9.3. - - .. seealso:: libpq docs for `PQconninfo()`__ for details. - - .. __: https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-PQCONNINFO - - .. versionadded:: 2.7 - - .. index:: pair: Connection; Status @@ -882,6 +859,32 @@ The ``connection`` class .. versionadded:: 2.0.12 + .. index:: + pair: Connection; Parameters + + .. method:: get_dsn_parameters() + + Also available as `~connection.info`\ `!.`\ + `~psycopg2.extensions.ConnectionInfo.dsn_parameters`. + + Get the effective dsn parameters for the connection as a dictionary. + + The *password* parameter is removed from the result. + + Example:: + + >>> conn.get_dsn_parameters() + {'dbname': 'test', 'user': 'postgres', 'port': '5432', 'sslmode': 'prefer'} + + Requires libpq >= 9.3. + + .. seealso:: libpq docs for `PQconninfo()`__ for details. + + .. __: https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-PQCONNINFO + + .. versionadded:: 2.7 + + .. testcode:: :hide: diff --git a/doc/src/extensions.rst b/doc/src/extensions.rst index ee45becf..22d9b5db 100644 --- a/doc/src/extensions.rst +++ b/doc/src/extensions.rst @@ -165,6 +165,15 @@ introspection etc. .. autoattribute:: host .. autoattribute:: port .. autoattribute:: options + .. autoattribute:: dsn_parameters + + Example:: + + >>> conn.info.dsn_parameters + {'dbname': 'test', 'user': 'postgres', 'port': '5432', 'sslmode': 'prefer'} + + Requires libpq >= 9.3. + .. autoattribute:: status .. autoattribute:: transaction_status .. automethod:: parameter_status(name) diff --git a/psycopg/conninfo_type.c b/psycopg/conninfo_type.c index af099d47..a74e7922 100644 --- a/psycopg/conninfo_type.c +++ b/psycopg/conninfo_type.c @@ -166,6 +166,46 @@ options_get(connInfoObject *self) } +static const char dsn_parameters_doc[] = +"The effective connection parameters.\n" +"\n" +":type: `!dict`\n" +"\n" +"The results include values which weren't explicitly set by the connection\n" +"string, such as defaults, environment variables, etc.\n" +"The *password* parameter is removed from the results.\n" +"\n" +".. seealso:: libpq docs for `PQconninfo()`__ for details.\n" +".. __: https://www.postgresql.org/docs/current/libpq-connect.html" + "#LIBPQ-PQCONNINFO"; + +static PyObject * +dsn_parameters_get(connInfoObject *self) +{ +#if PG_VERSION_NUM >= 90300 + PyObject *res = NULL; + PQconninfoOption *options = NULL; + + EXC_IF_CONN_CLOSED(self->conn); + + if (!(options = PQconninfo(self->conn->pgconn))) { + PyErr_NoMemory(); + goto exit; + } + + res = psycopg_dict_from_conninfo_options(options, /* include_password = */ 0); + +exit: + PQconninfoFree(options); + + return res; +#else + PyErr_SetString(NotSupportedError, "PQconninfo not available in libpq < 9.3"); + return NULL; +#endif +} + + static const char status_doc[] = "The status of the connection.\n" "\n" @@ -497,6 +537,8 @@ static struct PyGetSetDef connInfoObject_getsets[] = { { "host", (getter)host_get, NULL, (char *)host_doc }, { "port", (getter)port_get, NULL, (char *)port_doc }, { "options", (getter)options_get, NULL, (char *)options_doc }, + { "dsn_parameters", (getter)dsn_parameters_get, NULL, + (char *)dsn_parameters_doc }, { "status", (getter)status_get, NULL, (char *)status_doc }, { "transaction_status", (getter)transaction_status_get, NULL, (char *)transaction_status_doc }, diff --git a/tests/test_connection.py b/tests/test_connection.py index e60b7dd9..ea74e1e4 100755 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -1752,6 +1752,13 @@ class TestConnectionInfo(ConnectingTestCase): self.assert_(isinstance(self.conn.info.options, str)) self.assert_(self.bconn.info.options is None) + @skip_before_libpq(9, 3) + def test_dsn_parameters(self): + d = self.conn.info.dsn_parameters + self.assert_(isinstance(d, dict)) + self.assertEqual(d['dbname'], dbname) # the only param we can check reliably + self.assert_('password' not in d, d) + def test_status(self): self.assertEqual(self.conn.info.status, 0) self.assertEqual(self.bconn.info.status, 1)