mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-22 17:06:33 +03:00
Added several ConnectionInfo attributes
This commit is contained in:
parent
9ddf59959f
commit
0a04c8892d
|
@ -159,7 +159,13 @@ introspection etc.
|
|||
|
||||
.. versionadded:: 2.8
|
||||
|
||||
.. autoattribute:: dbname
|
||||
.. autoattribute:: user
|
||||
.. autoattribute:: password
|
||||
.. autoattribute:: host
|
||||
.. autoattribute:: port
|
||||
.. autoattribute:: options
|
||||
.. autoattribute:: status
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,79 @@
|
|||
#include "psycopg/conninfo.h"
|
||||
|
||||
|
||||
static const char connInfoType_doc[] =
|
||||
"Details about the native PostgreSQL database connection.\n"
|
||||
"\n"
|
||||
"This class exposes several `informative functions`__ about the status\n"
|
||||
"of the libpq connection.\n"
|
||||
"\n"
|
||||
"Objects of this class are exposed as the `connection.info` attribute.\n"
|
||||
"\n"
|
||||
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html";
|
||||
|
||||
|
||||
static const char dbname_doc[] =
|
||||
"The database name of the connection.\n"
|
||||
"\n"
|
||||
"Wrapper for the `PQdb()`__ function.\n"
|
||||
"\n"
|
||||
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
|
||||
"#LIBPQ-PQDB";
|
||||
|
||||
static PyObject *
|
||||
dbname_get(connInfoObject *self)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
val = PQdb(self->conn->pgconn);
|
||||
if (!val) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return conn_text_from_chars(self->conn, val);
|
||||
}
|
||||
|
||||
|
||||
static const char user_doc[] =
|
||||
"The user name of the connection.\n"
|
||||
"\n"
|
||||
"Wrapper for the `PQuser()`__ function.\n"
|
||||
"\n"
|
||||
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
|
||||
"#LIBPQ-PQUSER";
|
||||
|
||||
static PyObject *
|
||||
user_get(connInfoObject *self)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
val = PQuser(self->conn->pgconn);
|
||||
if (!val) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return conn_text_from_chars(self->conn, val);
|
||||
}
|
||||
|
||||
|
||||
static const char password_doc[] =
|
||||
"The password of the connection.\n"
|
||||
"\n"
|
||||
".. seealso:: libpq docs for `PQpass()`__ for details.\n"
|
||||
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
|
||||
"#LIBPQ-PQPASS";
|
||||
|
||||
static PyObject *
|
||||
password_get(connInfoObject *self)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
val = PQpass(self->conn->pgconn);
|
||||
if (!val) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return conn_text_from_chars(self->conn, val);
|
||||
}
|
||||
|
||||
|
||||
static const char host_doc[] =
|
||||
"The server host name of the connection.\n"
|
||||
"\n"
|
||||
|
@ -53,8 +126,71 @@ host_get(connInfoObject *self)
|
|||
}
|
||||
|
||||
|
||||
static const char port_doc[] =
|
||||
"The port of the connection.\n"
|
||||
"\n"
|
||||
".. seealso:: libpq docs for `PQport()`__ for details.\n"
|
||||
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
|
||||
"#LIBPQ-PQPORT";
|
||||
|
||||
static PyObject *
|
||||
port_get(connInfoObject *self)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
val = PQport(self->conn->pgconn);
|
||||
if (!val || !val[0]) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return PyInt_FromString((char *)val, NULL, 10);
|
||||
}
|
||||
|
||||
|
||||
static const char options_doc[] =
|
||||
"The command-line options passed in the the connection request.\n"
|
||||
"\n"
|
||||
".. seealso:: libpq docs for `PQoptions()`__ for details.\n"
|
||||
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
|
||||
"#LIBPQ-PQOPTIONS";
|
||||
|
||||
static PyObject *
|
||||
options_get(connInfoObject *self)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
val = PQoptions(self->conn->pgconn);
|
||||
if (!val) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return conn_text_from_chars(self->conn, val);
|
||||
}
|
||||
|
||||
|
||||
static const char status_doc[] =
|
||||
"Return the status of the connection.\n"
|
||||
"\n"
|
||||
".. seealso:: libpq docs for `PQstatus()`__ for details.\n"
|
||||
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html"
|
||||
"#LIBPQ-PQSTATUS";
|
||||
|
||||
static PyObject *
|
||||
status_get(connInfoObject *self)
|
||||
{
|
||||
ConnStatusType val;
|
||||
|
||||
val = PQstatus(self->conn->pgconn);
|
||||
return PyInt_FromLong((long)val);
|
||||
}
|
||||
|
||||
|
||||
static struct PyGetSetDef connInfoObject_getsets[] = {
|
||||
{ "dbname", (getter)dbname_get, NULL, (char *)dbname_doc },
|
||||
{ "user", (getter)user_get, NULL, (char *)user_doc },
|
||||
{ "password", (getter)password_get, NULL, (char *)password_doc },
|
||||
{ "host", (getter)host_get, NULL, (char *)host_doc },
|
||||
{ "port", (getter)port_get, NULL, (char *)port_doc },
|
||||
{ "options", (getter)options_get, NULL, (char *)options_doc },
|
||||
{ "status", (getter)status_get, NULL, (char *)status_doc },
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
@ -95,16 +231,6 @@ conninfo_dealloc(connInfoObject* self)
|
|||
|
||||
/* object type */
|
||||
|
||||
static const char connInfoType_doc[] =
|
||||
"Details about the native PostgreSQL database connection.\n"
|
||||
"\n"
|
||||
"This class exposes several `informative functions`__ about the status\n"
|
||||
"of the libpq connection.\n"
|
||||
"\n"
|
||||
"Objects of this class are exposed as the `connection.info` attribute.\n"
|
||||
"\n"
|
||||
".. __: https://www.postgresql.org/docs/current/static/libpq-status.html";
|
||||
|
||||
PyTypeObject connInfoType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"psycopg2.extensions.ConnectionInfo",
|
||||
|
|
|
@ -78,6 +78,7 @@ typedef unsigned long Py_uhash_t;
|
|||
#define PyInt_Check PyLong_Check
|
||||
#define PyInt_AsLong PyLong_AsLong
|
||||
#define PyInt_FromLong PyLong_FromLong
|
||||
#define PyInt_FromString PyLong_FromString
|
||||
#define PyInt_FromSsize_t PyLong_FromSsize_t
|
||||
#define PyExc_StandardError PyExc_Exception
|
||||
#define PyString_FromFormat PyUnicode_FromFormat
|
||||
|
|
|
@ -1683,14 +1683,50 @@ while True:
|
|||
|
||||
|
||||
class TestConnectionInfo(ConnectingTestCase):
|
||||
def setUp(self):
|
||||
ConnectingTestCase.setUp(self)
|
||||
|
||||
class BrokenConn(psycopg2.extensions.connection):
|
||||
def __init__(self, *args, **kwargs):
|
||||
# don't call superclass
|
||||
pass
|
||||
|
||||
# A "broken" connection
|
||||
self.bconn = self.connect(connection_factory=BrokenConn)
|
||||
|
||||
def test_dbname(self):
|
||||
self.assert_(isinstance(self.conn.info.dbname, str))
|
||||
self.assert_(self.bconn.info.dbname is None)
|
||||
|
||||
def test_user(self):
|
||||
self.assert_(isinstance(self.conn.info.user, str))
|
||||
self.assert_(self.bconn.info.user is None)
|
||||
|
||||
def test_password(self):
|
||||
self.assert_(isinstance(self.conn.info.password, str))
|
||||
self.assert_(self.bconn.info.password is None)
|
||||
|
||||
def test_host(self):
|
||||
expected = dbhost if dbhost else "/"
|
||||
self.assertIn(expected, self.conn.info.host)
|
||||
self.assert_(self.bconn.info.host is None)
|
||||
|
||||
def test_host_readonly(self):
|
||||
with self.assertRaises(AttributeError):
|
||||
self.conn.info.host = 'override'
|
||||
|
||||
def test_port(self):
|
||||
self.assert_(isinstance(self.conn.info.port, int))
|
||||
self.assert_(self.bconn.info.port is None)
|
||||
|
||||
def test_options(self):
|
||||
self.assert_(isinstance(self.conn.info.options, str))
|
||||
self.assert_(self.bconn.info.options is None)
|
||||
|
||||
def test_status(self):
|
||||
self.assertEqual(self.conn.info.status, 0)
|
||||
self.assertEqual(self.bconn.info.status, 1)
|
||||
|
||||
|
||||
def test_suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
|
Loading…
Reference in New Issue
Block a user