diff --git a/NEWS b/NEWS index 8cbaa7f2..5e2b1cd5 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ What's new in psycopg 2.8 New features: - Added `~psycopg2.extensions.encrypt_password()` function (:ticket:`#576`). +- Added `connection.host` property (:ticket:`#726`). - `~psycopg2.sql.Identifier` can represent qualified names in SQL composition (:ticket:`#732`). - `!str()` on `~psycopg2.extras.Range` produces a human-readable representation diff --git a/doc/src/connection.rst b/doc/src/connection.rst index 2910f301..f6e3f4ad 100644 --- a/doc/src/connection.rst +++ b/doc/src/connection.rst @@ -599,6 +599,24 @@ The ``connection`` class .. versionadded:: 2.5 + .. index:: + pair: Backend; Host + + .. attribute:: host + + The server host name of the active connection. + + This can be a host name, an IP address, or a directory path if the + connection is via Unix socket. (The path case can be distinguished + because it will always be an absolute path, beginning with ``/``.) + + .. seealso:: libpq docs for `PQhost()`__ for details. + + .. __: http://www.postgresql.org/docs/current/static/libpq-status.html#LIBPQ-PQHOST + + .. versionadded:: 2.8.0 + + .. index:: pair: Backend; PID diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index 6a66d48d..da421c01 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -992,6 +992,25 @@ psyco_conn_get_backend_pid(connectionObject *self) return PyInt_FromLong((long)PQbackendPID(self->pgconn)); } +/* get the current host */ + +#define psyco_conn_host_get_doc \ +"host -- Get the host name." + +static PyObject * +psyco_conn_host_get(connectionObject *self) +{ + const char *val = NULL; + + EXC_IF_CONN_CLOSED(self); + + val = PQhost(self->pgconn); + if (!val) { + Py_RETURN_NONE; + } + return conn_text_from_chars(self, val); +} + /* reset the currect connection */ #define psyco_conn_reset_doc \ @@ -1243,6 +1262,9 @@ static struct PyGetSetDef connectionObject_getsets[] = { (getter)psyco_conn_deferrable_get, (setter)psyco_conn_deferrable_set, psyco_conn_deferrable_doc }, + { "host", + (getter)psyco_conn_host_get, NULL, + psyco_conn_host_get_doc }, {NULL} }; #undef EXCEPTION_GETTER diff --git a/tests/test_connection.py b/tests/test_connection.py index 1342f9f8..498f3513 100755 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -39,7 +39,7 @@ from .testutils import ( skip_after_postgres, skip_before_libpq, skip_after_libpq, ConnectingTestCase, skip_if_tpc_disabled, skip_if_windows, slow) -from .testconfig import dsn, dbname +from .testconfig import dbhost, dsn, dbname class ConnectionTests(ConnectingTestCase): @@ -1682,6 +1682,19 @@ while True: self.assert_(not err, err) +class TestConnectionProps(ConnectingTestCase): + def test_host(self): + self.assertFalse(self.conn.closed) + expected = dbhost if dbhost else "/" + self.assertIn(expected, self.conn.host) + + def test_host_readonly(self): + self.assertFalse(self.conn.closed) + with self.assertRaises(AttributeError): + self.conn.host = 'override' + + + def test_suite(): return unittest.TestLoader().loadTestsFromName(__name__)