Title: [991] trunk: Add some more attributes to the connection object

Diff

Modified: trunk/conn.c (990 => 991)


--- trunk/conn.c	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/conn.c	2019-04-24 19:46:20 UTC (rev 991)
@@ -11,7 +11,7 @@
  *
  */
 
-/* Deallocate connection object */
+/* Deallocate connection object. */
 static void
 conn_dealloc(connObject *self)
 {
@@ -25,7 +25,7 @@
     PyObject_Del(self);
 }
 
-/* get connection attributes */
+/* Get connection attributes. */
 static PyObject *
 conn_getattr(connObject *self, PyObject *nameobj)
 {
@@ -85,10 +85,45 @@
     if (!strcmp(name, "server_version"))
         return PyInt_FromLong(PQserverVersion(self->cnx));
 
+    /* descriptor number of connection socket */
+    if (!strcmp(name, "socket")) {
+        return PyInt_FromLong(PQsocket(self->cnx));
+    }
+
+    /* PID of backend process */
+    if (!strcmp(name, "backend_pid")) {
+        return PyInt_FromLong(PQbackendPID(self->cnx));
+    }
+
+    /* whether the connection uses SSL */
+    if (!strcmp(name, "ssl_in_use")) {
+#ifdef SSL_INFO
+        if (PQsslInUse(self->cnx)) {
+            Py_INCREF(Py_True); return Py_True;
+        }
+        else {
+            Py_INCREF(Py_False); return Py_False;
+        }
+#else
+        set_error_msg(NotSupportedError, "SSL info functions not supported");
+        return NULL;
+#endif
+    }
+
+    /* SSL attributes */
+    if (!strcmp(name, "ssl_attributes")) {
+#ifdef SSL_INFO
+        return get_ssl_attributes(self->cnx);
+#else
+        set_error_msg(NotSupportedError, "SSL info functions not supported");
+        return NULL;
+#endif
+    }
+
     return PyObject_GenericGetAttr((PyObject *) self, nameobj);
 }
 
-/* Check connection validity */
+/* Check connection validity. */
 static int
 _check_cnx_obj(connObject *self)
 {
@@ -99,7 +134,7 @@
     return 1;
 }
 
-/* source creation */
+/* Create source object. */
 static char conn_source__doc__[] =
 "source() -- create a new source object for this connection";
 
@@ -128,7 +163,7 @@
     return (PyObject *) source_obj;
 }
 
-/* base method for execution of both unprepared and prepared queries */
+/* Base method for execution of both unprepared and prepared queries */
 static PyObject *
 _conn_query(connObject *self, PyObject *args, int prepared)
 {
@@ -350,7 +385,7 @@
     return (PyObject *) query_obj;
 }
 
-/* database query */
+/* Database query */
 static char conn_query__doc__[] =
 "query(sql, [arg]) -- create a new query object for this connection\n\n"
 "You must pass the SQL (string) request and you can optionally pass\n"
@@ -362,7 +397,7 @@
     return _conn_query(self, args, 0);
 }
 
-/* execute prepared statement */
+/* Execute prepared statement. */
 static char conn_query_prepared__doc__[] =
 "query_prepared(name, [arg]) -- execute a prepared statement\n\n"
 "You must pass the name (string) of the prepared statement and you can\n"
@@ -374,7 +409,7 @@
     return _conn_query(self, args, 1);
 }
 
-/* create prepared statement */
+/* Create prepared statement. */
 static char conn_prepare__doc__[] =
 "prepare(name, sql) -- create a prepared statement\n\n"
 "You must pass the name (string) of the prepared statement and the\n"
@@ -417,7 +452,7 @@
     return NULL; /* error */
 }
 
-/* describe prepared statement */
+/* Describe prepared statement. */
 static char conn_describe_prepared__doc__[] =
 "describe_prepared(name) -- describe a prepared statement\n\n"
 "You must pass the name (string) of the prepared statement.\n";
@@ -470,7 +505,7 @@
 static char conn_putline__doc__[] =
 "putline(line) -- send a line directly to the backend";
 
-/* direct access function: putline */
+/* Direct access function: putline. */
 static PyObject *
 conn_putline(connObject *self, PyObject *args)
 {
@@ -498,7 +533,7 @@
     return Py_None;
 }
 
-/* direct access function: getline */
+/* Direct access function: getline. */
 static char conn_getline__doc__[] =
 "getline() -- get a line directly from the backend";
 
@@ -531,7 +566,7 @@
     return str;
 }
 
-/* direct access function: end copy */
+/* Direct access function: end copy. */
 static char conn_endcopy__doc__[] =
 "endcopy() -- synchronize client and server";
 
@@ -554,7 +589,7 @@
 #endif /* DIRECT_ACCESS */
 
 
-/* insert table */
+/* Insert table */
 static char conn_inserttable__doc__[] =
 "inserttable(table, data) -- insert list into table\n\n"
 "The fields in the list must be in the same order as in the table.\n";
@@ -765,7 +800,7 @@
     return Py_None;
 }
 
-/* get transaction state */
+/* Get transaction state. */
 static char conn_transaction__doc__[] =
 "transaction() -- return the current transaction status";
 
@@ -780,7 +815,7 @@
     return PyInt_FromLong(PQtransactionStatus(self->cnx));
 }
 
-/* get parameter setting */
+/* Get parameter setting. */
 static char conn_parameter__doc__[] =
 "parameter(name) -- look up a current parameter setting";
 
@@ -811,7 +846,7 @@
     return Py_None;
 }
 
-/* get current date format */
+/* Get current date format. */
 static char conn_date_format__doc__[] =
 "date_format() -- return the current date format";
 
@@ -837,7 +872,7 @@
 
 #ifdef ESCAPING_FUNCS
 
-/* escape literal */
+/* Escape literal */
 static char conn_escape_literal__doc__[] =
 "escape_literal(str) -- escape a literal constant for use within SQL";
 
@@ -882,7 +917,7 @@
     return to_obj;
 }
 
-/* escape identifier */
+/* Escape identifier */
 static char conn_escape_identifier__doc__[] =
 "escape_identifier(str) -- escape an identifier for use within SQL";
 
@@ -929,7 +964,7 @@
 
 #endif /* ESCAPING_FUNCS */
 
-/* escape string */
+/* Escape string */
 static char conn_escape_string__doc__[] =
 "escape_string(str) -- escape a string for use within SQL";
 
@@ -979,7 +1014,7 @@
     return to_obj;
 }
 
-/* escape bytea */
+/* Escape bytea */
 static char conn_escape_bytea__doc__[] =
 "escape_bytea(data) -- escape binary data for use within SQL as type bytea";
 
@@ -1026,7 +1061,7 @@
 
 #ifdef LARGE_OBJECTS
 
-/* constructor for large objects (internal use only) */
+/* Constructor for large objects (internal use only) */
 static largeObject *
 large_new(connObject *pgcnx, Oid oid)
 {
@@ -1044,7 +1079,7 @@
     return large_obj;
 }
 
-/* creates large object */
+/* Create large object. */
 static char conn_locreate__doc__[] =
 "locreate(mode) -- create a new large object in the database";
 
@@ -1076,7 +1111,7 @@
     return (PyObject *) large_new(self, lo_oid);
 }
 
-/* init from already known oid */
+/* Init from already known oid. */
 static char conn_getlo__doc__[] =
 "getlo(oid) -- create a large object instance for the specified oid";
 
@@ -1108,7 +1143,7 @@
     return (PyObject *) large_new(self, lo_oid);
 }
 
-/* import unix file */
+/* Import unix file. */
 static char conn_loimport__doc__[] =
 "loimport(name) -- create a new large object from specified file";
 
@@ -1142,7 +1177,7 @@
 
 #endif /* LARGE_OBJECTS */
 
-/* resets connection */
+/* Reset connection. */
 static char conn_reset__doc__[] =
 "reset() -- reset connection with current parameters\n\n"
 "All derived queries and large objects derived from this connection\n"
@@ -1162,7 +1197,7 @@
     return Py_None;
 }
 
-/* cancels current command */
+/* Cancel current command. */
 static char conn_cancel__doc__[] =
 "cancel() -- abandon processing of the current command";
 
@@ -1178,7 +1213,7 @@
     return PyInt_FromLong((long) PQrequestCancel(self->cnx));
 }
 
-/* get connection socket */
+/* Get connection socket. */
 static char conn_fileno__doc__[] =
 "fileno() -- return database connection socket file handle";
 
@@ -1197,7 +1232,7 @@
 #endif
 }
 
-/* set external typecast callback function */
+/* Set external typecast callback function. */
 static char conn_set_cast_hook__doc__[] =
 "set_cast_hook(func) -- set a fallback typecast function";
 
@@ -1225,7 +1260,7 @@
     return ret;
 }
 
-/* get notice receiver callback function */
+/* Get notice receiver callback function. */
 static char conn_get_cast_hook__doc__[] =
 "get_cast_hook() -- get the fallback typecast function";
 
@@ -1241,7 +1276,7 @@
     return ret;
 }
 
-/* set notice receiver callback function */
+/* Set notice receiver callback function. */
 static char conn_set_notice_receiver__doc__[] =
 "set_notice_receiver(func) -- set the current notice receiver";
 
@@ -1270,7 +1305,7 @@
     return ret;
 }
 
-/* get notice receiver callback function */
+/* Get notice receiver callback function. */
 static char conn_get_notice_receiver__doc__[] =
 "get_notice_receiver() -- get the current notice receiver";
 
@@ -1286,7 +1321,7 @@
     return ret;
 }
 
-/* close without deleting */
+/* Close without deleting. */
 static char conn_close__doc__[] =
 "close() -- close connection\n\n"
 "All instances of the connection object and derived objects\n"
@@ -1310,7 +1345,7 @@
     return Py_None;
 }
 
-/* gets asynchronous notify */
+/* Get asynchronous notify. */
 static char conn_get_notify__doc__[] =
 "getnotify() -- get database notify for this connection";
 
@@ -1365,7 +1400,7 @@
     }
 }
 
-/* get the list of connection attributes */
+/* Get the list of connection attributes. */
 static PyObject *
 conn_dir(connObject *self, PyObject *noargs)
 {
@@ -1373,14 +1408,15 @@
 
     attrs = PyObject_Dir(PyObject_Type((PyObject *) self));
     PyObject_CallMethod(
-        attrs, "extend", "[sssssssss]",
+        attrs, "extend", "[sssssssssssss]",
         "host", "port", "db", "options", "error", "status", "user",
-        "protocol_version", "server_version");
+        "protocol_version", "server_version", "socket", "backend_pid",
+        "ssl_in_use", "ssl_attributes");
 
     return attrs;
 }
 
-/* connection object methods */
+/* Connection object methods */
 static struct PyMethodDef conn_methods[] = {
     {"__dir__", (PyCFunction) conn_dir,  METH_NOARGS, NULL},
 
@@ -1455,7 +1491,7 @@
 
 static char conn__doc__[] = "PostgreSQL connection object";
 
-/* connection type definition */
+/* Connection type definition */
 static PyTypeObject connType = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "pg.Connection",              /* tp_name */

Modified: trunk/docs/contents/changelog.rst (990 => 991)


--- trunk/docs/contents/changelog.rst	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/docs/contents/changelog.rst	2019-04-24 19:46:20 UTC (rev 991)
@@ -29,6 +29,8 @@
       factory with the pg.set_row_factory_size() function and change the
       implementation with pg.set_query_helps(), but this is not recommended
       and this function is not part of the official API.
+    - Added new connection attributes `socket`, `backend_pid`, `ssl_in_use`
+      and `ssl_attributes` (the latter need PostgreSQL >= 9.5 on the client).
 
 Vesion 5.0.7 (2019-mm-dd)
 -------------------------

Modified: trunk/docs/contents/pg/connection.rst (990 => 991)


--- trunk/docs/contents/pg/connection.rst	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/docs/contents/pg/connection.rst	2019-04-24 19:46:20 UTC (rev 991)
@@ -557,3 +557,27 @@
 .. attribute:: Connection.error
 
     the last warning/error message from the server (str)
+
+.. attribute:: Connection.socket
+
+    the file descriptor number of the connection socket to the server (int)
+
+.. versionadded:: 5.1
+
+.. attribute:: Connection.backend_pid
+
+     the PID of the backend process handling this connection (int)
+
+.. versionadded:: 5.1
+
+.. attribute:: Connection.ssl_in_use
+
+     this is True if the connection uses SSL, False if not
+
+.. versionadded:: 5.1 (needs PostgreSQL >= 9.5)
+
+.. attribute:: Connection.ssl_attributes
+
+     SSL-related information about the connection (dict)
+
+.. versionadded:: 5.1 (needs PostgreSQL >= 9.5)

Modified: trunk/internal.c (990 => 991)


--- trunk/internal.c	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/internal.c	2019-04-24 19:46:20 UTC (rev 991)
@@ -1,5 +1,5 @@
 /*
- * $Id: conn.c 985 2019-04-22 22:07:43Z cito $
+ * $Id: internal.c 985 2019-04-22 22:07:43Z cito $
  *
  * PyGreSQL - a Python interface for the PostgreSQL database.
  *
@@ -13,7 +13,7 @@
 
 /* PyGreSQL internal types */
 
-/* simple types */
+/* Simple types */
 #define PYGRES_INT 1
 #define PYGRES_LONG 2
 #define PYGRES_FLOAT 3
@@ -20,15 +20,15 @@
 #define PYGRES_DECIMAL 4
 #define PYGRES_MONEY 5
 #define PYGRES_BOOL 6
-/* text based types */
+/* Text based types */
 #define PYGRES_TEXT 8
 #define PYGRES_BYTEA 9
 #define PYGRES_JSON 10
 #define PYGRES_OTHER 11
-/* array types */
+/* Array types */
 #define PYGRES_ARRAY 16
 
-/* shared function for encoding and decoding strings */
+/* Shared functions for encoding and decoding strings */
 
 static PyObject *
 get_decoded_string(const char *str, Py_ssize_t size, int encoding)
@@ -58,9 +58,9 @@
         pg_encoding_to_char(encoding), "strict");
 }
 
-/* helper functions */
+/* Helper functions */
 
-/* get PyGreSQL internal types for a PostgreSQL type */
+/* Get PyGreSQL internal types for a PostgreSQL type. */
 static int
 get_type(Oid pgtype)
 {
@@ -175,7 +175,7 @@
     return t;
 }
 
-/* get PyGreSQL column types for all result columns */
+/* Get PyGreSQL column types for all result columns. */
 static int *
 get_col_types(PGresult *result, int nfields)
 {
@@ -444,7 +444,7 @@
     return obj;
 }
 
-/* quick case insensitive check if given sized string is null */
+/* Quick case insensitive check if given sized string is null. */
 #define STR_IS_NULL(s, n) (n == 4 && \
     (s[0] == 'n' || s[0] == 'N') && \
     (s[1] == 'u' || s[1] == 'U') && \
@@ -679,7 +679,6 @@
    functions to cast elements. The parameter len is the record size.
    The parameter delim can specify a delimiter for the elements,
    although composite types always use a comma as delimiter. */
-
 static PyObject *
 cast_record(char *s, Py_ssize_t size, int encoding,
      int *type, PyObject *cast, Py_ssize_t len, char delim)
@@ -840,7 +839,6 @@
 
 /* Cast string s with size and encoding to a Python dictionary.
    using the input and output syntax for hstore values. */
-
 static PyObject *
 cast_hstore(char *s, Py_ssize_t size, int encoding)
 {
@@ -997,7 +995,7 @@
     return result;
 }
 
-/* gets appropriate error type from sqlstate */
+/* Get appropriate error type from sqlstate. */
 static PyObject *
 get_error_type(const char *sqlstate)
 {
@@ -1063,7 +1061,7 @@
     return DatabaseError;
 }
 
-/* sets database error message and sqlstate attribute */
+/* Set database error message and sqlstate attribute. */
 static void
 set_error_msg_and_state(PyObject *type,
     const char *msg, int encoding, const char *sqlstate)
@@ -1099,7 +1097,7 @@
     }
 }
 
-/* sets given database error message */
+/* Set given database error message. */
 static void
 set_error_msg(PyObject *type, const char *msg)
 {
@@ -1106,7 +1104,7 @@
     set_error_msg_and_state(type, msg, pg_encoding_ascii, NULL);
 }
 
-/* sets database error from connection and/or result */
+/* Set database error from connection and/or result. */
 static void
 set_error(PyObject *type, const char * msg, PGconn *cnx, PGresult *result)
 {
@@ -1128,13 +1126,42 @@
     set_error_msg_and_state(type, msg, encoding, sqlstate);
 }
 
-/* format result (mostly useful for debugging) */
-/* Note: This is similar to the Postgres function PQprint().
- * PQprint() is not used because handing over a stream from Python to
- * Postgres can be problematic if they use different libs for streams
- * and because using PQprint() and tp_print is not recommended any more.
- */
+#ifdef SSL_INFO
+
+/* Get SSL attributes and values as a dictionary. */
 static PyObject *
+get_ssl_attributes(PGconn *cnx) {
+    PyObject *attr_dict = NULL;
+
+    if (!(attr_dict = PyDict_New())) {
+        return NULL;
+    }
+
+    for (const char * const *s = PQsslAttributeNames(cnx); *s; ++s) {
+        const char *val = PQsslAttribute(cnx, *s);
+
+        if (val) {
+            PyObject * val_obj = PyStr_FromString(val);
+
+            PyDict_SetItemString(attr_dict, *s, val_obj);
+            Py_DECREF(val_obj);
+        }
+        else {
+            PyDict_SetItemString(attr_dict, *s, Py_None);
+        }
+    }
+
+    return attr_dict;
+}
+
+#endif /* SSL_INFO */
+
+/* Format result (mostly useful for debugging).
+   Note: This is similar to the Postgres function PQprint().
+   PQprint() is not used because handing over a stream from Python to
+   PostgreSQL can be problematic if they use different libs for streams
+   and because using PQprint() and tp_print is not recommended any more. */
+static PyObject *
 format_result(const PGresult *res)
 {
     const int n = PQnfields(res);
@@ -1269,7 +1296,7 @@
         return PyStr_FromString("(nothing selected)");
 }
 
-/* internal function converting a Postgres datestyles to date formats */
+/* Internal function converting a Postgres datestyles to date formats. */
 static const char *
 date_style_to_format(const char *s)
 {
@@ -1299,7 +1326,7 @@
     }
 }
 
-/* internal function converting a date format to a Postgres datestyle */
+/* Internal function converting a date format to a Postgres datestyle. */
 static const char *
 date_format_to_style(const char *s)
 {
@@ -1335,7 +1362,7 @@
     }
 }
 
-/* internal wrapper for the notice receiver callback */
+/* Internal wrapper for the notice receiver callback. */
 static void
 notice_receiver(void *arg, const PGresult *res)
 {

Modified: trunk/large.c (990 => 991)


--- trunk/large.c	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/large.c	2019-04-24 19:46:20 UTC (rev 991)
@@ -1,5 +1,5 @@
 /*
- * $Id: conn.c 985 2019-04-22 22:07:43Z cito $
+ * $Id: large.c 985 2019-04-22 22:07:43Z cito $
  *
  * PyGreSQL - a Python interface for the PostgreSQL database.
  *
@@ -11,7 +11,7 @@
  *
  */
 
-/* Deallocate large object */
+/* Deallocate large object. */
 static void
 large_dealloc(largeObject *self)
 {
@@ -22,7 +22,7 @@
     PyObject_Del(self);
 }
 
-/* Return large object as string in human readable form */
+/* Return large object as string in human readable form. */
 static PyObject *
 large_str(largeObject *self)
 {
@@ -33,7 +33,7 @@
     return PyStr_FromString(str);
 }
 
-/* Check validity of large object */
+/* Check validity of large object. */
 static int
 _check_lo_obj(largeObject *self, int level)
 {
@@ -62,7 +62,7 @@
     return 1;
 }
 
-/* Get large object attributes */
+/* Get large object attributes. */
 static PyObject *
 large_getattr(largeObject *self, PyObject *nameobj)
 {
@@ -98,7 +98,7 @@
     return PyObject_GenericGetAttr((PyObject *) self, nameobj);
 }
 
-/* Get the list of large object attributes */
+/* Get the list of large object attributes. */
 static PyObject *
 large_dir(largeObject *self, PyObject *noargs)
 {
@@ -111,7 +111,7 @@
     return attrs;
 }
 
-/* Open large object */
+/* Open large object. */
 static char large_open__doc__[] =
 "open(mode) -- open access to large object with specified mode\n\n"
 "The mode must be one of INV_READ, INV_WRITE (module level constants).\n";
@@ -145,7 +145,7 @@
     return Py_None;
 }
 
-/* Close large object */
+/* Close large object. */
 static char large_close__doc__[] =
 "close() -- close access to large object data";
 
@@ -169,7 +169,7 @@
     return Py_None;
 }
 
-/* Read from large object */
+/* Read from large object. */
 static char large_read__doc__[] =
 "read(size) -- read from large object to sized string\n\n"
 "Object must be opened in read mode before calling this method.\n";
@@ -214,7 +214,7 @@
     return buffer;
 }
 
-/* Write to large object */
+/* Write to large object. */
 static char large_write__doc__[] =
 "write(string) -- write sized string to large object\n\n"
 "Object must be opened in read mode before calling this method.\n";
@@ -250,7 +250,7 @@
     return Py_None;
 }
 
-/* Go to position in large object */
+/* Go to position in large object. */
 static char large_seek__doc__[] =
 "seek(offset, whence) -- move to specified position\n\n"
 "Object must be opened before calling this method. The whence option\n"
@@ -286,7 +286,7 @@
     return PyInt_FromLong(ret);
 }
 
-/* Get large object size */
+/* Get large object size. */
 static char large_size__doc__[] =
 "size() -- return large object size\n\n"
 "The object must be opened before calling this method.\n";
@@ -326,7 +326,7 @@
     return PyInt_FromLong(end);
 }
 
-/* Get large object cursor position */
+/* Get large object cursor position. */
 static char large_tell__doc__[] =
 "tell() -- give current position in large object\n\n"
 "The object must be opened before calling this method.\n";
@@ -351,7 +351,7 @@
     return PyInt_FromLong(start);
 }
 
-/* Export large object as unix file */
+/* Export large object as unix file. */
 static char large_export__doc__[] =
 "export(filename) -- export large object data to specified file\n\n"
 "The object must be closed when calling this method.\n";
@@ -383,7 +383,7 @@
     return Py_None;
 }
 
-/* Delete a large object */
+/* Delete a large object. */
 static char large_unlink__doc__[] =
 "unlink() -- destroy large object\n\n"
 "The object must be closed when calling this method.\n";
@@ -407,7 +407,7 @@
     return Py_None;
 }
 
-/* large object methods */
+/* Large object methods */
 static struct PyMethodDef large_methods[] = {
     {"__dir__", (PyCFunction) large_dir,  METH_NOARGS, NULL},
     {"open", (PyCFunction) large_open, METH_VARARGS, large_open__doc__},
@@ -424,7 +424,7 @@
 
 static char large__doc__[] = "PostgreSQL large object";
 
-/* large object type definition */
+/* Large object type definition */
 static PyTypeObject largeType = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "pg.LargeObject",              /* tp_name */

Modified: trunk/notice.c (990 => 991)


--- trunk/notice.c	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/notice.c	2019-04-24 19:46:20 UTC (rev 991)
@@ -1,5 +1,5 @@
 /*
- * $Id: conn.c 985 2019-04-22 22:07:43Z cito $
+ * $Id: notice.c 985 2019-04-22 22:07:43Z cito $
  *
  * PyGreSQL - a Python interface for the PostgreSQL database.
  *
@@ -11,7 +11,7 @@
  *
  */
 
-/* Get notice object attributes */
+/* Get notice object attributes. */
 static PyObject *
 notice_getattr(noticeObject *self, PyObject *nameobj)
 {
@@ -64,7 +64,7 @@
     return PyObject_GenericGetAttr((PyObject *) self, nameobj);
 }
 
-/* Get the list of notice attributes */
+/* Get the list of notice attributes. */
 static PyObject *
 notice_dir(noticeObject *self, PyObject *noargs)
 {
@@ -78,7 +78,7 @@
     return attrs;
 }
 
-/* Return notice as string in human readable form */
+/* Return notice as string in human readable form. */
 static PyObject *
 notice_str(noticeObject *self)
 {
@@ -85,7 +85,7 @@
     return notice_getattr(self, PyBytes_FromString("message"));
 }
 
-/* notice object methods */
+/* Notice object methods */
 static struct PyMethodDef notice_methods[] = {
     {"__dir__", (PyCFunction) notice_dir,  METH_NOARGS, NULL},
     {NULL, NULL}
@@ -93,7 +93,7 @@
 
 static char notice__doc__[] = "PostgreSQL notice object";
 
-/* notice type definition */
+/* Notice type definition */
 static PyTypeObject noticeType = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "pg.Notice",                    /* tp_name */

Modified: trunk/pgmodule.c (990 => 991)


--- trunk/pgmodule.c	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/pgmodule.c	2019-04-24 19:46:20 UTC (rev 991)
@@ -18,10 +18,10 @@
 #include <libpq-fe.h>
 #include <libpq/libpq-fs.h>
 
-/* the type definitions from <server/catalog/pg_type.h> */
+/* The type definitions from <server/catalog/pg_type.h> */
 #include "pgtypes.h"
 
-/* macros for single-source Python 2/3 compatibility */
+/* Macros for single-source Python 2/3 compatibility */
 #include "py3c.h"
 
 static PyObject *Error, *Warning, *InterfaceError, *DatabaseError,
@@ -37,10 +37,10 @@
 #define Py_InitModule4 Py_InitModule4_64
 #endif
 
-/* default values */
+/* Default values */
 #define PG_ARRAYSIZE 1
 
-/* flags for object validity checks */
+/* Flags for object validity checks */
 #define CHECK_OPEN   1
 #define CHECK_CLOSE  2
 #define CHECK_CNX    4
@@ -47,13 +47,13 @@
 #define CHECK_RESULT 8
 #define CHECK_DQL   16
 
-/* query result types */
+/* Query result types */
 #define RESULT_EMPTY 1
 #define RESULT_DML   2
 #define RESULT_DDL   3
 #define RESULT_DQL   4
 
-/* flags for move methods */
+/* Flags for move methods */
 #define QUERY_MOVEFIRST 1
 #define QUERY_MOVELAST  2
 #define QUERY_MOVENEXT  3
@@ -109,13 +109,13 @@
    - source: Source object returned by pg.conn.source().
 */
 
-/* forward declarations for types */
+/* Forward declarations for types */
 static PyTypeObject connType, sourceType, queryType, noticeType, largeType;
 
-/* forward static declarations */
+/* Forward static declarations */
 static void notice_receiver(void *, const PGresult *);
 
-/* object declarations */
+/* Object declarations */
 
 typedef struct
 {
@@ -175,22 +175,22 @@
 #define is_largeObject(v) (PyType(v) == &largeType)
 #endif /* LARGE_OBJECTS */
 
-/* internal functions */
+/* Internal functions */
 #include "internal.c"
 
-/* connection object */
+/* Connection object */
 #include "conn.c"
 
-/* query object */
+/* Query object */
 #include "query.c"
 
-/* source object */
+/* Source object */
 #include "source.c"
 
-/* notice object */
+/* Notice object */
 #include "notice.c"
 
-/* large objects */
+/* Large objects */
 #ifdef LARGE_OBJECTS
 #include "large.c"
 #endif
@@ -197,7 +197,7 @@
 
 /* MODULE FUNCTIONS */
 
-/* connect to a database */
+/* Connect to a database. */
 static char pg_connect__doc__[] =
 "connect(dbname, host, port, opt) -- connect to a PostgreSQL database\n\n"
 "The connection uses the specified parameters (optional, keywords aware).\n";
@@ -282,7 +282,7 @@
     return (PyObject *) conn_obj;
 }
 
-/* escape string */
+/* Escape string */
 static char pg_escape_string__doc__[] =
 "escape_string(string) -- escape a string for use within SQL";
 
@@ -330,7 +330,7 @@
     return to_obj;
 }
 
-/* escape bytea */
+/* Escape bytea */
 static char pg_escape_bytea__doc__[] =
 "escape_bytea(data) -- escape binary data for use within SQL as type bytea";
 
@@ -374,7 +374,7 @@
     return to_obj;
 }
 
-/* unescape bytea */
+/* Unescape bytea */
 static char pg_unescape_bytea__doc__[] =
 "unescape_bytea(string) -- unescape bytea data retrieved as text";
 
@@ -415,7 +415,7 @@
     return to_obj;
 }
 
-/* set fixed datestyle */
+/* Set fixed datestyle. */
 static char pg_set_datestyle__doc__[] =
 "set_datestyle(style) -- set which style is assumed";
 
@@ -437,7 +437,7 @@
     Py_INCREF(Py_None); return Py_None;
 }
 
-/* get fixed datestyle */
+/* Get fixed datestyle. */
 static char pg_get_datestyle__doc__[] =
 "get_datestyle() -- get which date style is assumed";
 
@@ -452,7 +452,7 @@
     }
 }
 
-/* get decimal point */
+/* Get decimal point. */
 static char pg_get_decimal_point__doc__[] =
 "get_decimal_point() -- get decimal point to be used for money values";
 
@@ -473,7 +473,7 @@
     return ret;
 }
 
-/* set decimal point */
+/* Set decimal point. */
 static char pg_set_decimal_point__doc__[] =
 "set_decimal_point(char) -- set decimal point to be used for money values";
 
@@ -503,7 +503,7 @@
     return ret;
 }
 
-/* get decimal type */
+/* Get decimal type. */
 static char pg_get_decimal__doc__[] =
 "get_decimal() -- get the decimal type to be used for numeric values";
 
@@ -518,7 +518,7 @@
     return ret;
 }
 
-/* set decimal type */
+/* Set decimal type. */
 static char pg_set_decimal__doc__[] =
 "set_decimal(cls) -- set a decimal type to be used for numeric values";
 
@@ -544,7 +544,7 @@
     return ret;
 }
 
-/* get usage of bool values */
+/* Get usage of bool values. */
 static char pg_get_bool__doc__[] =
 "get_bool() -- check whether boolean values are converted to bool";
 
@@ -559,7 +559,7 @@
     return ret;
 }
 
-/* set usage of bool values */
+/* Set usage of bool values. */
 static char pg_set_bool__doc__[] =
 "set_bool(on) -- set whether boolean values should be converted to bool";
 
@@ -583,7 +583,7 @@
     return ret;
 }
 
-/* get conversion of arrays to lists */
+/* Get conversion of arrays to lists. */
 static char pg_get_array__doc__[] =
 "get_array() -- check whether arrays are converted as lists";
 
@@ -598,7 +598,7 @@
     return ret;
 }
 
-/* set conversion of arrays to lists */
+/* Set conversion of arrays to lists. */
 static char pg_set_array__doc__[] =
 "set_array(on) -- set whether arrays should be converted to lists";
 
@@ -622,7 +622,7 @@
     return ret;
 }
 
-/* check whether bytea values are unescaped */
+/* Check whether bytea values are unescaped. */
 static char pg_get_bytea_escaped__doc__[] =
 "get_bytea_escaped() -- check whether bytea will be returned escaped";
 
@@ -637,7 +637,7 @@
     return ret;
 }
 
-/* set usage of bool values */
+/* Set usage of bool values. */
 static char pg_set_bytea_escaped__doc__[] =
 "set_bytea_escaped(on) -- set whether bytea will be returned escaped";
 
@@ -683,7 +683,7 @@
     return Py_None;
 }
 
-/* get json decode function */
+/* Get json decode function. */
 static char pg_get_jsondecode__doc__[] =
 "get_jsondecode() -- get the function used for decoding json results";
 
@@ -700,7 +700,7 @@
     return ret;
 }
 
-/* set json decode function */
+/* Set json decode function. */
 static char pg_set_jsondecode__doc__[] =
 "set_jsondecode(func) -- set a function to be used for decoding json results";
 
@@ -728,7 +728,7 @@
 
 #ifdef DEFAULT_VARS
 
-/* gets default host */
+/* Get default host. */
 static char pg_get_defhost__doc__[] =
 "get_defhost() -- return default database host";
 
@@ -739,7 +739,7 @@
     return pg_default_host;
 }
 
-/* sets default host */
+/* Set default host. */
 static char pg_set_defhost__doc__[] =
 "set_defhost(string) -- set default database host and return previous value";
 
@@ -771,7 +771,7 @@
     return old;
 }
 
-/* gets default base */
+/* Get default database. */
 static char pg_get_defbase__doc__[] =
 "get_defbase() -- return default database name";
 
@@ -782,7 +782,7 @@
     return pg_default_base;
 }
 
-/* sets default base */
+/* Set default database. */
 static char pg_set_defbase__doc__[] =
 "set_defbase(string) -- set default database name and return previous value";
 
@@ -814,7 +814,7 @@
     return old;
 }
 
-/* gets default options */
+/* Get default options. */
 static char pg_get_defopt__doc__[] =
 "get_defopt() -- return default database options";
 
@@ -825,7 +825,7 @@
     return pg_default_opt;
 }
 
-/* sets default opt */
+/* Set default options. */
 static char pg_set_defopt__doc__[] =
 "set_defopt(string) -- set default options and return previous value";
 
@@ -857,7 +857,7 @@
     return old;
 }
 
-/* gets default username */
+/* Get default username. */
 static char pg_get_defuser__doc__[] =
 "get_defuser() -- return default database username";
 
@@ -868,7 +868,7 @@
     return pg_default_user;
 }
 
-/* sets default username */
+/* Set default username. */
 
 static char pg_set_defuser__doc__[] =
 "set_defuser(name) -- set default username and return previous value";
@@ -901,7 +901,7 @@
     return old;
 }
 
-/* sets default password */
+/* Set default password. */
 static char pg_set_defpasswd__doc__[] =
 "set_defpasswd(password) -- set default database password";
 
@@ -930,7 +930,7 @@
     return Py_None;
 }
 
-/* gets default port */
+/* Get default port. */
 static char pg_get_defport__doc__[] =
 "get_defport() -- return default database port";
 
@@ -941,7 +941,7 @@
     return pg_default_port;
 }
 
-/* sets default port */
+/* Set default port. */
 static char pg_set_defport__doc__[] =
 "set_defport(port) -- set default port and return previous value";
 
@@ -974,7 +974,7 @@
 }
 #endif /* DEFAULT_VARS */
 
-/* cast a string with a text representation of an array to a list */
+/* Cast a string with a text representation of an array to a list. */
 static char pg_cast_array__doc__[] =
 "cast_array(string, cast=None, delim=',') -- cast a string as an array";
 
@@ -1031,7 +1031,7 @@
     return ret;
 }
 
-/* cast a string with a text representation of a record to a tuple */
+/* Cast a string with a text representation of a record to a tuple. */
 static char pg_cast_record__doc__[] =
 "cast_record(string, cast=None, delim=',') -- cast a string as a record";
 
@@ -1095,7 +1095,7 @@
     return ret;
 }
 
-/* cast a string with a text representation of an hstore to a dict */
+/* Cast a string with a text representation of an hstore to a dict. */
 static char pg_cast_hstore__doc__[] =
 "cast_hstore(string) -- cast a string as an hstore";
 
@@ -1131,7 +1131,7 @@
     return ret;
 }
 
-/* List of functions defined in the module */
+/* The list of functions defined in the module */
 
 static struct PyMethodDef pg_methods[] = {
     {"connect", (PyCFunction) pg_connect,
@@ -1300,13 +1300,13 @@
     PyDict_SetItemString(dict, "__version__", s);
     Py_DECREF(s);
 
-    /* results type for queries */
+    /* Result types for queries */
     PyDict_SetItemString(dict, "RESULT_EMPTY", PyInt_FromLong(RESULT_EMPTY));
     PyDict_SetItemString(dict, "RESULT_DML", PyInt_FromLong(RESULT_DML));
     PyDict_SetItemString(dict, "RESULT_DDL", PyInt_FromLong(RESULT_DDL));
     PyDict_SetItemString(dict, "RESULT_DQL", PyInt_FromLong(RESULT_DQL));
 
-    /* transaction states */
+    /* Transaction states */
     PyDict_SetItemString(dict,"TRANS_IDLE",PyInt_FromLong(PQTRANS_IDLE));
     PyDict_SetItemString(dict,"TRANS_ACTIVE",PyInt_FromLong(PQTRANS_ACTIVE));
     PyDict_SetItemString(dict,"TRANS_INTRANS",PyInt_FromLong(PQTRANS_INTRANS));
@@ -1314,11 +1314,11 @@
     PyDict_SetItemString(dict,"TRANS_UNKNOWN",PyInt_FromLong(PQTRANS_UNKNOWN));
 
 #ifdef LARGE_OBJECTS
-    /* create mode for large objects */
+    /* Create mode for large objects */
     PyDict_SetItemString(dict, "INV_READ", PyInt_FromLong(INV_READ));
     PyDict_SetItemString(dict, "INV_WRITE", PyInt_FromLong(INV_WRITE));
 
-    /* position flags for lo_lseek */
+    /* Position flags for lo_lseek */
     PyDict_SetItemString(dict, "SEEK_SET", PyInt_FromLong(SEEK_SET));
     PyDict_SetItemString(dict, "SEEK_CUR", PyInt_FromLong(SEEK_CUR));
     PyDict_SetItemString(dict, "SEEK_END", PyInt_FromLong(SEEK_END));
@@ -1325,7 +1325,7 @@
 #endif /* LARGE_OBJECTS */
 
 #ifdef DEFAULT_VARS
-    /* prepares default values */
+    /* Prepare default values */
     Py_INCREF(Py_None);
     pg_default_host = Py_None;
     Py_INCREF(Py_None);
@@ -1340,7 +1340,7 @@
     pg_default_passwd = Py_None;
 #endif /* DEFAULT_VARS */
 
-    /* store common pg encoding ids */
+    /* Store common pg encoding ids */
 
     pg_encoding_utf8 = pg_char_to_encoding("UTF8");
     pg_encoding_latin1 = pg_char_to_encoding("LATIN1");

Modified: trunk/query.c (990 => 991)


--- trunk/query.c	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/query.c	2019-04-24 19:46:20 UTC (rev 991)
@@ -1,5 +1,5 @@
 /*
- * $Id: conn.c 985 2019-04-22 22:07:43Z cito $
+ * $Id: query.c 985 2019-04-22 22:07:43Z cito $
  *
  * PyGreSQL - a Python interface for the PostgreSQL database.
  *
@@ -11,7 +11,7 @@
  *
  */
 
-/* Deallocate query object */
+/* Deallocate the query object. */
 static void
 query_dealloc(queryObject *self)
 {
@@ -26,7 +26,7 @@
     PyObject_Del(self);
 }
 
-/* Return query as string in human readable form */
+/* Return query as string in human readable form. */
 static PyObject *
 query_str(queryObject *self)
 {
@@ -126,8 +126,8 @@
     return _query_row_as_tuple(q);
 }
 
-/* The __iter__() method of the queryObject.
-   This returns the default iterator yielding rows as tuples. */
+/* __iter__() method of the queryObject:
+   Returns the default iterator yielding rows as tuples. */
 static PyObject* query_iter(queryObject *self)
 {
     self->current_row = 0;
@@ -135,7 +135,7 @@
     return (PyObject*) self;
 }
 
-/* The __next__() method of the queryObject.
+/* __next__() method of the queryObject:
    Returns the current current row as a tuple and moves to the next one. */
 static PyObject *
 query_next(queryObject *self, PyObject *noargs)
@@ -152,7 +152,7 @@
     return row_tuple;
 }
 
-/* get number of rows */
+/* Get number of rows. */
 static char query_ntuples__doc__[] =
 "ntuples() -- return number of tuples returned by query";
 
@@ -162,7 +162,7 @@
     return PyInt_FromLong(self->max_row);
 }
 
-/* list fields names from query result */
+/* List field names from query result. */
 static char query_listfields__doc__[] =
 "listfields() -- List field names from result";
 
@@ -185,7 +185,7 @@
     return fieldstuple;
 }
 
-/* get field name from last result */
+/* Get field name from number in last result. */
 static char query_fieldname__doc__[] =
 "fieldname(num) -- return name of field from result from its position";
 
@@ -213,7 +213,7 @@
     return PyStr_FromString(name);
 }
 
-/* gets fields number from name in last result */
+/* Get field number from name in last result. */
 static char query_fieldnum__doc__[] =
 "fieldnum(name) -- return position in query for field from its name";
 
@@ -239,7 +239,7 @@
     return PyInt_FromLong(num);
 }
 
-/* Retrieves one row from the result as a tuple. */
+/* Retrieve one row from the result as a tuple. */
 static char query_one__doc__[] =
 "one() -- Get one row from the result of a query\n\n"
 "Only one row from the result is returned as a tuple of fields.\n"
@@ -260,7 +260,7 @@
     return row_tuple;
 }
 
-/* Retrieves the single row from the result as a tuple. */
+/* Retrieve the single row from the result as a tuple. */
 static char query_single__doc__[] =
 "single() -- Get the result of a query as single row\n\n"
 "The single row from the query result is returned as a tuple of fields.\n"
@@ -287,7 +287,7 @@
     return row_tuple;
 }
 
-/* Retrieves the last query result as a list of tuples. */
+/* Retrieve the last query result as a list of tuples. */
 static char query_getresult__doc__[] =
 "getresult() -- Get the result of a query\n\n"
 "The result is returned as a list of rows, each one a tuple of fields\n"
@@ -657,7 +657,7 @@
     return value;
 }
 
-/* query sequence protocol methods */
+/* Query sequence protocol methods */
 static PySequenceMethods query_sequence_methods = {
     (lenfunc) query_len,           /* sq_length */
     0,                             /* sq_concat */
@@ -669,7 +669,7 @@
     0,                             /* sq_inplace_repeat */
 };
 
-/* query object methods */
+/* Query object methods */
 static struct PyMethodDef query_methods[] = {
     {"getresult", (PyCFunction) query_getresult,
         METH_NOARGS, query_getresult__doc__},
@@ -714,7 +714,7 @@
 
 static char query__doc__[] = "PyGreSQL query object";
 
-/* query type definition */
+/* Query type definition */
 static PyTypeObject queryType = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "pg.Query",                  /* tp_name */

Modified: trunk/setup.py (990 => 991)


--- trunk/setup.py	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/setup.py	2019-04-24 19:46:20 UTC (rev 991)
@@ -117,10 +117,13 @@
         ('default-vars', None,
             "enable default variables use"),
         ('escaping-funcs', None,
-            "enable string escaping functions")]
+            "enable string escaping functions"),
+        ('ssl-info', None,
+            "use new ssl info functions")]
 
     boolean_options = build_ext.boolean_options + [
-        'direct-access', 'large-objects', 'default-vars', 'escaping-funcs']
+        'direct-access', 'large-objects', 'default-vars',
+        'escaping-funcs', 'ssl-info']
 
     def get_compiler(self):
         """Return the C compiler used for building the extension."""
@@ -131,7 +134,8 @@
         self.direct_access = True
         self.large_objects = True
         self.default_vars = True
-        self.escaping_funcs = pg_version[0] >= 9
+        self.escaping_funcs = pg_version >= (9, 0)
+        self.ssl_info = pg_version >= (9, 5)
         if pg_version < (9, 0):
             warnings.warn("PygreSQL does not support this PostgreSQL version.")
 
@@ -144,8 +148,10 @@
             define_macros.append(('LARGE_OBJECTS', None))
         if self.default_vars:
             define_macros.append(('DEFAULT_VARS', None))
-        if self.escaping_funcs and pg_version[0] >= 9:
+        if self.escaping_funcs and pg_version >= (9, 0):
             define_macros.append(('ESCAPING_FUNCS', None))
+        if self.ssl_info and pg_version >= (9, 5):
+            define_macros.append(('SSL_INFO', None))
         if sys.platform == 'win32':
             bits = platform.architecture()[0]
             if bits == '64bit':  # we need to find libpq64

Modified: trunk/source.c (990 => 991)


--- trunk/source.c	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/source.c	2019-04-24 19:46:20 UTC (rev 991)
@@ -1,5 +1,5 @@
 /*
- * $Id: conn.c 985 2019-04-22 22:07:43Z cito $
+ * $Id: source.c 985 2019-04-22 22:07:43Z cito $
  *
  * PyGreSQL - a Python interface for the PostgreSQL database.
  *
@@ -11,7 +11,7 @@
  *
  */
 
-/* Deallocate source object */
+/* Deallocate source object. */
 static void
 source_dealloc(sourceObject *self)
 {
@@ -22,7 +22,7 @@
     PyObject_Del(self);
 }
 
-/* return source object as string in human readable form */
+/* Return source object as string in human readable form. */
 static PyObject *
 source_str(sourceObject *self)
 {
@@ -38,7 +38,7 @@
     }
 }
 
-/* check source object validity */
+/* Check source object validity. */
 static int
 _check_source_obj(sourceObject *self, int level)
 {
@@ -64,7 +64,7 @@
     return 1;
 }
 
-/* get source object attributes */
+/* Get source object attributes. */
 static PyObject *
 source_getattr(sourceObject *self, PyObject *nameobj)
 {
@@ -100,7 +100,7 @@
     return PyObject_GenericGetAttr((PyObject *) self, nameobj);
 }
 
-/* set source object attributes */
+/* Set source object attributes. */
 static int
 source_setattr(sourceObject *self, char *name, PyObject *v)
 {
@@ -120,7 +120,7 @@
     return -1;
 }
 
-/* close object */
+/* Close object. */
 static char source_close__doc__[] =
 "close() -- close query object without deleting it\n\n"
 "All instances of the query object can no longer be used after this call.\n";
@@ -142,7 +142,7 @@
     return Py_None;
 }
 
-/* database query */
+/* Database query. */
 static char source_execute__doc__[] =
 "execute(sql) -- execute a SQL statement (string)\n\n"
 "On success, this call returns the number of affected rows, or None\n"
@@ -255,7 +255,7 @@
     return NULL;
 }
 
-/* gets oid status for last query (valid for INSERTs, 0 for other) */
+/* Get oid status for last query (valid for INSERTs, 0 for other). */
 static char source_oidstatus__doc__[] =
 "oidstatus() -- return oid of last inserted row (if available)";
 
@@ -278,7 +278,7 @@
     return PyInt_FromLong(oid);
 }
 
-/* fetches rows from last result */
+/* Fetch rows from last result. */
 static char source_fetch__doc__[] =
 "fetch(num) -- return the next num rows from the last result in a list\n\n"
 "If num parameter is omitted arraysize attribute value is used.\n"
@@ -362,7 +362,7 @@
     return res_list;
 }
 
-/* changes current row (internal wrapper for all "move" methods) */
+/* Change current row (internal wrapper for all "move" methods). */
 static PyObject *
 _source_move(sourceObject *self, int move)
 {
@@ -393,7 +393,7 @@
     return Py_None;
 }
 
-/* move to first result row */
+/* Move to first result row. */
 static char source_movefirst__doc__[] =
 "movefirst() -- move to first result row";
 
@@ -403,7 +403,7 @@
     return _source_move(self, QUERY_MOVEFIRST);
 }
 
-/* move to last result row */
+/* Move to last result row. */
 static char source_movelast__doc__[] =
 "movelast() -- move to last valid result row";
 
@@ -413,7 +413,7 @@
     return _source_move(self, QUERY_MOVELAST);
 }
 
-/* move to next result row */
+/* Move to next result row. */
 static char source_movenext__doc__[] =
 "movenext() -- move to next result row";
 
@@ -423,7 +423,7 @@
     return _source_move(self, QUERY_MOVENEXT);
 }
 
-/* move to previous result row */
+/* Move to previous result row. */
 static char source_moveprev__doc__[] =
 "moveprev() -- move to previous result row";
 
@@ -433,7 +433,7 @@
     return _source_move(self, QUERY_MOVEPREV);
 }
 
-/* put copy data */
+/* Put copy data. */
 static char source_putdata__doc__[] =
 "putdata(buffer) -- send data to server during copy from stdin";
 
@@ -550,7 +550,7 @@
     return ret; /* None or number of rows */
 }
 
-/* get copy data */
+/* Get copy data. */
 static char source_getdata__doc__[] =
 "getdata(decode) -- receive data to server during copy to stdout";
 
@@ -626,7 +626,7 @@
     return ret; /* buffer or number of rows */
 }
 
-/* finds field number from string/integer (internal use only) */
+/* Find field number from string/integer (internal use only). */
 static int
 _source_fieldindex(sourceObject *self, PyObject *param, const char *usage)
 {
@@ -657,7 +657,7 @@
     return num;
 }
 
-/* builds field information from position (internal use only) */
+/* Build field information from position (internal use only). */
 static PyObject *
 _source_buildinfo(sourceObject *self, int num)
 {
@@ -683,7 +683,7 @@
     return result;
 }
 
-/* lists fields info */
+/* Lists fields info. */
 static char source_listinfo__doc__[] =
 "listinfo() -- get information for all fields (position, name, type oid)";
 
@@ -716,7 +716,7 @@
     return result;
 };
 
-/* list fields information for last result */
+/* List fields information for last result. */
 static char source_fieldinfo__doc__[] =
 "fieldinfo(desc) -- get specified field info (position, name, type oid)";
 
@@ -737,7 +737,7 @@
     return _source_buildinfo(self, num);
 };
 
-/* retrieve field value */
+/* Retrieve field value. */
 static char source_field__doc__[] =
 "field(desc) -- return specified field value";
 
@@ -758,7 +758,7 @@
         PQgetvalue(self->result, self->current_row, num));
 }
 
-/* get the list of source object attributes */
+/* Get the list of source object attributes. */
 static PyObject *
 source_dir(connObject *self, PyObject *noargs)
 {
@@ -772,7 +772,7 @@
     return attrs;
 }
 
-/* source object methods */
+/* Source object methods */
 static PyMethodDef source_methods[] = {
     {"__dir__", (PyCFunction) source_dir, METH_NOARGS, NULL},
 
@@ -807,7 +807,7 @@
 
 static char source__doc__[] = "PyGreSQL source object";
 
-/* source type definition */
+/* Source type definition */
 static PyTypeObject sourceType = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "pgdb.Source",                  /* tp_name */

Modified: trunk/tests/test_classic_connection.py (990 => 991)


--- trunk/tests/test_classic_connection.py	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/tests/test_classic_connection.py	2019-04-24 19:46:20 UTC (rev 991)
@@ -114,8 +114,9 @@
         self.assertTrue(r.startswith('<pg.Connection object'), r)
 
     def testAllConnectAttributes(self):
-        attributes = '''db error host options port
-            protocol_version server_version status user'''.split()
+        attributes = '''backend_pid db error host options port
+            protocol_version server_version socket
+            ssl_attributes ssl_in_use status user'''.split()
         connection_attributes = [a for a in dir(self.connection)
             if not a.startswith('__') and not self.is_method(a)]
         self.assertEqual(attributes, connection_attributes)
@@ -168,6 +169,28 @@
         self.assertIsInstance(server_version, int)
         self.assertTrue(90000 <= server_version < 120000)
 
+    def testAttributeSocket(self):
+        socket = self.connection.socket
+        self.assertIsInstance(socket, int)
+        self.assertGreaterEqual(socket, 0)
+
+    def testAttributeBackendPid(self):
+        backend_pid = self.connection.backend_pid
+        self.assertIsInstance(backend_pid, int)
+        self.assertGreaterEqual(backend_pid, 1)
+
+    def testAttributeSslInUse(self):
+        ssl_in_use = self.connection.ssl_in_use
+        self.assertIsInstance(ssl_in_use, bool)
+        self.assertFalse(ssl_in_use)
+
+    def testAttributeSslAttributes(self):
+        ssl_attributes = self.connection.ssl_attributes
+        self.assertIsInstance(ssl_attributes, dict)
+        self.assertEqual(ssl_attributes, {
+            'cipher': None, 'compression': None, 'key_bits': None,
+            'library': None, 'protocol': None})
+
     def testAttributeStatus(self):
         status_ok = 1
         self.assertIsInstance(self.connection.status, int)

Modified: trunk/tests/test_classic_dbwrapper.py (990 => 991)


--- trunk/tests/test_classic_dbwrapper.py	2019-04-24 15:59:03 UTC (rev 990)
+++ trunk/tests/test_classic_dbwrapper.py	2019-04-24 19:46:20 UTC (rev 991)
@@ -194,7 +194,7 @@
     def testAllDBAttributes(self):
         attributes = [
             'abort', 'adapter',
-            'begin',
+            'backend_pid', 'begin',
             'cancel', 'clear', 'close', 'commit',
             'date_format', 'db', 'dbname', 'dbtypes',
             'debug', 'decode_json', 'delete',
@@ -219,8 +219,9 @@
             'release', 'reopen', 'reset', 'rollback',
             'savepoint', 'server_version',
             'set_cast_hook', 'set_notice_receiver',
-            'set_parameter',
-            'source', 'start', 'status',
+            'set_parameter', 'socket', 'source',
+            'ssl_attributes', 'ssl_in_use',
+            'start', 'status',
             'transaction', 'truncate',
             'unescape_bytea', 'update', 'upsert',
             'use_regtypes', 'user',
@@ -278,6 +279,28 @@
         self.assertTrue(90000 <= server_version < 120000)
         self.assertEqual(server_version, self.db.db.server_version)
 
+    def testAttributeSocket(self):
+        socket = self.db.socket
+        self.assertIsInstance(socket, int)
+        self.assertGreaterEqual(socket, 0)
+
+    def testAttributeBackendPid(self):
+        backend_pid = self.db.backend_pid
+        self.assertIsInstance(backend_pid, int)
+        self.assertGreaterEqual(backend_pid, 1)
+
+    def testAttributeSslInUse(self):
+        ssl_in_use = self.db.ssl_in_use
+        self.assertIsInstance(ssl_in_use, bool)
+        self.assertFalse(ssl_in_use)
+
+    def testAttributeSslAttributes(self):
+        ssl_attributes = self.db.ssl_attributes
+        self.assertIsInstance(ssl_attributes, dict)
+        self.assertEqual(ssl_attributes, {
+            'cipher': None, 'compression': None, 'key_bits': None,
+            'library': None, 'protocol': None})
+
     def testAttributeStatus(self):
         status_ok = 1
         status = self.db.status
_______________________________________________
PyGreSQL mailing list
PyGreSQL@Vex.Net
https://mail.vex.net/mailman/listinfo/pygresql

Reply via email to