source: trunk/pgmodule.c @ 918

Last change on this file since 918 was 918, checked in by darcy, 2 years ago

Update copyrights.

  • Property svn:keywords set to Id
File size: 142.5 KB
Line 
1/*
2 * $Id: pgmodule.c 918 2017-07-23 13:35:06Z darcy $
3 * PyGres, version 2.2 A Python interface for PostgreSQL database. Written by
4 * D'Arcy J.M. Cain, (darcy@druid.net).  Based heavily on code written by
5 * Pascal Andre, andre@chimay.via.ecp.fr. Copyright (c) 1995, Pascal Andre
6 * (andre@via.ecp.fr).
7 *
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation for any purpose, without fee, and without a written
10 * agreement is hereby granted, provided that the above copyright notice and
11 * this paragraph and the following two paragraphs appear in all copies or in
12 * any new file that contains a substantial portion of this file.
13 *
14 * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
15 * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
16 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
17 * AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18 *
19 * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE
22 * AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
23 * ENHANCEMENTS, OR MODIFICATIONS.
24 *
25 * Further modifications copyright 1997 to 2017 by D'Arcy J.M. Cain
26 * (darcy@PyGreSQL.org) subject to the same terms and conditions as above.
27 *
28 */
29
30/* Note: This should be linked against the same C runtime lib as Python */
31
32#include <Python.h>
33
34#include <libpq-fe.h>
35#include <libpq/libpq-fs.h>
36
37/* the type definitions from <server/catalog/pg_type.h> */
38#include "pgtypes.h"
39
40/* macros for single-source Python 2/3 compatibility */
41#include "py3c.h"
42
43static PyObject *Error, *Warning, *InterfaceError,
44        *DatabaseError, *InternalError, *OperationalError, *ProgrammingError,
45        *IntegrityError, *DataError, *NotSupportedError;
46
47#define _TOSTRING(x) #x
48#define TOSTRING(x) _TOSTRING(x)
49static const char *PyPgVersion = TOSTRING(PYGRESQL_VERSION);
50
51#if SIZEOF_SIZE_T != SIZEOF_INT
52#define Py_InitModule4 Py_InitModule4_64
53#endif
54
55/* default values */
56#define PG_ARRAYSIZE            1
57
58/* flags for object validity checks */
59#define CHECK_OPEN                      1
60#define CHECK_CLOSE                     2
61#define CHECK_CNX                       4
62#define CHECK_RESULT            8
63#define CHECK_DQL                       16
64
65/* query result types */
66#define RESULT_EMPTY            1
67#define RESULT_DML                      2
68#define RESULT_DDL                      3
69#define RESULT_DQL                      4
70
71/* flags for move methods */
72#define QUERY_MOVEFIRST         1
73#define QUERY_MOVELAST          2
74#define QUERY_MOVENEXT          3
75#define QUERY_MOVEPREV          4
76
77#define MAX_BUFFER_SIZE 8192    /* maximum transaction size */
78#define MAX_ARRAY_DEPTH 16              /* maximum allowed depth of an array */
79
80/* MODULE GLOBAL VARIABLES */
81
82#ifdef DEFAULT_VARS
83static PyObject *pg_default_host;       /* default database host */
84static PyObject *pg_default_base;       /* default database name */
85static PyObject *pg_default_opt;        /* default connection options */
86static PyObject *pg_default_port;       /* default connection port */
87static PyObject *pg_default_user;       /* default username */
88static PyObject *pg_default_passwd;     /* default password */
89#endif  /* DEFAULT_VARS */
90
91static PyObject *decimal = NULL, /* decimal type */
92                                *namedresult = NULL, /* function for getting named results */
93                                *jsondecode = NULL; /* function for decoding json strings */
94static const char *date_format = NULL; /* date format that is always assumed */
95static char decimal_point = '.'; /* decimal point used in money values */
96static int bool_as_text = 0; /* whether bool shall be returned as text */
97static int array_as_text = 0; /* whether arrays shall be returned as text */
98static int bytea_escaped = 0; /* whether bytea shall be returned escaped */
99
100static int pg_encoding_utf8 = 0;
101static int pg_encoding_latin1 = 0;
102static int pg_encoding_ascii = 0;
103
104/*
105OBJECTS
106=======
107
108  Each object has a number of elements.  The naming scheme will be based on
109  the object type.  Here are the elements using example object type "foo".
110   - fooObject: A structure to hold local object information.
111   - fooXxx: Object methods such as Delete and Getattr.
112   - fooMethods: Methods declaration.
113   - fooType: Type definition for object.
114
115  This is followed by the object methods.
116
117  The objects that we need to create:
118   - pg: The module itself.
119   - conn: Connection object returned from pg.connect().
120   - notice: Notice object returned from pg.notice().
121   - large: Large object returned by pg.conn.locreate() and Pg.Conn.loimport().
122   - query: Query object returned by pg.conn.Conn.query().
123   - source: Source object returned by pg.conn.source().
124*/
125
126/* forward declarations for types */
127static PyTypeObject noticeType;
128static PyTypeObject queryType;
129static PyTypeObject sourceType;
130static PyTypeObject largeType;
131static PyTypeObject connType;
132
133/* forward static declarations */
134static void notice_receiver(void *, const PGresult *);
135
136/* --------------------------------------------------------------------- */
137/* Object declarations                                                                                                   */
138/* --------------------------------------------------------------------- */
139typedef struct
140{
141        PyObject_HEAD
142        int                     valid;                          /* validity flag */
143        PGconn     *cnx;                                /* Postgres connection handle */
144        const char *date_format;                /* date format derived from datestyle */
145        PyObject   *cast_hook;                  /* external typecast method */
146        PyObject   *notice_receiver;    /* current notice receiver */
147}       connObject;
148#define is_connObject(v) (PyType(v) == &connType)
149
150typedef struct
151{
152        PyObject_HEAD
153        int                     valid;                  /* validity flag */
154        connObject *pgcnx;                      /* parent connection object */
155        PGresult        *result;                /* result content */
156        int                     encoding;               /* client encoding */
157        int                     result_type;    /* result type (DDL/DML/DQL) */
158        long            arraysize;              /* array size for fetch method */
159        int                     current_row;    /* current selected row */
160        int                     max_row;                /* number of rows in the result */
161        int                     num_fields;             /* number of fields in each row */
162}       sourceObject;
163#define is_sourceObject(v) (PyType(v) == &sourceType)
164
165typedef struct
166{
167        PyObject_HEAD
168        connObject *pgcnx;                      /* parent connection object */
169        PGresult        const *res;             /* an error or warning */
170}       noticeObject;
171#define is_noticeObject(v) (PyType(v) == &noticeType)
172
173typedef struct
174{
175        PyObject_HEAD
176        connObject *pgcnx;                      /* parent connection object */
177        PGresult   *result;                     /* result content */
178        int                     encoding;               /* client encoding */
179}       queryObject;
180#define is_queryObject(v) (PyType(v) == &queryType)
181
182#ifdef LARGE_OBJECTS
183typedef struct
184{
185        PyObject_HEAD
186        connObject *pgcnx;                      /* parent connection object */
187        Oid                     lo_oid;                 /* large object oid */
188        int                     lo_fd;                  /* large object fd */
189}       largeObject;
190#define is_largeObject(v) (PyType(v) == &largeType)
191#endif /* LARGE_OBJECTS */
192
193/* PyGreSQL internal types */
194
195/* simple types */
196#define PYGRES_INT 1
197#define PYGRES_LONG 2
198#define PYGRES_FLOAT 3
199#define PYGRES_DECIMAL 4
200#define PYGRES_MONEY 5
201#define PYGRES_BOOL 6
202/* text based types */
203#define PYGRES_TEXT 8
204#define PYGRES_BYTEA 9
205#define PYGRES_JSON 10
206#define PYGRES_OTHER 11
207/* array types */
208#define PYGRES_ARRAY 16
209
210/* --------------------------------------------------------------------- */
211/* Internal Functions                                                                                                    */
212/* --------------------------------------------------------------------- */
213
214/* shared function for encoding and decoding strings */
215
216static PyObject *
217get_decoded_string(const char *str, Py_ssize_t size, int encoding)
218{
219        if (encoding == pg_encoding_utf8)
220                return PyUnicode_DecodeUTF8(str, size, "strict");
221        if (encoding == pg_encoding_latin1)
222                return PyUnicode_DecodeLatin1(str, size, "strict");
223        if (encoding == pg_encoding_ascii)
224                return PyUnicode_DecodeASCII(str, size, "strict");
225        /* encoding name should be properly translated to Python here */
226        return PyUnicode_Decode(str, size,
227                pg_encoding_to_char(encoding), "strict");
228}
229
230static PyObject *
231get_encoded_string(PyObject *unicode_obj, int encoding)
232{
233        if (encoding == pg_encoding_utf8)
234                return PyUnicode_AsUTF8String(unicode_obj);
235        if (encoding == pg_encoding_latin1)
236                return PyUnicode_AsLatin1String(unicode_obj);
237        if (encoding == pg_encoding_ascii)
238                return PyUnicode_AsASCIIString(unicode_obj);
239        /* encoding name should be properly translated to Python here */
240        return PyUnicode_AsEncodedString(unicode_obj,
241                pg_encoding_to_char(encoding), "strict");
242}
243
244/* helper functions */
245
246/* get PyGreSQL internal types for a PostgreSQL type */
247static int
248get_type(Oid pgtype)
249{
250        int t;
251
252        switch (pgtype)
253        {
254                /* simple types */
255
256                case INT2OID:
257                case INT4OID:
258                case CIDOID:
259                case OIDOID:
260                case XIDOID:
261                        t = PYGRES_INT;
262                        break;
263
264                case INT8OID:
265                        t = PYGRES_LONG;
266                        break;
267
268                case FLOAT4OID:
269                case FLOAT8OID:
270                        t = PYGRES_FLOAT;
271                        break;
272
273                case NUMERICOID:
274                        t = PYGRES_DECIMAL;
275                        break;
276
277                case CASHOID:
278                        t = decimal_point ? PYGRES_MONEY : PYGRES_TEXT;
279                        break;
280
281                case BOOLOID:
282                        t = PYGRES_BOOL;
283                        break;
284
285                case BYTEAOID:
286                        t = bytea_escaped ? PYGRES_TEXT : PYGRES_BYTEA;
287                        break;
288
289                case JSONOID:
290                case JSONBOID:
291                        t = jsondecode ? PYGRES_JSON : PYGRES_TEXT;
292                        break;
293
294                case BPCHAROID:
295                case CHAROID:
296                case TEXTOID:
297                case VARCHAROID:
298                case NAMEOID:
299                case REGTYPEOID:
300                        t = PYGRES_TEXT;
301                        break;
302
303                /* array types */
304
305                case INT2ARRAYOID:
306                case INT4ARRAYOID:
307                case CIDARRAYOID:
308                case OIDARRAYOID:
309                case XIDARRAYOID:
310                        t = array_as_text ? PYGRES_TEXT : (PYGRES_INT | PYGRES_ARRAY);
311                        break;
312
313                case INT8ARRAYOID:
314                        t = array_as_text ? PYGRES_TEXT : (PYGRES_LONG | PYGRES_ARRAY);
315                        break;
316
317                case FLOAT4ARRAYOID:
318                case FLOAT8ARRAYOID:
319                        t = array_as_text ? PYGRES_TEXT : (PYGRES_FLOAT | PYGRES_ARRAY);
320                        break;
321
322                case NUMERICARRAYOID:
323                        t = array_as_text ? PYGRES_TEXT : (PYGRES_DECIMAL | PYGRES_ARRAY);
324                        break;
325
326                case CASHARRAYOID:
327                        t = array_as_text ? PYGRES_TEXT : ((decimal_point ?
328                                PYGRES_MONEY : PYGRES_TEXT) | PYGRES_ARRAY);
329                        break;
330
331                case BOOLARRAYOID:
332                        t = array_as_text ? PYGRES_TEXT : (PYGRES_BOOL | PYGRES_ARRAY);
333                        break;
334
335                case BYTEAARRAYOID:
336                        t = array_as_text ? PYGRES_TEXT : ((bytea_escaped ?
337                            PYGRES_TEXT : PYGRES_BYTEA) | PYGRES_ARRAY);
338                        break;
339
340                case JSONARRAYOID:
341                case JSONBARRAYOID:
342                        t = array_as_text ? PYGRES_TEXT : ((jsondecode ?
343                            PYGRES_JSON : PYGRES_TEXT) | PYGRES_ARRAY);
344                        break;
345
346                case BPCHARARRAYOID:
347                case CHARARRAYOID:
348                case TEXTARRAYOID:
349                case VARCHARARRAYOID:
350                case NAMEARRAYOID:
351                case REGTYPEARRAYOID:
352                        t = array_as_text ? PYGRES_TEXT : (PYGRES_TEXT | PYGRES_ARRAY);
353                        break;
354
355                default:
356                        t = PYGRES_OTHER;
357        }
358
359        return t;
360}
361
362/* get PyGreSQL column types for all result columns */
363static int *
364get_col_types(PGresult *result, int nfields)
365{
366        int *types, *t, j;
367
368        if (!(types = PyMem_Malloc(sizeof(int) * nfields)))
369                return (int *)PyErr_NoMemory();
370
371        for (j = 0, t=types; j < nfields; ++j)
372                *t++ = get_type(PQftype(result, j));
373
374        return types;
375}
376
377/* Cast a bytea encoded text based type to a Python object.
378   This assumes the text is null-terminated character string. */
379static PyObject *
380cast_bytea_text(char *s)
381{
382        PyObject   *obj;
383        char       *tmp_str;
384        size_t          str_len;
385
386    /* this function should not be called when bytea_escaped is set */
387        tmp_str = (char *)PQunescapeBytea((unsigned char*)s, &str_len);
388        obj = PyBytes_FromStringAndSize(tmp_str, str_len);
389        if (tmp_str)
390                PQfreemem(tmp_str);
391        return obj;
392}
393
394/* Cast a text based type to a Python object.
395   This needs the character string, size and encoding. */
396static PyObject *
397cast_sized_text(char *s, Py_ssize_t size, int encoding, int type)
398{
399        PyObject   *obj, *tmp_obj;
400        char       *tmp_str;
401        size_t          str_len;
402
403        switch (type) /* this must be the PyGreSQL internal type */
404        {
405                case PYGRES_BYTEA:
406                    /* this type should not be passed when bytea_escaped is set */
407                        /* we need to add a null byte */
408                        tmp_str = (char *) PyMem_Malloc(size + 1);
409                        if (!tmp_str) return PyErr_NoMemory();
410                        memcpy(tmp_str, s, size);
411                        s = tmp_str; *(s + size) = '\0';
412                        tmp_str = (char *)PQunescapeBytea((unsigned char*)s, &str_len);
413                        PyMem_Free(s);
414                        if (!tmp_str) return PyErr_NoMemory();
415                        obj = PyBytes_FromStringAndSize(tmp_str, str_len);
416                        if (tmp_str)
417                                PQfreemem(tmp_str);
418                        break;
419
420                case PYGRES_JSON:
421                        /* this type should only be passed when jsondecode is set */
422                        obj = get_decoded_string(s, size, encoding);
423                        if (obj && jsondecode) /* was able to decode */
424                        {
425                                tmp_obj = Py_BuildValue("(O)", obj);
426                                obj = PyObject_CallObject(jsondecode, tmp_obj);
427                                Py_DECREF(tmp_obj);
428                        }
429                        break;
430
431                default:  /* PYGRES_TEXT */
432#if IS_PY3
433                        obj = get_decoded_string(s, size, encoding);
434                        if (!obj) /* cannot decode */
435#endif
436                        obj = PyBytes_FromStringAndSize(s, size);
437        }
438
439        return obj;
440}
441
442/* Cast an arbitrary type to a Python object using a callback function.
443   This needs the character string, size, encoding, the Postgres type
444   and the external typecast function to be called. */
445static PyObject *
446cast_other(char *s, Py_ssize_t size, int encoding, Oid pgtype,
447        PyObject *cast_hook)
448{
449        PyObject *obj;
450
451        obj = cast_sized_text(s, size, encoding, PYGRES_TEXT);
452
453        if (cast_hook)
454        {
455                PyObject *tmp_obj = obj;
456                obj = PyObject_CallFunction(cast_hook, "(OI)", obj, pgtype);
457                Py_DECREF(tmp_obj);
458        }
459        return obj;
460}
461
462/* Cast a simple type to a Python object.
463   This needs a character string representation with a given size. */
464static PyObject *
465cast_sized_simple(char *s, Py_ssize_t size, int type)
466{
467        PyObject   *obj, *tmp_obj;
468        char            buf[64], *t;
469        int                     i, j, n;
470
471        switch (type) /* this must be the PyGreSQL internal type */
472        {
473                case PYGRES_INT:
474                        n = sizeof(buf)/sizeof(buf[0]) - 1;
475                        if ((int)size < n) n = (int)size;
476                        for (i = 0, t = buf; i < n; ++i) *t++ = *s++;
477                        *t = '\0';
478                        obj = PyInt_FromString(buf, NULL, 10);
479                        break;
480
481                case PYGRES_LONG:
482                        n = sizeof(buf)/sizeof(buf[0]) - 1;
483                        if ((int)size < n) n = (int)size;
484                        for (i = 0, t = buf; i < n; ++i) *t++ = *s++;
485                        *t = '\0';
486                        obj = PyLong_FromString(buf, NULL, 10);
487                        break;
488
489                case PYGRES_FLOAT:
490                        tmp_obj = PyStr_FromStringAndSize(s, size);
491                        obj = PyFloat_FromString(tmp_obj);
492                        Py_DECREF(tmp_obj);
493                        break;
494
495                case PYGRES_MONEY:
496                        /* this type should only be passed when decimal_point is set */
497                        n = sizeof(buf)/sizeof(buf[0]) - 1;
498                        for (i = 0, j = 0; i < size && j < n; ++i, ++s)
499                        {
500                                if (*s >= '0' && *s <= '9')
501                                        buf[j++] = *s;
502                                else if (*s == decimal_point)
503                                        buf[j++] = '.';
504                                else if (*s == '(' || *s == '-')
505                                        buf[j++] = '-';
506                        }
507                        if (decimal)
508                        {
509                                buf[j] = '\0';
510                                obj = PyObject_CallFunction(decimal, "(s)", buf);
511                        }
512                        else
513                        {
514                                tmp_obj = PyStr_FromString(buf);
515                                obj = PyFloat_FromString(tmp_obj);
516                                Py_DECREF(tmp_obj);
517
518                        }
519                        break;
520
521                case PYGRES_DECIMAL:
522                        tmp_obj = PyStr_FromStringAndSize(s, size);
523                        obj = decimal ? PyObject_CallFunctionObjArgs(
524                                decimal, tmp_obj, NULL) : PyFloat_FromString(tmp_obj);
525                        Py_DECREF(tmp_obj);
526                        break;
527
528                case PYGRES_BOOL:
529                        /* convert to bool only if bool_as_text is not set */
530                        if (bool_as_text)
531                        {
532                                obj = PyStr_FromString(*s == 't' ? "t" : "f");
533                        }
534                        else
535                        {
536                                obj = *s == 't' ? Py_True : Py_False;
537                                Py_INCREF(obj);
538                        }
539                        break;
540
541                default:
542                        /* other types should never be passed, use cast_sized_text */
543                        obj = PyStr_FromStringAndSize(s, size);
544        }
545
546        return obj;
547}
548
549/* Cast a simple type to a Python object.
550   This needs a null-terminated character string representation. */
551static PyObject *
552cast_unsized_simple(char *s, int type)
553{
554        PyObject   *obj, *tmp_obj;
555        char            buf[64];
556        int                     j, n;
557
558        switch (type) /* this must be the PyGreSQL internal type */
559        {
560                case PYGRES_INT:
561                        obj = PyInt_FromString(s, NULL, 10);
562                        break;
563
564                case PYGRES_LONG:
565                        obj = PyLong_FromString(s, NULL, 10);
566                        break;
567
568                case PYGRES_FLOAT:
569                        tmp_obj = PyStr_FromString(s);
570                        obj = PyFloat_FromString(tmp_obj);
571                        Py_DECREF(tmp_obj);
572                        break;
573
574                case PYGRES_MONEY:
575                        /* this type should only be passed when decimal_point is set */
576                        n = sizeof(buf)/sizeof(buf[0]) - 1;
577                        for (j = 0; *s && j < n; ++s)
578                        {
579                                if (*s >= '0' && *s <= '9')
580                                        buf[j++] = *s;
581                                else if (*s == decimal_point)
582                                        buf[j++] = '.';
583                                else if (*s == '(' || *s == '-')
584                                        buf[j++] = '-';
585                        }
586                        buf[j] = '\0'; s = buf;
587                        /* FALLTHROUGH */ /* no break here */
588
589                case PYGRES_DECIMAL:
590                        if (decimal)
591                        {
592                                obj = PyObject_CallFunction(decimal, "(s)", s);
593                        }
594                        else
595                        {
596                                tmp_obj = PyStr_FromString(s);
597                                obj = PyFloat_FromString(tmp_obj);
598                                Py_DECREF(tmp_obj);
599                        }
600                        break;
601
602                case PYGRES_BOOL:
603                        /* convert to bool only if bool_as_text is not set */
604                        if (bool_as_text)
605                        {
606                                obj = PyStr_FromString(*s == 't' ? "t" : "f");
607                        }
608                        else
609                        {
610                                obj = *s == 't' ? Py_True : Py_False;
611                                Py_INCREF(obj);
612                        }
613                        break;
614
615                default:
616                        /* other types should never be passed, use cast_sized_text */
617                        obj = PyStr_FromString(s);
618        }
619
620        return obj;
621}
622
623/* quick case insensitive check if given sized string is null */
624#define STR_IS_NULL(s, n) (n == 4 \
625        && (s[0] == 'n' || s[0] == 'N') \
626        && (s[1] == 'u' || s[1] == 'U') \
627        && (s[2] == 'l' || s[2] == 'L') \
628        && (s[3] == 'l' || s[3] == 'L'))
629
630/* Cast string s with size and encoding to a Python list,
631   using the input and output syntax for arrays.
632   Use internal type or cast function to cast elements.
633   The parameter delim specifies the delimiter for the elements,
634   since some types do not use the default delimiter of a comma. */
635static PyObject *
636cast_array(char *s, Py_ssize_t size, int encoding,
637         int type, PyObject *cast, char delim)
638{
639        PyObject   *result, *stack[MAX_ARRAY_DEPTH];
640        char       *end = s + size, *t;
641        int                     depth, ranges = 0, level = 0;
642
643        if (type)
644        {
645                type &= ~PYGRES_ARRAY; /* get the base type */
646                if (!type) type = PYGRES_TEXT;
647        }
648        if (!delim)
649                delim = ',';
650        else if (delim == '{' || delim =='}' || delim=='\\')
651        {
652                PyErr_SetString(PyExc_ValueError, "Invalid array delimiter");
653                return NULL;
654        }
655
656        /* strip blanks at the beginning */
657        while (s != end && *s == ' ') ++s;
658        if (*s == '[') /* dimension ranges */
659        {
660                int valid;
661
662                for (valid = 0; !valid;)
663                {
664                        if (s == end || *s++ != '[') break;
665                        while (s != end && *s == ' ') ++s;
666                        if (s != end && (*s == '+' || *s == '-')) ++s;
667                        if (s == end || *s <= '0' || *s >= '9') break;
668                        while (s != end && *s >= '0' && *s <= '9') ++s;
669                        if (s == end || *s++ != ':') break;
670                        if (s != end && (*s == '+' || *s == '-')) ++s;
671                        if (s == end || *s <= '0' || *s >= '9') break;
672                        while (s != end && *s >= '0' && *s <= '9') ++s;
673                        if (s == end || *s++ != ']') break;
674                        while (s != end && *s == ' ') ++s;
675                        ++ranges;
676                        if (s != end && *s == '=')
677                        {
678                                do ++s; while (s != end && *s == ' ');
679                                valid = 1;
680                        }
681                }
682                if (!valid)
683                {
684                        PyErr_SetString(PyExc_ValueError, "Invalid array dimensions");
685                        return NULL;
686                }
687        }
688        for (t = s, depth = 0; t != end && (*t == '{' || *t == ' '); ++t)
689                if (*t == '{') ++depth;
690        if (!depth)
691        {
692                PyErr_SetString(PyExc_ValueError,
693                        "Array must start with a left brace");
694                return NULL;
695        }
696        if (ranges && depth != ranges)
697        {
698                PyErr_SetString(PyExc_ValueError,
699                        "Array dimensions do not match content");
700                return NULL;
701        }
702        if (depth > MAX_ARRAY_DEPTH)
703        {
704                PyErr_SetString(PyExc_ValueError, "Array is too deeply nested");
705                return NULL;
706        }
707        depth--; /* next level of parsing */
708        result = PyList_New(0);
709        if (!result) return NULL;
710        do ++s; while (s != end && *s == ' ');
711        /* everything is set up, start parsing the array */
712        while (s != end)
713        {
714                if (*s == '}')
715                {
716                        PyObject *subresult;
717
718                        if (!level) break; /* top level array ended */
719                        do ++s; while (s != end && *s == ' ');
720                        if (s == end) break; /* error */
721                        if (*s == delim)
722                        {
723                                do ++s; while (s != end && *s == ' ');
724                                if (s == end) break; /* error */
725                                if (*s != '{')
726                                {
727                                        PyErr_SetString(PyExc_ValueError,
728                                                "Subarray expected but not found");
729                                        Py_DECREF(result); return NULL;
730                                }
731                        }
732                        else if (*s != '}') break; /* error */
733                        subresult = result;
734                        result = stack[--level];
735                        if (PyList_Append(result, subresult))
736                        {
737                                Py_DECREF(result); return NULL;
738                        }
739                }
740                else if (level == depth) /* we expect elements at this level */
741                {
742                        PyObject   *element;
743                        char       *estr;
744                        Py_ssize_t      esize;
745                        int escaped = 0;
746
747                        if (*s == '{')
748                        {
749                                PyErr_SetString(PyExc_ValueError,
750                                        "Subarray found where not expected");
751                                Py_DECREF(result); return NULL;
752                        }
753                        if (*s == '"') /* quoted element */
754                        {
755                                estr = ++s;
756                                while (s != end && *s != '"')
757                                {
758                                        if (*s == '\\')
759                                        {
760                                                ++s; if (s == end) break;
761                                                escaped = 1;
762                                        }
763                                        ++s;
764                                }
765                                esize = s - estr;
766                                do ++s; while (s != end && *s == ' ');
767                        }
768                        else /* unquoted element */
769                        {
770                                estr = s;
771                                /* can contain blanks inside */
772                                while (s != end && *s != '"' &&
773                                        *s != '{' && *s != '}' && *s != delim)
774                                {
775                                        if (*s == '\\')
776                                        {
777                                                ++s; if (s == end) break;
778                                                escaped = 1;
779                                        }
780                                        ++s;
781                                }
782                                t = s; while (t > estr && *(t - 1) == ' ') --t;
783                                if (!(esize = t - estr))
784                                {
785                                        s = end; break; /* error */
786                                }
787                                if (STR_IS_NULL(estr, esize)) /* NULL gives None */
788                                        estr = NULL;
789                        }
790                        if (s == end) break; /* error */
791                        if (estr)
792                        {
793                                if (escaped)
794                                {
795                                        char       *r;
796                                        Py_ssize_t      i;
797
798                                        /* create unescaped string */
799                                        t = estr;
800                                        estr = (char *) PyMem_Malloc(esize);
801                                        if (!estr)
802                                        {
803                                                Py_DECREF(result); return PyErr_NoMemory();
804                                        }
805                                        for (i = 0, r = estr; i < esize; ++i)
806                                        {
807                                                if (*t == '\\') ++t, ++i;
808                                                *r++ = *t++;
809                                        }
810                                        esize = r - estr;
811                                }
812                                if (type) /* internal casting of base type */
813                                {
814                                        if (type & PYGRES_TEXT)
815                                                element = cast_sized_text(estr, esize, encoding, type);
816                                        else
817                                                element = cast_sized_simple(estr, esize, type);
818                                }
819                                else /* external casting of base type */
820                                {
821#if IS_PY3
822                                        element = encoding == pg_encoding_ascii ? NULL :
823                                                get_decoded_string(estr, esize, encoding);
824                                        if (!element) /* no decoding necessary or possible */
825#endif
826                                        element = PyBytes_FromStringAndSize(estr, esize);
827                                        if (element && cast)
828                                        {
829                                                PyObject *tmp = element;
830                                                element = PyObject_CallFunctionObjArgs(
831                                                        cast, element, NULL);
832                                                Py_DECREF(tmp);
833                                        }
834                                }
835                                if (escaped) PyMem_Free(estr);
836                                if (!element)
837                                {
838                                        Py_DECREF(result); return NULL;
839                                }
840                        }
841                        else
842                        {
843                                Py_INCREF(Py_None); element = Py_None;
844                        }
845                        if (PyList_Append(result, element))
846                        {
847                                Py_DECREF(element); Py_DECREF(result); return NULL;
848                        }
849                        Py_DECREF(element);
850                        if (*s == delim)
851                        {
852                                do ++s; while (s != end && *s == ' ');
853                                if (s == end) break; /* error */
854                        }
855                        else if (*s != '}') break; /* error */
856                }
857                else /* we expect arrays at this level */
858                {
859                        if (*s != '{')
860                        {
861                                PyErr_SetString(PyExc_ValueError,
862                                        "Subarray must start with a left brace");
863                                Py_DECREF(result); return NULL;
864                        }
865                        do ++s; while (s != end && *s == ' ');
866                        if (s == end) break; /* error */
867                        stack[level++] = result;
868                        if (!(result = PyList_New(0))) return NULL;
869                }
870        }
871        if (s == end || *s != '}')
872        {
873                PyErr_SetString(PyExc_ValueError,
874                        "Unexpected end of array");
875                Py_DECREF(result); return NULL;
876        }
877        do ++s; while (s != end && *s == ' ');
878        if (s != end)
879        {
880                PyErr_SetString(PyExc_ValueError,
881                        "Unexpected characters after end of array");
882                Py_DECREF(result); return NULL;
883        }
884        return result;
885}
886
887/* Cast string s with size and encoding to a Python tuple.
888   using the input and output syntax for composite types.
889   Use array of internal types or cast function or sequence of cast
890   functions to cast elements. The parameter len is the record size.
891   The parameter delim can specify a delimiter for the elements,
892   although composite types always use a comma as delimiter. */
893
894static PyObject *
895cast_record(char *s, Py_ssize_t size, int encoding,
896         int *type, PyObject *cast, Py_ssize_t len, char delim)
897{
898        PyObject   *result, *ret;
899        char       *end = s + size, *t;
900        Py_ssize_t      i;
901
902        if (!delim)
903                delim = ',';
904        else if (delim == '(' || delim ==')' || delim=='\\')
905        {
906                PyErr_SetString(PyExc_ValueError, "Invalid record delimiter");
907                return NULL;
908        }
909
910        /* strip blanks at the beginning */
911        while (s != end && *s == ' ') ++s;
912        if (s == end || *s != '(')
913        {
914                PyErr_SetString(PyExc_ValueError,
915                        "Record must start with a left parenthesis");
916                return NULL;
917        }
918        result = PyList_New(0);
919        if (!result) return NULL;
920        i = 0;
921        /* everything is set up, start parsing the record */
922        while (++s != end)
923        {
924                PyObject   *element;
925
926                if (*s == ')' || *s == delim)
927                {
928                        Py_INCREF(Py_None); element = Py_None;
929                }
930                else
931                {
932                        char       *estr;
933                        Py_ssize_t      esize;
934                        int quoted = 0, escaped =0;
935
936                        estr = s;
937                        quoted = *s == '"';
938                        if (quoted) ++s;
939                        esize = 0;
940                        while (s != end)
941                        {
942                                if (!quoted && (*s == ')' || *s == delim))
943                                        break;
944                                if (*s == '"')
945                                {
946                                        ++s; if (s == end) break;
947                                        if (!(quoted && *s == '"'))
948                                        {
949                                                quoted = !quoted; continue;
950                                        }
951                                }
952                                if (*s == '\\')
953                                {
954                                        ++s; if (s == end) break;
955                                }
956                                ++s, ++esize;
957                        }
958                        if (s == end) break; /* error */
959                        if (estr + esize != s)
960                        {
961                                char       *r;
962
963                                escaped = 1;
964                                /* create unescaped string */
965                                t = estr;
966                                estr = (char *) PyMem_Malloc(esize);
967                                if (!estr)
968                                {
969                                        Py_DECREF(result); return PyErr_NoMemory();
970                                }
971                                quoted = 0;
972                                r = estr;
973                                while (t != s)
974                                {
975                                        if (*t == '"')
976                                        {
977                                                ++t;
978                                                if (!(quoted && *t == '"'))
979                                                {
980                                                        quoted = !quoted; continue;
981                                                }
982                                        }
983                                        if (*t == '\\') ++t;
984                                        *r++ = *t++;
985                                }
986                        }
987                        if (type) /* internal casting of element type */
988                        {
989                                int etype = type[i];
990
991                                if (etype & PYGRES_ARRAY)
992                                        element = cast_array(
993                                                estr, esize, encoding, etype, NULL, 0);
994                                else if (etype & PYGRES_TEXT)
995                                        element = cast_sized_text(estr, esize, encoding, etype);
996                                else
997                                        element = cast_sized_simple(estr, esize, etype);
998                        }
999                        else /* external casting of base type */
1000                        {
1001#if IS_PY3
1002                                element = encoding == pg_encoding_ascii ? NULL :
1003                                        get_decoded_string(estr, esize, encoding);
1004                                if (!element) /* no decoding necessary or possible */
1005#endif
1006                                element = PyBytes_FromStringAndSize(estr, esize);
1007                                if (element && cast)
1008                                {
1009                                        if (len)
1010                                        {
1011                                                PyObject *ecast = PySequence_GetItem(cast, i);
1012
1013                                                if (ecast)
1014                                                {
1015                                                        if (ecast != Py_None)
1016                                                        {
1017                                                                PyObject *tmp = element;
1018                                                                element = PyObject_CallFunctionObjArgs(
1019                                                                        ecast, element, NULL);
1020                                                                Py_DECREF(tmp);
1021                                                        }
1022                                                }
1023                                                else
1024                                                {
1025                                                        Py_DECREF(element); element = NULL;
1026                                                }
1027                                        }
1028                                        else
1029                                        {
1030                                                PyObject *tmp = element;
1031                                                element = PyObject_CallFunctionObjArgs(
1032                                                        cast, element, NULL);
1033                                                Py_DECREF(tmp);
1034                                        }
1035                                }
1036                        }
1037                        if (escaped) PyMem_Free(estr);
1038                        if (!element)
1039                        {
1040                                Py_DECREF(result); return NULL;
1041                        }
1042                }
1043                if (PyList_Append(result, element))
1044                {
1045                        Py_DECREF(element); Py_DECREF(result); return NULL;
1046                }
1047                Py_DECREF(element);
1048                if (len) ++i;
1049                if (*s != delim) break; /* no next record */
1050                if (len && i >= len)
1051                {
1052                        PyErr_SetString(PyExc_ValueError, "Too many columns");
1053                        Py_DECREF(result); return NULL;
1054                }
1055        }
1056        if (s == end || *s != ')')
1057        {
1058                PyErr_SetString(PyExc_ValueError, "Unexpected end of record");
1059                Py_DECREF(result); return NULL;
1060        }
1061        do ++s; while (s != end && *s == ' ');
1062        if (s != end)
1063        {
1064                PyErr_SetString(PyExc_ValueError,
1065                        "Unexpected characters after end of record");
1066                Py_DECREF(result); return NULL;
1067        }
1068        if (len && i < len)
1069        {
1070                PyErr_SetString(PyExc_ValueError, "Too few columns");
1071                Py_DECREF(result); return NULL;
1072        }
1073
1074        ret = PyList_AsTuple(result);
1075        Py_DECREF(result);
1076        return ret;
1077}
1078
1079/* Cast string s with size and encoding to a Python dictionary.
1080   using the input and output syntax for hstore values. */
1081
1082static PyObject *
1083cast_hstore(char *s, Py_ssize_t size, int encoding)
1084{
1085        PyObject   *result;
1086        char       *end = s + size;
1087
1088    result = PyDict_New();
1089
1090        /* everything is set up, start parsing the record */
1091        while (s != end)
1092        {
1093                char       *key, *val;
1094                PyObject   *key_obj, *val_obj;
1095                Py_ssize_t      key_esc = 0, val_esc = 0, size;
1096                int                     quoted;
1097
1098                while (s != end && *s == ' ') ++s;
1099                if (s == end) break;
1100                quoted = *s == '"';
1101                if (quoted)
1102                {
1103                        key = ++s;
1104                        while (s != end)
1105                        {
1106                                if (*s == '"') break;
1107                                if (*s == '\\')
1108                                {
1109                                        if (++s == end) break;
1110                                        ++key_esc;
1111                                }
1112                                ++s;
1113                        }
1114                        if (s == end)
1115                        {
1116                                PyErr_SetString(PyExc_ValueError, "Unterminated quote");
1117                                Py_DECREF(result); return NULL;
1118                        }
1119                }
1120                else
1121                {
1122                        key = s;
1123                        while (s != end)
1124                        {
1125                                if (*s == '=' || *s == ' ') break;
1126                                if (*s == '\\')
1127                                {
1128                                        if (++s == end) break;
1129                                        ++key_esc;
1130                                }
1131                                ++s;
1132                        }
1133                        if (s == key)
1134                        {
1135                                PyErr_SetString(PyExc_ValueError, "Missing key");
1136                                Py_DECREF(result); return NULL;
1137                        }
1138                }
1139                size = s - key - key_esc;
1140                if (key_esc)
1141                {
1142                        char *r = key, *t;
1143                        key = (char *) PyMem_Malloc(size);
1144                        if (!key)
1145                        {
1146                                Py_DECREF(result); return PyErr_NoMemory();
1147                        }
1148                        t = key;
1149                        while (r != s)
1150                        {
1151                                if (*r == '\\')
1152                                {
1153                                        ++r; if (r == s) break;
1154                                }
1155                                *t++ = *r++;
1156                        }
1157                }
1158                key_obj = cast_sized_text(key, size, encoding, PYGRES_TEXT);
1159                if (key_esc) PyMem_Free(key);
1160                if (!key_obj)
1161                {
1162                        Py_DECREF(result); return NULL;
1163                }
1164                if (quoted) ++s;
1165                while (s != end && *s == ' ') ++s;
1166                if (s == end || *s++ != '=' || s == end || *s++ != '>')
1167                {
1168                        PyErr_SetString(PyExc_ValueError, "Invalid characters after key");
1169                        Py_DECREF(key_obj); Py_DECREF(result); return NULL;
1170                }
1171                while (s != end && *s == ' ') ++s;
1172                quoted = *s == '"';
1173                if (quoted)
1174                {
1175                        val = ++s;
1176                        while (s != end)
1177                        {
1178                                if (*s == '"') break;
1179                                if (*s == '\\')
1180                                {
1181                                        if (++s == end) break;
1182                                        ++val_esc;
1183                                }
1184                                ++s;
1185                        }
1186                        if (s == end)
1187                        {
1188                                PyErr_SetString(PyExc_ValueError, "Unterminated quote");
1189                                Py_DECREF(result); return NULL;
1190                        }
1191                }
1192                else
1193                {
1194                        val = s;
1195                        while (s != end)
1196                        {
1197                                if (*s == ',' || *s == ' ') break;
1198                                if (*s == '\\')
1199                                {
1200                                        if (++s == end) break;
1201                                        ++val_esc;
1202                                }
1203                                ++s;
1204                        }
1205                        if (s == val)
1206                        {
1207                                PyErr_SetString(PyExc_ValueError, "Missing value");
1208                                Py_DECREF(key_obj); Py_DECREF(result); return NULL;
1209                        }
1210                        if (STR_IS_NULL(val, s - val))
1211                                val = NULL;
1212                }
1213                if (val)
1214                {
1215                        size = s - val - val_esc;
1216                        if (val_esc)
1217                        {
1218                                char *r = val, *t;
1219                                val = (char *) PyMem_Malloc(size);
1220                                if (!val)
1221                                {
1222                                        Py_DECREF(key_obj); Py_DECREF(result);
1223                                        return PyErr_NoMemory();
1224                                }
1225                                t = val;
1226                                while (r != s)
1227                                {
1228                                        if (*r == '\\')
1229                                        {
1230                                                ++r; if (r == s) break;
1231                                        }
1232                                        *t++ = *r++;
1233                                }
1234                        }
1235                        val_obj = cast_sized_text(val, size, encoding, PYGRES_TEXT);
1236                        if (val_esc) PyMem_Free(val);
1237                        if (!val_obj)
1238                        {
1239                                Py_DECREF(key_obj); Py_DECREF(result); return NULL;
1240                        }
1241                }
1242                else
1243                {
1244                        Py_INCREF(Py_None); val_obj = Py_None;
1245                }
1246                if (quoted) ++s;
1247                while (s != end && *s == ' ') ++s;
1248                if (s != end)
1249                {
1250                        if (*s++ != ',')
1251                        {
1252                                PyErr_SetString(PyExc_ValueError,
1253                                        "Invalid characters after val");
1254                                Py_DECREF(key_obj); Py_DECREF(val_obj);
1255                                Py_DECREF(result); return NULL;
1256                        }
1257                        while (s != end && *s == ' ') ++s;
1258                        if (s == end)
1259                        {
1260                                PyErr_SetString(PyExc_ValueError, "Missing entry");
1261                                Py_DECREF(key_obj); Py_DECREF(val_obj);
1262                                Py_DECREF(result); return NULL;
1263                        }
1264                }
1265                PyDict_SetItem(result, key_obj, val_obj);
1266                Py_DECREF(key_obj); Py_DECREF(val_obj);
1267        }
1268        return result;
1269}
1270
1271/* internal wrapper for the notice receiver callback */
1272static void
1273notice_receiver(void *arg, const PGresult *res)
1274{
1275        PyGILState_STATE gstate = PyGILState_Ensure();
1276        connObject *self = (connObject*) arg;
1277        PyObject *func = self->notice_receiver;
1278
1279        if (func)
1280        {
1281                noticeObject *notice = PyObject_NEW(noticeObject, &noticeType);
1282                PyObject *ret;
1283                if (notice)
1284                {
1285                        notice->pgcnx = arg;
1286                        notice->res = res;
1287                }
1288                else
1289                {
1290                        Py_INCREF(Py_None);
1291                        notice = (noticeObject *)(void *)Py_None;
1292                }
1293                ret = PyObject_CallFunction(func, "(O)", notice);
1294                Py_XDECREF(ret);
1295        }
1296        PyGILState_Release(gstate);
1297}
1298
1299/* gets appropriate error type from sqlstate */
1300static PyObject *
1301get_error_type(const char *sqlstate)
1302{
1303        switch (sqlstate[0]) {
1304                case '0':
1305                        switch (sqlstate[1])
1306                        {
1307                                case 'A':
1308                                        return NotSupportedError;
1309                        }
1310                        break;
1311                case '2':
1312                        switch (sqlstate[1])
1313                        {
1314                                case '0':
1315                                case '1':
1316                                        return ProgrammingError;
1317                                case '2':
1318                                        return DataError;
1319                                case '3':
1320                                        return IntegrityError;
1321                                case '4':
1322                                case '5':
1323                                        return InternalError;
1324                                case '6':
1325                                case '7':
1326                                case '8':
1327                                        return OperationalError;
1328                                case 'B':
1329                                case 'D':
1330                                case 'F':
1331                                        return InternalError;
1332                        }
1333                        break;
1334                case '3':
1335                        switch (sqlstate[1])
1336                        {
1337                                case '4':
1338                                        return OperationalError;
1339                                case '8':
1340                                case '9':
1341                                case 'B':
1342                                        return InternalError;
1343                                case 'D':
1344                                case 'F':
1345                                        return ProgrammingError;
1346                        }
1347                        break;
1348                case '4':
1349                        switch (sqlstate[1])
1350                        {
1351                                case '0':
1352                                        return OperationalError;
1353                                case '2':
1354                                case '4':
1355                                        return ProgrammingError;
1356                        }
1357                        break;
1358                case '5':
1359                case 'H':
1360                        return OperationalError;
1361                case 'F':
1362                case 'P':
1363                case 'X':
1364                        return InternalError;
1365        }
1366        return DatabaseError;
1367}
1368
1369/* sets database error message and sqlstate attribute */
1370static void
1371set_error_msg_and_state(PyObject *type,
1372        const char *msg, int encoding, const char *sqlstate)
1373{
1374        PyObject   *err_obj, *msg_obj, *sql_obj = NULL;
1375
1376#if IS_PY3
1377        if (encoding == -1) /* unknown */
1378        {
1379                msg_obj = PyUnicode_DecodeLocale(msg, NULL);
1380        }
1381        else
1382                msg_obj = get_decoded_string(msg, strlen(msg), encoding);
1383        if (!msg_obj) /* cannot decode */
1384#endif
1385        msg_obj = PyBytes_FromString(msg);
1386
1387        if (sqlstate)
1388                sql_obj = PyStr_FromStringAndSize(sqlstate, 5);
1389        else
1390        {
1391                Py_INCREF(Py_None); sql_obj = Py_None;
1392        }
1393
1394        err_obj = PyObject_CallFunctionObjArgs(type, msg_obj, NULL);
1395        if (err_obj)
1396        {
1397                Py_DECREF(msg_obj);
1398                PyObject_SetAttrString(err_obj, "sqlstate", sql_obj);
1399                Py_DECREF(sql_obj);
1400                PyErr_SetObject(type, err_obj);
1401                Py_DECREF(err_obj);
1402        }
1403        else
1404        {
1405                PyErr_SetString(type, msg);
1406        }
1407}
1408
1409/* sets given database error message */
1410static void
1411set_error_msg(PyObject *type, const char *msg)
1412{
1413        set_error_msg_and_state(type, msg, pg_encoding_ascii, NULL);
1414}
1415
1416/* sets database error from connection and/or result */
1417static void
1418set_error(PyObject *type, const char * msg, PGconn *cnx, PGresult *result)
1419{
1420        char *sqlstate = NULL; int encoding = pg_encoding_ascii;
1421
1422        if (cnx)
1423        {
1424                char *err_msg = PQerrorMessage(cnx);
1425                if (err_msg)
1426                {
1427                        msg = err_msg;
1428                        encoding = PQclientEncoding(cnx);
1429                }
1430        }
1431        if (result)
1432        {
1433                sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
1434                if (sqlstate) type = get_error_type(sqlstate);
1435        }
1436
1437        set_error_msg_and_state(type, msg, encoding, sqlstate);
1438}
1439
1440/* checks connection validity */
1441static int
1442check_cnx_obj(connObject *self)
1443{
1444        if (!self || !self->valid || !self->cnx)
1445        {
1446                set_error_msg(OperationalError, "Connection has been closed");
1447                return 0;
1448        }
1449        return 1;
1450}
1451
1452/* format result (mostly useful for debugging) */
1453/* Note: This is similar to the Postgres function PQprint().
1454 * PQprint() is not used because handing over a stream from Python to
1455 * Postgres can be problematic if they use different libs for streams
1456 * and because using PQprint() and tp_print is not recommended any more.
1457 */
1458static PyObject *
1459format_result(const PGresult *res)
1460{
1461        const int n = PQnfields(res);
1462
1463        if (n > 0)
1464        {
1465                char * const aligns = (char *) PyMem_Malloc(n * sizeof(char));
1466                int * const sizes = (int *) PyMem_Malloc(n * sizeof(int));
1467
1468                if (aligns && sizes)
1469                {
1470                        const int m = PQntuples(res);
1471                        int i, j;
1472                        size_t size;
1473                        char *buffer;
1474
1475                        /* calculate sizes and alignments */
1476                        for (j = 0; j < n; ++j)
1477                        {
1478                                const char * const s = PQfname(res, j);
1479                                const int format = PQfformat(res, j);
1480
1481                                sizes[j] = s ? (int)strlen(s) : 0;
1482                                if (format)
1483                                {
1484                                        aligns[j] = '\0';
1485                                        if (m && sizes[j] < 8)
1486                                                /* "<binary>" must fit */
1487                                                sizes[j] = 8;
1488                                }
1489                                else
1490                                {
1491                                        const Oid ftype = PQftype(res, j);
1492
1493                                        switch (ftype)
1494                                        {
1495                                                case INT2OID:
1496                                                case INT4OID:
1497                                                case INT8OID:
1498                                                case FLOAT4OID:
1499                                                case FLOAT8OID:
1500                                                case NUMERICOID:
1501                                                case OIDOID:
1502                                                case XIDOID:
1503                                                case CIDOID:
1504                                                case CASHOID:
1505                                                        aligns[j] = 'r';
1506                                                        break;
1507                                                default:
1508                                                        aligns[j] = 'l';
1509                                        }
1510                                }
1511                        }
1512                        for (i = 0; i < m; ++i)
1513                        {
1514                                for (j = 0; j < n; ++j)
1515                                {
1516                                        if (aligns[j])
1517                                        {
1518                                                const int k = PQgetlength(res, i, j);
1519
1520                                                if (sizes[j] < k)
1521                                                        /* value must fit */
1522                                                        sizes[j] = k;
1523                                        }
1524                                }
1525                        }
1526                        size = 0;
1527                        /* size of one row */
1528                        for (j = 0; j < n; ++j) size += sizes[j] + 1;
1529                        /* times number of rows incl. heading */
1530                        size *= (m + 2);
1531                        /* plus size of footer */
1532                        size += 40;
1533                        /* is the buffer size that needs to be allocated */
1534                        buffer = (char *) PyMem_Malloc(size);
1535                        if (buffer)
1536                        {
1537                                char *p = buffer;
1538                                PyObject *result;
1539
1540                                /* create the header */
1541                                for (j = 0; j < n; ++j)
1542                                {
1543                                        const char * const s = PQfname(res, j);
1544                                        const int k = sizes[j];
1545                                        const int h = (k - (int)strlen(s)) / 2;
1546
1547                                        sprintf(p, "%*s", h, "");
1548                                        sprintf(p + h, "%-*s", k - h, s);
1549                                        p += k;
1550                                        if (j + 1 < n)
1551                                                *p++ = '|';
1552                                }
1553                                *p++ = '\n';
1554                                for (j = 0; j < n; ++j)
1555                                {
1556                                        int k = sizes[j];
1557
1558                                        while (k--)
1559                                                *p++ = '-';
1560                                        if (j + 1 < n)
1561                                                *p++ = '+';
1562                                }
1563                                *p++ = '\n';
1564                                /* create the body */
1565                                for (i = 0; i < m; ++i)
1566                                {
1567                                        for (j = 0; j < n; ++j)
1568                                        {
1569                                                const char align = aligns[j];
1570                                                const int k = sizes[j];
1571
1572                                                if (align)
1573                                                {
1574                                                        sprintf(p, align == 'r' ?
1575                                                                "%*s" : "%-*s", k,
1576                                                                PQgetvalue(res, i, j));
1577                                                }
1578                                                else
1579                                                {
1580                                                        sprintf(p, "%-*s", k,
1581                                                                PQgetisnull(res, i, j) ?
1582                                                                "" : "<binary>");
1583                                                }
1584                                                p += k;
1585                                                if (j + 1 < n)
1586                                                        *p++ = '|';
1587                                        }
1588                                        *p++ = '\n';
1589                                }
1590                                /* free memory */
1591                                PyMem_Free(aligns); PyMem_Free(sizes);
1592                                /* create the footer */
1593                                sprintf(p, "(%d row%s)", m, m == 1 ? "" : "s");
1594                                /* return the result */
1595                                result = PyStr_FromString(buffer);
1596                                PyMem_Free(buffer);
1597                                return result;
1598                        }
1599                        else
1600                        {
1601                                PyMem_Free(aligns); PyMem_Free(sizes); return PyErr_NoMemory();
1602                        }
1603                }
1604                else
1605                {
1606                        PyMem_Free(aligns); PyMem_Free(sizes); return PyErr_NoMemory();
1607                }
1608        }
1609        else
1610                return PyStr_FromString("(nothing selected)");
1611}
1612
1613/* --------------------------------------------------------------------- */
1614/* large objects                                                                                                                 */
1615/* --------------------------------------------------------------------- */
1616#ifdef LARGE_OBJECTS
1617
1618/* checks large object validity */
1619static int
1620check_lo_obj(largeObject *self, int level)
1621{
1622        if (!check_cnx_obj(self->pgcnx))
1623                return 0;
1624
1625        if (!self->lo_oid)
1626        {
1627                set_error_msg(IntegrityError, "Object is not valid (null oid)");
1628                return 0;
1629        }
1630
1631        if (level & CHECK_OPEN)
1632        {
1633                if (self->lo_fd < 0)
1634                {
1635                        PyErr_SetString(PyExc_IOError, "Object is not opened");
1636                        return 0;
1637                }
1638        }
1639
1640        if (level & CHECK_CLOSE)
1641        {
1642                if (self->lo_fd >= 0)
1643                {
1644                        PyErr_SetString(PyExc_IOError, "Object is already opened");
1645                        return 0;
1646                }
1647        }
1648
1649        return 1;
1650}
1651
1652/* constructor (internal use only) */
1653static largeObject *
1654largeNew(connObject *pgcnx, Oid oid)
1655{
1656        largeObject *npglo;
1657
1658        if (!(npglo = PyObject_NEW(largeObject, &largeType)))
1659                return NULL;
1660
1661        Py_XINCREF(pgcnx);
1662        npglo->pgcnx = pgcnx;
1663        npglo->lo_fd = -1;
1664        npglo->lo_oid = oid;
1665
1666        return npglo;
1667}
1668
1669/* destructor */
1670static void
1671largeDealloc(largeObject *self)
1672{
1673        if (self->lo_fd >= 0 && self->pgcnx->valid)
1674                lo_close(self->pgcnx->cnx, self->lo_fd);
1675
1676        Py_XDECREF(self->pgcnx);
1677        PyObject_Del(self);
1678}
1679
1680/* opens large object */
1681static char largeOpen__doc__[] =
1682"open(mode) -- open access to large object with specified mode\n\n"
1683"The mode must be one of INV_READ, INV_WRITE (module level constants).\n";
1684
1685static PyObject *
1686largeOpen(largeObject *self, PyObject *args)
1687{
1688        int                     mode,
1689                                fd;
1690
1691        /* gets arguments */
1692        if (!PyArg_ParseTuple(args, "i", &mode))
1693        {
1694                PyErr_SetString(PyExc_TypeError,
1695                        "The open() method takes an integer argument");
1696                return NULL;
1697        }
1698
1699        /* check validity */
1700        if (!check_lo_obj(self, CHECK_CLOSE))
1701                return NULL;
1702
1703        /* opens large object */
1704        if ((fd = lo_open(self->pgcnx->cnx, self->lo_oid, mode)) == -1)
1705        {
1706                PyErr_SetString(PyExc_IOError, "Can't open large object");
1707                return NULL;
1708        }
1709        self->lo_fd = fd;
1710
1711        /* no error : returns Py_None */
1712        Py_INCREF(Py_None);
1713        return Py_None;
1714}
1715
1716/* close large object */
1717static char largeClose__doc__[] =
1718"close() -- close access to large object data";
1719
1720static PyObject *
1721largeClose(largeObject *self, PyObject *noargs)
1722{
1723        /* checks validity */
1724        if (!check_lo_obj(self, CHECK_OPEN))
1725                return NULL;
1726
1727        /* closes large object */
1728        if (lo_close(self->pgcnx->cnx, self->lo_fd))
1729        {
1730                PyErr_SetString(PyExc_IOError, "Error while closing large object fd");
1731                return NULL;
1732        }
1733        self->lo_fd = -1;
1734
1735        /* no error : returns Py_None */
1736        Py_INCREF(Py_None);
1737        return Py_None;
1738}
1739
1740/* reads from large object */
1741static char largeRead__doc__[] =
1742"read(size) -- read from large object to sized string\n\n"
1743"Object must be opened in read mode before calling this method.\n";
1744
1745static PyObject *
1746largeRead(largeObject *self, PyObject *args)
1747{
1748        int                     size;
1749        PyObject   *buffer;
1750
1751        /* gets arguments */
1752        if (!PyArg_ParseTuple(args, "i", &size))
1753        {
1754                PyErr_SetString(PyExc_TypeError,
1755                        "Method read() takes an integer argument");
1756                return NULL;
1757        }
1758
1759        if (size <= 0)
1760        {
1761                PyErr_SetString(PyExc_ValueError,
1762                        "Method read() takes a positive integer as argument");
1763                return NULL;
1764        }
1765
1766        /* checks validity */
1767        if (!check_lo_obj(self, CHECK_OPEN))
1768                return NULL;
1769
1770        /* allocate buffer and runs read */
1771        buffer = PyBytes_FromStringAndSize((char *) NULL, size);
1772
1773        if ((size = lo_read(self->pgcnx->cnx, self->lo_fd,
1774                PyBytes_AS_STRING((PyBytesObject *)(buffer)), size)) == -1)
1775        {
1776                PyErr_SetString(PyExc_IOError, "Error while reading");
1777                Py_XDECREF(buffer);
1778                return NULL;
1779        }
1780
1781        /* resize buffer and returns it */
1782        _PyBytes_Resize(&buffer, size);
1783        return buffer;
1784}
1785
1786/* write to large object */
1787static char largeWrite__doc__[] =
1788"write(string) -- write sized string to large object\n\n"
1789"Object must be opened in read mode before calling this method.\n";
1790
1791static PyObject *
1792largeWrite(largeObject *self, PyObject *args)
1793{
1794        char       *buffer;
1795        int                     size,
1796                                bufsize;
1797
1798        /* gets arguments */
1799        if (!PyArg_ParseTuple(args, "s#", &buffer, &bufsize))
1800        {
1801                PyErr_SetString(PyExc_TypeError,
1802                        "Method write() expects a sized string as argument");
1803                return NULL;
1804        }
1805
1806        /* checks validity */
1807        if (!check_lo_obj(self, CHECK_OPEN))
1808                return NULL;
1809
1810        /* sends query */
1811        if ((size = lo_write(self->pgcnx->cnx, self->lo_fd, buffer,
1812                                                 bufsize)) != bufsize)
1813        {
1814                PyErr_SetString(PyExc_IOError, "Buffer truncated during write");
1815                return NULL;
1816        }
1817
1818        /* no error : returns Py_None */
1819        Py_INCREF(Py_None);
1820        return Py_None;
1821}
1822
1823/* go to position in large object */
1824static char largeSeek__doc__[] =
1825"seek(offset, whence) -- move to specified position\n\n"
1826"Object must be opened before calling this method. The whence option\n"
1827"can be SEEK_SET, SEEK_CUR or SEEK_END (module level constants).\n";
1828
1829static PyObject *
1830largeSeek(largeObject *self, PyObject *args)
1831{
1832        /* offset and whence are initialized to keep compiler happy */
1833        int                     ret,
1834                                offset = 0,
1835                                whence = 0;
1836
1837        /* gets arguments */
1838        if (!PyArg_ParseTuple(args, "ii", &offset, &whence))
1839        {
1840                PyErr_SetString(PyExc_TypeError,
1841                        "Method lseek() expects two integer arguments");
1842                return NULL;
1843        }
1844
1845        /* checks validity */
1846        if (!check_lo_obj(self, CHECK_OPEN))
1847                return NULL;
1848
1849        /* sends query */
1850        if ((ret = lo_lseek(self->pgcnx->cnx, self->lo_fd, offset, whence)) == -1)
1851        {
1852                PyErr_SetString(PyExc_IOError, "Error while moving cursor");
1853                return NULL;
1854        }
1855
1856        /* returns position */
1857        return PyInt_FromLong(ret);
1858}
1859
1860/* gets large object size */
1861static char largeSize__doc__[] =
1862"size() -- return large object size\n\n"
1863"The object must be opened before calling this method.\n";
1864
1865static PyObject *
1866largeSize(largeObject *self, PyObject *noargs)
1867{
1868        int                     start,
1869                                end;
1870
1871        /* checks validity */
1872        if (!check_lo_obj(self, CHECK_OPEN))
1873                return NULL;
1874
1875        /* gets current position */
1876        if ((start = lo_tell(self->pgcnx->cnx, self->lo_fd)) == -1)
1877        {
1878                PyErr_SetString(PyExc_IOError, "Error while getting current position");
1879                return NULL;
1880        }
1881
1882        /* gets end position */
1883        if ((end = lo_lseek(self->pgcnx->cnx, self->lo_fd, 0, SEEK_END)) == -1)
1884        {
1885                PyErr_SetString(PyExc_IOError, "Error while getting end position");
1886                return NULL;
1887        }
1888
1889        /* move back to start position */
1890        if ((start = lo_lseek(
1891                self->pgcnx->cnx, self->lo_fd, start, SEEK_SET)) == -1)
1892        {
1893                PyErr_SetString(PyExc_IOError,
1894                        "Error while moving back to first position");
1895                return NULL;
1896        }
1897
1898        /* returns size */
1899        return PyInt_FromLong(end);
1900}
1901
1902/* gets large object cursor position */
1903static char largeTell__doc__[] =
1904"tell() -- give current position in large object\n\n"
1905"The object must be opened before calling this method.\n";
1906
1907static PyObject *
1908largeTell(largeObject *self, PyObject *noargs)
1909{
1910        int                     start;
1911
1912        /* checks validity */
1913        if (!check_lo_obj(self, CHECK_OPEN))
1914                return NULL;
1915
1916        /* gets current position */
1917        if ((start = lo_tell(self->pgcnx->cnx, self->lo_fd)) == -1)
1918        {
1919                PyErr_SetString(PyExc_IOError, "Error while getting position");
1920                return NULL;
1921        }
1922
1923        /* returns size */
1924        return PyInt_FromLong(start);
1925}
1926
1927/* exports large object as unix file */
1928static char largeExport__doc__[] =
1929"export(filename) -- export large object data to specified file\n\n"
1930"The object must be closed when calling this method.\n";
1931
1932static PyObject *
1933largeExport(largeObject *self, PyObject *args)
1934{
1935        char *name;
1936
1937        /* checks validity */
1938        if (!check_lo_obj(self, CHECK_CLOSE))
1939                return NULL;
1940
1941        /* gets arguments */
1942        if (!PyArg_ParseTuple(args, "s", &name))
1943        {
1944                PyErr_SetString(PyExc_TypeError,
1945                        "The method export() takes a filename as argument");
1946                return NULL;
1947        }
1948
1949        /* runs command */
1950        if (lo_export(self->pgcnx->cnx, self->lo_oid, name) != 1)
1951        {
1952                PyErr_SetString(PyExc_IOError, "Error while exporting large object");
1953                return NULL;
1954        }
1955
1956        Py_INCREF(Py_None);
1957        return Py_None;
1958}
1959
1960/* deletes a large object */
1961static char largeUnlink__doc__[] =
1962"unlink() -- destroy large object\n\n"
1963"The object must be closed when calling this method.\n";
1964
1965static PyObject *
1966largeUnlink(largeObject *self, PyObject *noargs)
1967{
1968        /* checks validity */
1969        if (!check_lo_obj(self, CHECK_CLOSE))
1970                return NULL;
1971
1972        /* deletes the object, invalidate it on success */
1973        if (lo_unlink(self->pgcnx->cnx, self->lo_oid) != 1)
1974        {
1975                PyErr_SetString(PyExc_IOError, "Error while unlinking large object");
1976                return NULL;
1977        }
1978        self->lo_oid = 0;
1979
1980        Py_INCREF(Py_None);
1981        return Py_None;
1982}
1983
1984/* get the list of large object attributes */
1985static PyObject *
1986largeDir(largeObject *self, PyObject *noargs)
1987{
1988        PyObject *attrs;
1989
1990        attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
1991        PyObject_CallMethod(attrs, "extend", "[sss]",
1992                "oid", "pgcnx", "error");
1993
1994        return attrs;
1995}
1996
1997/* large object methods */
1998static struct PyMethodDef largeMethods[] = {
1999        {"__dir__", (PyCFunction) largeDir,  METH_NOARGS, NULL},
2000        {"open", (PyCFunction) largeOpen, METH_VARARGS, largeOpen__doc__},
2001        {"close", (PyCFunction) largeClose, METH_NOARGS, largeClose__doc__},
2002        {"read", (PyCFunction) largeRead, METH_VARARGS, largeRead__doc__},
2003        {"write", (PyCFunction) largeWrite, METH_VARARGS, largeWrite__doc__},
2004        {"seek", (PyCFunction) largeSeek, METH_VARARGS, largeSeek__doc__},
2005        {"size", (PyCFunction) largeSize, METH_NOARGS, largeSize__doc__},
2006        {"tell", (PyCFunction) largeTell, METH_NOARGS, largeTell__doc__},
2007        {"export",(PyCFunction) largeExport, METH_VARARGS, largeExport__doc__},
2008        {"unlink",(PyCFunction) largeUnlink, METH_NOARGS, largeUnlink__doc__},
2009        {NULL, NULL}
2010};
2011
2012/* gets large object attributes */
2013static PyObject *
2014largeGetAttr(largeObject *self, PyObject *nameobj)
2015{
2016        const char *name = PyStr_AsString(nameobj);
2017
2018        /* list postgreSQL large object fields */
2019
2020        /* associated pg connection object */
2021        if (!strcmp(name, "pgcnx"))
2022        {
2023                if (check_lo_obj(self, 0))
2024                {
2025                        Py_INCREF(self->pgcnx);
2026                        return (PyObject *) (self->pgcnx);
2027                }
2028                PyErr_Clear();
2029                Py_INCREF(Py_None);
2030                return Py_None;
2031        }
2032
2033        /* large object oid */
2034        if (!strcmp(name, "oid"))
2035        {
2036                if (check_lo_obj(self, 0))
2037                        return PyInt_FromLong(self->lo_oid);
2038                PyErr_Clear();
2039                Py_INCREF(Py_None);
2040                return Py_None;
2041        }
2042
2043        /* error (status) message */
2044        if (!strcmp(name, "error"))
2045                return PyStr_FromString(PQerrorMessage(self->pgcnx->cnx));
2046
2047        /* seeks name in methods (fallback) */
2048        return PyObject_GenericGetAttr((PyObject *) self, nameobj);
2049}
2050
2051/* return large object as string in human readable form */
2052static PyObject *
2053largeStr(largeObject *self)
2054{
2055        char            str[80];
2056        sprintf(str, self->lo_fd >= 0 ?
2057                        "Opened large object, oid %ld" :
2058                        "Closed large object, oid %ld", (long) self->lo_oid);
2059        return PyStr_FromString(str);
2060}
2061
2062static char large__doc__[] = "PostgreSQL large object";
2063
2064/* large object type definition */
2065static PyTypeObject largeType = {
2066        PyVarObject_HEAD_INIT(NULL, 0)
2067        "pg.LargeObject",                               /* tp_name */
2068        sizeof(largeObject),                    /* tp_basicsize */
2069        0,                                                              /* tp_itemsize */
2070
2071        /* methods */
2072        (destructor) largeDealloc,              /* tp_dealloc */
2073        0,                                                              /* tp_print */
2074        0,                                                              /* tp_getattr */
2075        0,                                                              /* tp_setattr */
2076        0,                                                              /* tp_compare */
2077        0,                                                              /* tp_repr */
2078        0,                                                              /* tp_as_number */
2079        0,                                                              /* tp_as_sequence */
2080        0,                                                              /* tp_as_mapping */
2081        0,                                                              /* tp_hash */
2082        0,                                                              /* tp_call */
2083        (reprfunc) largeStr,                    /* tp_str */
2084        (getattrofunc) largeGetAttr,    /* tp_getattro */
2085        0,                                                              /* tp_setattro */
2086        0,                                                              /* tp_as_buffer */
2087        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
2088        large__doc__,                                   /* tp_doc */
2089        0,                                                              /* tp_traverse */
2090        0,                                                              /* tp_clear */
2091        0,                                                              /* tp_richcompare */
2092        0,                                                              /* tp_weaklistoffset */
2093        0,                                                              /* tp_iter */
2094        0,                                                              /* tp_iternext */
2095        largeMethods,                                   /* tp_methods */
2096};
2097#endif /* LARGE_OBJECTS */
2098
2099/* --------------------------------------------------------------------- */
2100/* connection object                                                                                                     */
2101/* --------------------------------------------------------------------- */
2102static void
2103connDelete(connObject *self)
2104{
2105        if (self->cnx)
2106        {
2107                Py_BEGIN_ALLOW_THREADS
2108                PQfinish(self->cnx);
2109                Py_END_ALLOW_THREADS
2110        }
2111        Py_XDECREF(self->cast_hook);
2112        Py_XDECREF(self->notice_receiver);
2113        PyObject_Del(self);
2114}
2115
2116/* source creation */
2117static char connSource__doc__[] =
2118"source() -- create a new source object for this connection";
2119
2120static PyObject *
2121connSource(connObject *self, PyObject *noargs)
2122{
2123        sourceObject *npgobj;
2124
2125        /* checks validity */
2126        if (!check_cnx_obj(self))
2127                return NULL;
2128
2129        /* allocates new query object */
2130        if (!(npgobj = PyObject_NEW(sourceObject, &sourceType)))
2131                return NULL;
2132
2133        /* initializes internal parameters */
2134        Py_XINCREF(self);
2135        npgobj->pgcnx = self;
2136        npgobj->result = NULL;
2137        npgobj->valid = 1;
2138        npgobj->arraysize = PG_ARRAYSIZE;
2139
2140        return (PyObject *) npgobj;
2141}
2142
2143/* database query */
2144static char connQuery__doc__[] =
2145"query(sql, [arg]) -- create a new query object for this connection\n\n"
2146"You must pass the SQL (string) request and you can optionally pass\n"
2147"a tuple with positional parameters.\n";
2148
2149static PyObject *
2150connQuery(connObject *self, PyObject *args)
2151{
2152        PyObject        *query_obj;
2153        PyObject        *param_obj = NULL;
2154        char            *query;
2155        PGresult        *result;
2156        queryObject *npgobj;
2157        int                     encoding,
2158                                status,
2159                                nparms = 0;
2160
2161        if (!self->cnx)
2162        {
2163                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2164                return NULL;
2165        }
2166
2167        /* get query args */
2168        if (!PyArg_ParseTuple(args, "O|O", &query_obj, &param_obj))
2169        {
2170                return NULL;
2171        }
2172
2173        encoding = PQclientEncoding(self->cnx);
2174
2175        if (PyBytes_Check(query_obj))
2176        {
2177                query = PyBytes_AsString(query_obj);
2178                query_obj = NULL;
2179        }
2180        else if (PyUnicode_Check(query_obj))
2181        {
2182                query_obj = get_encoded_string(query_obj, encoding);
2183                if (!query_obj) return NULL; /* pass the UnicodeEncodeError */
2184                query = PyBytes_AsString(query_obj);
2185        }
2186        else
2187        {
2188                PyErr_SetString(PyExc_TypeError,
2189                        "Method query() expects a string as first argument");
2190                return NULL;
2191        }
2192
2193        /* If param_obj is passed, ensure it's a non-empty tuple. We want to treat
2194         * an empty tuple the same as no argument since we'll get that when the
2195         * caller passes no arguments to db.query(), and historic behaviour was
2196         * to call PQexec() in that case, which can execute multiple commands. */
2197        if (param_obj)
2198        {
2199                param_obj = PySequence_Fast(param_obj,
2200                        "Method query() expects a sequence as second argument");
2201                if (!param_obj)
2202                {
2203                        Py_XDECREF(query_obj);
2204                        return NULL;
2205                }
2206                nparms = (int)PySequence_Fast_GET_SIZE(param_obj);
2207
2208                /* if there's a single argument and it's a list or tuple, it
2209                 * contains the positional arguments. */
2210                if (nparms == 1)
2211                {
2212                        PyObject *first_obj = PySequence_Fast_GET_ITEM(param_obj, 0);
2213                        if (PyList_Check(first_obj) || PyTuple_Check(first_obj))
2214                        {
2215                                Py_DECREF(param_obj);
2216                                param_obj = PySequence_Fast(first_obj, NULL);
2217                                nparms = (int)PySequence_Fast_GET_SIZE(param_obj);
2218                        }
2219                }
2220        }
2221
2222        /* gets result */
2223        if (nparms)
2224        {
2225                /* prepare arguments */
2226                PyObject        **str, **s;
2227                char            **parms, **p;
2228                register int i;
2229
2230                str = (PyObject **)PyMem_Malloc(nparms * sizeof(*str));
2231                parms = (char **)PyMem_Malloc(nparms * sizeof(*parms));
2232                if (!str || !parms)
2233                {
2234                        PyMem_Free(parms); PyMem_Free(str);
2235                        Py_XDECREF(query_obj); Py_XDECREF(param_obj);
2236                        return PyErr_NoMemory();
2237                }
2238
2239                /* convert optional args to a list of strings -- this allows
2240                 * the caller to pass whatever they like, and prevents us
2241                 * from having to map types to OIDs */
2242                for (i = 0, s=str, p=parms; i < nparms; ++i, ++p)
2243                {
2244                        PyObject *obj = PySequence_Fast_GET_ITEM(param_obj, i);
2245
2246                        if (obj == Py_None)
2247                        {
2248                                *p = NULL;
2249                        }
2250                        else if (PyBytes_Check(obj))
2251                        {
2252                                *p = PyBytes_AsString(obj);
2253                        }
2254                        else if (PyUnicode_Check(obj))
2255                        {
2256                                PyObject *str_obj = get_encoded_string(obj, encoding);
2257                                if (!str_obj)
2258                                {
2259                                        PyMem_Free(parms);
2260                                        while (s != str) { s--; Py_DECREF(*s); }
2261                                        PyMem_Free(str);
2262                                        Py_XDECREF(query_obj);
2263                                        Py_XDECREF(param_obj);
2264                                        /* pass the UnicodeEncodeError */
2265                                        return NULL;
2266                                }
2267                                *s++ = str_obj;
2268                                *p = PyBytes_AsString(str_obj);
2269                        }
2270                        else
2271                        {
2272                                PyObject *str_obj = PyObject_Str(obj);
2273                                if (!str_obj)
2274                                {
2275                                        PyMem_Free(parms);
2276                                        while (s != str) { s--; Py_DECREF(*s); }
2277                                        PyMem_Free(str);
2278                                        Py_XDECREF(query_obj);
2279                                        Py_XDECREF(param_obj);
2280                                        PyErr_SetString(PyExc_TypeError,
2281                                                "Query parameter has no string representation");
2282                                        return NULL;
2283                                }
2284                                *s++ = str_obj;
2285                                *p = PyStr_AsString(str_obj);
2286                        }
2287                }
2288
2289                Py_BEGIN_ALLOW_THREADS
2290                result = PQexecParams(self->cnx, query, nparms,
2291                        NULL, (const char * const *)parms, NULL, NULL, 0);
2292                Py_END_ALLOW_THREADS
2293
2294                PyMem_Free(parms);
2295                while (s != str) { s--; Py_DECREF(*s); }
2296                PyMem_Free(str);
2297        }
2298        else
2299        {
2300                Py_BEGIN_ALLOW_THREADS
2301                result = PQexec(self->cnx, query);
2302                Py_END_ALLOW_THREADS
2303        }
2304
2305        /* we don't need the query and its params any more */
2306        Py_XDECREF(query_obj);
2307        Py_XDECREF(param_obj);
2308
2309        /* checks result validity */
2310        if (!result)
2311        {
2312                PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->cnx));
2313                return NULL;
2314        }
2315
2316        /* this may have changed the datestyle, so we reset the date format
2317           in order to force fetching it newly when next time requested */
2318        self->date_format = date_format; /* this is normally NULL */
2319
2320        /* checks result status */
2321        if ((status = PQresultStatus(result)) != PGRES_TUPLES_OK)
2322        {
2323                switch (status)
2324                {
2325                        case PGRES_EMPTY_QUERY:
2326                                PyErr_SetString(PyExc_ValueError, "Empty query");
2327                                break;
2328                        case PGRES_BAD_RESPONSE:
2329                        case PGRES_FATAL_ERROR:
2330                        case PGRES_NONFATAL_ERROR:
2331                                set_error(ProgrammingError, "Cannot execute query",
2332                                        self->cnx, result);
2333                                break;
2334                        case PGRES_COMMAND_OK:
2335                                {                                               /* INSERT, UPDATE, DELETE */
2336                                        Oid             oid = PQoidValue(result);
2337                                        if (oid == InvalidOid)  /* not a single insert */
2338                                        {
2339                                                char    *ret = PQcmdTuples(result);
2340
2341                                                PQclear(result);
2342                                                if (ret[0])             /* return number of rows affected */
2343                                                {
2344                                                        return PyStr_FromString(ret);
2345                                                }
2346                                                Py_INCREF(Py_None);
2347                                                return Py_None;
2348                                        }
2349                                        /* for a single insert, return the oid */
2350                                        PQclear(result);
2351                                        return PyInt_FromLong(oid);
2352                                }
2353                        case PGRES_COPY_OUT:            /* no data will be received */
2354                        case PGRES_COPY_IN:
2355                                PQclear(result);
2356                                Py_INCREF(Py_None);
2357                                return Py_None;
2358                        default:
2359                                set_error_msg(InternalError, "Unknown result status");
2360                }
2361
2362                PQclear(result);
2363                return NULL;                    /* error detected on query */
2364        }
2365
2366        if (!(npgobj = PyObject_NEW(queryObject, &queryType)))
2367                return PyErr_NoMemory();
2368
2369        /* stores result and returns object */
2370        Py_XINCREF(self);
2371        npgobj->pgcnx = self;
2372        npgobj->result = result;
2373        npgobj->encoding = encoding;
2374        return (PyObject *) npgobj;
2375}
2376
2377#ifdef DIRECT_ACCESS
2378static char connPutLine__doc__[] =
2379"putline(line) -- send a line directly to the backend";
2380
2381/* direct access function: putline */
2382static PyObject *
2383connPutLine(connObject *self, PyObject *args)
2384{
2385        char *line;
2386        int line_length;
2387
2388        if (!self->cnx)
2389        {
2390                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2391                return NULL;
2392        }
2393
2394        /* reads args */
2395        if (!PyArg_ParseTuple(args, "s#", &line, &line_length))
2396        {
2397                PyErr_SetString(PyExc_TypeError,
2398                        "Method putline() takes a string argument");
2399                return NULL;
2400        }
2401
2402        /* sends line to backend */
2403        if (PQputline(self->cnx, line))
2404        {
2405                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2406                return NULL;
2407        }
2408        Py_INCREF(Py_None);
2409        return Py_None;
2410}
2411
2412/* direct access function: getline */
2413static char connGetLine__doc__[] =
2414"getline() -- get a line directly from the backend";
2415
2416static PyObject *
2417connGetLine(connObject *self, PyObject *noargs)
2418{
2419        char            line[MAX_BUFFER_SIZE];
2420        PyObject   *str = NULL;         /* GCC */
2421
2422        if (!self->cnx)
2423        {
2424                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2425                return NULL;
2426        }
2427
2428        /* gets line */
2429        switch (PQgetline(self->cnx, line, MAX_BUFFER_SIZE))
2430        {
2431                case 0:
2432                        str = PyStr_FromString(line);
2433                        break;
2434                case 1:
2435                        PyErr_SetString(PyExc_MemoryError, "Buffer overflow");
2436                        str = NULL;
2437                        break;
2438                case EOF:
2439                        Py_INCREF(Py_None);
2440                        str = Py_None;
2441                        break;
2442        }
2443
2444        return str;
2445}
2446
2447/* direct access function: end copy */
2448static char connEndCopy__doc__[] =
2449"endcopy() -- synchronize client and server";
2450
2451static PyObject *
2452connEndCopy(connObject *self, PyObject *noargs)
2453{
2454        if (!self->cnx)
2455        {
2456                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2457                return NULL;
2458        }
2459
2460        /* ends direct copy */
2461        if (PQendcopy(self->cnx))
2462        {
2463                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2464                return NULL;
2465        }
2466        Py_INCREF(Py_None);
2467        return Py_None;
2468}
2469#endif /* DIRECT_ACCESS */
2470
2471/* return query as string in human readable form */
2472static PyObject *
2473queryStr(queryObject *self)
2474{
2475        return format_result(self->result);
2476}
2477
2478/* insert table */
2479static char connInsertTable__doc__[] =
2480"inserttable(table, data) -- insert list into table\n\n"
2481"The fields in the list must be in the same order as in the table.\n";
2482
2483static PyObject *
2484connInsertTable(connObject *self, PyObject *args)
2485{
2486        PGresult        *result;
2487        char            *table,
2488                                *buffer,
2489                                *bufpt;
2490        int                     encoding;
2491        size_t          bufsiz;
2492        PyObject        *list,
2493                                *sublist,
2494                                *item;
2495        PyObject        *(*getitem) (PyObject *, Py_ssize_t);
2496        PyObject        *(*getsubitem) (PyObject *, Py_ssize_t);
2497        Py_ssize_t      i,
2498                                j,
2499                                m,
2500                                n;
2501
2502        if (!self->cnx)
2503        {
2504                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2505                return NULL;
2506        }
2507
2508        /* gets arguments */
2509        if (!PyArg_ParseTuple(args, "sO:filter", &table, &list))
2510        {
2511                PyErr_SetString(PyExc_TypeError,
2512                        "Method inserttable() expects a string and a list as arguments");
2513                return NULL;
2514        }
2515
2516        /* checks list type */
2517        if (PyTuple_Check(list))
2518        {
2519                m = PyTuple_Size(list);
2520                getitem = PyTuple_GetItem;
2521        }
2522        else if (PyList_Check(list))
2523        {
2524                m = PyList_Size(list);
2525                getitem = PyList_GetItem;
2526        }
2527        else
2528        {
2529                PyErr_SetString(PyExc_TypeError,
2530                        "Method inserttable() expects some kind of array"
2531                        " as second argument");
2532                return NULL;
2533        }
2534
2535        /* allocate buffer */
2536        if (!(buffer = PyMem_Malloc(MAX_BUFFER_SIZE)))
2537                return PyErr_NoMemory();
2538
2539        /* starts query */
2540        sprintf(buffer, "copy %s from stdin", table);
2541
2542        Py_BEGIN_ALLOW_THREADS
2543        result = PQexec(self->cnx, buffer);
2544        Py_END_ALLOW_THREADS
2545
2546        if (!result)
2547        {
2548                PyMem_Free(buffer);
2549                PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->cnx));
2550                return NULL;
2551        }
2552
2553        encoding = PQclientEncoding(self->cnx);
2554
2555        PQclear(result);
2556
2557        n = 0; /* not strictly necessary but avoids warning */
2558
2559        /* feed table */
2560        for (i = 0; i < m; ++i)
2561        {
2562                sublist = getitem(list, i);
2563                if (PyTuple_Check(sublist))
2564                {
2565                        j = PyTuple_Size(sublist);
2566                        getsubitem = PyTuple_GetItem;
2567                }
2568                else if (PyList_Check(sublist))
2569                {
2570                        j = PyList_Size(sublist);
2571                        getsubitem = PyList_GetItem;
2572                }
2573                else
2574                {
2575                        PyErr_SetString(PyExc_TypeError,
2576                                "Second arg must contain some kind of arrays");
2577                        return NULL;
2578                }
2579                if (i)
2580                {
2581                        if (j != n)
2582                        {
2583                                PyMem_Free(buffer);
2584                                PyErr_SetString(PyExc_TypeError,
2585                                        "Arrays contained in second arg must have same size");
2586                                return NULL;
2587                        }
2588                }
2589                else
2590                {
2591                        n = j; /* never used before this assignment */
2592                }
2593
2594                /* builds insert line */
2595                bufpt = buffer;
2596                bufsiz = MAX_BUFFER_SIZE - 1;
2597
2598                for (j = 0; j < n; ++j)
2599                {
2600                        if (j)
2601                        {
2602                                *bufpt++ = '\t'; --bufsiz;
2603                        }
2604
2605                        item = getsubitem(sublist, j);
2606
2607                        /* convert item to string and append to buffer */
2608                        if (item == Py_None)
2609                        {
2610                                if (bufsiz > 2)
2611                                {
2612                                        *bufpt++ = '\\'; *bufpt++ = 'N';
2613                                        bufsiz -= 2;
2614                                }
2615                                else
2616                                        bufsiz = 0;
2617                        }
2618                        else if (PyBytes_Check(item))
2619                        {
2620                                const char* t = PyBytes_AsString(item);
2621                                while (*t && bufsiz)
2622                                {
2623                                        if (*t == '\\' || *t == '\t' || *t == '\n')
2624                                        {
2625                                                *bufpt++ = '\\'; --bufsiz;
2626                                                if (!bufsiz) break;
2627                                        }
2628                                        *bufpt++ = *t++; --bufsiz;
2629                                }
2630                        }
2631                        else if (PyUnicode_Check(item))
2632                        {
2633                                PyObject *s = get_encoded_string(item, encoding);
2634                                if (!s)
2635                                {
2636                                        PyMem_Free(buffer);
2637                                        return NULL; /* pass the UnicodeEncodeError */
2638                                }
2639                                else
2640                                {
2641                                        const char* t = PyBytes_AsString(s);
2642                                        while (*t && bufsiz)
2643                                        {
2644                                                if (*t == '\\' || *t == '\t' || *t == '\n')
2645                                                {
2646                                                        *bufpt++ = '\\'; --bufsiz;
2647                                                        if (!bufsiz) break;
2648                                                }
2649                                                *bufpt++ = *t++; --bufsiz;
2650                                        }
2651                                        Py_DECREF(s);
2652                                }
2653                        }
2654                        else if (PyInt_Check(item) || PyLong_Check(item))
2655                        {
2656                                PyObject* s = PyObject_Str(item);
2657                                const char* t = PyStr_AsString(s);
2658                                while (*t && bufsiz)
2659                                {
2660                                        *bufpt++ = *t++; --bufsiz;
2661                                }
2662                                Py_DECREF(s);
2663                        }
2664                        else
2665                        {
2666                                PyObject* s = PyObject_Repr(item);
2667                                const char* t = PyStr_AsString(s);
2668                                while (*t && bufsiz)
2669                                {
2670                                        if (*t == '\\' || *t == '\t' || *t == '\n')
2671                                        {
2672                                                *bufpt++ = '\\'; --bufsiz;
2673                                                if (!bufsiz) break;
2674                                        }
2675                                        *bufpt++ = *t++; --bufsiz;
2676                                }
2677                                Py_DECREF(s);
2678                        }
2679
2680                        if (bufsiz <= 0)
2681                        {
2682                                PyMem_Free(buffer); return PyErr_NoMemory();
2683                        }
2684
2685                }
2686
2687                *bufpt++ = '\n'; *bufpt = '\0';
2688
2689                /* sends data */
2690                if (PQputline(self->cnx, buffer))
2691                {
2692                        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2693                        PQendcopy(self->cnx);
2694                        PyMem_Free(buffer);
2695                        return NULL;
2696                }
2697        }
2698
2699        /* ends query */
2700        if (PQputline(self->cnx, "\\.\n"))
2701        {
2702                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2703                PQendcopy(self->cnx);
2704                PyMem_Free(buffer);
2705                return NULL;
2706        }
2707
2708        if (PQendcopy(self->cnx))
2709        {
2710                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2711                PyMem_Free(buffer);
2712                return NULL;
2713        }
2714
2715        PyMem_Free(buffer);
2716
2717        /* no error : returns nothing */
2718        Py_INCREF(Py_None);
2719        return Py_None;
2720}
2721
2722/* get transaction state */
2723static char connTransaction__doc__[] =
2724"transaction() -- return the current transaction status";
2725
2726static PyObject *
2727connTransaction(connObject *self, PyObject *noargs)
2728{
2729        if (!self->cnx)
2730        {
2731                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2732                return NULL;
2733        }
2734
2735        return PyInt_FromLong(PQtransactionStatus(self->cnx));
2736}
2737
2738/* get parameter setting */
2739static char connParameter__doc__[] =
2740"parameter(name) -- look up a current parameter setting";
2741
2742static PyObject *
2743connParameter(connObject *self, PyObject *args)
2744{
2745        const char *name;
2746
2747        if (!self->cnx)
2748        {
2749                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2750                return NULL;
2751        }
2752
2753        /* get query args */
2754        if (!PyArg_ParseTuple(args, "s", &name))
2755        {
2756                PyErr_SetString(PyExc_TypeError,
2757                        "Method parameter() takes a string as argument");
2758                return NULL;
2759        }
2760
2761        name = PQparameterStatus(self->cnx, name);
2762
2763        if (name)
2764                return PyStr_FromString(name);
2765
2766        /* unknown parameter, return None */
2767        Py_INCREF(Py_None);
2768        return Py_None;
2769}
2770
2771/* internal function converting a Postgres datestyles to date formats */
2772static const char *
2773date_style_to_format(const char *s)
2774{
2775        static const char *formats[] = {
2776                "%Y-%m-%d",             /* 0 = ISO */
2777                "%m-%d-%Y",             /* 1 = Postgres, MDY */
2778                "%d-%m-%Y",             /* 2 = Postgres, DMY */
2779                "%m/%d/%Y",             /* 3 = SQL, MDY */
2780                "%d/%m/%Y",             /* 4 = SQL, DMY */
2781                "%d.%m.%Y"};    /* 5 = German */
2782
2783        switch (s ? *s : 'I')
2784        {
2785                case 'P': /* Postgres */
2786                        s = strchr(s + 1, ',');
2787                        if (s) do ++s; while (*s && *s == ' ');
2788                        return formats[s && *s == 'D' ? 2 : 1];
2789                case 'S': /* SQL */
2790                        s = strchr(s + 1, ',');
2791                        if (s) do ++s; while (*s && *s == ' ');
2792                        return formats[s && *s == 'D' ? 4 : 3];
2793                case 'G': /* German */
2794                        return formats[5];
2795                default: /* ISO */
2796                        return formats[0]; /* ISO is the default */
2797        }
2798}
2799
2800/* internal function converting a date format to a Postgres datestyle */
2801static const char *
2802date_format_to_style(const char *s)
2803{
2804        static const char *datestyle[] = {
2805                "ISO, YMD",                     /* 0 = %Y-%m-%d */
2806                "Postgres, MDY",        /* 1 = %m-%d-%Y */
2807                "Postgres, DMY",        /* 2 = %d-%m-%Y */
2808                "SQL, MDY",             /* 3 = %m/%d/%Y */
2809                "SQL, DMY",             /* 4 = %d/%m/%Y */
2810                "German, DMY"};         /* 5 = %d.%m.%Y */
2811
2812        switch (s ? s[1] : 'Y')
2813        {
2814                case 'm':
2815                        switch (s[2])
2816                        {
2817                                case '/':
2818                                        return datestyle[3]; /* SQL, MDY */
2819                                default:
2820                                        return datestyle[1]; /* Postgres, MDY */
2821                        }
2822                case 'd':
2823                        switch (s[2])
2824                        {
2825                                case '/':
2826                                        return datestyle[4]; /* SQL, DMY */
2827                                case '.':
2828                                        return datestyle[5]; /* German */
2829                                default:
2830                                        return datestyle[2]; /* Postgres, DMY */
2831                        }
2832                default:
2833                        return datestyle[0]; /* ISO */
2834        }
2835}
2836
2837/* get current date format */
2838static char connDateFormat__doc__[] =
2839"date_format() -- return the current date format";
2840
2841static PyObject *
2842connDateFormat(connObject *self, PyObject *noargs)
2843{
2844        const char *fmt;
2845
2846        if (!self->cnx)
2847        {
2848                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2849                return NULL;
2850        }
2851
2852        /* check if the date format is cached in the connection */
2853        fmt = self->date_format;
2854        if (!fmt)
2855        {
2856                fmt = date_style_to_format(PQparameterStatus(self->cnx, "DateStyle"));
2857                self->date_format = fmt; /* cache the result */
2858        }
2859
2860        return PyStr_FromString(fmt);
2861}
2862
2863#ifdef ESCAPING_FUNCS
2864
2865/* escape literal */
2866static char connEscapeLiteral__doc__[] =
2867"escape_literal(str) -- escape a literal constant for use within SQL";
2868
2869static PyObject *
2870connEscapeLiteral(connObject *self, PyObject *string)
2871{
2872        PyObject   *tmp_obj = NULL, /* auxiliary string object */
2873                           *to_obj; /* string object to return */
2874        char       *from, /* our string argument as encoded string */
2875                           *to; /* the result as encoded string */
2876        Py_ssize_t      from_length; /* length of string */
2877        size_t          to_length; /* length of result */
2878        int                     encoding = -1; /* client encoding */
2879
2880        if (PyBytes_Check(string))
2881        {
2882                PyBytes_AsStringAndSize(string, &from, &from_length);
2883        }
2884        else if (PyUnicode_Check(string))
2885        {
2886                encoding = PQclientEncoding(self->cnx);
2887                tmp_obj = get_encoded_string(string, encoding);
2888                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
2889                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
2890        }
2891        else
2892        {
2893                PyErr_SetString(PyExc_TypeError,
2894                        "Method escape_literal() expects a string as argument");
2895                return NULL;
2896        }
2897
2898        to = PQescapeLiteral(self->cnx, from, (size_t)from_length);
2899        to_length = strlen(to);
2900
2901        Py_XDECREF(tmp_obj);
2902
2903        if (encoding == -1)
2904                to_obj = PyBytes_FromStringAndSize(to, to_length);
2905        else
2906                to_obj = get_decoded_string(to, to_length, encoding);
2907        if (to)
2908                PQfreemem(to);
2909        return to_obj;
2910}
2911
2912/* escape identifier */
2913static char connEscapeIdentifier__doc__[] =
2914"escape_identifier(str) -- escape an identifier for use within SQL";
2915
2916static PyObject *
2917connEscapeIdentifier(connObject *self, PyObject *string)
2918{
2919        PyObject   *tmp_obj = NULL, /* auxiliary string object */
2920                           *to_obj; /* string object to return */
2921        char       *from, /* our string argument as encoded string */
2922                           *to; /* the result as encoded string */
2923        Py_ssize_t      from_length; /* length of string */
2924        size_t          to_length; /* length of result */
2925        int                     encoding = -1; /* client encoding */
2926
2927        if (PyBytes_Check(string))
2928        {
2929                PyBytes_AsStringAndSize(string, &from, &from_length);
2930        }
2931        else if (PyUnicode_Check(string))
2932        {
2933                encoding = PQclientEncoding(self->cnx);
2934                tmp_obj = get_encoded_string(string, encoding);
2935                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
2936                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
2937        }
2938        else
2939        {
2940                PyErr_SetString(PyExc_TypeError,
2941                        "Method escape_identifier() expects a string as argument");
2942                return NULL;
2943        }
2944
2945        to = PQescapeIdentifier(self->cnx, from, (size_t)from_length);
2946        to_length = strlen(to);
2947
2948        Py_XDECREF(tmp_obj);
2949
2950        if (encoding == -1)
2951                to_obj = PyBytes_FromStringAndSize(to, to_length);
2952        else
2953                to_obj = get_decoded_string(to, to_length, encoding);
2954        if (to)
2955                PQfreemem(to);
2956        return to_obj;
2957}
2958
2959#endif  /* ESCAPING_FUNCS */
2960
2961/* escape string */
2962static char connEscapeString__doc__[] =
2963"escape_string(str) -- escape a string for use within SQL";
2964
2965static PyObject *
2966connEscapeString(connObject *self, PyObject *string)
2967{
2968        PyObject   *tmp_obj = NULL, /* auxiliary string object */
2969                           *to_obj; /* string object to return */
2970        char       *from, /* our string argument as encoded string */
2971                           *to; /* the result as encoded string */
2972        Py_ssize_t      from_length; /* length of string */
2973        size_t          to_length; /* length of result */
2974        int                     encoding = -1; /* client encoding */
2975
2976        if (PyBytes_Check(string))
2977        {
2978                PyBytes_AsStringAndSize(string, &from, &from_length);
2979        }
2980        else if (PyUnicode_Check(string))
2981        {
2982                encoding = PQclientEncoding(self->cnx);
2983                tmp_obj = get_encoded_string(string, encoding);
2984                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
2985                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
2986        }
2987        else
2988        {
2989                PyErr_SetString(PyExc_TypeError,
2990                        "Method escape_string() expects a string as argument");
2991                return NULL;
2992        }
2993
2994        to_length = 2*from_length + 1;
2995        if ((Py_ssize_t)to_length < from_length) /* overflow */
2996        {
2997                to_length = from_length;
2998                from_length = (from_length - 1)/2;
2999        }
3000        to = (char *)PyMem_Malloc(to_length);
3001        to_length = PQescapeStringConn(self->cnx,
3002                to, from, (size_t)from_length, NULL);
3003
3004        Py_XDECREF(tmp_obj);
3005
3006        if (encoding == -1)
3007                to_obj = PyBytes_FromStringAndSize(to, to_length);
3008        else
3009                to_obj = get_decoded_string(to, to_length, encoding);
3010        PyMem_Free(to);
3011        return to_obj;
3012}
3013
3014/* escape bytea */
3015static char connEscapeBytea__doc__[] =
3016"escape_bytea(data) -- escape binary data for use within SQL as type bytea";
3017
3018static PyObject *
3019connEscapeBytea(connObject *self, PyObject *data)
3020{
3021        PyObject   *tmp_obj = NULL, /* auxiliary string object */
3022                           *to_obj; /* string object to return */
3023        char       *from, /* our string argument as encoded string */
3024                           *to; /* the result as encoded string */
3025        Py_ssize_t      from_length; /* length of string */
3026        size_t          to_length; /* length of result */
3027        int                     encoding = -1; /* client encoding */
3028
3029        if (PyBytes_Check(data))
3030        {
3031                PyBytes_AsStringAndSize(data, &from, &from_length);
3032        }
3033        else if (PyUnicode_Check(data))
3034        {
3035                encoding = PQclientEncoding(self->cnx);
3036                tmp_obj = get_encoded_string(data, encoding);
3037                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3038                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
3039        }
3040        else
3041        {
3042                PyErr_SetString(PyExc_TypeError,
3043                        "Method escape_bytea() expects a string as argument");
3044                return NULL;
3045        }
3046
3047        to = (char *)PQescapeByteaConn(self->cnx,
3048                (unsigned char *)from, (size_t)from_length, &to_length);
3049
3050        Py_XDECREF(tmp_obj);
3051
3052        if (encoding == -1)
3053                to_obj = PyBytes_FromStringAndSize(to, to_length - 1);
3054        else
3055                to_obj = get_decoded_string(to, to_length - 1, encoding);
3056        if (to)
3057                PQfreemem(to);
3058        return to_obj;
3059}
3060
3061#ifdef LARGE_OBJECTS
3062/* creates large object */
3063static char connCreateLO__doc__[] =
3064"locreate(mode) -- create a new large object in the database";
3065
3066static PyObject *
3067connCreateLO(connObject *self, PyObject *args)
3068{
3069        int                     mode;
3070        Oid                     lo_oid;
3071
3072        /* checks validity */
3073        if (!check_cnx_obj(self))
3074                return NULL;
3075
3076        /* gets arguments */
3077        if (!PyArg_ParseTuple(args, "i", &mode))
3078        {
3079                PyErr_SetString(PyExc_TypeError,
3080                        "Method locreate() takes an integer argument");
3081                return NULL;
3082        }
3083
3084        /* creates large object */
3085        lo_oid = lo_creat(self->cnx, mode);
3086        if (lo_oid == 0)
3087        {
3088                set_error_msg(OperationalError, "Can't create large object");
3089                return NULL;
3090        }
3091
3092        return (PyObject *) largeNew(self, lo_oid);
3093}
3094
3095/* init from already known oid */
3096static char connGetLO__doc__[] =
3097"getlo(oid) -- create a large object instance for the specified oid";
3098
3099static PyObject *
3100connGetLO(connObject *self, PyObject *args)
3101{
3102        int                     oid;
3103        Oid                     lo_oid;
3104
3105        /* checks validity */
3106        if (!check_cnx_obj(self))
3107                return NULL;
3108
3109        /* gets arguments */
3110        if (!PyArg_ParseTuple(args, "i", &oid))
3111        {
3112                PyErr_SetString(PyExc_TypeError,
3113                        "Method getlo() takes an integer argument");
3114                return NULL;
3115        }
3116
3117        lo_oid = (Oid)oid;
3118        if (lo_oid == 0)
3119        {
3120                PyErr_SetString(PyExc_ValueError, "The object oid can't be null");
3121                return NULL;
3122        }
3123
3124        /* creates object */
3125        return (PyObject *) largeNew(self, lo_oid);
3126}
3127
3128/* import unix file */
3129static char connImportLO__doc__[] =
3130"loimport(name) -- create a new large object from specified file";
3131
3132static PyObject *
3133connImportLO(connObject *self, PyObject *args)
3134{
3135        char   *name;
3136        Oid             lo_oid;
3137
3138        /* checks validity */
3139        if (!check_cnx_obj(self))
3140                return NULL;
3141
3142        /* gets arguments */
3143        if (!PyArg_ParseTuple(args, "s", &name))
3144        {
3145                PyErr_SetString(PyExc_TypeError,
3146                        "Method loimport() takes a string argument");
3147                return NULL;
3148        }
3149
3150        /* imports file and checks result */
3151        lo_oid = lo_import(self->cnx, name);
3152        if (lo_oid == 0)
3153        {
3154                set_error_msg(OperationalError, "Can't create large object");
3155                return NULL;
3156        }
3157
3158        return (PyObject *) largeNew(self, lo_oid);
3159}
3160#endif /* LARGE_OBJECTS */
3161
3162/* resets connection */
3163static char connReset__doc__[] =
3164"reset() -- reset connection with current parameters\n\n"
3165"All derived queries and large objects derived from this connection\n"
3166"will not be usable after this call.\n";
3167
3168static PyObject *
3169connReset(connObject *self, PyObject *noargs)
3170{
3171        if (!self->cnx)
3172        {
3173                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3174                return NULL;
3175        }
3176
3177        /* resets the connection */
3178        PQreset(self->cnx);
3179        Py_INCREF(Py_None);
3180        return Py_None;
3181}
3182
3183/* cancels current command */
3184static char connCancel__doc__[] =
3185"cancel() -- abandon processing of the current command";
3186
3187static PyObject *
3188connCancel(connObject *self, PyObject *noargs)
3189{
3190        if (!self->cnx)
3191        {
3192                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3193                return NULL;
3194        }
3195
3196        /* request that the server abandon processing of the current command */
3197        return PyInt_FromLong((long) PQrequestCancel(self->cnx));
3198}
3199
3200/* get connection socket */
3201static char connFileno__doc__[] =
3202"fileno() -- return database connection socket file handle";
3203
3204static PyObject *
3205connFileno(connObject *self, PyObject *noargs)
3206{
3207        if (!self->cnx)
3208        {
3209                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3210                return NULL;
3211        }
3212
3213#ifdef NO_PQSOCKET
3214        return PyInt_FromLong((long) self->cnx->sock);
3215#else
3216        return PyInt_FromLong((long) PQsocket(self->cnx));
3217#endif
3218}
3219
3220/* set external typecast callback function */
3221static char connSetCastHook__doc__[] =
3222"set_cast_hook(func) -- set a fallback typecast function";
3223
3224static PyObject *
3225connSetCastHook(connObject *self, PyObject *func)
3226{
3227        PyObject *ret = NULL;
3228
3229        if (func == Py_None)
3230        {
3231                Py_XDECREF(self->cast_hook);
3232                self->cast_hook = NULL;
3233                Py_INCREF(Py_None); ret = Py_None;
3234        }
3235        else if (PyCallable_Check(func))
3236        {
3237                Py_XINCREF(func); Py_XDECREF(self->cast_hook);
3238                self->cast_hook = func;
3239                Py_INCREF(Py_None); ret = Py_None;
3240        }
3241        else
3242                PyErr_SetString(PyExc_TypeError,
3243                        "Method set_cast_hook() expects"
3244                         " a callable or None as argument");
3245
3246        return ret;
3247}
3248
3249/* get notice receiver callback function */
3250static char connGetCastHook__doc__[] =
3251"get_cast_hook() -- get the fallback typecast function";
3252
3253static PyObject *
3254connGetCastHook(connObject *self, PyObject *noargs)
3255{
3256        PyObject *ret = self->cast_hook;;
3257
3258        if (!ret)
3259                ret = Py_None;
3260        Py_INCREF(ret);
3261
3262        return ret;
3263}
3264
3265/* set notice receiver callback function */
3266static char connSetNoticeReceiver__doc__[] =
3267"set_notice_receiver(func) -- set the current notice receiver";
3268
3269static PyObject *
3270connSetNoticeReceiver(connObject *self, PyObject *func)
3271{
3272        PyObject *ret = NULL;
3273
3274        if (func == Py_None)
3275        {
3276                Py_XDECREF(self->notice_receiver);
3277                self->notice_receiver = NULL;
3278                Py_INCREF(Py_None); ret = Py_None;
3279        }
3280        else if (PyCallable_Check(func))
3281        {
3282                Py_XINCREF(func); Py_XDECREF(self->notice_receiver);
3283                self->notice_receiver = func;
3284                PQsetNoticeReceiver(self->cnx, notice_receiver, self);
3285                Py_INCREF(Py_None); ret = Py_None;
3286        }
3287        else
3288                PyErr_SetString(PyExc_TypeError,
3289                        "Method set_notice_receiver() expects"
3290                         " a callable or None as argument");
3291
3292        return ret;
3293}
3294
3295/* get notice receiver callback function */
3296static char connGetNoticeReceiver__doc__[] =
3297"get_notice_receiver() -- get the current notice receiver";
3298
3299static PyObject *
3300connGetNoticeReceiver(connObject *self, PyObject *noargs)
3301{
3302        PyObject *ret = self->notice_receiver;
3303
3304        if (!ret)
3305                ret = Py_None;
3306        Py_INCREF(ret);
3307
3308        return ret;
3309}
3310
3311/* close without deleting */
3312static char connClose__doc__[] =
3313"close() -- close connection\n\n"
3314"All instances of the connection object and derived objects\n"
3315"(queries and large objects) can no longer be used after this call.\n";
3316
3317static PyObject *
3318connClose(connObject *self, PyObject *noargs)
3319{
3320        /* connection object cannot already be closed */
3321        if (!self->cnx)
3322        {
3323                set_error_msg(InternalError, "Connection already closed");
3324                return NULL;
3325        }
3326
3327        Py_BEGIN_ALLOW_THREADS
3328        PQfinish(self->cnx);
3329        Py_END_ALLOW_THREADS
3330
3331        self->cnx = NULL;
3332        Py_INCREF(Py_None);
3333        return Py_None;
3334}
3335
3336/* gets asynchronous notify */
3337static char connGetNotify__doc__[] =
3338"getnotify() -- get database notify for this connection";
3339
3340static PyObject *
3341connGetNotify(connObject *self, PyObject *noargs)
3342{
3343        PGnotify   *notify;
3344
3345        if (!self->cnx)
3346        {
3347                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3348                return NULL;
3349        }
3350
3351        /* checks for NOTIFY messages */
3352        PQconsumeInput(self->cnx);
3353
3354        if (!(notify = PQnotifies(self->cnx)))
3355        {
3356                Py_INCREF(Py_None);
3357                return Py_None;
3358        }
3359        else
3360        {
3361                PyObject   *notify_result,
3362                                   *temp;
3363
3364                if (!(temp = PyStr_FromString(notify->relname)))
3365                        return NULL;
3366
3367                if (!(notify_result = PyTuple_New(3)))
3368                        return NULL;
3369
3370                PyTuple_SET_ITEM(notify_result, 0, temp);
3371
3372                if (!(temp = PyInt_FromLong(notify->be_pid)))
3373                {
3374                        Py_DECREF(notify_result);
3375                        return NULL;
3376                }
3377
3378                PyTuple_SET_ITEM(notify_result, 1, temp);
3379
3380                /* extra exists even in old versions that did not support it */
3381                if (!(temp = PyStr_FromString(notify->extra)))
3382                {
3383                        Py_DECREF(notify_result);
3384                        return NULL;
3385                }
3386
3387                PyTuple_SET_ITEM(notify_result, 2, temp);
3388
3389                PQfreemem(notify);
3390
3391                return notify_result;
3392        }
3393}
3394
3395/* get the list of connection attributes */
3396static PyObject *
3397connDir(connObject *self, PyObject *noargs)
3398{
3399        PyObject *attrs;
3400
3401        attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
3402        PyObject_CallMethod(attrs, "extend", "[sssssssss]",
3403                "host", "port", "db", "options", "error", "status", "user",
3404                "protocol_version", "server_version");
3405
3406        return attrs;
3407}
3408
3409/* connection object methods */
3410static struct PyMethodDef connMethods[] = {
3411        {"__dir__", (PyCFunction) connDir,  METH_NOARGS, NULL},
3412
3413        {"source", (PyCFunction) connSource, METH_NOARGS, connSource__doc__},
3414        {"query", (PyCFunction) connQuery, METH_VARARGS, connQuery__doc__},
3415        {"reset", (PyCFunction) connReset, METH_NOARGS, connReset__doc__},
3416        {"cancel", (PyCFunction) connCancel, METH_NOARGS, connCancel__doc__},
3417        {"close", (PyCFunction) connClose, METH_NOARGS, connClose__doc__},
3418        {"fileno", (PyCFunction) connFileno, METH_NOARGS, connFileno__doc__},
3419        {"get_cast_hook", (PyCFunction) connGetCastHook, METH_NOARGS,
3420                        connGetCastHook__doc__},
3421        {"set_cast_hook", (PyCFunction) connSetCastHook, METH_O,
3422                        connSetCastHook__doc__},
3423        {"get_notice_receiver", (PyCFunction) connGetNoticeReceiver, METH_NOARGS,
3424                        connGetNoticeReceiver__doc__},
3425        {"set_notice_receiver", (PyCFunction) connSetNoticeReceiver, METH_O,
3426                        connSetNoticeReceiver__doc__},
3427        {"getnotify", (PyCFunction) connGetNotify, METH_NOARGS,
3428                        connGetNotify__doc__},
3429        {"inserttable", (PyCFunction) connInsertTable, METH_VARARGS,
3430                        connInsertTable__doc__},
3431        {"transaction", (PyCFunction) connTransaction, METH_NOARGS,
3432                        connTransaction__doc__},
3433        {"parameter", (PyCFunction) connParameter, METH_VARARGS,
3434                        connParameter__doc__},
3435        {"date_format", (PyCFunction) connDateFormat, METH_NOARGS,
3436                        connDateFormat__doc__},
3437
3438#ifdef ESCAPING_FUNCS
3439        {"escape_literal", (PyCFunction) connEscapeLiteral, METH_O,
3440                        connEscapeLiteral__doc__},
3441        {"escape_identifier", (PyCFunction) connEscapeIdentifier, METH_O,
3442                        connEscapeIdentifier__doc__},
3443#endif  /* ESCAPING_FUNCS */
3444        {"escape_string", (PyCFunction) connEscapeString, METH_O,
3445                        connEscapeString__doc__},
3446        {"escape_bytea", (PyCFunction) connEscapeBytea, METH_O,
3447                        connEscapeBytea__doc__},
3448
3449#ifdef DIRECT_ACCESS
3450        {"putline", (PyCFunction) connPutLine, METH_VARARGS, connPutLine__doc__},
3451        {"getline", (PyCFunction) connGetLine, METH_NOARGS, connGetLine__doc__},
3452        {"endcopy", (PyCFunction) connEndCopy, METH_NOARGS, connEndCopy__doc__},
3453#endif /* DIRECT_ACCESS */
3454
3455#ifdef LARGE_OBJECTS
3456        {"locreate", (PyCFunction) connCreateLO, METH_VARARGS, connCreateLO__doc__},
3457        {"getlo", (PyCFunction) connGetLO, METH_VARARGS, connGetLO__doc__},
3458        {"loimport", (PyCFunction) connImportLO, METH_VARARGS, connImportLO__doc__},
3459#endif /* LARGE_OBJECTS */
3460
3461        {NULL, NULL} /* sentinel */
3462};
3463
3464/* gets connection attributes */
3465static PyObject *
3466connGetAttr(connObject *self, PyObject *nameobj)
3467{
3468        const char *name = PyStr_AsString(nameobj);
3469
3470        /*
3471         * Although we could check individually, there are only a few
3472         * attributes that don't require a live connection and unless someone
3473         * has an urgent need, this will have to do
3474         */
3475
3476        /* first exception - close which returns a different error */
3477        if (strcmp(name, "close") && !self->cnx)
3478        {
3479                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3480                return NULL;
3481        }
3482
3483        /* list PostgreSQL connection fields */
3484
3485        /* postmaster host */
3486        if (!strcmp(name, "host"))
3487        {
3488                char *r = PQhost(self->cnx);
3489                if (!r || r[0] == '/') /* Pg 9.6 can return a Unix socket path */
3490                        r = "localhost";
3491                return PyStr_FromString(r);
3492        }
3493
3494        /* postmaster port */
3495        if (!strcmp(name, "port"))
3496                return PyInt_FromLong(atol(PQport(self->cnx)));
3497
3498        /* selected database */
3499        if (!strcmp(name, "db"))
3500                return PyStr_FromString(PQdb(self->cnx));
3501
3502        /* selected options */
3503        if (!strcmp(name, "options"))
3504                return PyStr_FromString(PQoptions(self->cnx));
3505
3506        /* error (status) message */
3507        if (!strcmp(name, "error"))
3508                return PyStr_FromString(PQerrorMessage(self->cnx));
3509
3510        /* connection status : 1 - OK, 0 - BAD */
3511        if (!strcmp(name, "status"))
3512                return PyInt_FromLong(PQstatus(self->cnx) == CONNECTION_OK ? 1 : 0);
3513
3514        /* provided user name */
3515        if (!strcmp(name, "user"))
3516                return PyStr_FromString(PQuser(self->cnx));
3517
3518        /* protocol version */
3519        if (!strcmp(name, "protocol_version"))
3520                return PyInt_FromLong(PQprotocolVersion(self->cnx));
3521
3522        /* backend version */
3523        if (!strcmp(name, "server_version"))
3524                return PyInt_FromLong(PQserverVersion(self->cnx));
3525
3526        return PyObject_GenericGetAttr((PyObject *) self, nameobj);
3527}
3528
3529/* connection type definition */
3530static PyTypeObject connType = {
3531        PyVarObject_HEAD_INIT(NULL, 0)
3532        "pg.Connection",                        /* tp_name */
3533        sizeof(connObject),                     /* tp_basicsize */
3534        0,                                                      /* tp_itemsize */
3535        (destructor) connDelete,        /* tp_dealloc */
3536        0,                                                      /* tp_print */
3537        0,                                                      /* tp_getattr */
3538        0,                                                      /* tp_setattr */
3539        0,                                                      /* tp_reserved */
3540        0,                                                      /* tp_repr */
3541        0,                                                      /* tp_as_number */
3542        0,                                                      /* tp_as_sequence */
3543        0,                                                      /* tp_as_mapping */
3544        0,                                                      /* tp_hash */
3545        0,                                                      /* tp_call */
3546        0,                                                      /* tp_str */
3547        (getattrofunc) connGetAttr,     /* tp_getattro */
3548        0,                                                      /* tp_setattro */
3549        0,                                                      /* tp_as_buffer */
3550        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
3551        0,                                                      /* tp_doc */
3552        0,                                                      /* tp_traverse */
3553        0,                                                      /* tp_clear */
3554        0,                                                      /* tp_richcompare */
3555        0,                                                      /* tp_weaklistoffset */
3556        0,                                                      /* tp_iter */
3557        0,                                                      /* tp_iternext */
3558        connMethods,                            /* tp_methods */
3559};
3560
3561/* --------------------------------------------------------------------- */
3562/* source object                                                                                                                 */
3563/* --------------------------------------------------------------------- */
3564/* checks source object validity */
3565static int
3566check_source_obj(sourceObject *self, int level)
3567{
3568        if (!self->valid)
3569        {
3570                set_error_msg(OperationalError, "Object has been closed");
3571                return 0;
3572        }
3573
3574        if ((level & CHECK_RESULT) && !self->result)
3575        {
3576                set_error_msg(DatabaseError, "No result");
3577                return 0;
3578        }
3579
3580        if ((level & CHECK_DQL) && self->result_type != RESULT_DQL)
3581        {
3582                set_error_msg(DatabaseError, "Last query did not return tuples");
3583                return 0;
3584        }
3585
3586        if ((level & CHECK_CNX) && !check_cnx_obj(self->pgcnx))
3587                return 0;
3588
3589        return 1;
3590}
3591
3592/* destructor */
3593static void
3594sourceDealloc(sourceObject *self)
3595{
3596        if (self->result)
3597                PQclear(self->result);
3598
3599        Py_XDECREF(self->pgcnx);
3600        PyObject_Del(self);
3601}
3602
3603/* closes object */
3604static char sourceClose__doc__[] =
3605"close() -- close query object without deleting it\n\n"
3606"All instances of the query object can no longer be used after this call.\n";
3607
3608static PyObject *
3609sourceClose(sourceObject *self, PyObject *noargs)
3610{
3611        /* frees result if necessary and invalidates object */
3612        if (self->result)
3613        {
3614                PQclear(self->result);
3615                self->result_type = RESULT_EMPTY;
3616                self->result = NULL;
3617        }
3618
3619        self->valid = 0;
3620
3621        /* return None */
3622        Py_INCREF(Py_None);
3623        return Py_None;
3624}
3625
3626/* database query */
3627static char sourceExecute__doc__[] =
3628"execute(sql) -- execute a SQL statement (string)\n\n"
3629"On success, this call returns the number of affected rows, or None\n"
3630"for DQL (SELECT, ...) statements.  The fetch (fetch(), fetchone()\n"
3631"and fetchall()) methods can be used to get result rows.\n";
3632
3633static PyObject *
3634sourceExecute(sourceObject *self, PyObject *sql)
3635{
3636        PyObject   *tmp_obj = NULL; /* auxiliary string object */
3637        char       *query;
3638        int                     encoding;
3639
3640        /* checks validity */
3641        if (!check_source_obj(self, CHECK_CNX))
3642                return NULL;
3643
3644        encoding = PQclientEncoding(self->pgcnx->cnx);
3645
3646        if (PyBytes_Check(sql))
3647        {
3648                query = PyBytes_AsString(sql);
3649        }
3650        else if (PyUnicode_Check(sql))
3651        {
3652                tmp_obj = get_encoded_string(sql, encoding);
3653                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3654                query = PyBytes_AsString(tmp_obj);
3655        }
3656        else
3657        {
3658                PyErr_SetString(PyExc_TypeError,
3659                        "Method execute() expects a string as argument");
3660                return NULL;
3661        }
3662
3663        /* frees previous result */
3664        if (self->result)
3665        {
3666                PQclear(self->result);
3667                self->result = NULL;
3668        }
3669        self->max_row = 0;
3670        self->current_row = 0;
3671        self->num_fields = 0;
3672        self->encoding = encoding;
3673
3674        /* gets result */
3675        Py_BEGIN_ALLOW_THREADS
3676        self->result = PQexec(self->pgcnx->cnx, query);
3677        Py_END_ALLOW_THREADS
3678
3679        /* we don't need the auxiliary string any more */
3680        Py_XDECREF(tmp_obj);
3681
3682        /* checks result validity */
3683        if (!self->result)
3684        {
3685                PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->pgcnx->cnx));
3686                return NULL;
3687        }
3688
3689        /* this may have changed the datestyle, so we reset the date format
3690           in order to force fetching it newly when next time requested */
3691        self->pgcnx->date_format = date_format; /* this is normally NULL */
3692
3693        /* checks result status */
3694        switch (PQresultStatus(self->result))
3695        {
3696                /* query succeeded */
3697                case PGRES_TUPLES_OK:   /* DQL: returns None (DB-SIG compliant) */
3698                        self->result_type = RESULT_DQL;
3699                        self->max_row = PQntuples(self->result);
3700                        self->num_fields = PQnfields(self->result);
3701                        Py_INCREF(Py_None);
3702                        return Py_None;
3703                case PGRES_COMMAND_OK:  /* other requests */
3704                case PGRES_COPY_OUT:
3705                case PGRES_COPY_IN:
3706                        {
3707                                long    num_rows;
3708                                char   *temp;
3709                                temp = PQcmdTuples(self->result);
3710                                if (temp[0])
3711                                {
3712                                        self->result_type = RESULT_DML;
3713                                        num_rows = atol(temp);
3714                                }
3715                                else
3716                                {
3717                                        self->result_type = RESULT_DDL;
3718                                        num_rows = -1;
3719                                }
3720                                return PyInt_FromLong(num_rows);
3721                        }
3722
3723                /* query failed */
3724                case PGRES_EMPTY_QUERY:
3725                        PyErr_SetString(PyExc_ValueError, "Empty query");
3726                        break;
3727                case PGRES_BAD_RESPONSE:
3728                case PGRES_FATAL_ERROR:
3729                case PGRES_NONFATAL_ERROR:
3730                        set_error(ProgrammingError, "Cannot execute command",
3731                                self->pgcnx->cnx, self->result);
3732                        break;
3733                default:
3734                        set_error_msg(InternalError, "Internal error: "
3735                                "unknown result status");
3736        }
3737
3738        /* frees result and returns error */
3739        PQclear(self->result);
3740        self->result = NULL;
3741        self->result_type = RESULT_EMPTY;
3742        return NULL;
3743}
3744
3745/* gets oid status for last query (valid for INSERTs, 0 for other) */
3746static char sourceStatusOID__doc__[] =
3747"oidstatus() -- return oid of last inserted row (if available)";
3748
3749static PyObject *
3750sourceStatusOID(sourceObject *self, PyObject *noargs)
3751{
3752        Oid                     oid;
3753
3754        /* checks validity */
3755        if (!check_source_obj(self, CHECK_RESULT))
3756                return NULL;
3757
3758        /* retrieves oid status */
3759        if ((oid = PQoidValue(self->result)) == InvalidOid)
3760        {
3761                Py_INCREF(Py_None);
3762                return Py_None;
3763        }
3764
3765        return PyInt_FromLong(oid);
3766}
3767
3768/* fetches rows from last result */
3769static char sourceFetch__doc__[] =
3770"fetch(num) -- return the next num rows from the last result in a list\n\n"
3771"If num parameter is omitted arraysize attribute value is used.\n"
3772"If size equals -1, all rows are fetched.\n";
3773
3774static PyObject *
3775sourceFetch(sourceObject *self, PyObject *args)
3776{
3777        PyObject   *reslist;
3778        int                     i,
3779                                k;
3780        long            size;
3781#if IS_PY3
3782        int                     encoding;
3783#endif
3784
3785        /* checks validity */
3786        if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL | CHECK_CNX))
3787                return NULL;
3788
3789        /* checks args */
3790        size = self->arraysize;
3791        if (!PyArg_ParseTuple(args, "|l", &size))
3792        {
3793                PyErr_SetString(PyExc_TypeError,
3794                        "fetch(num), with num (integer, optional)");
3795                return NULL;
3796        }
3797
3798        /* seeks last line */
3799        /* limit size to be within the amount of data we actually have */
3800        if (size == -1 || (self->max_row - self->current_row) < size)
3801                size = self->max_row - self->current_row;
3802
3803        /* allocate list for result */
3804        if (!(reslist = PyList_New(0))) return NULL;
3805
3806#if IS_PY3
3807        encoding = self->encoding;
3808#endif
3809
3810        /* builds result */
3811        for (i = 0, k = self->current_row; i < size; ++i, ++k)
3812        {
3813                PyObject   *rowtuple;
3814                int                     j;
3815
3816                if (!(rowtuple = PyTuple_New(self->num_fields)))
3817                {
3818                        Py_DECREF(reslist); return NULL;
3819                }
3820
3821                for (j = 0; j < self->num_fields; ++j)
3822                {
3823                        PyObject   *str;
3824
3825                        if (PQgetisnull(self->result, k, j))
3826                        {
3827                                Py_INCREF(Py_None);
3828                                str = Py_None;
3829                        }
3830                        else
3831                        {
3832                                char *s = PQgetvalue(self->result, k, j);
3833                                Py_ssize_t size = PQgetlength(self->result, k, j);
3834#if IS_PY3
3835                                if (PQfformat(self->result, j) == 0) /* textual format */
3836                                {
3837                                        str = get_decoded_string(s, size, encoding);
3838                                        if (!str) /* cannot decode */
3839                                                str = PyBytes_FromStringAndSize(s, size);
3840                                }
3841                                else
3842#endif
3843                                str = PyBytes_FromStringAndSize(s, size);
3844                        }
3845                        PyTuple_SET_ITEM(rowtuple, j, str);
3846                }
3847
3848                if (PyList_Append(reslist, rowtuple))
3849                {
3850                        Py_DECREF(rowtuple); Py_DECREF(reslist); return NULL;
3851                }
3852                Py_DECREF(rowtuple);
3853        }
3854
3855        self->current_row = k;
3856        return reslist;
3857}
3858
3859/* changes current row (internal wrapper for all "move" methods) */
3860static PyObject *
3861pgsource_move(sourceObject *self, int move)
3862{
3863        /* checks validity */
3864        if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
3865                return NULL;
3866
3867        /* changes the current row */
3868        switch (move)
3869        {
3870                case QUERY_MOVEFIRST:
3871                        self->current_row = 0;
3872                        break;
3873                case QUERY_MOVELAST:
3874                        self->current_row = self->max_row - 1;
3875                        break;
3876                case QUERY_MOVENEXT:
3877                        if (self->current_row != self->max_row)
3878                                ++self->current_row;
3879                        break;
3880                case QUERY_MOVEPREV:
3881                        if (self->current_row > 0)
3882                                self->current_row--;
3883                        break;
3884        }
3885
3886        Py_INCREF(Py_None);
3887        return Py_None;
3888}
3889
3890/* move to first result row */
3891static char sourceMoveFirst__doc__[] =
3892"movefirst() -- move to first result row";
3893
3894static PyObject *
3895sourceMoveFirst(sourceObject *self, PyObject *noargs)
3896{
3897        return pgsource_move(self, QUERY_MOVEFIRST);
3898}
3899
3900/* move to last result row */
3901static char sourceMoveLast__doc__[] =
3902"movelast() -- move to last valid result row";
3903
3904static PyObject *
3905sourceMoveLast(sourceObject *self, PyObject *noargs)
3906{
3907        return pgsource_move(self, QUERY_MOVELAST);
3908}
3909
3910/* move to next result row */
3911static char sourceMoveNext__doc__[] =
3912"movenext() -- move to next result row";
3913
3914static PyObject *
3915sourceMoveNext(sourceObject *self, PyObject *noargs)
3916{
3917        return pgsource_move(self, QUERY_MOVENEXT);
3918}
3919
3920/* move to previous result row */
3921static char sourceMovePrev__doc__[] =
3922"moveprev() -- move to previous result row";
3923
3924static PyObject *
3925sourceMovePrev(sourceObject *self, PyObject *noargs)
3926{
3927        return pgsource_move(self, QUERY_MOVEPREV);
3928}
3929
3930/* put copy data */
3931static char sourcePutData__doc__[] =
3932"putdata(buffer) -- send data to server during copy from stdin";
3933
3934static PyObject *
3935sourcePutData(sourceObject *self, PyObject *buffer)
3936{
3937        PyObject   *tmp_obj = NULL; /* an auxiliary object */
3938        char       *buf; /* the buffer as encoded string */
3939        Py_ssize_t      nbytes; /* length of string */
3940        char       *errormsg = NULL; /* error message */
3941        int                     res; /* direct result of the operation */
3942        PyObject   *ret; /* return value */
3943
3944        /* checks validity */
3945        if (!check_source_obj(self, CHECK_CNX))
3946                return NULL;
3947
3948        /* make sure that the connection object is valid */
3949        if (!self->pgcnx->cnx)
3950                return NULL;
3951
3952        if (buffer == Py_None)
3953        {
3954                /* pass None for terminating the operation */
3955                buf = errormsg = NULL;
3956        }
3957        else if (PyBytes_Check(buffer))
3958        {
3959                /* or pass a byte string */
3960                PyBytes_AsStringAndSize(buffer, &buf, &nbytes);
3961        }
3962        else if (PyUnicode_Check(buffer))
3963        {
3964                /* or pass a unicode string */
3965                tmp_obj = get_encoded_string(
3966                        buffer, PQclientEncoding(self->pgcnx->cnx));
3967                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3968                PyBytes_AsStringAndSize(tmp_obj, &buf, &nbytes);
3969        }
3970        else if (PyErr_GivenExceptionMatches(buffer, PyExc_BaseException))
3971        {
3972                /* or pass a Python exception for sending an error message */
3973                tmp_obj = PyObject_Str(buffer);
3974                if (PyUnicode_Check(tmp_obj))
3975                {
3976                        PyObject *obj = tmp_obj;
3977                        tmp_obj = get_encoded_string(
3978                                obj, PQclientEncoding(self->pgcnx->cnx));
3979                        Py_DECREF(obj);
3980                        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3981                }
3982                errormsg = PyBytes_AsString(tmp_obj);
3983                buf = NULL;
3984        }
3985        else
3986        {
3987                PyErr_SetString(PyExc_TypeError,
3988                        "Method putdata() expects a buffer, None"
3989                         " or an exception as argument");
3990                return NULL;
3991        }
3992
3993        /* checks validity */
3994        if (!check_source_obj(self, CHECK_CNX | CHECK_RESULT) ||
3995                        PQresultStatus(self->result) != PGRES_COPY_IN)
3996        {
3997                PyErr_SetString(PyExc_IOError,
3998                        "Connection is invalid or not in copy_in state");
3999                Py_XDECREF(tmp_obj);
4000                return NULL;
4001        }
4002
4003        if (buf)
4004        {
4005                res = nbytes ? PQputCopyData(self->pgcnx->cnx, buf, (int)nbytes) : 1;
4006        }
4007        else
4008        {
4009                res = PQputCopyEnd(self->pgcnx->cnx, errormsg);
4010        }
4011
4012        Py_XDECREF(tmp_obj);
4013
4014        if (res != 1)
4015        {
4016                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->pgcnx->cnx));
4017                return NULL;
4018        }
4019
4020        if (buf) /* buffer has been sent */
4021        {
4022                ret = Py_None;
4023                Py_INCREF(ret);
4024        }
4025        else /* copy is done */
4026        {
4027                PGresult   *result; /* final result of the operation */
4028
4029                Py_BEGIN_ALLOW_THREADS;
4030                result = PQgetResult(self->pgcnx->cnx);
4031                Py_END_ALLOW_THREADS;
4032
4033                if (PQresultStatus(result) == PGRES_COMMAND_OK)
4034                {
4035                        char   *temp;
4036                        long    num_rows;
4037
4038                        temp = PQcmdTuples(result);
4039                        num_rows = temp[0] ? atol(temp) : -1;
4040                        ret = PyInt_FromLong(num_rows);
4041                }
4042                else
4043                {
4044                        if (!errormsg) errormsg = PQerrorMessage(self->pgcnx->cnx);
4045                        PyErr_SetString(PyExc_IOError, errormsg);
4046                        ret = NULL;
4047                }
4048
4049                PQclear(self->result);
4050                self->result = NULL;
4051                self->result_type = RESULT_EMPTY;
4052        }
4053
4054        return ret; /* None or number of rows */
4055}
4056
4057/* get copy data */
4058static char sourceGetData__doc__[] =
4059"getdata(decode) -- receive data to server during copy to stdout";
4060
4061static PyObject *
4062sourceGetData(sourceObject *self, PyObject *args)
4063{
4064        int                *decode = 0; /* decode flag */
4065        char       *buffer; /* the copied buffer as encoded byte string */
4066        Py_ssize_t      nbytes; /* length of the byte string */
4067        PyObject   *ret; /* return value */
4068
4069        /* checks validity */
4070        if (!check_source_obj(self, CHECK_CNX))
4071                return NULL;
4072
4073        /* make sure that the connection object is valid */
4074        if (!self->pgcnx->cnx)
4075                return NULL;
4076
4077        if (!PyArg_ParseTuple(args, "|i", &decode))
4078                return NULL;
4079
4080        /* checks validity */
4081        if (!check_source_obj(self, CHECK_CNX | CHECK_RESULT) ||
4082                        PQresultStatus(self->result) != PGRES_COPY_OUT)
4083        {
4084                PyErr_SetString(PyExc_IOError,
4085                        "Connection is invalid or not in copy_out state");
4086                return NULL;
4087        }
4088
4089        nbytes = PQgetCopyData(self->pgcnx->cnx, &buffer, 0);
4090
4091        if (!nbytes || nbytes < -1) /* an error occurred */
4092        {
4093                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->pgcnx->cnx));
4094                return NULL;
4095        }
4096
4097        if (nbytes == -1) /* copy is done */
4098        {
4099                PGresult   *result; /* final result of the operation */
4100
4101                Py_BEGIN_ALLOW_THREADS;
4102                result = PQgetResult(self->pgcnx->cnx);
4103                Py_END_ALLOW_THREADS;
4104
4105                if (PQresultStatus(result) == PGRES_COMMAND_OK)
4106                {
4107                        char   *temp;
4108                        long    num_rows;
4109
4110                        temp = PQcmdTuples(result);
4111                        num_rows = temp[0] ? atol(temp) : -1;
4112                        ret = PyInt_FromLong(num_rows);
4113                }
4114                else
4115                {
4116                        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->pgcnx->cnx));
4117                        ret = NULL;
4118                }
4119
4120                PQclear(self->result);
4121                self->result = NULL;
4122                self->result_type = RESULT_EMPTY;
4123        }
4124        else /* a row has been returned */
4125        {
4126                ret = decode ? get_decoded_string(
4127                                buffer, nbytes, PQclientEncoding(self->pgcnx->cnx)) :
4128                        PyBytes_FromStringAndSize(buffer, nbytes);
4129                PQfreemem(buffer);
4130        }
4131
4132        return ret; /* buffer or number of rows */
4133}
4134
4135/* finds field number from string/integer (internal use only) */
4136static int
4137sourceFieldindex(sourceObject *self, PyObject *param, const char *usage)
4138{
4139        int                     num;
4140
4141        /* checks validity */
4142        if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
4143                return -1;
4144
4145        /* gets field number */
4146        if (PyStr_Check(param))
4147                num = PQfnumber(self->result, PyBytes_AsString(param));
4148        else if (PyInt_Check(param))
4149                num = (int)PyInt_AsLong(param);
4150        else
4151        {
4152                PyErr_SetString(PyExc_TypeError, usage);
4153                return -1;
4154        }
4155
4156        /* checks field validity */
4157        if (num < 0 || num >= self->num_fields)
4158        {
4159                PyErr_SetString(PyExc_ValueError, "Unknown field");
4160                return -1;
4161        }
4162
4163        return num;
4164}
4165
4166/* builds field information from position (internal use only) */
4167static PyObject *
4168pgsource_buildinfo(sourceObject *self, int num)
4169{
4170        PyObject *result;
4171
4172        /* allocates tuple */
4173        result = PyTuple_New(5);
4174        if (!result)
4175                return NULL;
4176
4177        /* affects field information */
4178        PyTuple_SET_ITEM(result, 0, PyInt_FromLong(num));
4179        PyTuple_SET_ITEM(result, 1,
4180                PyStr_FromString(PQfname(self->result, num)));
4181        PyTuple_SET_ITEM(result, 2,
4182                PyInt_FromLong(PQftype(self->result, num)));
4183        PyTuple_SET_ITEM(result, 3,
4184                PyInt_FromLong(PQfsize(self->result, num)));
4185        PyTuple_SET_ITEM(result, 4,
4186                PyInt_FromLong(PQfmod(self->result, num)));
4187
4188        return result;
4189}
4190
4191/* lists fields info */
4192static char sourceListInfo__doc__[] =
4193"listinfo() -- get information for all fields (position, name, type oid)";
4194
4195static PyObject *
4196sourceListInfo(sourceObject *self, PyObject *noargs)
4197{
4198        int                     i;
4199        PyObject   *result,
4200                           *info;
4201
4202        /* checks validity */
4203        if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
4204                return NULL;
4205
4206        /* builds result */
4207        if (!(result = PyTuple_New(self->num_fields)))
4208                return NULL;
4209
4210        for (i = 0; i < self->num_fields; ++i)
4211        {
4212                info = pgsource_buildinfo(self, i);
4213                if (!info)
4214                {
4215                        Py_DECREF(result);
4216                        return NULL;
4217                }
4218                PyTuple_SET_ITEM(result, i, info);
4219        }
4220
4221        /* returns result */
4222        return result;
4223};
4224
4225/* list fields information for last result */
4226static char sourceFieldInfo__doc__[] =
4227"fieldinfo(desc) -- get specified field info (position, name, type oid)";
4228
4229static PyObject *
4230sourceFieldInfo(sourceObject *self, PyObject *desc)
4231{
4232        int                     num;
4233
4234        /* checks args and validity */
4235        if ((num = sourceFieldindex(self, desc,
4236                        "Method fieldinfo() needs a string or integer as argument")) == -1)
4237                return NULL;
4238
4239        /* returns result */
4240        return pgsource_buildinfo(self, num);
4241};
4242
4243/* retrieve field value */
4244static char sourceField__doc__[] =
4245"field(desc) -- return specified field value";
4246
4247static PyObject *
4248sourceField(sourceObject *self, PyObject *desc)
4249{
4250        int                     num;
4251
4252        /* checks args and validity */
4253        if ((num = sourceFieldindex(self, desc,
4254                        "Method field() needs a string or integer as argument")) == -1)
4255                return NULL;
4256
4257        return PyStr_FromString(
4258                PQgetvalue(self->result, self->current_row, num));
4259}
4260
4261/* get the list of source object attributes */
4262static PyObject *
4263sourceDir(connObject *self, PyObject *noargs)
4264{
4265        PyObject *attrs;
4266
4267        attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
4268        PyObject_CallMethod(attrs, "extend", "[sssss]",
4269                "pgcnx", "arraysize", "resulttype", "ntuples", "nfields");
4270
4271        return attrs;
4272}
4273
4274/* source object methods */
4275static PyMethodDef sourceMethods[] = {
4276        {"__dir__", (PyCFunction) sourceDir,  METH_NOARGS, NULL},
4277        {"close", (PyCFunction) sourceClose, METH_NOARGS, sourceClose__doc__},
4278        {"execute", (PyCFunction) sourceExecute, METH_O, sourceExecute__doc__},
4279        {"oidstatus", (PyCFunction) sourceStatusOID, METH_NOARGS,
4280                        sourceStatusOID__doc__},
4281        {"fetch", (PyCFunction) sourceFetch, METH_VARARGS,
4282                        sourceFetch__doc__},
4283        {"movefirst", (PyCFunction) sourceMoveFirst, METH_NOARGS,
4284                        sourceMoveFirst__doc__},
4285        {"movelast", (PyCFunction) sourceMoveLast, METH_NOARGS,
4286                        sourceMoveLast__doc__},
4287        {"movenext", (PyCFunction) sourceMoveNext, METH_NOARGS,
4288                        sourceMoveNext__doc__},
4289        {"moveprev", (PyCFunction) sourceMovePrev, METH_NOARGS,
4290                        sourceMovePrev__doc__},
4291        {"putdata", (PyCFunction) sourcePutData, METH_O, sourcePutData__doc__},
4292        {"getdata", (PyCFunction) sourceGetData, METH_VARARGS,
4293                        sourceGetData__doc__},
4294        {"field", (PyCFunction) sourceField, METH_O,
4295                        sourceField__doc__},
4296        {"fieldinfo", (PyCFunction) sourceFieldInfo, METH_O,
4297                        sourceFieldInfo__doc__},
4298        {"listinfo", (PyCFunction) sourceListInfo, METH_NOARGS,
4299                        sourceListInfo__doc__},
4300        {NULL, NULL}
4301};
4302
4303/* gets source object attributes */
4304static PyObject *
4305sourceGetAttr(sourceObject *self, PyObject *nameobj)
4306{
4307        const char *name = PyStr_AsString(nameobj);
4308
4309        /* pg connection object */
4310        if (!strcmp(name, "pgcnx"))
4311        {
4312                if (check_source_obj(self, 0))
4313                {
4314                        Py_INCREF(self->pgcnx);
4315                        return (PyObject *) (self->pgcnx);
4316                }
4317                Py_INCREF(Py_None);
4318                return Py_None;
4319        }
4320
4321        /* arraysize */
4322        if (!strcmp(name, "arraysize"))
4323                return PyInt_FromLong(self->arraysize);
4324
4325        /* resulttype */
4326        if (!strcmp(name, "resulttype"))
4327                return PyInt_FromLong(self->result_type);
4328
4329        /* ntuples */
4330        if (!strcmp(name, "ntuples"))
4331                return PyInt_FromLong(self->max_row);
4332
4333        /* nfields */
4334        if (!strcmp(name, "nfields"))
4335                return PyInt_FromLong(self->num_fields);
4336
4337        /* seeks name in methods (fallback) */
4338        return PyObject_GenericGetAttr((PyObject *) self, nameobj);
4339}
4340
4341/* sets query object attributes */
4342static int
4343sourceSetAttr(sourceObject *self, char *name, PyObject *v)
4344{
4345        /* arraysize */
4346        if (!strcmp(name, "arraysize"))
4347        {
4348                if (!PyInt_Check(v))
4349                {
4350                        PyErr_SetString(PyExc_TypeError, "arraysize must be integer");
4351                        return -1;
4352                }
4353
4354                self->arraysize = PyInt_AsLong(v);
4355                return 0;
4356        }
4357
4358        /* unknown attribute */
4359        PyErr_SetString(PyExc_TypeError, "Not a writable attribute");
4360        return -1;
4361}
4362
4363/* return source object as string in human readable form */
4364static PyObject *
4365sourceStr(sourceObject *self)
4366{
4367        switch (self->result_type)
4368        {
4369                case RESULT_DQL:
4370                        return format_result(self->result);
4371                case RESULT_DDL:
4372                case RESULT_DML:
4373                        return PyStr_FromString(PQcmdStatus(self->result));
4374                case RESULT_EMPTY:
4375                default:
4376                        return PyStr_FromString("(empty PostgreSQL source object)");
4377        }
4378}
4379
4380static char source__doc__[] = "PyGreSQL source object";
4381
4382/* source type definition */
4383static PyTypeObject sourceType = {
4384        PyVarObject_HEAD_INIT(NULL, 0)
4385        "pgdb.Source",                                  /* tp_name */
4386        sizeof(sourceObject),                   /* tp_basicsize */
4387        0,                                                              /* tp_itemsize */
4388        /* methods */
4389        (destructor) sourceDealloc,             /* tp_dealloc */
4390        0,                                                              /* tp_print */
4391        0,                                                              /* tp_getattr */
4392        (setattrfunc) sourceSetAttr,    /* tp_setattr */
4393        0,                                                              /* tp_compare */
4394        0,                                                              /* tp_repr */
4395        0,                                                              /* tp_as_number */
4396        0,                                                              /* tp_as_sequence */
4397        0,                                                              /* tp_as_mapping */
4398        0,                                                              /* tp_hash */
4399        0,                                                              /* tp_call */
4400        (reprfunc) sourceStr,                   /* tp_str */
4401        (getattrofunc) sourceGetAttr,   /* tp_getattro */
4402        0,                                                              /* tp_setattro */
4403        0,                                                              /* tp_as_buffer */
4404        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
4405        source__doc__,                                  /* tp_doc */
4406        0,                                                              /* tp_traverse */
4407        0,                                                              /* tp_clear */
4408        0,                                                              /* tp_richcompare */
4409        0,                                                              /* tp_weaklistoffset */
4410        0,                                                              /* tp_iter */
4411        0,                                                              /* tp_iternext */
4412        sourceMethods,                                  /* tp_methods */
4413};
4414
4415/* connects to a database */
4416static char pgConnect__doc__[] =
4417"connect(dbname, host, port, opt) -- connect to a PostgreSQL database\n\n"
4418"The connection uses the specified parameters (optional, keywords aware).\n";
4419
4420static PyObject *
4421pgConnect(PyObject *self, PyObject *args, PyObject *dict)
4422{
4423        static const char *kwlist[] = {"dbname", "host", "port", "opt",
4424        "user", "passwd", NULL};
4425
4426        char       *pghost,
4427                           *pgopt,
4428                           *pgdbname,
4429                           *pguser,
4430                           *pgpasswd;
4431        int                     pgport;
4432        char            port_buffer[20];
4433        connObject *npgobj;
4434
4435        pghost = pgopt = pgdbname = pguser = pgpasswd = NULL;
4436        pgport = -1;
4437
4438        /*
4439         * parses standard arguments With the right compiler warnings, this
4440         * will issue a diagnostic. There is really no way around it.  If I
4441         * don't declare kwlist as const char *kwlist[] then it complains when
4442         * I try to assign all those constant strings to it.
4443         */
4444        if (!PyArg_ParseTupleAndKeywords(args, dict, "|zzizzz", (char **) kwlist,
4445                &pgdbname, &pghost, &pgport, &pgopt, &pguser, &pgpasswd))
4446                return NULL;
4447
4448#ifdef DEFAULT_VARS
4449        /* handles defaults variables (for uninitialised vars) */
4450        if ((!pghost) && (pg_default_host != Py_None))
4451                pghost = PyBytes_AsString(pg_default_host);
4452
4453        if ((pgport == -1) && (pg_default_port != Py_None))
4454                pgport = (int)PyInt_AsLong(pg_default_port);
4455
4456        if ((!pgopt) && (pg_default_opt != Py_None))
4457                pgopt = PyBytes_AsString(pg_default_opt);
4458
4459        if ((!pgdbname) && (pg_default_base != Py_None))
4460                pgdbname = PyBytes_AsString(pg_default_base);
4461
4462        if ((!pguser) && (pg_default_user != Py_None))
4463                pguser = PyBytes_AsString(pg_default_user);
4464
4465        if ((!pgpasswd) && (pg_default_passwd != Py_None))
4466                pgpasswd = PyBytes_AsString(pg_default_passwd);
4467#endif /* DEFAULT_VARS */
4468
4469        if (!(npgobj = PyObject_NEW(connObject, &connType)))
4470        {
4471                set_error_msg(InternalError, "Can't create new connection object");
4472                return NULL;
4473        }
4474
4475        npgobj->valid = 1;
4476        npgobj->cnx = NULL;
4477        npgobj->date_format = date_format;
4478        npgobj->cast_hook = NULL;
4479        npgobj->notice_receiver = NULL;
4480
4481        if (pgport != -1)
4482        {
4483                memset(port_buffer, 0, sizeof(port_buffer));
4484                sprintf(port_buffer, "%d", pgport);
4485        }
4486
4487        Py_BEGIN_ALLOW_THREADS
4488        npgobj->cnx = PQsetdbLogin(pghost, pgport == -1 ? NULL : port_buffer,
4489                pgopt, NULL, pgdbname, pguser, pgpasswd);
4490        Py_END_ALLOW_THREADS
4491
4492        if (PQstatus(npgobj->cnx) == CONNECTION_BAD)
4493        {
4494                set_error(InternalError, "Cannot connect", npgobj->cnx, NULL);
4495                Py_XDECREF(npgobj);
4496                return NULL;
4497        }
4498
4499        return (PyObject *) npgobj;
4500}
4501
4502static void
4503queryDealloc(queryObject *self)
4504{
4505        Py_XDECREF(self->pgcnx);
4506        if (self->result)
4507                PQclear(self->result);
4508
4509        PyObject_Del(self);
4510}
4511
4512/* get number of rows */
4513static char queryNTuples__doc__[] =
4514"ntuples() -- return number of tuples returned by query";
4515
4516static PyObject *
4517queryNTuples(queryObject *self, PyObject *noargs)
4518{
4519        return PyInt_FromLong((long) PQntuples(self->result));
4520}
4521
4522/* list fields names from query result */
4523static char queryListFields__doc__[] =
4524"listfields() -- List field names from result";
4525
4526static PyObject *
4527queryListFields(queryObject *self, PyObject *noargs)
4528{
4529        int                     i,
4530                                n;
4531        char       *name;
4532        PyObject   *fieldstuple,
4533                           *str;
4534
4535        /* builds tuple */
4536        n = PQnfields(self->result);
4537        fieldstuple = PyTuple_New(n);
4538
4539        for (i = 0; i < n; ++i)
4540        {
4541                name = PQfname(self->result, i);
4542                str = PyStr_FromString(name);
4543                PyTuple_SET_ITEM(fieldstuple, i, str);
4544        }
4545
4546        return fieldstuple;
4547}
4548
4549/* get field name from last result */
4550static char queryFieldName__doc__[] =
4551"fieldname(num) -- return name of field from result from its position";
4552
4553static PyObject *
4554queryFieldName(queryObject *self, PyObject *args)
4555{
4556        int             i;
4557        char   *name;
4558
4559        /* gets args */
4560        if (!PyArg_ParseTuple(args, "i", &i))
4561        {
4562                PyErr_SetString(PyExc_TypeError,
4563                        "Method fieldname() takes an integer as argument");
4564                return NULL;
4565        }
4566
4567        /* checks number validity */
4568        if (i >= PQnfields(self->result))
4569        {
4570                PyErr_SetString(PyExc_ValueError, "Invalid field number");
4571                return NULL;
4572        }
4573
4574        /* gets fields name and builds object */
4575        name = PQfname(self->result, i);
4576        return PyStr_FromString(name);
4577}
4578
4579/* gets fields number from name in last result */
4580static char queryFieldNumber__doc__[] =
4581"fieldnum(name) -- return position in query for field from its name";
4582
4583static PyObject *
4584queryFieldNumber(queryObject *self, PyObject *args)
4585{
4586        int             num;
4587        char   *name;
4588
4589        /* gets args */
4590        if (!PyArg_ParseTuple(args, "s", &name))
4591        {
4592                PyErr_SetString(PyExc_TypeError,
4593                        "Method fieldnum() takes a string as argument");
4594                return NULL;
4595        }
4596
4597        /* gets field number */
4598        if ((num = PQfnumber(self->result, name)) == -1)
4599        {
4600                PyErr_SetString(PyExc_ValueError, "Unknown field");
4601                return NULL;
4602        }
4603
4604        return PyInt_FromLong(num);
4605}
4606
4607/* retrieves last result */
4608static char queryGetResult__doc__[] =
4609"getresult() -- Get the result of a query\n\n"
4610"The result is returned as a list of rows, each one a tuple of fields\n"
4611"in the order returned by the server.\n";
4612
4613static PyObject *
4614queryGetResult(queryObject *self, PyObject *noargs)
4615{
4616        PyObject   *reslist;
4617        int                     i, m, n, *col_types;
4618        int                     encoding = self->encoding;
4619
4620        /* stores result in tuple */
4621        m = PQntuples(self->result);
4622        n = PQnfields(self->result);
4623        if (!(reslist = PyList_New(m))) return NULL;
4624
4625        if (!(col_types = get_col_types(self->result, n))) return NULL;
4626
4627        for (i = 0; i < m; ++i)
4628        {
4629                PyObject   *rowtuple;
4630                int                     j;
4631
4632                if (!(rowtuple = PyTuple_New(n)))
4633                {
4634                        Py_DECREF(reslist);
4635                        reslist = NULL;
4636                        goto exit;
4637                }
4638
4639                for (j = 0; j < n; ++j)
4640                {
4641                        PyObject * val;
4642
4643                        if (PQgetisnull(self->result, i, j))
4644                        {
4645                                Py_INCREF(Py_None);
4646                                val = Py_None;
4647                        }
4648                        else /* not null */
4649                        {
4650                                /* get the string representation of the value */
4651                                /* note: this is always null-terminated text format */
4652                                char   *s = PQgetvalue(self->result, i, j);
4653                                /* get the PyGreSQL type of the column */
4654                                int             type = col_types[j];
4655
4656                                if (type & PYGRES_ARRAY)
4657                                        val = cast_array(s, PQgetlength(self->result, i, j),
4658                                                encoding, type, NULL, 0);
4659                                else if (type == PYGRES_BYTEA)
4660                                        val = cast_bytea_text(s);
4661                                else if (type == PYGRES_OTHER)
4662                                        val = cast_other(s,
4663                                                PQgetlength(self->result, i, j), encoding,
4664                                                PQftype(self->result, j), self->pgcnx->cast_hook);
4665                                else if (type & PYGRES_TEXT)
4666                                        val = cast_sized_text(s, PQgetlength(self->result, i, j),
4667                                                encoding, type);
4668                                else
4669                                        val = cast_unsized_simple(s, type);
4670                        }
4671
4672                        if (!val)
4673                        {
4674                                Py_DECREF(reslist);
4675                                Py_DECREF(rowtuple);
4676                                reslist = NULL;
4677                                goto exit;
4678                        }
4679
4680                        PyTuple_SET_ITEM(rowtuple, j, val);
4681                }
4682
4683                PyList_SET_ITEM(reslist, i, rowtuple);
4684        }
4685
4686exit:
4687        PyMem_Free(col_types);
4688
4689        /* returns list */
4690        return reslist;
4691}
4692
4693/* retrieves last result as a list of dictionaries*/
4694static char queryDictResult__doc__[] =
4695"dictresult() -- Get the result of a query\n\n"
4696"The result is returned as a list of rows, each one a dictionary with\n"
4697"the field names used as the labels.\n";
4698
4699static PyObject *
4700queryDictResult(queryObject *self, PyObject *noargs)
4701{
4702        PyObject   *reslist;
4703        int                     i,
4704                                m,
4705                                n,
4706                           *col_types;
4707        int                     encoding = self->encoding;
4708
4709        /* stores result in list */
4710        m = PQntuples(self->result);
4711        n = PQnfields(self->result);
4712        if (!(reslist = PyList_New(m))) return NULL;
4713
4714        if (!(col_types = get_col_types(self->result, n))) return NULL;
4715
4716        for (i = 0; i < m; ++i)
4717        {
4718                PyObject   *dict;
4719                int                     j;
4720
4721                if (!(dict = PyDict_New()))
4722                {
4723                        Py_DECREF(reslist);
4724                        reslist = NULL;
4725                        goto exit;
4726                }
4727
4728                for (j = 0; j < n; ++j)
4729                {
4730                        PyObject * val;
4731
4732                        if (PQgetisnull(self->result, i, j))
4733                        {
4734                                Py_INCREF(Py_None);
4735                                val = Py_None;
4736                        }
4737                        else /* not null */
4738                        {
4739                                /* get the string representation of the value */
4740                                /* note: this is always null-terminated text format */
4741                                char   *s = PQgetvalue(self->result, i, j);
4742                                /* get the PyGreSQL type of the column */
4743                                int             type = col_types[j];
4744
4745                                if (type & PYGRES_ARRAY)
4746                                        val = cast_array(s, PQgetlength(self->result, i, j),
4747                                                encoding, type, NULL, 0);
4748                                else if (type == PYGRES_BYTEA)
4749                                        val = cast_bytea_text(s);
4750                                else if (type == PYGRES_OTHER)
4751                                        val = cast_other(s,
4752                                                PQgetlength(self->result, i, j), encoding,
4753                                                PQftype(self->result, j), self->pgcnx->cast_hook);
4754                                else if (type & PYGRES_TEXT)
4755                                        val = cast_sized_text(s, PQgetlength(self->result, i, j),
4756                                                encoding, type);
4757                                else
4758                                        val = cast_unsized_simple(s, type);
4759                        }
4760
4761                        if (!val)
4762                        {
4763                                Py_DECREF(dict);
4764                                Py_DECREF(reslist);
4765                                reslist = NULL;
4766                                goto exit;
4767                        }
4768
4769                        PyDict_SetItemString(dict, PQfname(self->result, j), val);
4770                        Py_DECREF(val);
4771                }
4772
4773                PyList_SET_ITEM(reslist, i, dict);
4774        }
4775
4776exit:
4777        PyMem_Free(col_types);
4778
4779        /* returns list */
4780        return reslist;
4781}
4782
4783/* retrieves last result as named tuples */
4784static char queryNamedResult__doc__[] =
4785"namedresult() -- Get the result of a query\n\n"
4786"The result is returned as a list of rows, each one a tuple of fields\n"
4787"in the order returned by the server.\n";
4788
4789static PyObject *
4790queryNamedResult(queryObject *self, PyObject *noargs)
4791{
4792        PyObject   *ret;
4793
4794        if (namedresult)
4795        {
4796                ret = PyObject_CallFunction(namedresult, "(O)", self);
4797
4798                if (ret == NULL)
4799                        return NULL;
4800                }
4801        else
4802        {
4803                ret = queryGetResult(self, NULL);
4804        }
4805
4806        return ret;
4807}
4808
4809/* gets notice object attributes */
4810static PyObject *
4811noticeGetAttr(noticeObject *self, PyObject *nameobj)
4812{
4813        PGresult const *res = self->res;
4814        const char *name = PyStr_AsString(nameobj);
4815        int fieldcode;
4816
4817        if (!res)
4818        {
4819                PyErr_SetString(PyExc_TypeError, "Cannot get current notice");
4820                return NULL;
4821        }
4822
4823        /* pg connection object */
4824        if (!strcmp(name, "pgcnx"))
4825        {
4826                if (self->pgcnx && check_cnx_obj(self->pgcnx))
4827                {
4828                        Py_INCREF(self->pgcnx);
4829                        return (PyObject *) self->pgcnx;
4830                }
4831                else
4832                {
4833                        Py_INCREF(Py_None);
4834                        return Py_None;
4835                }
4836        }
4837
4838        /* full message */
4839        if (!strcmp(name, "message"))
4840                return PyStr_FromString(PQresultErrorMessage(res));
4841
4842        /* other possible fields */
4843        fieldcode = 0;
4844        if (!strcmp(name, "severity"))
4845                fieldcode = PG_DIAG_SEVERITY;
4846        else if (!strcmp(name, "primary"))
4847                fieldcode = PG_DIAG_MESSAGE_PRIMARY;
4848        else if (!strcmp(name, "detail"))
4849                fieldcode = PG_DIAG_MESSAGE_DETAIL;
4850        else if (!strcmp(name, "hint"))
4851                fieldcode = PG_DIAG_MESSAGE_HINT;
4852        if (fieldcode)
4853        {
4854                char *s = PQresultErrorField(res, fieldcode);
4855                if (s)
4856                        return PyStr_FromString(s);
4857                else
4858                {
4859                        Py_INCREF(Py_None); return Py_None;
4860                }
4861        }
4862
4863        return PyObject_GenericGetAttr((PyObject *) self, nameobj);
4864}
4865
4866/* return notice as string in human readable form */
4867static PyObject *
4868noticeStr(noticeObject *self)
4869{
4870        return noticeGetAttr(self, PyBytes_FromString("message"));
4871}
4872
4873/* get the list of notice attributes */
4874static PyObject *
4875noticeDir(noticeObject *self, PyObject *noargs)
4876{
4877        PyObject *attrs;
4878
4879        attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
4880        PyObject_CallMethod(attrs, "extend", "[ssssss]",
4881                "pgcnx", "severity", "message", "primary", "detail", "hint");
4882
4883        return attrs;
4884}
4885
4886/* notice object methods */
4887static struct PyMethodDef noticeMethods[] = {
4888        {"__dir__", (PyCFunction) noticeDir,  METH_NOARGS, NULL},
4889        {NULL, NULL}
4890};
4891
4892/* notice type definition */
4893static PyTypeObject noticeType = {
4894        PyVarObject_HEAD_INIT(NULL, 0)
4895        "pg.Notice",                                    /* tp_name */
4896        sizeof(noticeObject),                   /* tp_basicsize */
4897        0,                                                              /* tp_itemsize */
4898        /* methods */
4899        0,                                                              /* tp_dealloc */
4900        0,                                                              /* tp_print */
4901        0,                                                              /* tp_getattr */
4902        0,                                                              /* tp_setattr */
4903        0,                                                              /* tp_compare */
4904        0,                                                              /* tp_repr */
4905        0,                                                              /* tp_as_number */
4906        0,                                                              /* tp_as_sequence */
4907        0,                                                              /* tp_as_mapping */
4908        0,                                                              /* tp_hash */
4909        0,                                                              /* tp_call */
4910        (reprfunc) noticeStr,                   /* tp_str */
4911        (getattrofunc) noticeGetAttr,   /* tp_getattro */
4912        PyObject_GenericSetAttr,                /* tp_setattro */
4913        0,                                                              /* tp_as_buffer */
4914        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
4915        0,                                                              /* tp_doc */
4916        0,                                                              /* tp_traverse */
4917        0,                                                              /* tp_clear */
4918        0,                                                              /* tp_richcompare */
4919        0,                                                              /* tp_weaklistoffset */
4920        0,                                                              /* tp_iter */
4921        0,                                                              /* tp_iternext */
4922        noticeMethods,                                  /* tp_methods */
4923};
4924
4925/* query object methods */
4926static struct PyMethodDef queryMethods[] = {
4927        {"getresult", (PyCFunction) queryGetResult, METH_NOARGS,
4928                        queryGetResult__doc__},
4929        {"dictresult", (PyCFunction) queryDictResult, METH_NOARGS,
4930                        queryDictResult__doc__},
4931        {"namedresult", (PyCFunction) queryNamedResult, METH_NOARGS,
4932                        queryNamedResult__doc__},
4933        {"fieldname", (PyCFunction) queryFieldName, METH_VARARGS,
4934                         queryFieldName__doc__},
4935        {"fieldnum", (PyCFunction) queryFieldNumber, METH_VARARGS,
4936                        queryFieldNumber__doc__},
4937        {"listfields", (PyCFunction) queryListFields, METH_NOARGS,
4938                        queryListFields__doc__},
4939        {"ntuples", (PyCFunction) queryNTuples, METH_NOARGS,
4940                        queryNTuples__doc__},
4941        {NULL, NULL}
4942};
4943
4944/* query type definition */
4945static PyTypeObject queryType = {
4946        PyVarObject_HEAD_INIT(NULL, 0)
4947        "pg.Query",                                             /* tp_name */
4948        sizeof(queryObject),                    /* tp_basicsize */
4949        0,                                                              /* tp_itemsize */
4950        /* methods */
4951        (destructor) queryDealloc,              /* tp_dealloc */
4952        0,                                                              /* tp_print */
4953        0,                                                              /* tp_getattr */
4954        0,                                                              /* tp_setattr */
4955        0,                                                              /* tp_compare */
4956        0,                                                              /* tp_repr */
4957        0,                                                              /* tp_as_number */
4958        0,                                                              /* tp_as_sequence */
4959        0,                                                              /* tp_as_mapping */
4960        0,                                                              /* tp_hash */
4961        0,                                                              /* tp_call */
4962        (reprfunc) queryStr,                    /* tp_str */
4963        PyObject_GenericGetAttr,                /* tp_getattro */
4964        0,                                                              /* tp_setattro */
4965        0,                                                              /* tp_as_buffer */
4966        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
4967        0,                                                              /* tp_doc */
4968        0,                                                              /* tp_traverse */
4969        0,                                                              /* tp_clear */
4970        0,                                                              /* tp_richcompare */
4971        0,                                                              /* tp_weaklistoffset */
4972        0,                                                              /* tp_iter */
4973        0,                                                              /* tp_iternext */
4974        queryMethods,                                   /* tp_methods */
4975};
4976
4977/* --------------------------------------------------------------------- */
4978
4979/* MODULE FUNCTIONS */
4980
4981/* escape string */
4982static char pgEscapeString__doc__[] =
4983"escape_string(string) -- escape a string for use within SQL";
4984
4985static PyObject *
4986pgEscapeString(PyObject *self, PyObject *string)
4987{
4988        PyObject   *tmp_obj = NULL, /* auxiliary string object */
4989                           *to_obj; /* string object to return */
4990        char       *from, /* our string argument as encoded string */
4991                           *to; /* the result as encoded string */
4992        Py_ssize_t      from_length; /* length of string */
4993        size_t          to_length; /* length of result */
4994        int                     encoding = -1; /* client encoding */
4995
4996        if (PyBytes_Check(string))
4997        {
4998                PyBytes_AsStringAndSize(string, &from, &from_length);
4999        }
5000        else if (PyUnicode_Check(string))
5001        {
5002                encoding = pg_encoding_ascii;
5003                tmp_obj = get_encoded_string(string, encoding);
5004                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
5005                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
5006        }
5007        else
5008        {
5009                PyErr_SetString(PyExc_TypeError,
5010                        "Method escape_string() expects a string as argument");
5011                return NULL;
5012        }
5013
5014        to_length = 2*from_length + 1;
5015        if ((Py_ssize_t)to_length < from_length) /* overflow */
5016        {
5017                to_length = from_length;
5018                from_length = (from_length - 1)/2;
5019        }
5020        to = (char *)PyMem_Malloc(to_length);
5021        to_length = (int)PQescapeString(to, from, (size_t)from_length);
5022
5023        Py_XDECREF(tmp_obj);
5024
5025        if (encoding == -1)
5026                to_obj = PyBytes_FromStringAndSize(to, to_length);
5027        else
5028                to_obj = get_decoded_string(to, to_length, encoding);
5029        PyMem_Free(to);
5030        return to_obj;
5031}
5032
5033/* escape bytea */
5034static char pgEscapeBytea__doc__[] =
5035"escape_bytea(data) -- escape binary data for use within SQL as type bytea";
5036
5037static PyObject *
5038pgEscapeBytea(PyObject *self, PyObject *data)
5039{
5040        PyObject   *tmp_obj = NULL, /* auxiliary string object */
5041                           *to_obj; /* string object to return */
5042        char       *from, /* our string argument as encoded string */
5043                           *to; /* the result as encoded string */
5044        Py_ssize_t      from_length; /* length of string */
5045        size_t          to_length; /* length of result */
5046        int                     encoding = -1; /* client encoding */
5047
5048        if (PyBytes_Check(data))
5049        {
5050                PyBytes_AsStringAndSize(data, &from, &from_length);
5051        }
5052        else if (PyUnicode_Check(data))
5053        {
5054                encoding = pg_encoding_ascii;
5055                tmp_obj = get_encoded_string(data, encoding);
5056                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
5057                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
5058        }
5059        else
5060        {
5061                PyErr_SetString(PyExc_TypeError,
5062                        "Method escape_bytea() expects a string as argument");
5063                return NULL;
5064        }
5065
5066        to = (char *)PQescapeBytea(
5067                (unsigned char*)from, (size_t)from_length, &to_length);
5068
5069        Py_XDECREF(tmp_obj);
5070
5071        if (encoding == -1)
5072                to_obj = PyBytes_FromStringAndSize(to, to_length - 1);
5073        else
5074                to_obj = get_decoded_string(to, to_length - 1, encoding);
5075        if (to)
5076                PQfreemem(to);
5077        return to_obj;
5078}
5079
5080/* unescape bytea */
5081static char pgUnescapeBytea__doc__[] =
5082"unescape_bytea(string) -- unescape bytea data retrieved as text";
5083
5084static PyObject *
5085pgUnescapeBytea(PyObject *self, PyObject *data)
5086{
5087        PyObject   *tmp_obj = NULL, /* auxiliary string object */
5088                           *to_obj; /* string object to return */
5089        char       *from, /* our string argument as encoded string */
5090                           *to; /* the result as encoded string */
5091        Py_ssize_t      from_length; /* length of string */
5092        size_t          to_length; /* length of result */
5093
5094        if (PyBytes_Check(data))
5095        {
5096                PyBytes_AsStringAndSize(data, &from, &from_length);
5097        }
5098        else if (PyUnicode_Check(data))
5099        {
5100                tmp_obj = get_encoded_string(data, pg_encoding_ascii);
5101                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
5102                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
5103        }
5104        else
5105        {
5106                PyErr_SetString(PyExc_TypeError,
5107                        "Method unescape_bytea() expects a string as argument");
5108                return NULL;
5109        }
5110
5111        to = (char *)PQunescapeBytea((unsigned char*)from, &to_length);
5112
5113        Py_XDECREF(tmp_obj);
5114
5115        if (!to) return PyErr_NoMemory();
5116
5117        to_obj = PyBytes_FromStringAndSize(to, to_length);
5118        PQfreemem(to);
5119
5120        return to_obj;
5121}
5122
5123/* set fixed datestyle */
5124static char pgSetDatestyle__doc__[] =
5125"set_datestyle(style) -- set which style is assumed";
5126
5127static PyObject *
5128pgSetDatestyle(PyObject *self, PyObject *args)
5129{
5130        const char         *datestyle = NULL;
5131
5132        /* gets arguments */
5133        if (!PyArg_ParseTuple(args, "z", &datestyle))
5134        {
5135                PyErr_SetString(PyExc_TypeError,
5136                        "Function set_datestyle() expects a string or None as argument");
5137                return NULL;
5138        }
5139
5140        date_format = datestyle ? date_style_to_format(datestyle) : NULL;
5141
5142        Py_INCREF(Py_None); return Py_None;
5143}
5144
5145/* get fixed datestyle */
5146static char pgGetDatestyle__doc__[] =
5147"get_datestyle() -- get which date style is assumed";
5148
5149static PyObject *
5150pgGetDatestyle(PyObject *self, PyObject *noargs)
5151{
5152        if (date_format)
5153        {
5154                return PyStr_FromString(date_format_to_style(date_format));
5155        }
5156        else
5157        {
5158                Py_INCREF(Py_None); return Py_None;
5159        }
5160}
5161
5162/* get decimal point */
5163static char pgGetDecimalPoint__doc__[] =
5164"get_decimal_point() -- get decimal point to be used for money values";
5165
5166static PyObject *
5167pgGetDecimalPoint(PyObject *self, PyObject *noargs)
5168{
5169        PyObject *ret;
5170        char s[2];
5171
5172        if (decimal_point)
5173        {
5174                s[0] = decimal_point; s[1] = '\0';
5175                ret = PyStr_FromString(s);
5176        }
5177        else
5178        {
5179                Py_INCREF(Py_None); ret = Py_None;
5180        }
5181
5182        return ret;
5183}
5184
5185/* set decimal point */
5186static char pgSetDecimalPoint__doc__[] =
5187"set_decimal_point(char) -- set decimal point to be used for money values";
5188
5189static PyObject *
5190pgSetDecimalPoint(PyObject *self, PyObject *args)
5191{
5192        PyObject *ret = NULL;
5193        char *s = NULL;
5194
5195        /* gets arguments */
5196        if (PyArg_ParseTuple(args, "z", &s))
5197        {
5198                if (!s)
5199                        s = "\0";
5200                else if (*s && (*(s+1) || !strchr(".,;: '*/_`|", *s)))
5201                        s = NULL;
5202        }
5203
5204        if (s)
5205        {
5206                decimal_point = *s;
5207                Py_INCREF(Py_None); ret = Py_None;
5208        }
5209        else
5210                PyErr_SetString(PyExc_TypeError,
5211                        "Function set_decimal_mark() expects"
5212                        " a decimal mark character as argument");
5213
5214        return ret;
5215}
5216
5217/* get decimal type */
5218static char pgGetDecimal__doc__[] =
5219"get_decimal() -- get the decimal type to be used for numeric values";
5220
5221static PyObject *
5222pgGetDecimal(PyObject *self, PyObject *noargs)
5223{
5224        PyObject *ret;
5225
5226        ret = decimal ? decimal : Py_None;
5227        Py_INCREF(ret);
5228
5229        return ret;
5230}
5231
5232/* set decimal type */
5233static char pgSetDecimal__doc__[] =
5234"set_decimal(cls) -- set a decimal type to be used for numeric values";
5235
5236static PyObject *
5237pgSetDecimal(PyObject *self, PyObject *cls)
5238{
5239        PyObject *ret = NULL;
5240
5241        if (cls == Py_None)
5242        {
5243                Py_XDECREF(decimal); decimal = NULL;
5244                Py_INCREF(Py_None); ret = Py_None;
5245        }
5246        else if (PyCallable_Check(cls))
5247        {
5248                Py_XINCREF(cls); Py_XDECREF(decimal); decimal = cls;
5249                Py_INCREF(Py_None); ret = Py_None;
5250        }
5251        else
5252                PyErr_SetString(PyExc_TypeError,
5253                        "Function set_decimal() expects"
5254                         " a callable or None as argument");
5255
5256        return ret;
5257}
5258
5259/* get usage of bool values */
5260static char pgGetBool__doc__[] =
5261"get_bool() -- check whether boolean values are converted to bool";
5262
5263static PyObject *
5264pgGetBool(PyObject *self, PyObject *noargs)
5265{
5266        PyObject *ret;
5267
5268        ret = bool_as_text ? Py_False : Py_True;
5269        Py_INCREF(ret);
5270
5271        return ret;
5272}
5273
5274/* set usage of bool values */
5275static char pgSetBool__doc__[] =
5276"set_bool(on) -- set whether boolean values should be converted to bool";
5277
5278static PyObject *
5279pgSetBool(PyObject *self, PyObject *args)
5280{
5281        PyObject *ret = NULL;
5282        int                     i;
5283
5284        /* gets arguments */
5285        if (PyArg_ParseTuple(args, "i", &i))
5286        {
5287                bool_as_text = i ? 0 : 1;
5288                Py_INCREF(Py_None); ret = Py_None;
5289        }
5290        else
5291                PyErr_SetString(PyExc_TypeError,
5292                        "Function set_bool() expects a boolean value as argument");
5293
5294        return ret;
5295}
5296
5297/* get conversion of arrays to lists */
5298static char pgGetArray__doc__[] =
5299"get_array() -- check whether arrays are converted as lists";
5300
5301static PyObject *
5302pgGetArray(PyObject *self, PyObject *noargs)
5303{
5304        PyObject *ret;
5305
5306        ret = array_as_text ? Py_False : Py_True;
5307        Py_INCREF(ret);
5308
5309        return ret;
5310}
5311
5312/* set conversion of arrays to lists */
5313static char pgSetArray__doc__[] =
5314"set_array(on) -- set whether arrays should be converted to lists";
5315
5316static PyObject *
5317pgSetArray(PyObject *self, PyObject *args)
5318{
5319        PyObject *ret = NULL;
5320        int                     i;
5321
5322        /* gets arguments */
5323        if (PyArg_ParseTuple(args, "i", &i))
5324        {
5325                array_as_text = i ? 0 : 1;
5326                Py_INCREF(Py_None); ret = Py_None;
5327        }
5328        else
5329                PyErr_SetString(PyExc_TypeError,
5330                        "Function set_array() expects a boolean value as argument");
5331
5332        return ret;
5333}
5334
5335/* check whether bytea values are unescaped */
5336static char pgGetByteaEscaped__doc__[] =
5337"get_bytea_escaped() -- check whether bytea will be returned escaped";
5338
5339static PyObject *
5340pgGetByteaEscaped(PyObject *self, PyObject *noargs)
5341{
5342        PyObject *ret;
5343
5344        ret = bytea_escaped ? Py_True : Py_False;
5345        Py_INCREF(ret);
5346
5347        return ret;
5348}
5349
5350/* set usage of bool values */
5351static char pgSetByteaEscaped__doc__[] =
5352"set_bytea_escaped(on) -- set whether bytea will be returned escaped";
5353
5354static PyObject *
5355pgSetByteaEscaped(PyObject *self, PyObject *args)
5356{
5357        PyObject *ret = NULL;
5358        int                     i;
5359
5360        /* gets arguments */
5361        if (PyArg_ParseTuple(args, "i", &i))
5362        {
5363                bytea_escaped = i ? 1 : 0;
5364                Py_INCREF(Py_None); ret = Py_None;
5365        }
5366        else
5367                PyErr_SetString(PyExc_TypeError,
5368                        "Function set_bytea_escaped() expects a boolean value as argument");
5369
5370        return ret;
5371}
5372
5373/* get named result factory */
5374static char pgGetNamedresult__doc__[] =
5375"get_namedresult() -- get the function used for getting named results";
5376
5377static PyObject *
5378pgGetNamedresult(PyObject *self, PyObject *noargs)
5379{
5380        PyObject *ret;
5381
5382        ret = namedresult ? namedresult : Py_None;
5383        Py_INCREF(ret);
5384
5385        return ret;
5386}
5387
5388/* set named result factory */
5389static char pgSetNamedresult__doc__[] =
5390"set_namedresult(func) -- set a function to be used for getting named results";
5391
5392static PyObject *
5393pgSetNamedresult(PyObject *self, PyObject *func)
5394{
5395        PyObject *ret = NULL;
5396
5397        if (func == Py_None)
5398        {
5399                Py_XDECREF(namedresult); namedresult = NULL;
5400                Py_INCREF(Py_None); ret = Py_None;
5401        }
5402        else if (PyCallable_Check(func))
5403        {
5404                Py_XINCREF(func); Py_XDECREF(namedresult); namedresult = func;
5405                Py_INCREF(Py_None); ret = Py_None;
5406        }
5407        else
5408                PyErr_SetString(PyExc_TypeError,
5409                        "Function set_namedresult() expects"
5410                         " a callable or None as argument");
5411
5412        return ret;
5413}
5414
5415/* get json decode function */
5416static char pgGetJsondecode__doc__[] =
5417"get_jsondecode() -- get the function used for decoding json results";
5418
5419static PyObject *
5420pgGetJsondecode(PyObject *self, PyObject *noargs)
5421{
5422        PyObject *ret;
5423
5424        ret = jsondecode;
5425        if (!ret)
5426                ret = Py_None;
5427        Py_INCREF(ret);
5428
5429        return ret;
5430}
5431
5432/* set json decode function */
5433static char pgSetJsondecode__doc__[] =
5434"set_jsondecode(func) -- set a function to be used for decoding json results";
5435
5436static PyObject *
5437pgSetJsondecode(PyObject *self, PyObject *func)
5438{
5439        PyObject *ret = NULL;
5440
5441        if (func == Py_None)
5442        {
5443                Py_XDECREF(jsondecode); jsondecode = NULL;
5444                Py_INCREF(Py_None); ret = Py_None;
5445        }
5446        else if (PyCallable_Check(func))
5447        {
5448                Py_XINCREF(func); Py_XDECREF(jsondecode); jsondecode = func;
5449                Py_INCREF(Py_None); ret = Py_None;
5450        }
5451        else
5452                PyErr_SetString(PyExc_TypeError,
5453                        "Function jsondecode() expects"
5454                         " a callable or None as argument");
5455
5456        return ret;
5457}
5458
5459#ifdef DEFAULT_VARS
5460
5461/* gets default host */
5462static char pgGetDefHost__doc__[] =
5463"get_defhost() -- return default database host";
5464
5465static PyObject *
5466pgGetDefHost(PyObject *self, PyObject *noargs)
5467{
5468        Py_XINCREF(pg_default_host);
5469        return pg_default_host;
5470}
5471
5472/* sets default host */
5473static char pgSetDefHost__doc__[] =
5474"set_defhost(string) -- set default database host and return previous value";
5475
5476static PyObject *
5477pgSetDefHost(PyObject *self, PyObject *args)
5478{
5479        char       *temp = NULL;
5480        PyObject   *old;
5481
5482        /* gets arguments */
5483        if (!PyArg_ParseTuple(args, "z", &temp))
5484        {
5485                PyErr_SetString(PyExc_TypeError,
5486                        "Function set_defhost() expects a string or None as argument");
5487                return NULL;
5488        }
5489
5490        /* adjusts value */
5491        old = pg_default_host;
5492
5493        if (temp)
5494                pg_default_host = PyStr_FromString(temp);
5495        else
5496        {
5497                Py_INCREF(Py_None);
5498                pg_default_host = Py_None;
5499        }
5500
5501        return old;
5502}
5503
5504/* gets default base */
5505static char pgGetDefBase__doc__[] =
5506"get_defbase() -- return default database name";
5507
5508static PyObject *
5509pgGetDefBase(PyObject *self, PyObject *noargs)
5510{
5511        Py_XINCREF(pg_default_base);
5512        return pg_default_base;
5513}
5514
5515/* sets default base */
5516static char pgSetDefBase__doc__[] =
5517"set_defbase(string) -- set default database name and return previous value";
5518
5519static PyObject *
5520pgSetDefBase(PyObject *self, PyObject *args)
5521{
5522        char       *temp = NULL;
5523        PyObject   *old;
5524
5525        /* gets arguments */
5526        if (!PyArg_ParseTuple(args, "z", &temp))
5527        {
5528                PyErr_SetString(PyExc_TypeError,
5529                        "Function set_defbase() Argument a string or None as argument");
5530                return NULL;
5531        }
5532
5533        /* adjusts value */
5534        old = pg_default_base;
5535
5536        if (temp)
5537                pg_default_base = PyStr_FromString(temp);
5538        else
5539        {
5540                Py_INCREF(Py_None);
5541                pg_default_base = Py_None;
5542        }
5543
5544        return old;
5545}
5546
5547/* gets default options */
5548static char pgGetDefOpt__doc__[] =
5549"get_defopt() -- return default database options";
5550
5551static PyObject *
5552pgGetDefOpt(PyObject *self, PyObject *noargs)
5553{
5554        Py_XINCREF(pg_default_opt);
5555        return pg_default_opt;
5556}
5557
5558/* sets default opt */
5559static char pgSetDefOpt__doc__[] =
5560"set_defopt(string) -- set default options and return previous value";
5561
5562static PyObject *
5563pgSetDefOpt(PyObject *self, PyObject *args)
5564{
5565        char       *temp = NULL;
5566        PyObject   *old;
5567
5568        /* gets arguments */
5569        if (!PyArg_ParseTuple(args, "z", &temp))
5570        {
5571                PyErr_SetString(PyExc_TypeError,
5572                        "Function set_defopt() expects a string or None as argument");
5573                return NULL;
5574        }
5575
5576        /* adjusts value */
5577        old = pg_default_opt;
5578
5579        if (temp)
5580                pg_default_opt = PyStr_FromString(temp);
5581        else
5582        {
5583                Py_INCREF(Py_None);
5584                pg_default_opt = Py_None;
5585        }
5586
5587        return old;
5588}
5589
5590/* gets default username */
5591static char pgGetDefUser__doc__[] =
5592"get_defuser() -- return default database username";
5593
5594static PyObject *
5595pgGetDefUser(PyObject *self, PyObject *noargs)
5596{
5597        Py_XINCREF(pg_default_user);
5598        return pg_default_user;
5599}
5600
5601/* sets default username */
5602
5603static char pgSetDefUser__doc__[] =
5604"set_defuser(name) -- set default username and return previous value";
5605
5606static PyObject *
5607pgSetDefUser(PyObject *self, PyObject *args)
5608{
5609        char       *temp = NULL;
5610        PyObject   *old;
5611
5612        /* gets arguments */
5613        if (!PyArg_ParseTuple(args, "z", &temp))
5614        {
5615                PyErr_SetString(PyExc_TypeError,
5616                        "Function set_defuser() expects a string or None as argument");
5617                return NULL;
5618        }
5619
5620        /* adjusts value */
5621        old = pg_default_user;
5622
5623        if (temp)
5624                pg_default_user = PyStr_FromString(temp);
5625        else
5626        {
5627                Py_INCREF(Py_None);
5628                pg_default_user = Py_None;
5629        }
5630
5631        return old;
5632}
5633
5634/* sets default password */
5635static char pgSetDefPassword__doc__[] =
5636"set_defpasswd(password) -- set default database password";
5637
5638static PyObject *
5639pgSetDefPassword(PyObject *self, PyObject *args)
5640{
5641        char       *temp = NULL;
5642
5643        /* gets arguments */
5644        if (!PyArg_ParseTuple(args, "z", &temp))
5645        {
5646                PyErr_SetString(PyExc_TypeError,
5647                        "Function set_defpasswd() expects a string or None as argument");
5648                return NULL;
5649        }
5650
5651        if (temp)
5652                pg_default_passwd = PyStr_FromString(temp);
5653        else
5654        {
5655                Py_INCREF(Py_None);
5656                pg_default_passwd = Py_None;
5657        }
5658
5659        Py_INCREF(Py_None);
5660        return Py_None;
5661}
5662
5663/* gets default port */
5664static char pgGetDefPort__doc__[] =
5665"get_defport() -- return default database port";
5666
5667static PyObject *
5668pgGetDefPort(PyObject *self, PyObject *noargs)
5669{
5670        Py_XINCREF(pg_default_port);
5671        return pg_default_port;
5672}
5673
5674/* sets default port */
5675static char pgSetDefPort__doc__[] =
5676"set_defport(port) -- set default port and return previous value";
5677
5678static PyObject *
5679pgSetDefPort(PyObject *self, PyObject *args)
5680{
5681        long int        port = -2;
5682        PyObject   *old;
5683
5684        /* gets arguments */
5685        if ((!PyArg_ParseTuple(args, "l", &port)) || (port < -1))
5686        {
5687                PyErr_SetString(PyExc_TypeError,
5688                        "Function set_deport expects"
5689                         " a positive integer or -1 as argument");
5690                return NULL;
5691        }
5692
5693        /* adjusts value */
5694        old = pg_default_port;
5695
5696        if (port != -1)
5697                pg_default_port = PyInt_FromLong(port);
5698        else
5699        {
5700                Py_INCREF(Py_None);
5701                pg_default_port = Py_None;
5702        }
5703
5704        return old;
5705}
5706#endif /* DEFAULT_VARS */
5707
5708/* cast a string with a text representation of an array to a list */
5709static char pgCastArray__doc__[] =
5710"cast_array(string, cast=None, delim=',') -- cast a string as an array";
5711
5712PyObject *
5713pgCastArray(PyObject *self, PyObject *args, PyObject *dict)
5714{
5715        static const char *kwlist[] = {"string", "cast", "delim", NULL};
5716        PyObject   *string_obj, *cast_obj = NULL, *ret;
5717        char       *string, delim = ',';
5718        Py_ssize_t      size;
5719        int                     encoding;
5720
5721        if (!PyArg_ParseTupleAndKeywords(args, dict, "O|Oc",
5722                        (char **) kwlist, &string_obj, &cast_obj, &delim))
5723                return NULL;
5724
5725        if (PyBytes_Check(string_obj))
5726        {
5727                PyBytes_AsStringAndSize(string_obj, &string, &size);
5728                string_obj = NULL;
5729                encoding = pg_encoding_ascii;
5730        }
5731        else if (PyUnicode_Check(string_obj))
5732        {
5733                string_obj = PyUnicode_AsUTF8String(string_obj);
5734                if (!string_obj) return NULL; /* pass the UnicodeEncodeError */
5735                PyBytes_AsStringAndSize(string_obj, &string, &size);
5736                encoding = pg_encoding_utf8;
5737        }
5738        else
5739        {
5740                PyErr_SetString(PyExc_TypeError,
5741                        "Function cast_array() expects a string as first argument");
5742                return NULL;
5743        }
5744
5745        if (!cast_obj || cast_obj == Py_None)
5746        {
5747                if (cast_obj)
5748                {
5749                        Py_DECREF(cast_obj); cast_obj = NULL;
5750                }
5751        }
5752        else if (!PyCallable_Check(cast_obj))
5753        {
5754                PyErr_SetString(PyExc_TypeError,
5755                        "Function cast_array() expects a callable as second argument");
5756                return NULL;
5757        }
5758
5759        ret = cast_array(string, size, encoding, 0, cast_obj, delim);
5760
5761        Py_XDECREF(string_obj);
5762
5763        return ret;
5764}
5765
5766/* cast a string with a text representation of a record to a tuple */
5767static char pgCastRecord__doc__[] =
5768"cast_record(string, cast=None, delim=',') -- cast a string as a record";
5769
5770PyObject *
5771pgCastRecord(PyObject *self, PyObject *args, PyObject *dict)
5772{
5773        static const char *kwlist[] = {"string", "cast", "delim", NULL};
5774        PyObject   *string_obj, *cast_obj = NULL, *ret;
5775        char       *string, delim = ',';
5776        Py_ssize_t      size, len;
5777        int                     encoding;
5778
5779        if (!PyArg_ParseTupleAndKeywords(args, dict, "O|Oc",
5780                        (char **) kwlist, &string_obj, &cast_obj, &delim))
5781                return NULL;
5782
5783        if (PyBytes_Check(string_obj))
5784        {
5785                PyBytes_AsStringAndSize(string_obj, &string, &size);
5786                string_obj = NULL;
5787                encoding = pg_encoding_ascii;
5788        }
5789        else if (PyUnicode_Check(string_obj))
5790        {
5791                string_obj = PyUnicode_AsUTF8String(string_obj);
5792                if (!string_obj) return NULL; /* pass the UnicodeEncodeError */
5793                PyBytes_AsStringAndSize(string_obj, &string, &size);
5794                encoding = pg_encoding_utf8;
5795        }
5796        else
5797        {
5798                PyErr_SetString(PyExc_TypeError,
5799                        "Function cast_record() expects a string as first argument");
5800                return NULL;
5801        }
5802
5803        if (!cast_obj || PyCallable_Check(cast_obj))
5804        {
5805                len = 0;
5806        }
5807        else if (cast_obj == Py_None)
5808        {
5809                Py_DECREF(cast_obj); cast_obj = NULL; len = 0;
5810        }
5811        else if (PyTuple_Check(cast_obj) || PyList_Check(cast_obj))
5812        {
5813                len = PySequence_Size(cast_obj);
5814                if (!len)
5815                {
5816                        Py_DECREF(cast_obj); cast_obj = NULL;
5817                }
5818        }
5819        else
5820        {
5821                PyErr_SetString(PyExc_TypeError,
5822                        "Function cast_record() expects a callable"
5823                         " or tuple or list of callables as second argument");
5824                return NULL;
5825        }
5826
5827        ret = cast_record(string, size, encoding, 0, cast_obj, len, delim);
5828
5829        Py_XDECREF(string_obj);
5830
5831        return ret;
5832}
5833
5834/* cast a string with a text representation of an hstore to a dict */
5835static char pgCastHStore__doc__[] =
5836"cast_hstore(string) -- cast a string as an hstore";
5837
5838PyObject *
5839pgCastHStore(PyObject *self, PyObject *string)
5840{
5841        PyObject   *tmp_obj = NULL, *ret;
5842        char       *s;
5843        Py_ssize_t      size;
5844        int                     encoding;
5845
5846        if (PyBytes_Check(string))
5847        {
5848                PyBytes_AsStringAndSize(string, &s, &size);
5849                encoding = pg_encoding_ascii;
5850        }
5851        else if (PyUnicode_Check(string))
5852        {
5853                tmp_obj = PyUnicode_AsUTF8String(string);
5854                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
5855                PyBytes_AsStringAndSize(tmp_obj, &s, &size);
5856                encoding = pg_encoding_utf8;
5857        }
5858        else
5859        {
5860                PyErr_SetString(PyExc_TypeError,
5861                        "Function cast_hstore() expects a string as first argument");
5862                return NULL;
5863        }
5864
5865        ret = cast_hstore(s, size, encoding);
5866
5867        Py_XDECREF(tmp_obj);
5868
5869        return ret;
5870}
5871
5872/* List of functions defined in the module */
5873
5874static struct PyMethodDef pgMethods[] = {
5875        {"connect", (PyCFunction) pgConnect, METH_VARARGS|METH_KEYWORDS,
5876                        pgConnect__doc__},
5877        {"escape_string", (PyCFunction) pgEscapeString, METH_O,
5878                        pgEscapeString__doc__},
5879        {"escape_bytea", (PyCFunction) pgEscapeBytea, METH_O,
5880                        pgEscapeBytea__doc__},
5881        {"unescape_bytea", (PyCFunction) pgUnescapeBytea, METH_O,
5882                        pgUnescapeBytea__doc__},
5883        {"get_datestyle", (PyCFunction) pgGetDatestyle, METH_NOARGS,
5884                        pgGetDatestyle__doc__},
5885        {"set_datestyle", (PyCFunction) pgSetDatestyle, METH_VARARGS,
5886                        pgSetDatestyle__doc__},
5887        {"get_decimal_point", (PyCFunction) pgGetDecimalPoint, METH_NOARGS,
5888                        pgGetDecimalPoint__doc__},
5889        {"set_decimal_point", (PyCFunction) pgSetDecimalPoint, METH_VARARGS,
5890                        pgSetDecimalPoint__doc__},
5891        {"get_decimal", (PyCFunction) pgGetDecimal, METH_NOARGS,
5892                        pgGetDecimal__doc__},
5893        {"set_decimal", (PyCFunction) pgSetDecimal, METH_O,
5894                        pgSetDecimal__doc__},
5895        {"get_bool", (PyCFunction) pgGetBool, METH_NOARGS, pgGetBool__doc__},
5896        {"set_bool", (PyCFunction) pgSetBool, METH_VARARGS, pgSetBool__doc__},
5897        {"get_array", (PyCFunction) pgGetArray, METH_NOARGS, pgGetArray__doc__},
5898        {"set_array", (PyCFunction) pgSetArray, METH_VARARGS, pgSetArray__doc__},
5899        {"get_bytea_escaped", (PyCFunction) pgGetByteaEscaped, METH_NOARGS,
5900                pgGetByteaEscaped__doc__},
5901        {"set_bytea_escaped", (PyCFunction) pgSetByteaEscaped, METH_VARARGS,
5902                pgSetByteaEscaped__doc__},
5903        {"get_namedresult", (PyCFunction) pgGetNamedresult, METH_NOARGS,
5904                        pgGetNamedresult__doc__},
5905        {"set_namedresult", (PyCFunction) pgSetNamedresult, METH_O,
5906                        pgSetNamedresult__doc__},
5907        {"get_jsondecode", (PyCFunction) pgGetJsondecode, METH_NOARGS,
5908                        pgGetJsondecode__doc__},
5909        {"set_jsondecode", (PyCFunction) pgSetJsondecode, METH_O,
5910                        pgSetJsondecode__doc__},
5911        {"cast_array", (PyCFunction) pgCastArray, METH_VARARGS|METH_KEYWORDS,
5912                        pgCastArray__doc__},
5913        {"cast_record", (PyCFunction) pgCastRecord, METH_VARARGS|METH_KEYWORDS,
5914                        pgCastRecord__doc__},
5915        {"cast_hstore", (PyCFunction) pgCastHStore, METH_O, pgCastHStore__doc__},
5916
5917#ifdef DEFAULT_VARS
5918        {"get_defhost", pgGetDefHost, METH_NOARGS, pgGetDefHost__doc__},
5919        {"set_defhost", pgSetDefHost, METH_VARARGS, pgSetDefHost__doc__},
5920        {"get_defbase", pgGetDefBase, METH_NOARGS, pgGetDefBase__doc__},
5921        {"set_defbase", pgSetDefBase, METH_VARARGS, pgSetDefBase__doc__},
5922        {"get_defopt", pgGetDefOpt, METH_NOARGS, pgGetDefOpt__doc__},
5923        {"set_defopt", pgSetDefOpt, METH_VARARGS, pgSetDefOpt__doc__},
5924        {"get_defport", pgGetDefPort, METH_NOARGS, pgGetDefPort__doc__},
5925        {"set_defport", pgSetDefPort, METH_VARARGS, pgSetDefPort__doc__},
5926        {"get_defuser", pgGetDefUser, METH_NOARGS, pgGetDefUser__doc__},
5927        {"set_defuser", pgSetDefUser, METH_VARARGS, pgSetDefUser__doc__},
5928        {"set_defpasswd", pgSetDefPassword, METH_VARARGS, pgSetDefPassword__doc__},
5929#endif /* DEFAULT_VARS */
5930        {NULL, NULL} /* sentinel */
5931};
5932
5933static char pg__doc__[] = "Python interface to PostgreSQL DB";
5934
5935static struct PyModuleDef moduleDef = {
5936        PyModuleDef_HEAD_INIT,
5937        "_pg",          /* m_name */
5938        pg__doc__,      /* m_doc */
5939        -1,                     /* m_size */
5940        pgMethods       /* m_methods */
5941};
5942
5943/* Initialization function for the module */
5944MODULE_INIT_FUNC(_pg)
5945{
5946        PyObject   *mod, *dict, *s;
5947
5948        /* Create the module and add the functions */
5949
5950        mod = PyModule_Create(&moduleDef);
5951
5952        /* Initialize here because some Windows platforms get confused otherwise */
5953#if IS_PY3
5954        connType.tp_base = noticeType.tp_base =
5955                queryType.tp_base = sourceType.tp_base = &PyBaseObject_Type;
5956#ifdef LARGE_OBJECTS
5957        largeType.tp_base = &PyBaseObject_Type;
5958#endif
5959#else
5960        connType.ob_type = noticeType.ob_type =
5961                queryType.ob_type = sourceType.ob_type = &PyType_Type;
5962#ifdef LARGE_OBJECTS
5963        largeType.ob_type = &PyType_Type;
5964#endif
5965#endif
5966
5967        if (PyType_Ready(&connType)
5968                || PyType_Ready(&noticeType)
5969                || PyType_Ready(&queryType)
5970                || PyType_Ready(&sourceType)
5971#ifdef LARGE_OBJECTS
5972                || PyType_Ready(&largeType)
5973#endif
5974                ) return NULL;
5975
5976        dict = PyModule_GetDict(mod);
5977
5978        /* Exceptions as defined by DB-API 2.0 */
5979        Error = PyErr_NewException("pg.Error", PyExc_Exception, NULL);
5980        PyDict_SetItemString(dict, "Error", Error);
5981
5982        Warning = PyErr_NewException("pg.Warning", PyExc_Exception, NULL);
5983        PyDict_SetItemString(dict, "Warning", Warning);
5984
5985        InterfaceError = PyErr_NewException("pg.InterfaceError", Error, NULL);
5986        PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
5987
5988        DatabaseError = PyErr_NewException("pg.DatabaseError", Error, NULL);
5989        PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
5990
5991        InternalError = PyErr_NewException("pg.InternalError", DatabaseError, NULL);
5992        PyDict_SetItemString(dict, "InternalError", InternalError);
5993
5994        OperationalError =
5995                PyErr_NewException("pg.OperationalError", DatabaseError, NULL);
5996        PyDict_SetItemString(dict, "OperationalError", OperationalError);
5997
5998        ProgrammingError =
5999                PyErr_NewException("pg.ProgrammingError", DatabaseError, NULL);
6000        PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
6001
6002        IntegrityError =
6003                PyErr_NewException("pg.IntegrityError", DatabaseError, NULL);
6004        PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
6005
6006        DataError = PyErr_NewException("pg.DataError", DatabaseError, NULL);
6007        PyDict_SetItemString(dict, "DataError", DataError);
6008
6009        NotSupportedError =
6010                PyErr_NewException("pg.NotSupportedError", DatabaseError, NULL);
6011        PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
6012
6013        /* Make the version available */
6014        s = PyStr_FromString(PyPgVersion);
6015        PyDict_SetItemString(dict, "version", s);
6016        PyDict_SetItemString(dict, "__version__", s);
6017        Py_DECREF(s);
6018
6019        /* results type for queries */
6020        PyDict_SetItemString(dict, "RESULT_EMPTY", PyInt_FromLong(RESULT_EMPTY));
6021        PyDict_SetItemString(dict, "RESULT_DML", PyInt_FromLong(RESULT_DML));
6022        PyDict_SetItemString(dict, "RESULT_DDL", PyInt_FromLong(RESULT_DDL));
6023        PyDict_SetItemString(dict, "RESULT_DQL", PyInt_FromLong(RESULT_DQL));
6024
6025        /* transaction states */
6026        PyDict_SetItemString(dict,"TRANS_IDLE",PyInt_FromLong(PQTRANS_IDLE));
6027        PyDict_SetItemString(dict,"TRANS_ACTIVE",PyInt_FromLong(PQTRANS_ACTIVE));
6028        PyDict_SetItemString(dict,"TRANS_INTRANS",PyInt_FromLong(PQTRANS_INTRANS));
6029        PyDict_SetItemString(dict,"TRANS_INERROR",PyInt_FromLong(PQTRANS_INERROR));
6030        PyDict_SetItemString(dict,"TRANS_UNKNOWN",PyInt_FromLong(PQTRANS_UNKNOWN));
6031
6032#ifdef LARGE_OBJECTS
6033        /* create mode for large objects */
6034        PyDict_SetItemString(dict, "INV_READ", PyInt_FromLong(INV_READ));
6035        PyDict_SetItemString(dict, "INV_WRITE", PyInt_FromLong(INV_WRITE));
6036
6037        /* position flags for lo_lseek */
6038        PyDict_SetItemString(dict, "SEEK_SET", PyInt_FromLong(SEEK_SET));
6039        PyDict_SetItemString(dict, "SEEK_CUR", PyInt_FromLong(SEEK_CUR));
6040        PyDict_SetItemString(dict, "SEEK_END", PyInt_FromLong(SEEK_END));
6041#endif /* LARGE_OBJECTS */
6042
6043#ifdef DEFAULT_VARS
6044        /* prepares default values */
6045        Py_INCREF(Py_None);
6046        pg_default_host = Py_None;
6047        Py_INCREF(Py_None);
6048        pg_default_base = Py_None;
6049        Py_INCREF(Py_None);
6050        pg_default_opt = Py_None;
6051        Py_INCREF(Py_None);
6052        pg_default_port = Py_None;
6053        Py_INCREF(Py_None);
6054        pg_default_user = Py_None;
6055        Py_INCREF(Py_None);
6056        pg_default_passwd = Py_None;
6057#endif /* DEFAULT_VARS */
6058
6059        /* store common pg encoding ids */
6060
6061        pg_encoding_utf8 = pg_char_to_encoding("UTF8");
6062        pg_encoding_latin1 = pg_char_to_encoding("LATIN1");
6063        pg_encoding_ascii = pg_char_to_encoding("SQL_ASCII");
6064
6065        /* Check for errors */
6066        if (PyErr_Occurred())
6067                return NULL;
6068
6069        return mod;
6070}
Note: See TracBrowser for help on using the repository browser.