summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2018-10-13 01:36:07 +0100
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2018-10-13 01:36:07 +0100
commitcb3d5f9d925cd8b06e1ba5ed02d0997d84da26d6 (patch)
treebb119fd6987a299845689d4c03dfcb78cd32f852
parent4f7bbdca26b9d4bac0de375d5a531e9ff913ac52 (diff)
downloadpsycopg2-cb3d5f9d925cd8b06e1ba5ed02d0997d84da26d6.tar.gz
Added all the missing ConnectionInfo attributes
-rw-r--r--doc/src/extensions.rst5
-rw-r--r--psycopg/conninfo_type.c122
-rwxr-xr-xtests/test_connection.py28
3 files changed, 151 insertions, 4 deletions
diff --git a/doc/src/extensions.rst b/doc/src/extensions.rst
index a7ee289..456d1da 100644
--- a/doc/src/extensions.rst
+++ b/doc/src/extensions.rst
@@ -183,6 +183,11 @@ introspection etc.
returned as ``90305``, version 10.2 as ``100002``.
.. autoattribute:: error_message
+ .. autoattribute:: socket
+ .. autoattribute:: backend_pid
+ .. autoattribute:: needs_password
+ .. autoattribute:: used_password
+ .. autoattribute:: ssl_in_use
.. class:: Column(\*args, \*\*kwargs)
diff --git a/psycopg/conninfo_type.c b/psycopg/conninfo_type.c
index 4dbaef2..33f2bef 100644
--- a/psycopg/conninfo_type.c
+++ b/psycopg/conninfo_type.c
@@ -43,8 +43,7 @@ static const char connInfoType_doc[] =
static const char dbname_doc[] =
"The database name of the connection.\n"
"\n"
-"Wrapper for the `PQdb()`__ function.\n"
-"\n"
+".. seealso:: libpq docs for `PQdb()`__ for details.\n"
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
"#LIBPQ-PQDB";
@@ -64,8 +63,7 @@ dbname_get(connInfoObject *self)
static const char user_doc[] =
"The user name of the connection.\n"
"\n"
-"Wrapper for the `PQuser()`__ function.\n"
-"\n"
+".. seealso:: libpq docs for `PQuser()`__ for details.\n"
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
"#LIBPQ-PQUSER";
@@ -129,6 +127,8 @@ host_get(connInfoObject *self)
static const char port_doc[] =
"The port of the connection.\n"
"\n"
+":type: `!int`\n"
+"\n"
".. seealso:: libpq docs for `PQport()`__ for details.\n"
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
"#LIBPQ-PQPORT";
@@ -169,6 +169,8 @@ options_get(connInfoObject *self)
static const char status_doc[] =
"The status of the connection.\n"
"\n"
+":type: `!int`\n"
+"\n"
".. seealso:: libpq docs for `PQstatus()`__ for details.\n"
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
"#LIBPQ-PQSTATUS";
@@ -190,6 +192,8 @@ static const char transaction_status_doc[] =
"`psycopg2.extensions`: see :ref:`transaction-status-constants` for the\n"
"available values.\n"
"\n"
+":type: `!int`\n"
+"\n"
".. seealso:: libpq docs for `PQtransactionStatus()`__ for details.\n"
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
"#LIBPQ-PQTRANSACTIONSTATUS";
@@ -207,6 +211,8 @@ transaction_status_get(connInfoObject *self)
static const char protocol_version_doc[] =
"The frontend/backend protocol being used.\n"
"\n"
+":type: `!int`\n"
+"\n"
".. seealso:: libpq docs for `PQprotocolVersion()`__ for details.\n"
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
"#LIBPQ-PQPROTOCOLVERSION";
@@ -224,6 +230,8 @@ protocol_version_get(connInfoObject *self)
static const char server_version_doc[] =
"Returns an integer representing the server version.\n"
"\n"
+":type: `!int`\n"
+"\n"
".. seealso:: libpq docs for `PQserverVersion()`__ for details.\n"
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
"#LIBPQ-PQSERVERVERSION";
@@ -260,6 +268,104 @@ error_message_get(connInfoObject *self)
}
+static const char socket_doc[] =
+"The file descriptor number of the connection socket to the server.\n"
+"\n"
+":type: `!int`\n"
+"\n"
+".. seealso:: libpq docs for `PQsocket()`__ for details.\n"
+".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
+ "#LIBPQ-PQSOCKET";
+
+static PyObject *
+socket_get(connInfoObject *self)
+{
+ int val;
+
+ val = PQsocket(self->conn->pgconn);
+ return PyInt_FromLong((long)val);
+}
+
+
+static const char backend_pid_doc[] =
+"The process ID (PID) of the backend process handling this connection.\n"
+"\n"
+":type: `!int`\n"
+"\n"
+".. seealso:: libpq docs for `PQbackendPID()`__ for details.\n"
+".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
+ "#LIBPQ-PQBACKENDPID";
+
+static PyObject *
+backend_pid_get(connInfoObject *self)
+{
+ int val;
+
+ val = PQbackendPID(self->conn->pgconn);
+ return PyInt_FromLong((long)val);
+}
+
+
+static const char needs_password_doc[] =
+"The connection authentication method required a password, but none was available.\n"
+"\n"
+":type: `!bool`\n"
+"\n"
+".. seealso:: libpq docs for `PQconnectionNeedsPassword()`__ for details.\n"
+".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
+ "#LIBPQ-PQCONNECTIONNEEDSPASSWORD";
+
+static PyObject *
+needs_password_get(connInfoObject *self)
+{
+ PyObject *rv;
+
+ rv = PQconnectionNeedsPassword(self->conn->pgconn) ? Py_True : Py_False;
+ Py_INCREF(rv);
+ return rv;
+}
+
+
+static const char used_password_doc[] =
+"The connection authentication method used a password.\n"
+"\n"
+":type: `!bool`\n"
+"\n"
+".. seealso:: libpq docs for `PQconnectionUsedPassword()`__ for details.\n"
+".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
+ "#LIBPQ-PQCONNECTIONUSEDPASSWORD";
+
+static PyObject *
+used_password_get(connInfoObject *self)
+{
+ PyObject *rv;
+
+ rv = PQconnectionUsedPassword(self->conn->pgconn) ? Py_True : Py_False;
+ Py_INCREF(rv);
+ return rv;
+}
+
+
+static const char ssl_in_use_doc[] =
+"`!True` if the connection uses SSL, `!False` if not.\n"
+"\n"
+":type: `!bool`\n"
+"\n"
+".. seealso:: libpq docs for `PQsslInUse()`__ for details.\n"
+".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
+ "#LIBPQ-PQSSLINUSE";
+
+static PyObject *
+ssl_in_use_get(connInfoObject *self)
+{
+ PyObject *rv;
+
+ rv = PQsslInUse(self->conn->pgconn) ? Py_True : Py_False;
+ Py_INCREF(rv);
+ return rv;
+}
+
+
static struct PyGetSetDef connInfoObject_getsets[] = {
{ "dbname", (getter)dbname_get, NULL, (char *)dbname_doc },
{ "user", (getter)user_get, NULL, (char *)user_doc },
@@ -276,6 +382,14 @@ static struct PyGetSetDef connInfoObject_getsets[] = {
(char *)server_version_doc },
{ "error_message", (getter)error_message_get, NULL,
(char *)error_message_doc },
+ { "socket", (getter)socket_get, NULL, (char *)socket_doc },
+ { "backend_pid", (getter)backend_pid_get, NULL, (char *)backend_pid_doc },
+ { "used_password", (getter)used_password_get, NULL,
+ (char *)used_password_doc },
+ { "needs_password", (getter)needs_password_get, NULL,
+ (char *)needs_password_doc },
+ { "ssl_in_use", (getter)ssl_in_use_get, NULL,
+ (char *)ssl_in_use_doc },
{NULL}
};
diff --git a/tests/test_connection.py b/tests/test_connection.py
index 3d67857..c0bc6cc 100755
--- a/tests/test_connection.py
+++ b/tests/test_connection.py
@@ -1764,6 +1764,34 @@ class TestConnectionInfo(ConnectingTestCase):
self.assert_('nosuchtable' in self.conn.info.error_message)
+ def test_socket(self):
+ self.assert_(self.conn.info.socket >= 0)
+ self.assert_(self.bconn.info.socket < 0)
+
+ def test_backend_pid(self):
+ cur = self.conn.cursor()
+ try:
+ cur.execute("select pg_backend_pid()")
+ except psycopg2.DatabaseError:
+ self.assert_(self.conn.info.backend_pid > 0)
+ else:
+ self.assertEqual(
+ self.conn.info.backend_pid, int(cur.fetchone()[0]))
+
+ self.assert_(self.bconn.info.backend_pid == 0)
+
+ def test_needs_password(self):
+ self.assertIs(self.conn.info.needs_password, False)
+ self.assertIs(self.bconn.info.needs_password, False)
+
+ def test_used_password(self):
+ self.assertIsInstance(self.conn.info.used_password, bool)
+ self.assertIs(self.bconn.info.used_password, False)
+
+ def test_ssl_in_use(self):
+ self.assertIsInstance(self.conn.info.ssl_in_use, bool)
+ self.assertIs(self.bconn.info.ssl_in_use, False)
+
def test_suite():
return unittest.TestLoader().loadTestsFromName(__name__)