Changeset 991


Ignore:
Timestamp:
Apr 24, 2019, 3:46:20 PM (5 months ago)
Author:
cito
Message:

Add some more attributes to the connection object

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/conn.c

    r987 r991  
    1212 */
    1313
    14 /* Deallocate connection object */
     14/* Deallocate connection object. */
    1515static void
    1616conn_dealloc(connObject *self)
     
    2626}
    2727
    28 /* get connection attributes */
     28/* Get connection attributes. */
    2929static PyObject *
    3030conn_getattr(connObject *self, PyObject *nameobj)
     
    8686        return PyInt_FromLong(PQserverVersion(self->cnx));
    8787
     88    /* descriptor number of connection socket */
     89    if (!strcmp(name, "socket")) {
     90        return PyInt_FromLong(PQsocket(self->cnx));
     91    }
     92
     93    /* PID of backend process */
     94    if (!strcmp(name, "backend_pid")) {
     95        return PyInt_FromLong(PQbackendPID(self->cnx));
     96    }
     97
     98    /* whether the connection uses SSL */
     99    if (!strcmp(name, "ssl_in_use")) {
     100#ifdef SSL_INFO
     101        if (PQsslInUse(self->cnx)) {
     102            Py_INCREF(Py_True); return Py_True;
     103        }
     104        else {
     105            Py_INCREF(Py_False); return Py_False;
     106        }
     107#else
     108        set_error_msg(NotSupportedError, "SSL info functions not supported");
     109        return NULL;
     110#endif
     111    }
     112
     113    /* SSL attributes */
     114    if (!strcmp(name, "ssl_attributes")) {
     115#ifdef SSL_INFO
     116        return get_ssl_attributes(self->cnx);
     117#else
     118        set_error_msg(NotSupportedError, "SSL info functions not supported");
     119        return NULL;
     120#endif
     121    }
     122
    88123    return PyObject_GenericGetAttr((PyObject *) self, nameobj);
    89124}
    90125
    91 /* Check connection validity */
     126/* Check connection validity. */
    92127static int
    93128_check_cnx_obj(connObject *self)
     
    100135}
    101136
    102 /* source creation */
     137/* Create source object. */
    103138static char conn_source__doc__[] =
    104139"source() -- create a new source object for this connection";
     
    129164}
    130165
    131 /* base method for execution of both unprepared and prepared queries */
     166/* Base method for execution of both unprepared and prepared queries */
    132167static PyObject *
    133168_conn_query(connObject *self, PyObject *args, int prepared)
     
    351386}
    352387
    353 /* database query */
     388/* Database query */
    354389static char conn_query__doc__[] =
    355390"query(sql, [arg]) -- create a new query object for this connection\n\n"
     
    363398}
    364399
    365 /* execute prepared statement */
     400/* Execute prepared statement. */
    366401static char conn_query_prepared__doc__[] =
    367402"query_prepared(name, [arg]) -- execute a prepared statement\n\n"
     
    375410}
    376411
    377 /* create prepared statement */
     412/* Create prepared statement. */
    378413static char conn_prepare__doc__[] =
    379414"prepare(name, sql) -- create a prepared statement\n\n"
     
    418453}
    419454
    420 /* describe prepared statement */
     455/* Describe prepared statement. */
    421456static char conn_describe_prepared__doc__[] =
    422457"describe_prepared(name) -- describe a prepared statement\n\n"
     
    471506"putline(line) -- send a line directly to the backend";
    472507
    473 /* direct access function: putline */
     508/* Direct access function: putline. */
    474509static PyObject *
    475510conn_putline(connObject *self, PyObject *args)
     
    499534}
    500535
    501 /* direct access function: getline */
     536/* Direct access function: getline. */
    502537static char conn_getline__doc__[] =
    503538"getline() -- get a line directly from the backend";
     
    532567}
    533568
    534 /* direct access function: end copy */
     569/* Direct access function: end copy. */
    535570static char conn_endcopy__doc__[] =
    536571"endcopy() -- synchronize client and server";
     
    555590
    556591
    557 /* insert table */
     592/* Insert table */
    558593static char conn_inserttable__doc__[] =
    559594"inserttable(table, data) -- insert list into table\n\n"
     
    766801}
    767802
    768 /* get transaction state */
     803/* Get transaction state. */
    769804static char conn_transaction__doc__[] =
    770805"transaction() -- return the current transaction status";
     
    781816}
    782817
    783 /* get parameter setting */
     818/* Get parameter setting. */
    784819static char conn_parameter__doc__[] =
    785820"parameter(name) -- look up a current parameter setting";
     
    812847}
    813848
    814 /* get current date format */
     849/* Get current date format. */
    815850static char conn_date_format__doc__[] =
    816851"date_format() -- return the current date format";
     
    838873#ifdef ESCAPING_FUNCS
    839874
    840 /* escape literal */
     875/* Escape literal */
    841876static char conn_escape_literal__doc__[] =
    842877"escape_literal(str) -- escape a literal constant for use within SQL";
     
    883918}
    884919
    885 /* escape identifier */
     920/* Escape identifier */
    886921static char conn_escape_identifier__doc__[] =
    887922"escape_identifier(str) -- escape an identifier for use within SQL";
     
    930965#endif /* ESCAPING_FUNCS */
    931966
    932 /* escape string */
     967/* Escape string */
    933968static char conn_escape_string__doc__[] =
    934969"escape_string(str) -- escape a string for use within SQL";
     
    9801015}
    9811016
    982 /* escape bytea */
     1017/* Escape bytea */
    9831018static char conn_escape_bytea__doc__[] =
    9841019"escape_bytea(data) -- escape binary data for use within SQL as type bytea";
     
    10271062#ifdef LARGE_OBJECTS
    10281063
    1029 /* constructor for large objects (internal use only) */
     1064/* Constructor for large objects (internal use only) */
    10301065static largeObject *
    10311066large_new(connObject *pgcnx, Oid oid)
     
    10451080}
    10461081
    1047 /* creates large object */
     1082/* Create large object. */
    10481083static char conn_locreate__doc__[] =
    10491084"locreate(mode) -- create a new large object in the database";
     
    10771112}
    10781113
    1079 /* init from already known oid */
     1114/* Init from already known oid. */
    10801115static char conn_getlo__doc__[] =
    10811116"getlo(oid) -- create a large object instance for the specified oid";
     
    11091144}
    11101145
    1111 /* import unix file */
     1146/* Import unix file. */
    11121147static char conn_loimport__doc__[] =
    11131148"loimport(name) -- create a new large object from specified file";
     
    11431178#endif /* LARGE_OBJECTS */
    11441179
    1145 /* resets connection */
     1180/* Reset connection. */
    11461181static char conn_reset__doc__[] =
    11471182"reset() -- reset connection with current parameters\n\n"
     
    11631198}
    11641199
    1165 /* cancels current command */
     1200/* Cancel current command. */
    11661201static char conn_cancel__doc__[] =
    11671202"cancel() -- abandon processing of the current command";
     
    11791214}
    11801215
    1181 /* get connection socket */
     1216/* Get connection socket. */
    11821217static char conn_fileno__doc__[] =
    11831218"fileno() -- return database connection socket file handle";
     
    11981233}
    11991234
    1200 /* set external typecast callback function */
     1235/* Set external typecast callback function. */
    12011236static char conn_set_cast_hook__doc__[] =
    12021237"set_cast_hook(func) -- set a fallback typecast function";
     
    12261261}
    12271262
    1228 /* get notice receiver callback function */
     1263/* Get notice receiver callback function. */
    12291264static char conn_get_cast_hook__doc__[] =
    12301265"get_cast_hook() -- get the fallback typecast function";
     
    12421277}
    12431278
    1244 /* set notice receiver callback function */
     1279/* Set notice receiver callback function. */
    12451280static char conn_set_notice_receiver__doc__[] =
    12461281"set_notice_receiver(func) -- set the current notice receiver";
     
    12711306}
    12721307
    1273 /* get notice receiver callback function */
     1308/* Get notice receiver callback function. */
    12741309static char conn_get_notice_receiver__doc__[] =
    12751310"get_notice_receiver() -- get the current notice receiver";
     
    12871322}
    12881323
    1289 /* close without deleting */
     1324/* Close without deleting. */
    12901325static char conn_close__doc__[] =
    12911326"close() -- close connection\n\n"
     
    13111346}
    13121347
    1313 /* gets asynchronous notify */
     1348/* Get asynchronous notify. */
    13141349static char conn_get_notify__doc__[] =
    13151350"getnotify() -- get database notify for this connection";
     
    13661401}
    13671402
    1368 /* get the list of connection attributes */
     1403/* Get the list of connection attributes. */
    13691404static PyObject *
    13701405conn_dir(connObject *self, PyObject *noargs)
     
    13741409    attrs = PyObject_Dir(PyObject_Type((PyObject *) self));
    13751410    PyObject_CallMethod(
    1376         attrs, "extend", "[sssssssss]",
     1411        attrs, "extend", "[sssssssssssss]",
    13771412        "host", "port", "db", "options", "error", "status", "user",
    1378         "protocol_version", "server_version");
     1413        "protocol_version", "server_version", "socket", "backend_pid",
     1414        "ssl_in_use", "ssl_attributes");
    13791415
    13801416    return attrs;
    13811417}
    13821418
    1383 /* connection object methods */
     1419/* Connection object methods */
    13841420static struct PyMethodDef conn_methods[] = {
    13851421    {"__dir__", (PyCFunction) conn_dir,  METH_NOARGS, NULL},
     
    14561492static char conn__doc__[] = "PostgreSQL connection object";
    14571493
    1458 /* connection type definition */
     1494/* Connection type definition */
    14591495static PyTypeObject connType = {
    14601496    PyVarObject_HEAD_INIT(NULL, 0)
  • trunk/docs/contents/changelog.rst

    r980 r991  
    3030      implementation with pg.set_query_helps(), but this is not recommended
    3131      and this function is not part of the official API.
     32    - Added new connection attributes `socket`, `backend_pid`, `ssl_in_use`
     33      and `ssl_attributes` (the latter need PostgreSQL >= 9.5 on the client).
    3234
    3335Vesion 5.0.7 (2019-mm-dd)
  • trunk/docs/contents/pg/connection.rst

    r978 r991  
    558558
    559559    the last warning/error message from the server (str)
     560
     561.. attribute:: Connection.socket
     562
     563    the file descriptor number of the connection socket to the server (int)
     564
     565.. versionadded:: 5.1
     566
     567.. attribute:: Connection.backend_pid
     568
     569     the PID of the backend process handling this connection (int)
     570
     571.. versionadded:: 5.1
     572
     573.. attribute:: Connection.ssl_in_use
     574
     575     this is True if the connection uses SSL, False if not
     576
     577.. versionadded:: 5.1 (needs PostgreSQL >= 9.5)
     578
     579.. attribute:: Connection.ssl_attributes
     580
     581     SSL-related information about the connection (dict)
     582
     583.. versionadded:: 5.1 (needs PostgreSQL >= 9.5)
  • trunk/internal.c

    r987 r991  
    11/*
    2  * $Id: conn.c 985 2019-04-22 22:07:43Z cito $
     2 * $Id: internal.c 985 2019-04-22 22:07:43Z cito $
    33 *
    44 * PyGreSQL - a Python interface for the PostgreSQL database.
     
    1414/* PyGreSQL internal types */
    1515
    16 /* simple types */
     16/* Simple types */
    1717#define PYGRES_INT 1
    1818#define PYGRES_LONG 2
     
    2121#define PYGRES_MONEY 5
    2222#define PYGRES_BOOL 6
    23 /* text based types */
     23/* Text based types */
    2424#define PYGRES_TEXT 8
    2525#define PYGRES_BYTEA 9
    2626#define PYGRES_JSON 10
    2727#define PYGRES_OTHER 11
    28 /* array types */
     28/* Array types */
    2929#define PYGRES_ARRAY 16
    3030
    31 /* shared function for encoding and decoding strings */
     31/* Shared functions for encoding and decoding strings */
    3232
    3333static PyObject *
     
    5959}
    6060
    61 /* helper functions */
    62 
    63 /* get PyGreSQL internal types for a PostgreSQL type */
     61/* Helper functions */
     62
     63/* Get PyGreSQL internal types for a PostgreSQL type. */
    6464static int
    6565get_type(Oid pgtype)
     
    176176}
    177177
    178 /* get PyGreSQL column types for all result columns */
     178/* Get PyGreSQL column types for all result columns. */
    179179static int *
    180180get_col_types(PGresult *result, int nfields)
     
    445445}
    446446
    447 /* quick case insensitive check if given sized string is null */
     447/* Quick case insensitive check if given sized string is null. */
    448448#define STR_IS_NULL(s, n) (n == 4 && \
    449449    (s[0] == 'n' || s[0] == 'N') && \
     
    680680   The parameter delim can specify a delimiter for the elements,
    681681   although composite types always use a comma as delimiter. */
    682 
    683682static PyObject *
    684683cast_record(char *s, Py_ssize_t size, int encoding,
     
    841840/* Cast string s with size and encoding to a Python dictionary.
    842841   using the input and output syntax for hstore values. */
    843 
    844842static PyObject *
    845843cast_hstore(char *s, Py_ssize_t size, int encoding)
     
    998996}
    999997
    1000 /* gets appropriate error type from sqlstate */
     998/* Get appropriate error type from sqlstate. */
    1001999static PyObject *
    10021000get_error_type(const char *sqlstate)
     
    10641062}
    10651063
    1066 /* sets database error message and sqlstate attribute */
     1064/* Set database error message and sqlstate attribute. */
    10671065static void
    10681066set_error_msg_and_state(PyObject *type,
     
    11001098}
    11011099
    1102 /* sets given database error message */
     1100/* Set given database error message. */
    11031101static void
    11041102set_error_msg(PyObject *type, const char *msg)
     
    11071105}
    11081106
    1109 /* sets database error from connection and/or result */
     1107/* Set database error from connection and/or result. */
    11101108static void
    11111109set_error(PyObject *type, const char * msg, PGconn *cnx, PGresult *result)
     
    11291127}
    11301128
    1131 /* format result (mostly useful for debugging) */
    1132 /* Note: This is similar to the Postgres function PQprint().
    1133  * PQprint() is not used because handing over a stream from Python to
    1134  * Postgres can be problematic if they use different libs for streams
    1135  * and because using PQprint() and tp_print is not recommended any more.
    1136  */
     1129#ifdef SSL_INFO
     1130
     1131/* Get SSL attributes and values as a dictionary. */
     1132static PyObject *
     1133get_ssl_attributes(PGconn *cnx) {
     1134    PyObject *attr_dict = NULL;
     1135
     1136    if (!(attr_dict = PyDict_New())) {
     1137        return NULL;
     1138    }
     1139
     1140    for (const char * const *s = PQsslAttributeNames(cnx); *s; ++s) {
     1141        const char *val = PQsslAttribute(cnx, *s);
     1142
     1143        if (val) {
     1144            PyObject * val_obj = PyStr_FromString(val);
     1145
     1146            PyDict_SetItemString(attr_dict, *s, val_obj);
     1147            Py_DECREF(val_obj);
     1148        }
     1149        else {
     1150            PyDict_SetItemString(attr_dict, *s, Py_None);
     1151        }
     1152    }
     1153
     1154    return attr_dict;
     1155}
     1156
     1157#endif /* SSL_INFO */
     1158
     1159/* Format result (mostly useful for debugging).
     1160   Note: This is similar to the Postgres function PQprint().
     1161   PQprint() is not used because handing over a stream from Python to
     1162   PostgreSQL can be problematic if they use different libs for streams
     1163   and because using PQprint() and tp_print is not recommended any more. */
    11371164static PyObject *
    11381165format_result(const PGresult *res)
     
    12701297}
    12711298
    1272 /* internal function converting a Postgres datestyles to date formats */
     1299/* Internal function converting a Postgres datestyles to date formats. */
    12731300static const char *
    12741301date_style_to_format(const char *s)
     
    13001327}
    13011328
    1302 /* internal function converting a date format to a Postgres datestyle */
     1329/* Internal function converting a date format to a Postgres datestyle. */
    13031330static const char *
    13041331date_format_to_style(const char *s)
     
    13361363}
    13371364
    1338 /* internal wrapper for the notice receiver callback */
     1365/* Internal wrapper for the notice receiver callback. */
    13391366static void
    13401367notice_receiver(void *arg, const PGresult *res)
  • trunk/large.c

    r987 r991  
    11/*
    2  * $Id: conn.c 985 2019-04-22 22:07:43Z cito $
     2 * $Id: large.c 985 2019-04-22 22:07:43Z cito $
    33 *
    44 * PyGreSQL - a Python interface for the PostgreSQL database.
     
    1212 */
    1313
    14 /* Deallocate large object */
     14/* Deallocate large object. */
    1515static void
    1616large_dealloc(largeObject *self)
     
    2323}
    2424
    25 /* Return large object as string in human readable form */
     25/* Return large object as string in human readable form. */
    2626static PyObject *
    2727large_str(largeObject *self)
     
    3434}
    3535
    36 /* Check validity of large object */
     36/* Check validity of large object. */
    3737static int
    3838_check_lo_obj(largeObject *self, int level)
     
    6363}
    6464
    65 /* Get large object attributes */
     65/* Get large object attributes. */
    6666static PyObject *
    6767large_getattr(largeObject *self, PyObject *nameobj)
     
    9999}
    100100
    101 /* Get the list of large object attributes */
     101/* Get the list of large object attributes. */
    102102static PyObject *
    103103large_dir(largeObject *self, PyObject *noargs)
     
    112112}
    113113
    114 /* Open large object */
     114/* Open large object. */
    115115static char large_open__doc__[] =
    116116"open(mode) -- open access to large object with specified mode\n\n"
     
    146146}
    147147
    148 /* Close large object */
     148/* Close large object. */
    149149static char large_close__doc__[] =
    150150"close() -- close access to large object data";
     
    170170}
    171171
    172 /* Read from large object */
     172/* Read from large object. */
    173173static char large_read__doc__[] =
    174174"read(size) -- read from large object to sized string\n\n"
     
    215215}
    216216
    217 /* Write to large object */
     217/* Write to large object. */
    218218static char large_write__doc__[] =
    219219"write(string) -- write sized string to large object\n\n"
     
    251251}
    252252
    253 /* Go to position in large object */
     253/* Go to position in large object. */
    254254static char large_seek__doc__[] =
    255255"seek(offset, whence) -- move to specified position\n\n"
     
    287287}
    288288
    289 /* Get large object size */
     289/* Get large object size. */
    290290static char large_size__doc__[] =
    291291"size() -- return large object size\n\n"
     
    327327}
    328328
    329 /* Get large object cursor position */
     329/* Get large object cursor position. */
    330330static char large_tell__doc__[] =
    331331"tell() -- give current position in large object\n\n"
     
    352352}
    353353
    354 /* Export large object as unix file */
     354/* Export large object as unix file. */
    355355static char large_export__doc__[] =
    356356"export(filename) -- export large object data to specified file\n\n"
     
    384384}
    385385
    386 /* Delete a large object */
     386/* Delete a large object. */
    387387static char large_unlink__doc__[] =
    388388"unlink() -- destroy large object\n\n"
     
    408408}
    409409
    410 /* large object methods */
     410/* Large object methods */
    411411static struct PyMethodDef large_methods[] = {
    412412    {"__dir__", (PyCFunction) large_dir,  METH_NOARGS, NULL},
     
    425425static char large__doc__[] = "PostgreSQL large object";
    426426
    427 /* large object type definition */
     427/* Large object type definition */
    428428static PyTypeObject largeType = {
    429429    PyVarObject_HEAD_INIT(NULL, 0)
  • trunk/notice.c

    r987 r991  
    11/*
    2  * $Id: conn.c 985 2019-04-22 22:07:43Z cito $
     2 * $Id: notice.c 985 2019-04-22 22:07:43Z cito $
    33 *
    44 * PyGreSQL - a Python interface for the PostgreSQL database.
     
    1212 */
    1313
    14 /* Get notice object attributes */
     14/* Get notice object attributes. */
    1515static PyObject *
    1616notice_getattr(noticeObject *self, PyObject *nameobj)
     
    6565}
    6666
    67 /* Get the list of notice attributes */
     67/* Get the list of notice attributes. */
    6868static PyObject *
    6969notice_dir(noticeObject *self, PyObject *noargs)
     
    7979}
    8080
    81 /* Return notice as string in human readable form */
     81/* Return notice as string in human readable form. */
    8282static PyObject *
    8383notice_str(noticeObject *self)
     
    8686}
    8787
    88 /* notice object methods */
     88/* Notice object methods */
    8989static struct PyMethodDef notice_methods[] = {
    9090    {"__dir__", (PyCFunction) notice_dir,  METH_NOARGS, NULL},
     
    9494static char notice__doc__[] = "PostgreSQL notice object";
    9595
    96 /* notice type definition */
     96/* Notice type definition */
    9797static PyTypeObject noticeType = {
    9898    PyVarObject_HEAD_INIT(NULL, 0)
  • trunk/pgmodule.c

    r987 r991  
    1919#include <libpq/libpq-fs.h>
    2020
    21 /* the type definitions from <server/catalog/pg_type.h> */
     21/* The type definitions from <server/catalog/pg_type.h> */
    2222#include "pgtypes.h"
    2323
    24 /* macros for single-source Python 2/3 compatibility */
     24/* Macros for single-source Python 2/3 compatibility */
    2525#include "py3c.h"
    2626
     
    3838#endif
    3939
    40 /* default values */
     40/* Default values */
    4141#define PG_ARRAYSIZE 1
    4242
    43 /* flags for object validity checks */
     43/* Flags for object validity checks */
    4444#define CHECK_OPEN   1
    4545#define CHECK_CLOSE  2
     
    4848#define CHECK_DQL   16
    4949
    50 /* query result types */
     50/* Query result types */
    5151#define RESULT_EMPTY 1
    5252#define RESULT_DML   2
     
    5454#define RESULT_DQL   4
    5555
    56 /* flags for move methods */
     56/* Flags for move methods */
    5757#define QUERY_MOVEFIRST 1
    5858#define QUERY_MOVELAST  2
     
    110110*/
    111111
    112 /* forward declarations for types */
     112/* Forward declarations for types */
    113113static PyTypeObject connType, sourceType, queryType, noticeType, largeType;
    114114
    115 /* forward static declarations */
     115/* Forward static declarations */
    116116static void notice_receiver(void *, const PGresult *);
    117117
    118 /* object declarations */
     118/* Object declarations */
    119119
    120120typedef struct
     
    176176#endif /* LARGE_OBJECTS */
    177177
    178 /* internal functions */
     178/* Internal functions */
    179179#include "internal.c"
    180180
    181 /* connection object */
     181/* Connection object */
    182182#include "conn.c"
    183183
    184 /* query object */
     184/* Query object */
    185185#include "query.c"
    186186
    187 /* source object */
     187/* Source object */
    188188#include "source.c"
    189189
    190 /* notice object */
     190/* Notice object */
    191191#include "notice.c"
    192192
    193 /* large objects */
     193/* Large objects */
    194194#ifdef LARGE_OBJECTS
    195195#include "large.c"
     
    198198/* MODULE FUNCTIONS */
    199199
    200 /* connect to a database */
     200/* Connect to a database. */
    201201static char pg_connect__doc__[] =
    202202"connect(dbname, host, port, opt) -- connect to a PostgreSQL database\n\n"
     
    283283}
    284284
    285 /* escape string */
     285/* Escape string */
    286286static char pg_escape_string__doc__[] =
    287287"escape_string(string) -- escape a string for use within SQL";
     
    331331}
    332332
    333 /* escape bytea */
     333/* Escape bytea */
    334334static char pg_escape_bytea__doc__[] =
    335335"escape_bytea(data) -- escape binary data for use within SQL as type bytea";
     
    375375}
    376376
    377 /* unescape bytea */
     377/* Unescape bytea */
    378378static char pg_unescape_bytea__doc__[] =
    379379"unescape_bytea(string) -- unescape bytea data retrieved as text";
     
    416416}
    417417
    418 /* set fixed datestyle */
     418/* Set fixed datestyle. */
    419419static char pg_set_datestyle__doc__[] =
    420420"set_datestyle(style) -- set which style is assumed";
     
    438438}
    439439
    440 /* get fixed datestyle */
     440/* Get fixed datestyle. */
    441441static char pg_get_datestyle__doc__[] =
    442442"get_datestyle() -- get which date style is assumed";
     
    453453}
    454454
    455 /* get decimal point */
     455/* Get decimal point. */
    456456static char pg_get_decimal_point__doc__[] =
    457457"get_decimal_point() -- get decimal point to be used for money values";
     
    474474}
    475475
    476 /* set decimal point */
     476/* Set decimal point. */
    477477static char pg_set_decimal_point__doc__[] =
    478478"set_decimal_point(char) -- set decimal point to be used for money values";
     
    504504}
    505505
    506 /* get decimal type */
     506/* Get decimal type. */
    507507static char pg_get_decimal__doc__[] =
    508508"get_decimal() -- get the decimal type to be used for numeric values";
     
    519519}
    520520
    521 /* set decimal type */
     521/* Set decimal type. */
    522522static char pg_set_decimal__doc__[] =
    523523"set_decimal(cls) -- set a decimal type to be used for numeric values";
     
    545545}
    546546
    547 /* get usage of bool values */
     547/* Get usage of bool values. */
    548548static char pg_get_bool__doc__[] =
    549549"get_bool() -- check whether boolean values are converted to bool";
     
    560560}
    561561
    562 /* set usage of bool values */
     562/* Set usage of bool values. */
    563563static char pg_set_bool__doc__[] =
    564564"set_bool(on) -- set whether boolean values should be converted to bool";
     
    584584}
    585585
    586 /* get conversion of arrays to lists */
     586/* Get conversion of arrays to lists. */
    587587static char pg_get_array__doc__[] =
    588588"get_array() -- check whether arrays are converted as lists";
     
    599599}
    600600
    601 /* set conversion of arrays to lists */
     601/* Set conversion of arrays to lists. */
    602602static char pg_set_array__doc__[] =
    603603"set_array(on) -- set whether arrays should be converted to lists";
     
    623623}
    624624
    625 /* check whether bytea values are unescaped */
     625/* Check whether bytea values are unescaped. */
    626626static char pg_get_bytea_escaped__doc__[] =
    627627"get_bytea_escaped() -- check whether bytea will be returned escaped";
     
    638638}
    639639
    640 /* set usage of bool values */
     640/* Set usage of bool values. */
    641641static char pg_set_bytea_escaped__doc__[] =
    642642"set_bytea_escaped(on) -- set whether bytea will be returned escaped";
     
    684684}
    685685
    686 /* get json decode function */
     686/* Get json decode function. */
    687687static char pg_get_jsondecode__doc__[] =
    688688"get_jsondecode() -- get the function used for decoding json results";
     
    701701}
    702702
    703 /* set json decode function */
     703/* Set json decode function. */
    704704static char pg_set_jsondecode__doc__[] =
    705705"set_jsondecode(func) -- set a function to be used for decoding json results";
     
    729729#ifdef DEFAULT_VARS
    730730
    731 /* gets default host */
     731/* Get default host. */
    732732static char pg_get_defhost__doc__[] =
    733733"get_defhost() -- return default database host";
     
    740740}
    741741
    742 /* sets default host */
     742/* Set default host. */
    743743static char pg_set_defhost__doc__[] =
    744744"set_defhost(string) -- set default database host and return previous value";
     
    772772}
    773773
    774 /* gets default base */
     774/* Get default database. */
    775775static char pg_get_defbase__doc__[] =
    776776"get_defbase() -- return default database name";
     
    783783}
    784784
    785 /* sets default base */
     785/* Set default database. */
    786786static char pg_set_defbase__doc__[] =
    787787"set_defbase(string) -- set default database name and return previous value";
     
    815815}
    816816
    817 /* gets default options */
     817/* Get default options. */
    818818static char pg_get_defopt__doc__[] =
    819819"get_defopt() -- return default database options";
     
    826826}
    827827
    828 /* sets default opt */
     828/* Set default options. */
    829829static char pg_set_defopt__doc__[] =
    830830"set_defopt(string) -- set default options and return previous value";
     
    858858}
    859859
    860 /* gets default username */
     860/* Get default username. */
    861861static char pg_get_defuser__doc__[] =
    862862"get_defuser() -- return default database username";
     
    869869}
    870870
    871 /* sets default username */
     871/* Set default username. */
    872872
    873873static char pg_set_defuser__doc__[] =
     
    902902}
    903903
    904 /* sets default password */
     904/* Set default password. */
    905905static char pg_set_defpasswd__doc__[] =
    906906"set_defpasswd(password) -- set default database password";
     
    931931}
    932932
    933 /* gets default port */
     933/* Get default port. */
    934934static char pg_get_defport__doc__[] =
    935935"get_defport() -- return default database port";
     
    942942}
    943943
    944 /* sets default port */
     944/* Set default port. */
    945945static char pg_set_defport__doc__[] =
    946946"set_defport(port) -- set default port and return previous value";
     
    975975#endif /* DEFAULT_VARS */
    976976
    977 /* cast a string with a text representation of an array to a list */
     977/* Cast a string with a text representation of an array to a list. */
    978978static char pg_cast_array__doc__[] =
    979979"cast_array(string, cast=None, delim=',') -- cast a string as an array";
     
    10321032}
    10331033
    1034 /* cast a string with a text representation of a record to a tuple */
     1034/* Cast a string with a text representation of a record to a tuple. */
    10351035static char pg_cast_record__doc__[] =
    10361036"cast_record(string, cast=None, delim=',') -- cast a string as a record";
     
    10961096}
    10971097
    1098 /* cast a string with a text representation of an hstore to a dict */
     1098/* Cast a string with a text representation of an hstore to a dict. */
    10991099static char pg_cast_hstore__doc__[] =
    11001100"cast_hstore(string) -- cast a string as an hstore";
     
    11321132}
    11331133
    1134 /* List of functions defined in the module */
     1134/* The list of functions defined in the module */
    11351135
    11361136static struct PyMethodDef pg_methods[] = {
     
    13011301    Py_DECREF(s);
    13021302
    1303     /* results type for queries */
     1303    /* Result types for queries */
    13041304    PyDict_SetItemString(dict, "RESULT_EMPTY", PyInt_FromLong(RESULT_EMPTY));
    13051305    PyDict_SetItemString(dict, "RESULT_DML", PyInt_FromLong(RESULT_DML));
     
    13071307    PyDict_SetItemString(dict, "RESULT_DQL", PyInt_FromLong(RESULT_DQL));
    13081308
    1309     /* transaction states */
     1309    /* Transaction states */
    13101310    PyDict_SetItemString(dict,"TRANS_IDLE",PyInt_FromLong(PQTRANS_IDLE));
    13111311    PyDict_SetItemString(dict,"TRANS_ACTIVE",PyInt_FromLong(PQTRANS_ACTIVE));
     
    13151315
    13161316#ifdef LARGE_OBJECTS
    1317     /* create mode for large objects */
     1317    /* Create mode for large objects */
    13181318    PyDict_SetItemString(dict, "INV_READ", PyInt_FromLong(INV_READ));
    13191319    PyDict_SetItemString(dict, "INV_WRITE", PyInt_FromLong(INV_WRITE));
    13201320
    1321     /* position flags for lo_lseek */
     1321    /* Position flags for lo_lseek */
    13221322    PyDict_SetItemString(dict, "SEEK_SET", PyInt_FromLong(SEEK_SET));
    13231323    PyDict_SetItemString(dict, "SEEK_CUR", PyInt_FromLong(SEEK_CUR));
     
    13261326
    13271327#ifdef DEFAULT_VARS
    1328     /* prepares default values */
     1328    /* Prepare default values */
    13291329    Py_INCREF(Py_None);
    13301330    pg_default_host = Py_None;
     
    13411341#endif /* DEFAULT_VARS */
    13421342
    1343     /* store common pg encoding ids */
     1343    /* Store common pg encoding ids */
    13441344
    13451345    pg_encoding_utf8 = pg_char_to_encoding("UTF8");
  • trunk/query.c

    r987 r991  
    11/*
    2  * $Id: conn.c 985 2019-04-22 22:07:43Z cito $
     2 * $Id: query.c 985 2019-04-22 22:07:43Z cito $
    33 *
    44 * PyGreSQL - a Python interface for the PostgreSQL database.
     
    1212 */
    1313
    14 /* Deallocate query object */
     14/* Deallocate the query object. */
    1515static void
    1616query_dealloc(queryObject *self)
     
    2727}
    2828
    29 /* Return query as string in human readable form */
     29/* Return query as string in human readable form. */
    3030static PyObject *
    3131query_str(queryObject *self)
     
    127127}
    128128
    129 /* The __iter__() method of the queryObject.
    130    This returns the default iterator yielding rows as tuples. */
     129/* __iter__() method of the queryObject:
     130   Returns the default iterator yielding rows as tuples. */
    131131static PyObject* query_iter(queryObject *self)
    132132{
     
    136136}
    137137
    138 /* The __next__() method of the queryObject.
     138/* __next__() method of the queryObject:
    139139   Returns the current current row as a tuple and moves to the next one. */
    140140static PyObject *
     
    153153}
    154154
    155 /* get number of rows */
     155/* Get number of rows. */
    156156static char query_ntuples__doc__[] =
    157157"ntuples() -- return number of tuples returned by query";
     
    163163}
    164164
    165 /* list fields names from query result */
     165/* List field names from query result. */
    166166static char query_listfields__doc__[] =
    167167"listfields() -- List field names from result";
     
    186186}
    187187
    188 /* get field name from last result */
     188/* Get field name from number in last result. */
    189189static char query_fieldname__doc__[] =
    190190"fieldname(num) -- return name of field from result from its position";
     
    214214}
    215215
    216 /* gets fields number from name in last result */
     216/* Get field number from name in last result. */
    217217static char query_fieldnum__doc__[] =
    218218"fieldnum(name) -- return position in query for field from its name";
     
    240240}
    241241
    242 /* Retrieves one row from the result as a tuple. */
     242/* Retrieve one row from the result as a tuple. */
    243243static char query_one__doc__[] =
    244244"one() -- Get one row from the result of a query\n\n"
     
    261261}
    262262
    263 /* Retrieves the single row from the result as a tuple. */
     263/* Retrieve the single row from the result as a tuple. */
    264264static char query_single__doc__[] =
    265265"single() -- Get the result of a query as single row\n\n"
     
    288288}
    289289
    290 /* Retrieves the last query result as a list of tuples. */
     290/* Retrieve the last query result as a list of tuples. */
    291291static char query_getresult__doc__[] =
    292292"getresult() -- Get the result of a query\n\n"
     
    658658}
    659659
    660 /* query sequence protocol methods */
     660/* Query sequence protocol methods */
    661661static PySequenceMethods query_sequence_methods = {
    662662    (lenfunc) query_len,           /* sq_length */
     
    670670};
    671671
    672 /* query object methods */
     672/* Query object methods */
    673673static struct PyMethodDef query_methods[] = {
    674674    {"getresult", (PyCFunction) query_getresult,
     
    715715static char query__doc__[] = "PyGreSQL query object";
    716716
    717 /* query type definition */
     717/* Query type definition */
    718718static PyTypeObject queryType = {
    719719    PyVarObject_HEAD_INIT(NULL, 0)
  • trunk/setup.py

    r990 r991  
    118118            "enable default variables use"),
    119119        ('escaping-funcs', None,
    120             "enable string escaping functions")]
     120            "enable string escaping functions"),
     121        ('ssl-info', None,
     122            "use new ssl info functions")]
    121123
    122124    boolean_options = build_ext.boolean_options + [
    123         'direct-access', 'large-objects', 'default-vars', 'escaping-funcs']
     125        'direct-access', 'large-objects', 'default-vars',
     126        'escaping-funcs', 'ssl-info']
    124127
    125128    def get_compiler(self):
     
    132135        self.large_objects = True
    133136        self.default_vars = True
    134         self.escaping_funcs = pg_version[0] >= 9
     137        self.escaping_funcs = pg_version >= (9, 0)
     138        self.ssl_info = pg_version >= (9, 5)
    135139        if pg_version < (9, 0):
    136140            warnings.warn("PygreSQL does not support this PostgreSQL version.")
     
    145149        if self.default_vars:
    146150            define_macros.append(('DEFAULT_VARS', None))
    147         if self.escaping_funcs and pg_version[0] >= 9:
     151        if self.escaping_funcs and pg_version >= (9, 0):
    148152            define_macros.append(('ESCAPING_FUNCS', None))
     153        if self.ssl_info and pg_version >= (9, 5):
     154            define_macros.append(('SSL_INFO', None))
    149155        if sys.platform == 'win32':
    150156            bits = platform.architecture()[0]
  • trunk/source.c

    r987 r991  
    11/*
    2  * $Id: conn.c 985 2019-04-22 22:07:43Z cito $
     2 * $Id: source.c 985 2019-04-22 22:07:43Z cito $
    33 *
    44 * PyGreSQL - a Python interface for the PostgreSQL database.
     
    1212 */
    1313
    14 /* Deallocate source object */
     14/* Deallocate source object. */
    1515static void
    1616source_dealloc(sourceObject *self)
     
    2323}
    2424
    25 /* return source object as string in human readable form */
     25/* Return source object as string in human readable form. */
    2626static PyObject *
    2727source_str(sourceObject *self)
     
    3939}
    4040
    41 /* check source object validity */
     41/* Check source object validity. */
    4242static int
    4343_check_source_obj(sourceObject *self, int level)
     
    6565}
    6666
    67 /* get source object attributes */
     67/* Get source object attributes. */
    6868static PyObject *
    6969source_getattr(sourceObject *self, PyObject *nameobj)
     
    101101}
    102102
    103 /* set source object attributes */
     103/* Set source object attributes. */
    104104static int
    105105source_setattr(sourceObject *self, char *name, PyObject *v)
     
    121121}
    122122
    123 /* close object */
     123/* Close object. */
    124124static char source_close__doc__[] =
    125125"close() -- close query object without deleting it\n\n"
     
    143143}
    144144
    145 /* database query */
     145/* Database query. */
    146146static char source_execute__doc__[] =
    147147"execute(sql) -- execute a SQL statement (string)\n\n"
     
    256256}
    257257
    258 /* gets oid status for last query (valid for INSERTs, 0 for other) */
     258/* Get oid status for last query (valid for INSERTs, 0 for other). */
    259259static char source_oidstatus__doc__[] =
    260260"oidstatus() -- return oid of last inserted row (if available)";
     
    279279}
    280280
    281 /* fetches rows from last result */
     281/* Fetch rows from last result. */
    282282static char source_fetch__doc__[] =
    283283"fetch(num) -- return the next num rows from the last result in a list\n\n"
     
    363363}
    364364
    365 /* changes current row (internal wrapper for all "move" methods) */
     365/* Change current row (internal wrapper for all "move" methods). */
    366366static PyObject *
    367367_source_move(sourceObject *self, int move)
     
    394394}
    395395
    396 /* move to first result row */
     396/* Move to first result row. */
    397397static char source_movefirst__doc__[] =
    398398"movefirst() -- move to first result row";
     
    404404}
    405405
    406 /* move to last result row */
     406/* Move to last result row. */
    407407static char source_movelast__doc__[] =
    408408"movelast() -- move to last valid result row";
     
    414414}
    415415
    416 /* move to next result row */
     416/* Move to next result row. */
    417417static char source_movenext__doc__[] =
    418418"movenext() -- move to next result row";
     
    424424}
    425425
    426 /* move to previous result row */
     426/* Move to previous result row. */
    427427static char source_moveprev__doc__[] =
    428428"moveprev() -- move to previous result row";
     
    434434}
    435435
    436 /* put copy data */
     436/* Put copy data. */
    437437static char source_putdata__doc__[] =
    438438"putdata(buffer) -- send data to server during copy from stdin";
     
    551551}
    552552
    553 /* get copy data */
     553/* Get copy data. */
    554554static char source_getdata__doc__[] =
    555555"getdata(decode) -- receive data to server during copy to stdout";
     
    627627}
    628628
    629 /* finds field number from string/integer (internal use only) */
     629/* Find field number from string/integer (internal use only). */
    630630static int
    631631_source_fieldindex(sourceObject *self, PyObject *param, const char *usage)
     
    658658}
    659659
    660 /* builds field information from position (internal use only) */
     660/* Build field information from position (internal use only). */
    661661static PyObject *
    662662_source_buildinfo(sourceObject *self, int num)
     
    684684}
    685685
    686 /* lists fields info */
     686/* Lists fields info. */
    687687static char source_listinfo__doc__[] =
    688688"listinfo() -- get information for all fields (position, name, type oid)";
     
    717717};
    718718
    719 /* list fields information for last result */
     719/* List fields information for last result. */
    720720static char source_fieldinfo__doc__[] =
    721721"fieldinfo(desc) -- get specified field info (position, name, type oid)";
     
    738738};
    739739
    740 /* retrieve field value */
     740/* Retrieve field value. */
    741741static char source_field__doc__[] =
    742742"field(desc) -- return specified field value";
     
    759759}
    760760
    761 /* get the list of source object attributes */
     761/* Get the list of source object attributes. */
    762762static PyObject *
    763763source_dir(connObject *self, PyObject *noargs)
     
    773773}
    774774
    775 /* source object methods */
     775/* Source object methods */
    776776static PyMethodDef source_methods[] = {
    777777    {"__dir__", (PyCFunction) source_dir, METH_NOARGS, NULL},
     
    808808static char source__doc__[] = "PyGreSQL source object";
    809809
    810 /* source type definition */
     810/* Source type definition */
    811811static PyTypeObject sourceType = {
    812812    PyVarObject_HEAD_INIT(NULL, 0)
  • trunk/tests/test_classic_connection.py

    r985 r991  
    115115
    116116    def testAllConnectAttributes(self):
    117         attributes = '''db error host options port
    118             protocol_version server_version status user'''.split()
     117        attributes = '''backend_pid db error host options port
     118            protocol_version server_version socket
     119            ssl_attributes ssl_in_use status user'''.split()
    119120        connection_attributes = [a for a in dir(self.connection)
    120121            if not a.startswith('__') and not self.is_method(a)]
     
    168169        self.assertIsInstance(server_version, int)
    169170        self.assertTrue(90000 <= server_version < 120000)
     171
     172    def testAttributeSocket(self):
     173        socket = self.connection.socket
     174        self.assertIsInstance(socket, int)
     175        self.assertGreaterEqual(socket, 0)
     176
     177    def testAttributeBackendPid(self):
     178        backend_pid = self.connection.backend_pid
     179        self.assertIsInstance(backend_pid, int)
     180        self.assertGreaterEqual(backend_pid, 1)
     181
     182    def testAttributeSslInUse(self):
     183        ssl_in_use = self.connection.ssl_in_use
     184        self.assertIsInstance(ssl_in_use, bool)
     185        self.assertFalse(ssl_in_use)
     186
     187    def testAttributeSslAttributes(self):
     188        ssl_attributes = self.connection.ssl_attributes
     189        self.assertIsInstance(ssl_attributes, dict)
     190        self.assertEqual(ssl_attributes, {
     191            'cipher': None, 'compression': None, 'key_bits': None,
     192            'library': None, 'protocol': None})
    170193
    171194    def testAttributeStatus(self):
  • trunk/tests/test_classic_dbwrapper.py

    r980 r991  
    195195        attributes = [
    196196            'abort', 'adapter',
    197             'begin',
     197            'backend_pid', 'begin',
    198198            'cancel', 'clear', 'close', 'commit',
    199199            'date_format', 'db', 'dbname', 'dbtypes',
     
    220220            'savepoint', 'server_version',
    221221            'set_cast_hook', 'set_notice_receiver',
    222             'set_parameter',
    223             'source', 'start', 'status',
     222            'set_parameter', 'socket', 'source',
     223            'ssl_attributes', 'ssl_in_use',
     224            'start', 'status',
    224225            'transaction', 'truncate',
    225226            'unescape_bytea', 'update', 'upsert',
     
    278279        self.assertTrue(90000 <= server_version < 120000)
    279280        self.assertEqual(server_version, self.db.db.server_version)
     281
     282    def testAttributeSocket(self):
     283        socket = self.db.socket
     284        self.assertIsInstance(socket, int)
     285        self.assertGreaterEqual(socket, 0)
     286
     287    def testAttributeBackendPid(self):
     288        backend_pid = self.db.backend_pid
     289        self.assertIsInstance(backend_pid, int)
     290        self.assertGreaterEqual(backend_pid, 1)
     291
     292    def testAttributeSslInUse(self):
     293        ssl_in_use = self.db.ssl_in_use
     294        self.assertIsInstance(ssl_in_use, bool)
     295        self.assertFalse(ssl_in_use)
     296
     297    def testAttributeSslAttributes(self):
     298        ssl_attributes = self.db.ssl_attributes
     299        self.assertIsInstance(ssl_attributes, dict)
     300        self.assertEqual(ssl_attributes, {
     301            'cipher': None, 'compression': None, 'key_bits': None,
     302            'library': None, 'protocol': None})
    280303
    281304    def testAttributeStatus(self):
Note: See TracChangeset for help on using the changeset viewer.