source: trunk/pgmodule.c @ 824

Last change on this file since 824 was 824, checked in by cito, 4 years ago

Decode error message properly when using Python 3

The error message can contain non-ASCII characters and must be properly decoded,
using either the client encoding or the current locale if the error happened during
connection and the client encoding is not yet set.

  • Property svn:keywords set to Id
File size: 142.0 KB
Line 
1/*
2 * $Id: pgmodule.c 824 2016-02-06 12:17:34Z cito $
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 2016 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, int 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 (size < n) n = 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 (size < n) n = 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->valid)
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                return PyStr_FromString("(nothing selected)");
1465
1466        char * const aligns = (char *) PyMem_Malloc(n * sizeof(char));
1467        int * const sizes = (int *) PyMem_Malloc(n * sizeof(int));
1468
1469        if (!aligns || !sizes)
1470        {
1471                PyMem_Free(aligns); PyMem_Free(sizes); return PyErr_NoMemory();
1472        }
1473
1474        const int m = PQntuples(res);
1475        int i, j;
1476        size_t size;
1477        char *buffer;
1478
1479        /* calculate sizes and alignments */
1480        for (j = 0; j < n; ++j)
1481        {
1482                const char * const s = PQfname(res, j);
1483                const int format = PQfformat(res, j);
1484
1485                sizes[j] = s ? (int)strlen(s) : 0;
1486                if (format)
1487                {
1488                        aligns[j] = '\0';
1489                        if (m && sizes[j] < 8)
1490                                /* "<binary>" must fit */
1491                                sizes[j] = 8;
1492                }
1493                else
1494                {
1495                        const Oid ftype = PQftype(res, j);
1496
1497                        switch (ftype)
1498                        {
1499                                case INT2OID:
1500                                case INT4OID:
1501                                case INT8OID:
1502                                case FLOAT4OID:
1503                                case FLOAT8OID:
1504                                case NUMERICOID:
1505                                case OIDOID:
1506                                case XIDOID:
1507                                case CIDOID:
1508                                case CASHOID:
1509                                        aligns[j] = 'r';
1510                                        break;
1511                                default:
1512                                        aligns[j] = 'l';
1513                        }
1514                }
1515        }
1516        for (i = 0; i < m; ++i)
1517        {
1518                for (j = 0; j < n; ++j)
1519                {
1520                        if (aligns[j])
1521                        {
1522                                const int k = PQgetlength(res, i, j);
1523
1524                                if (sizes[j] < k)
1525                                        /* value must fit */
1526                                        sizes[j] = k;
1527                        }
1528                }
1529        }
1530        size = 0;
1531        /* size of one row */
1532        for (j = 0; j < n; ++j) size += sizes[j] + 1;
1533        /* times number of rows incl. heading */
1534        size *= (m + 2);
1535        /* plus size of footer */
1536        size += 40;
1537        /* is the buffer size that needs to be allocated */
1538        buffer = (char *) PyMem_Malloc(size);
1539        if (!buffer)
1540        {
1541                PyMem_Free(aligns); PyMem_Free(sizes); return PyErr_NoMemory();
1542        }
1543        char *p = buffer;
1544        PyObject *result;
1545
1546        /* create the header */
1547        for (j = 0; j < n; ++j)
1548        {
1549                const char * const s = PQfname(res, j);
1550                const int k = sizes[j];
1551                const int h = (k - (int)strlen(s)) / 2;
1552
1553                sprintf(p, "%*s", h, "");
1554                sprintf(p + h, "%-*s", k - h, s);
1555                p += k;
1556                if (j + 1 < n)
1557                        *p++ = '|';
1558        }
1559        *p++ = '\n';
1560        for (j = 0; j < n; ++j)
1561        {
1562                int k = sizes[j];
1563
1564                while (k--)
1565                        *p++ = '-';
1566                if (j + 1 < n)
1567                        *p++ = '+';
1568        }
1569        *p++ = '\n';
1570        /* create the body */
1571        for (i = 0; i < m; ++i)
1572        {
1573                for (j = 0; j < n; ++j)
1574                {
1575                        const char align = aligns[j];
1576                        const int k = sizes[j];
1577
1578                        if (align)
1579                        {
1580                                sprintf(p, align == 'r' ?
1581                                        "%*s" : "%-*s", k,
1582                                        PQgetvalue(res, i, j));
1583                        }
1584                        else
1585                        {
1586                                sprintf(p, "%-*s", k,
1587                                        PQgetisnull(res, i, j) ?
1588                                        "" : "<binary>");
1589                        }
1590                        p += k;
1591                        if (j + 1 < n)
1592                                *p++ = '|';
1593                }
1594                *p++ = '\n';
1595        }
1596        /* free memory */
1597        PyMem_Free(aligns); PyMem_Free(sizes);
1598        /* create the footer */
1599        sprintf(p, "(%d row%s)", m, m == 1 ? "" : "s");
1600        /* return the result */
1601        result = PyStr_FromString(buffer);
1602        PyMem_Free(buffer);
1603        return result;
1604}
1605
1606/* --------------------------------------------------------------------- */
1607/* large objects                                                                                                                 */
1608/* --------------------------------------------------------------------- */
1609#ifdef LARGE_OBJECTS
1610
1611/* checks large object validity */
1612static int
1613check_lo_obj(largeObject *self, int level)
1614{
1615        if (!check_cnx_obj(self->pgcnx))
1616                return 0;
1617
1618        if (!self->lo_oid)
1619        {
1620                set_error_msg(IntegrityError, "Object is not valid (null oid)");
1621                return 0;
1622        }
1623
1624        if (level & CHECK_OPEN)
1625        {
1626                if (self->lo_fd < 0)
1627                {
1628                        PyErr_SetString(PyExc_IOError, "Object is not opened");
1629                        return 0;
1630                }
1631        }
1632
1633        if (level & CHECK_CLOSE)
1634        {
1635                if (self->lo_fd >= 0)
1636                {
1637                        PyErr_SetString(PyExc_IOError, "Object is already opened");
1638                        return 0;
1639                }
1640        }
1641
1642        return 1;
1643}
1644
1645/* constructor (internal use only) */
1646static largeObject *
1647largeNew(connObject *pgcnx, Oid oid)
1648{
1649        largeObject *npglo;
1650
1651        if (!(npglo = PyObject_NEW(largeObject, &largeType)))
1652                return NULL;
1653
1654        Py_XINCREF(pgcnx);
1655        npglo->pgcnx = pgcnx;
1656        npglo->lo_fd = -1;
1657        npglo->lo_oid = oid;
1658
1659        return npglo;
1660}
1661
1662/* destructor */
1663static void
1664largeDealloc(largeObject *self)
1665{
1666        if (self->lo_fd >= 0 && self->pgcnx->valid)
1667                lo_close(self->pgcnx->cnx, self->lo_fd);
1668
1669        Py_XDECREF(self->pgcnx);
1670        PyObject_Del(self);
1671}
1672
1673/* opens large object */
1674static char largeOpen__doc__[] =
1675"open(mode) -- open access to large object with specified mode\n\n"
1676"The mode must be one of INV_READ, INV_WRITE (module level constants).\n";
1677
1678static PyObject *
1679largeOpen(largeObject *self, PyObject *args)
1680{
1681        int                     mode,
1682                                fd;
1683
1684        /* gets arguments */
1685        if (!PyArg_ParseTuple(args, "i", &mode))
1686        {
1687                PyErr_SetString(PyExc_TypeError,
1688                        "The open() method takes an integer argument");
1689                return NULL;
1690        }
1691
1692        /* check validity */
1693        if (!check_lo_obj(self, CHECK_CLOSE))
1694                return NULL;
1695
1696        /* opens large object */
1697        if ((fd = lo_open(self->pgcnx->cnx, self->lo_oid, mode)) < 0)
1698        {
1699                PyErr_SetString(PyExc_IOError, "Can't open large object");
1700                return NULL;
1701        }
1702        self->lo_fd = fd;
1703
1704        /* no error : returns Py_None */
1705        Py_INCREF(Py_None);
1706        return Py_None;
1707}
1708
1709/* close large object */
1710static char largeClose__doc__[] =
1711"close() -- close access to large object data";
1712
1713static PyObject *
1714largeClose(largeObject *self, PyObject *noargs)
1715{
1716        /* checks validity */
1717        if (!check_lo_obj(self, CHECK_OPEN))
1718                return NULL;
1719
1720        /* closes large object */
1721        if (lo_close(self->pgcnx->cnx, self->lo_fd))
1722        {
1723                PyErr_SetString(PyExc_IOError, "Error while closing large object fd");
1724                return NULL;
1725        }
1726        self->lo_fd = -1;
1727
1728        /* no error : returns Py_None */
1729        Py_INCREF(Py_None);
1730        return Py_None;
1731}
1732
1733/* reads from large object */
1734static char largeRead__doc__[] =
1735"read(size) -- read from large object to sized string\n\n"
1736"Object must be opened in read mode before calling this method.\n";
1737
1738static PyObject *
1739largeRead(largeObject *self, PyObject *args)
1740{
1741        int                     size;
1742        PyObject   *buffer;
1743
1744        /* gets arguments */
1745        if (!PyArg_ParseTuple(args, "i", &size))
1746        {
1747                PyErr_SetString(PyExc_TypeError,
1748                        "Method read() takes an integer argument");
1749                return NULL;
1750        }
1751
1752        if (size <= 0)
1753        {
1754                PyErr_SetString(PyExc_ValueError,
1755                        "Method read() takes a positive integer as argument");
1756                return NULL;
1757        }
1758
1759        /* checks validity */
1760        if (!check_lo_obj(self, CHECK_OPEN))
1761                return NULL;
1762
1763        /* allocate buffer and runs read */
1764        buffer = PyBytes_FromStringAndSize((char *) NULL, size);
1765
1766        if ((size = lo_read(self->pgcnx->cnx, self->lo_fd,
1767                PyBytes_AS_STRING((PyBytesObject *)(buffer)), size)) < 0)
1768        {
1769                PyErr_SetString(PyExc_IOError, "Error while reading");
1770                Py_XDECREF(buffer);
1771                return NULL;
1772        }
1773
1774        /* resize buffer and returns it */
1775        _PyBytes_Resize(&buffer, size);
1776        return buffer;
1777}
1778
1779/* write to large object */
1780static char largeWrite__doc__[] =
1781"write(string) -- write sized string to large object\n\n"
1782"Object must be opened in read mode before calling this method.\n";
1783
1784static PyObject *
1785largeWrite(largeObject *self, PyObject *args)
1786{
1787        char       *buffer;
1788        int                     size,
1789                                bufsize;
1790
1791        /* gets arguments */
1792        if (!PyArg_ParseTuple(args, "s#", &buffer, &bufsize))
1793        {
1794                PyErr_SetString(PyExc_TypeError,
1795                        "Method write() expects a sized string as argument");
1796                return NULL;
1797        }
1798
1799        /* checks validity */
1800        if (!check_lo_obj(self, CHECK_OPEN))
1801                return NULL;
1802
1803        /* sends query */
1804        if ((size = lo_write(self->pgcnx->cnx, self->lo_fd, buffer,
1805                                                 bufsize)) < bufsize)
1806        {
1807                PyErr_SetString(PyExc_IOError, "Buffer truncated during write");
1808                return NULL;
1809        }
1810
1811        /* no error : returns Py_None */
1812        Py_INCREF(Py_None);
1813        return Py_None;
1814}
1815
1816/* go to position in large object */
1817static char largeSeek__doc__[] =
1818"seek(offset, whence) -- move to specified position\n\n"
1819"Object must be opened before calling this method. The whence option\n"
1820"can be SEEK_SET, SEEK_CUR or SEEK_END (module level constants).\n";
1821
1822static PyObject *
1823largeSeek(largeObject *self, PyObject *args)
1824{
1825        /* offset and whence are initialized to keep compiler happy */
1826        int                     ret,
1827                                offset = 0,
1828                                whence = 0;
1829
1830        /* gets arguments */
1831        if (!PyArg_ParseTuple(args, "ii", &offset, &whence))
1832        {
1833                PyErr_SetString(PyExc_TypeError,
1834                        "Method lseek() expects two integer arguments");
1835                return NULL;
1836        }
1837
1838        /* checks validity */
1839        if (!check_lo_obj(self, CHECK_OPEN))
1840                return NULL;
1841
1842        /* sends query */
1843        if ((ret = lo_lseek(self->pgcnx->cnx, self->lo_fd, offset, whence)) == -1)
1844        {
1845                PyErr_SetString(PyExc_IOError, "Error while moving cursor");
1846                return NULL;
1847        }
1848
1849        /* returns position */
1850        return PyInt_FromLong(ret);
1851}
1852
1853/* gets large object size */
1854static char largeSize__doc__[] =
1855"size() -- return large object size\n\n"
1856"The object must be opened before calling this method.\n";
1857
1858static PyObject *
1859largeSize(largeObject *self, PyObject *noargs)
1860{
1861        int                     start,
1862                                end;
1863
1864        /* checks validity */
1865        if (!check_lo_obj(self, CHECK_OPEN))
1866                return NULL;
1867
1868        /* gets current position */
1869        if ((start = lo_tell(self->pgcnx->cnx, self->lo_fd)) == -1)
1870        {
1871                PyErr_SetString(PyExc_IOError, "Error while getting current position");
1872                return NULL;
1873        }
1874
1875        /* gets end position */
1876        if ((end = lo_lseek(self->pgcnx->cnx, self->lo_fd, 0, SEEK_END)) == -1)
1877        {
1878                PyErr_SetString(PyExc_IOError, "Error while getting end position");
1879                return NULL;
1880        }
1881
1882        /* move back to start position */
1883        if ((start = lo_lseek(
1884                self->pgcnx->cnx, self->lo_fd, start, SEEK_SET)) == -1)
1885        {
1886                PyErr_SetString(PyExc_IOError,
1887                        "Error while moving back to first position");
1888                return NULL;
1889        }
1890
1891        /* returns size */
1892        return PyInt_FromLong(end);
1893}
1894
1895/* gets large object cursor position */
1896static char largeTell__doc__[] =
1897"tell() -- give current position in large object\n\n"
1898"The object must be opened before calling this method.\n";
1899
1900static PyObject *
1901largeTell(largeObject *self, PyObject *noargs)
1902{
1903        int                     start;
1904
1905        /* checks validity */
1906        if (!check_lo_obj(self, CHECK_OPEN))
1907                return NULL;
1908
1909        /* gets current position */
1910        if ((start = lo_tell(self->pgcnx->cnx, self->lo_fd)) == -1)
1911        {
1912                PyErr_SetString(PyExc_IOError, "Error while getting position");
1913                return NULL;
1914        }
1915
1916        /* returns size */
1917        return PyInt_FromLong(start);
1918}
1919
1920/* exports large object as unix file */
1921static char largeExport__doc__[] =
1922"export(filename) -- export large object data to specified file\n\n"
1923"The object must be closed when calling this method.\n";
1924
1925static PyObject *
1926largeExport(largeObject *self, PyObject *args)
1927{
1928        char *name;
1929
1930        /* checks validity */
1931        if (!check_lo_obj(self, CHECK_CLOSE))
1932                return NULL;
1933
1934        /* gets arguments */
1935        if (!PyArg_ParseTuple(args, "s", &name))
1936        {
1937                PyErr_SetString(PyExc_TypeError,
1938                        "The method export() takes a filename as argument");
1939                return NULL;
1940        }
1941
1942        /* runs command */
1943        if (!lo_export(self->pgcnx->cnx, self->lo_oid, name))
1944        {
1945                PyErr_SetString(PyExc_IOError, "Error while exporting large object");
1946                return NULL;
1947        }
1948
1949        Py_INCREF(Py_None);
1950        return Py_None;
1951}
1952
1953/* deletes a large object */
1954static char largeUnlink__doc__[] =
1955"unlink() -- destroy large object\n\n"
1956"The object must be closed when calling this method.\n";
1957
1958static PyObject *
1959largeUnlink(largeObject *self, PyObject *noargs)
1960{
1961        /* checks validity */
1962        if (!check_lo_obj(self, CHECK_CLOSE))
1963                return NULL;
1964
1965        /* deletes the object, invalidate it on success */
1966        if (!lo_unlink(self->pgcnx->cnx, self->lo_oid))
1967        {
1968                PyErr_SetString(PyExc_IOError, "Error while unlinking large object");
1969                return NULL;
1970        }
1971        self->lo_oid = 0;
1972
1973        Py_INCREF(Py_None);
1974        return Py_None;
1975}
1976
1977/* get the list of large object attributes */
1978static PyObject *
1979largeDir(largeObject *self, PyObject *noargs)
1980{
1981        PyObject *attrs;
1982
1983        attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
1984        PyObject_CallMethod(attrs, "extend", "[sss]",
1985                "oid", "pgcnx", "error");
1986
1987        return attrs;
1988}
1989
1990/* large object methods */
1991static struct PyMethodDef largeMethods[] = {
1992        {"__dir__", (PyCFunction) largeDir,  METH_NOARGS, NULL},
1993        {"open", (PyCFunction) largeOpen, METH_VARARGS, largeOpen__doc__},
1994        {"close", (PyCFunction) largeClose, METH_NOARGS, largeClose__doc__},
1995        {"read", (PyCFunction) largeRead, METH_VARARGS, largeRead__doc__},
1996        {"write", (PyCFunction) largeWrite, METH_VARARGS, largeWrite__doc__},
1997        {"seek", (PyCFunction) largeSeek, METH_VARARGS, largeSeek__doc__},
1998        {"size", (PyCFunction) largeSize, METH_NOARGS, largeSize__doc__},
1999        {"tell", (PyCFunction) largeTell, METH_NOARGS, largeTell__doc__},
2000        {"export",(PyCFunction) largeExport, METH_VARARGS, largeExport__doc__},
2001        {"unlink",(PyCFunction) largeUnlink, METH_NOARGS, largeUnlink__doc__},
2002        {NULL, NULL}
2003};
2004
2005/* gets large object attributes */
2006static PyObject *
2007largeGetAttr(largeObject *self, PyObject *nameobj)
2008{
2009        const char *name = PyStr_AsString(nameobj);
2010
2011        /* list postgreSQL large object fields */
2012
2013        /* associated pg connection object */
2014        if (!strcmp(name, "pgcnx"))
2015        {
2016                if (check_lo_obj(self, 0))
2017                {
2018                        Py_INCREF(self->pgcnx);
2019                        return (PyObject *) (self->pgcnx);
2020                }
2021                PyErr_Clear();
2022                Py_INCREF(Py_None);
2023                return Py_None;
2024        }
2025
2026        /* large object oid */
2027        if (!strcmp(name, "oid"))
2028        {
2029                if (check_lo_obj(self, 0))
2030                        return PyInt_FromLong(self->lo_oid);
2031                PyErr_Clear();
2032                Py_INCREF(Py_None);
2033                return Py_None;
2034        }
2035
2036        /* error (status) message */
2037        if (!strcmp(name, "error"))
2038                return PyStr_FromString(PQerrorMessage(self->pgcnx->cnx));
2039
2040        /* seeks name in methods (fallback) */
2041        return PyObject_GenericGetAttr((PyObject *) self, nameobj);
2042}
2043
2044/* return large object as string in human readable form */
2045static PyObject *
2046largeStr(largeObject *self)
2047{
2048        char            str[80];
2049        sprintf(str, self->lo_fd >= 0 ?
2050                        "Opened large object, oid %ld" :
2051                        "Closed large object, oid %ld", (long) self->lo_oid);
2052        return PyStr_FromString(str);
2053}
2054
2055static char large__doc__[] = "PostgreSQL large object";
2056
2057/* large object type definition */
2058static PyTypeObject largeType = {
2059        PyVarObject_HEAD_INIT(NULL, 0)
2060        "pg.LargeObject",                               /* tp_name */
2061        sizeof(largeObject),                    /* tp_basicsize */
2062        0,                                                              /* tp_itemsize */
2063
2064        /* methods */
2065        (destructor) largeDealloc,              /* tp_dealloc */
2066        0,                                                              /* tp_print */
2067        0,                                                              /* tp_getattr */
2068        0,                                                              /* tp_setattr */
2069        0,                                                              /* tp_compare */
2070        0,                                                              /* tp_repr */
2071        0,                                                              /* tp_as_number */
2072        0,                                                              /* tp_as_sequence */
2073        0,                                                              /* tp_as_mapping */
2074        0,                                                              /* tp_hash */
2075        0,                                                              /* tp_call */
2076        (reprfunc) largeStr,                    /* tp_str */
2077        (getattrofunc) largeGetAttr,    /* tp_getattro */
2078        0,                                                              /* tp_setattro */
2079        0,                                                              /* tp_as_buffer */
2080        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
2081        large__doc__,                                   /* tp_doc */
2082        0,                                                              /* tp_traverse */
2083        0,                                                              /* tp_clear */
2084        0,                                                              /* tp_richcompare */
2085        0,                                                              /* tp_weaklistoffset */
2086        0,                                                              /* tp_iter */
2087        0,                                                              /* tp_iternext */
2088        largeMethods,                                   /* tp_methods */
2089};
2090#endif /* LARGE_OBJECTS */
2091
2092/* --------------------------------------------------------------------- */
2093/* connection object                                                                                                     */
2094/* --------------------------------------------------------------------- */
2095static void
2096connDelete(connObject *self)
2097{
2098        if (self->cnx)
2099        {
2100                Py_BEGIN_ALLOW_THREADS
2101                PQfinish(self->cnx);
2102                Py_END_ALLOW_THREADS
2103        }
2104        Py_XDECREF(self->cast_hook);
2105        Py_XDECREF(self->notice_receiver);
2106        PyObject_Del(self);
2107}
2108
2109/* source creation */
2110static char connSource__doc__[] =
2111"source() -- create a new source object for this connection";
2112
2113static PyObject *
2114connSource(connObject *self, PyObject *noargs)
2115{
2116        sourceObject *npgobj;
2117
2118        /* checks validity */
2119        if (!check_cnx_obj(self))
2120                return NULL;
2121
2122        /* allocates new query object */
2123        if (!(npgobj = PyObject_NEW(sourceObject, &sourceType)))
2124                return NULL;
2125
2126        /* initializes internal parameters */
2127        Py_XINCREF(self);
2128        npgobj->pgcnx = self;
2129        npgobj->result = NULL;
2130        npgobj->valid = 1;
2131        npgobj->arraysize = PG_ARRAYSIZE;
2132
2133        return (PyObject *) npgobj;
2134}
2135
2136/* database query */
2137static char connQuery__doc__[] =
2138"query(sql, [arg]) -- create a new query object for this connection\n\n"
2139"You must pass the SQL (string) request and you can optionally pass\n"
2140"a tuple with positional parameters.\n";
2141
2142static PyObject *
2143connQuery(connObject *self, PyObject *args)
2144{
2145        PyObject        *query_obj;
2146        PyObject        *param_obj = NULL;
2147        char            *query;
2148        PGresult        *result;
2149        queryObject *npgobj;
2150        int                     encoding,
2151                                status,
2152                                nparms = 0;
2153
2154        if (!self->cnx)
2155        {
2156                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2157                return NULL;
2158        }
2159
2160        /* get query args */
2161        if (!PyArg_ParseTuple(args, "O|O", &query_obj, &param_obj))
2162        {
2163                return NULL;
2164        }
2165
2166        encoding = PQclientEncoding(self->cnx);
2167
2168        if (PyBytes_Check(query_obj))
2169        {
2170                query = PyBytes_AsString(query_obj);
2171                query_obj = NULL;
2172        }
2173        else if (PyUnicode_Check(query_obj))
2174        {
2175                query_obj = get_encoded_string(query_obj, encoding);
2176                if (!query_obj) return NULL; /* pass the UnicodeEncodeError */
2177                query = PyBytes_AsString(query_obj);
2178        }
2179        else
2180        {
2181                PyErr_SetString(PyExc_TypeError,
2182                        "Method query() expects a string as first argument");
2183                return NULL;
2184        }
2185
2186        /* If param_obj is passed, ensure it's a non-empty tuple. We want to treat
2187         * an empty tuple the same as no argument since we'll get that when the
2188         * caller passes no arguments to db.query(), and historic behaviour was
2189         * to call PQexec() in that case, which can execute multiple commands. */
2190        if (param_obj)
2191        {
2192                param_obj = PySequence_Fast(param_obj,
2193                        "Method query() expects a sequence as second argument");
2194                if (!param_obj)
2195                {
2196                        Py_XDECREF(query_obj);
2197                        return NULL;
2198                }
2199                nparms = (int)PySequence_Fast_GET_SIZE(param_obj);
2200
2201                /* if there's a single argument and it's a list or tuple, it
2202                 * contains the positional arguments. */
2203                if (nparms == 1)
2204                {
2205                        PyObject *first_obj = PySequence_Fast_GET_ITEM(param_obj, 0);
2206                        if (PyList_Check(first_obj) || PyTuple_Check(first_obj))
2207                        {
2208                                Py_DECREF(param_obj);
2209                                param_obj = PySequence_Fast(first_obj, NULL);
2210                                nparms = (int)PySequence_Fast_GET_SIZE(param_obj);
2211                        }
2212                }
2213        }
2214
2215        /* gets result */
2216        if (nparms)
2217        {
2218                /* prepare arguments */
2219                PyObject        **str, **s;
2220                char            **parms, **p;
2221                register int i;
2222
2223                str = (PyObject **)PyMem_Malloc(nparms * sizeof(*str));
2224                parms = (char **)PyMem_Malloc(nparms * sizeof(*parms));
2225                if (!str || !parms)
2226                {
2227                        PyMem_Free(parms); PyMem_Free(str);
2228                        Py_XDECREF(query_obj); Py_XDECREF(param_obj);
2229                        return PyErr_NoMemory();
2230                }
2231
2232                /* convert optional args to a list of strings -- this allows
2233                 * the caller to pass whatever they like, and prevents us
2234                 * from having to map types to OIDs */
2235                for (i = 0, s=str, p=parms; i < nparms; ++i, ++p)
2236                {
2237                        PyObject *obj = PySequence_Fast_GET_ITEM(param_obj, i);
2238
2239                        if (obj == Py_None)
2240                        {
2241                                *p = NULL;
2242                        }
2243                        else if (PyBytes_Check(obj))
2244                        {
2245                                *p = PyBytes_AsString(obj);
2246                        }
2247                        else if (PyUnicode_Check(obj))
2248                        {
2249                                PyObject *str_obj = get_encoded_string(obj, encoding);
2250                                if (!str_obj)
2251                                {
2252                                        PyMem_Free(parms);
2253                                        while (s != str) { s--; Py_DECREF(*s); }
2254                                        PyMem_Free(str);
2255                                        Py_XDECREF(query_obj);
2256                                        Py_XDECREF(param_obj);
2257                                        /* pass the UnicodeEncodeError */
2258                                        return NULL;
2259                                }
2260                                *s++ = str_obj;
2261                                *p = PyBytes_AsString(str_obj);
2262                        }
2263                        else
2264                        {
2265                                PyObject *str_obj = PyObject_Str(obj);
2266                                if (!str_obj)
2267                                {
2268                                        PyMem_Free(parms);
2269                                        while (s != str) { s--; Py_DECREF(*s); }
2270                                        PyMem_Free(str);
2271                                        Py_XDECREF(query_obj);
2272                                        Py_XDECREF(param_obj);
2273                                        PyErr_SetString(PyExc_TypeError,
2274                                                "Query parameter has no string representation");
2275                                        return NULL;
2276                                }
2277                                *s++ = str_obj;
2278                                *p = PyStr_AsString(str_obj);
2279                        }
2280                }
2281
2282                Py_BEGIN_ALLOW_THREADS
2283                result = PQexecParams(self->cnx, query, nparms,
2284                        NULL, (const char * const *)parms, NULL, NULL, 0);
2285                Py_END_ALLOW_THREADS
2286
2287                PyMem_Free(parms);
2288                while (s != str) { s--; Py_DECREF(*s); }
2289                PyMem_Free(str);
2290        }
2291        else
2292        {
2293                Py_BEGIN_ALLOW_THREADS
2294                result = PQexec(self->cnx, query);
2295                Py_END_ALLOW_THREADS
2296        }
2297
2298        /* we don't need the query and its params any more */
2299        Py_XDECREF(query_obj);
2300        Py_XDECREF(param_obj);
2301
2302        /* checks result validity */
2303        if (!result)
2304        {
2305                PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->cnx));
2306                return NULL;
2307        }
2308
2309        /* this may have changed the datestyle, so we reset the date format
2310           in order to force fetching it newly when next time requested */
2311        self->date_format = date_format; /* this is normally NULL */
2312
2313        /* checks result status */
2314        if ((status = PQresultStatus(result)) != PGRES_TUPLES_OK)
2315        {
2316                switch (status)
2317                {
2318                        case PGRES_EMPTY_QUERY:
2319                                PyErr_SetString(PyExc_ValueError, "Empty query");
2320                                break;
2321                        case PGRES_BAD_RESPONSE:
2322                        case PGRES_FATAL_ERROR:
2323                        case PGRES_NONFATAL_ERROR:
2324                                set_error(ProgrammingError, "Cannot execute query",
2325                                        self->cnx, result);
2326                                break;
2327                        case PGRES_COMMAND_OK:
2328                                {                                               /* INSERT, UPDATE, DELETE */
2329                                        Oid             oid = PQoidValue(result);
2330                                        if (oid == InvalidOid)  /* not a single insert */
2331                                        {
2332                                                char    *ret = PQcmdTuples(result);
2333
2334                                                PQclear(result);
2335                                                if (ret[0])             /* return number of rows affected */
2336                                                {
2337                                                        return PyStr_FromString(ret);
2338                                                }
2339                                                Py_INCREF(Py_None);
2340                                                return Py_None;
2341                                        }
2342                                        /* for a single insert, return the oid */
2343                                        PQclear(result);
2344                                        return PyInt_FromLong(oid);
2345                                }
2346                        case PGRES_COPY_OUT:            /* no data will be received */
2347                        case PGRES_COPY_IN:
2348                                PQclear(result);
2349                                Py_INCREF(Py_None);
2350                                return Py_None;
2351                        default:
2352                                set_error_msg(InternalError, "Unknown result status");
2353                }
2354
2355                PQclear(result);
2356                return NULL;                    /* error detected on query */
2357        }
2358
2359        if (!(npgobj = PyObject_NEW(queryObject, &queryType)))
2360                return PyErr_NoMemory();
2361
2362        /* stores result and returns object */
2363        Py_XINCREF(self);
2364        npgobj->pgcnx = self;
2365        npgobj->result = result;
2366        npgobj->encoding = encoding;
2367        return (PyObject *) npgobj;
2368}
2369
2370#ifdef DIRECT_ACCESS
2371static char connPutLine__doc__[] =
2372"putline(line) -- send a line directly to the backend";
2373
2374/* direct access function: putline */
2375static PyObject *
2376connPutLine(connObject *self, PyObject *args)
2377{
2378        char *line;
2379        int line_length;
2380
2381        if (!self->cnx)
2382        {
2383                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2384                return NULL;
2385        }
2386
2387        /* reads args */
2388        if (!PyArg_ParseTuple(args, "s#", &line, &line_length))
2389        {
2390                PyErr_SetString(PyExc_TypeError,
2391                        "Method putline() takes a string argument");
2392                return NULL;
2393        }
2394
2395        /* sends line to backend */
2396        if (PQputline(self->cnx, line))
2397        {
2398                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2399                return NULL;
2400        }
2401        Py_INCREF(Py_None);
2402        return Py_None;
2403}
2404
2405/* direct access function: getline */
2406static char connGetLine__doc__[] =
2407"getline() -- get a line directly from the backend";
2408
2409static PyObject *
2410connGetLine(connObject *self, PyObject *noargs)
2411{
2412        char            line[MAX_BUFFER_SIZE];
2413        PyObject   *str = NULL;         /* GCC */
2414
2415        if (!self->cnx)
2416        {
2417                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2418                return NULL;
2419        }
2420
2421        /* gets line */
2422        switch (PQgetline(self->cnx, line, MAX_BUFFER_SIZE))
2423        {
2424                case 0:
2425                        str = PyStr_FromString(line);
2426                        break;
2427                case 1:
2428                        PyErr_SetString(PyExc_MemoryError, "Buffer overflow");
2429                        str = NULL;
2430                        break;
2431                case EOF:
2432                        Py_INCREF(Py_None);
2433                        str = Py_None;
2434                        break;
2435        }
2436
2437        return str;
2438}
2439
2440/* direct access function: end copy */
2441static char connEndCopy__doc__[] =
2442"endcopy() -- synchronize client and server";
2443
2444static PyObject *
2445connEndCopy(connObject *self, PyObject *noargs)
2446{
2447        if (!self->cnx)
2448        {
2449                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2450                return NULL;
2451        }
2452
2453        /* ends direct copy */
2454        if (PQendcopy(self->cnx))
2455        {
2456                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2457                return NULL;
2458        }
2459        Py_INCREF(Py_None);
2460        return Py_None;
2461}
2462#endif /* DIRECT_ACCESS */
2463
2464/* return query as string in human readable form */
2465static PyObject *
2466queryStr(queryObject *self)
2467{
2468        return format_result(self->result);
2469}
2470
2471/* insert table */
2472static char connInsertTable__doc__[] =
2473"inserttable(table, data) -- insert list into table\n\n"
2474"The fields in the list must be in the same order as in the table.\n";
2475
2476static PyObject *
2477connInsertTable(connObject *self, PyObject *args)
2478{
2479        PGresult        *result;
2480        char            *table,
2481                                *buffer,
2482                                *bufpt;
2483        int                     encoding;
2484        size_t          bufsiz;
2485        PyObject        *list,
2486                                *sublist,
2487                                *item;
2488        PyObject        *(*getitem) (PyObject *, Py_ssize_t);
2489        PyObject        *(*getsubitem) (PyObject *, Py_ssize_t);
2490        Py_ssize_t      i,
2491                                j,
2492                                m,
2493                                n;
2494
2495        if (!self->cnx)
2496        {
2497                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2498                return NULL;
2499        }
2500
2501        /* gets arguments */
2502        if (!PyArg_ParseTuple(args, "sO:filter", &table, &list))
2503        {
2504                PyErr_SetString(PyExc_TypeError,
2505                        "Method inserttable() expects a string and a list as arguments");
2506                return NULL;
2507        }
2508
2509        /* checks list type */
2510        if (PyTuple_Check(list))
2511        {
2512                m = PyTuple_Size(list);
2513                getitem = PyTuple_GetItem;
2514        }
2515        else if (PyList_Check(list))
2516        {
2517                m = PyList_Size(list);
2518                getitem = PyList_GetItem;
2519        }
2520        else
2521        {
2522                PyErr_SetString(PyExc_TypeError,
2523                        "Method inserttable() expects some kind of array"
2524                        " as second argument");
2525                return NULL;
2526        }
2527
2528        /* allocate buffer */
2529        if (!(buffer = PyMem_Malloc(MAX_BUFFER_SIZE)))
2530                return PyErr_NoMemory();
2531
2532        /* starts query */
2533        sprintf(buffer, "copy %s from stdin", table);
2534
2535        Py_BEGIN_ALLOW_THREADS
2536        result = PQexec(self->cnx, buffer);
2537        Py_END_ALLOW_THREADS
2538
2539        if (!result)
2540        {
2541                PyMem_Free(buffer);
2542                PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->cnx));
2543                return NULL;
2544        }
2545
2546        encoding = PQclientEncoding(self->cnx);
2547
2548        PQclear(result);
2549
2550        n = 0; /* not strictly necessary but avoids warning */
2551
2552        /* feed table */
2553        for (i = 0; i < m; ++i)
2554        {
2555                sublist = getitem(list, i);
2556                if (PyTuple_Check(sublist))
2557                {
2558                        j = PyTuple_Size(sublist);
2559                        getsubitem = PyTuple_GetItem;
2560                }
2561                else if (PyList_Check(sublist))
2562                {
2563                        j = PyList_Size(sublist);
2564                        getsubitem = PyList_GetItem;
2565                }
2566                else
2567                {
2568                        PyErr_SetString(PyExc_TypeError,
2569                                "Second arg must contain some kind of arrays");
2570                        return NULL;
2571                }
2572                if (i)
2573                {
2574                        if (j != n)
2575                        {
2576                                PyMem_Free(buffer);
2577                                PyErr_SetString(PyExc_TypeError,
2578                                        "Arrays contained in second arg must have same size");
2579                                return NULL;
2580                        }
2581                }
2582                else
2583                {
2584                        n = j; /* never used before this assignment */
2585                }
2586
2587                /* builds insert line */
2588                bufpt = buffer;
2589                bufsiz = MAX_BUFFER_SIZE - 1;
2590
2591                for (j = 0; j < n; ++j)
2592                {
2593                        if (j)
2594                        {
2595                                *bufpt++ = '\t'; --bufsiz;
2596                        }
2597
2598                        item = getsubitem(sublist, j);
2599
2600                        /* convert item to string and append to buffer */
2601                        if (item == Py_None)
2602                        {
2603                                if (bufsiz > 2)
2604                                {
2605                                        *bufpt++ = '\\'; *bufpt++ = 'N';
2606                                        bufsiz -= 2;
2607                                }
2608                                else
2609                                        bufsiz = 0;
2610                        }
2611                        else if (PyBytes_Check(item))
2612                        {
2613                                const char* t = PyBytes_AsString(item);
2614                                while (*t && bufsiz)
2615                                {
2616                                        if (*t == '\\' || *t == '\t' || *t == '\n')
2617                                        {
2618                                                *bufpt++ = '\\'; --bufsiz;
2619                                                if (!bufsiz) break;
2620                                        }
2621                                        *bufpt++ = *t++; --bufsiz;
2622                                }
2623                        }
2624                        else if (PyUnicode_Check(item))
2625                        {
2626                                PyObject *s = get_encoded_string(item, encoding);
2627                                if (!s)
2628                                {
2629                                        PyMem_Free(buffer);
2630                                        return NULL; /* pass the UnicodeEncodeError */
2631                                }
2632                                const char* t = PyBytes_AsString(s);
2633                                while (*t && bufsiz)
2634                                {
2635                                        if (*t == '\\' || *t == '\t' || *t == '\n')
2636                                        {
2637                                                *bufpt++ = '\\'; --bufsiz;
2638                                                if (!bufsiz) break;
2639                                        }
2640                                        *bufpt++ = *t++; --bufsiz;
2641                                }
2642                                Py_DECREF(s);
2643                        }
2644                        else if (PyInt_Check(item) || PyLong_Check(item))
2645                        {
2646                                PyObject* s = PyObject_Str(item);
2647                                const char* t = PyStr_AsString(s);
2648                                while (*t && bufsiz)
2649                                {
2650                                        *bufpt++ = *t++; --bufsiz;
2651                                }
2652                                Py_DECREF(s);
2653                        }
2654                        else
2655                        {
2656                                PyObject* s = PyObject_Repr(item);
2657                                const char* t = PyStr_AsString(s);
2658                                while (*t && bufsiz)
2659                                {
2660                                        if (*t == '\\' || *t == '\t' || *t == '\n')
2661                                        {
2662                                                *bufpt++ = '\\'; --bufsiz;
2663                                                if (!bufsiz) break;
2664                                        }
2665                                        *bufpt++ = *t++; --bufsiz;
2666                                }
2667                                Py_DECREF(s);
2668                        }
2669
2670                        if (bufsiz <= 0)
2671                        {
2672                                PyMem_Free(buffer); return PyErr_NoMemory();
2673                        }
2674
2675                }
2676
2677                *bufpt++ = '\n'; *bufpt = '\0';
2678
2679                /* sends data */
2680                if (PQputline(self->cnx, buffer))
2681                {
2682                        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2683                        PQendcopy(self->cnx);
2684                        PyMem_Free(buffer);
2685                        return NULL;
2686                }
2687        }
2688
2689        /* ends query */
2690        if (PQputline(self->cnx, "\\.\n"))
2691        {
2692                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2693                PQendcopy(self->cnx);
2694                PyMem_Free(buffer);
2695                return NULL;
2696        }
2697
2698        if (PQendcopy(self->cnx))
2699        {
2700                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2701                PyMem_Free(buffer);
2702                return NULL;
2703        }
2704
2705        PyMem_Free(buffer);
2706
2707        /* no error : returns nothing */
2708        Py_INCREF(Py_None);
2709        return Py_None;
2710}
2711
2712/* get transaction state */
2713static char connTransaction__doc__[] =
2714"transaction() -- return the current transaction status";
2715
2716static PyObject *
2717connTransaction(connObject *self, PyObject *noargs)
2718{
2719        if (!self->cnx)
2720        {
2721                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2722                return NULL;
2723        }
2724
2725        return PyInt_FromLong(PQtransactionStatus(self->cnx));
2726}
2727
2728/* get parameter setting */
2729static char connParameter__doc__[] =
2730"parameter(name) -- look up a current parameter setting";
2731
2732static PyObject *
2733connParameter(connObject *self, PyObject *args)
2734{
2735        const char *name;
2736
2737        if (!self->cnx)
2738        {
2739                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2740                return NULL;
2741        }
2742
2743        /* get query args */
2744        if (!PyArg_ParseTuple(args, "s", &name))
2745        {
2746                PyErr_SetString(PyExc_TypeError,
2747                        "Method parameter() takes a string as argument");
2748                return NULL;
2749        }
2750
2751        name = PQparameterStatus(self->cnx, name);
2752
2753        if (name)
2754                return PyStr_FromString(name);
2755
2756        /* unknown parameter, return None */
2757        Py_INCREF(Py_None);
2758        return Py_None;
2759}
2760
2761/* internal function converting a Postgres datestyles to date formats */
2762static const char *
2763date_style_to_format(const char *s)
2764{
2765        static const char *formats[] = {
2766                "%Y-%m-%d",             /* 0 = ISO */
2767                "%m-%d-%Y",             /* 1 = Postgres, MDY */
2768                "%d-%m-%Y",             /* 2 = Postgres, DMY */
2769                "%m/%d/%Y",             /* 3 = SQL, MDY */
2770                "%d/%m/%Y",             /* 4 = SQL, DMY */
2771                "%d.%m.%Y"};    /* 5 = German */
2772
2773        switch (s ? *s : 'I')
2774        {
2775                case 'P': /* Postgres */
2776                        s = strchr(s + 1, ',');
2777                        if (s) do ++s; while (*s && *s == ' ');
2778                        return formats[s && *s == 'D' ? 2 : 1];
2779                case 'S': /* SQL */
2780                        s = strchr(s + 1, ',');
2781                        if (s) do ++s; while (*s && *s == ' ');
2782                        return formats[s && *s == 'D' ? 4 : 3];
2783                case 'G': /* German */
2784                        return formats[5];
2785                default: /* ISO */
2786                        return formats[0]; /* ISO is the default */
2787        }
2788}
2789
2790/* internal function converting a date format to a Postgres datestyle */
2791static const char *
2792date_format_to_style(const char *s)
2793{
2794        static const char *datestyle[] = {
2795                "ISO, YMD",                     /* 0 = %Y-%m-%d */
2796                "Postgres, MDY",        /* 1 = %m-%d-%Y */
2797                "Postgres, DMY",        /* 2 = %d-%m-%Y */
2798                "SQL, MDY",             /* 3 = %m/%d/%Y */
2799                "SQL, DMY",             /* 4 = %d/%m/%Y */
2800                "German, DMY"};         /* 5 = %d.%m.%Y */
2801
2802        switch (s ? s[1] : 'Y')
2803        {
2804                case 'm':
2805                        switch (s[2])
2806                        {
2807                                case '/':
2808                                        return datestyle[3]; /* SQL, MDY */
2809                                default:
2810                                        return datestyle[1]; /* Postgres, MDY */
2811                        }
2812                case 'd':
2813                        switch (s[2])
2814                        {
2815                                case '/':
2816                                        return datestyle[4]; /* SQL, DMY */
2817                                case '.':
2818                                        return datestyle[5]; /* German */
2819                                default:
2820                                        return datestyle[2]; /* Postgres, DMY */
2821                        }
2822                default:
2823                        return datestyle[0]; /* ISO */
2824        }
2825}
2826
2827/* get current date format */
2828static char connDateFormat__doc__[] =
2829"date_format() -- return the current date format";
2830
2831static PyObject *
2832connDateFormat(connObject *self, PyObject *noargs)
2833{
2834        const char *fmt;
2835
2836        if (!self->cnx)
2837        {
2838                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2839                return NULL;
2840        }
2841
2842        /* check if the date format is cached in the connection */
2843        fmt = self->date_format;
2844        if (!fmt)
2845        {
2846                fmt = date_style_to_format(PQparameterStatus(self->cnx, "DateStyle"));
2847                self->date_format = fmt; /* cache the result */
2848        }
2849
2850        return PyStr_FromString(fmt);
2851}
2852
2853#ifdef ESCAPING_FUNCS
2854
2855/* escape literal */
2856static char connEscapeLiteral__doc__[] =
2857"escape_literal(str) -- escape a literal constant for use within SQL";
2858
2859static PyObject *
2860connEscapeLiteral(connObject *self, PyObject *string)
2861{
2862        PyObject   *tmp_obj = NULL, /* auxiliary string object */
2863                           *to_obj; /* string object to return */
2864        char       *from, /* our string argument as encoded string */
2865                           *to; /* the result as encoded string */
2866        Py_ssize_t      from_length; /* length of string */
2867        size_t          to_length; /* length of result */
2868        int                     encoding = -1; /* client encoding */
2869
2870        if (PyBytes_Check(string))
2871        {
2872                PyBytes_AsStringAndSize(string, &from, &from_length);
2873        }
2874        else if (PyUnicode_Check(string))
2875        {
2876                encoding = PQclientEncoding(self->cnx);
2877                tmp_obj = get_encoded_string(string, encoding);
2878                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
2879                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
2880        }
2881        else
2882        {
2883                PyErr_SetString(PyExc_TypeError,
2884                        "Method escape_literal() expects a string as argument");
2885                return NULL;
2886        }
2887
2888        to = PQescapeLiteral(self->cnx, from, (size_t)from_length);
2889        to_length = strlen(to);
2890
2891        Py_XDECREF(tmp_obj);
2892
2893        if (encoding == -1)
2894                to_obj = PyBytes_FromStringAndSize(to, to_length);
2895        else
2896                to_obj = get_decoded_string(to, to_length, encoding);
2897        if (to)
2898                PQfreemem(to);
2899        return to_obj;
2900}
2901
2902/* escape identifier */
2903static char connEscapeIdentifier__doc__[] =
2904"escape_identifier(str) -- escape an identifier for use within SQL";
2905
2906static PyObject *
2907connEscapeIdentifier(connObject *self, PyObject *string)
2908{
2909        PyObject   *tmp_obj = NULL, /* auxiliary string object */
2910                           *to_obj; /* string object to return */
2911        char       *from, /* our string argument as encoded string */
2912                           *to; /* the result as encoded string */
2913        Py_ssize_t      from_length; /* length of string */
2914        size_t          to_length; /* length of result */
2915        int                     encoding = -1; /* client encoding */
2916
2917        if (PyBytes_Check(string))
2918        {
2919                PyBytes_AsStringAndSize(string, &from, &from_length);
2920        }
2921        else if (PyUnicode_Check(string))
2922        {
2923                encoding = PQclientEncoding(self->cnx);
2924                tmp_obj = get_encoded_string(string, encoding);
2925                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
2926                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
2927        }
2928        else
2929        {
2930                PyErr_SetString(PyExc_TypeError,
2931                        "Method escape_identifier() expects a string as argument");
2932                return NULL;
2933        }
2934
2935        to = PQescapeIdentifier(self->cnx, from, (size_t)from_length);
2936        to_length = strlen(to);
2937
2938        Py_XDECREF(tmp_obj);
2939
2940        if (encoding == -1)
2941                to_obj = PyBytes_FromStringAndSize(to, to_length);
2942        else
2943                to_obj = get_decoded_string(to, to_length, encoding);
2944        if (to)
2945                PQfreemem(to);
2946        return to_obj;
2947}
2948
2949#endif  /* ESCAPING_FUNCS */
2950
2951/* escape string */
2952static char connEscapeString__doc__[] =
2953"escape_string(str) -- escape a string for use within SQL";
2954
2955static PyObject *
2956connEscapeString(connObject *self, PyObject *string)
2957{
2958        PyObject   *tmp_obj = NULL, /* auxiliary string object */
2959                           *to_obj; /* string object to return */
2960        char       *from, /* our string argument as encoded string */
2961                           *to; /* the result as encoded string */
2962        Py_ssize_t      from_length; /* length of string */
2963        size_t          to_length; /* length of result */
2964        int                     encoding = -1; /* client encoding */
2965
2966        if (PyBytes_Check(string))
2967        {
2968                PyBytes_AsStringAndSize(string, &from, &from_length);
2969        }
2970        else if (PyUnicode_Check(string))
2971        {
2972                encoding = PQclientEncoding(self->cnx);
2973                tmp_obj = get_encoded_string(string, encoding);
2974                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
2975                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
2976        }
2977        else
2978        {
2979                PyErr_SetString(PyExc_TypeError,
2980                        "Method escape_string() expects a string as argument");
2981                return NULL;
2982        }
2983
2984        to_length = 2*from_length + 1;
2985        if ((Py_ssize_t)to_length < from_length) /* overflow */
2986        {
2987                to_length = from_length;
2988                from_length = (from_length - 1)/2;
2989        }
2990        to = (char *)PyMem_Malloc(to_length);
2991        to_length = PQescapeStringConn(self->cnx,
2992                to, from, (size_t)from_length, NULL);
2993
2994        Py_XDECREF(tmp_obj);
2995
2996        if (encoding == -1)
2997                to_obj = PyBytes_FromStringAndSize(to, to_length);
2998        else
2999                to_obj = get_decoded_string(to, to_length, encoding);
3000        PyMem_Free(to);
3001        return to_obj;
3002}
3003
3004/* escape bytea */
3005static char connEscapeBytea__doc__[] =
3006"escape_bytea(data) -- escape binary data for use within SQL as type bytea";
3007
3008static PyObject *
3009connEscapeBytea(connObject *self, PyObject *data)
3010{
3011        PyObject   *tmp_obj = NULL, /* auxiliary string object */
3012                           *to_obj; /* string object to return */
3013        char       *from, /* our string argument as encoded string */
3014                           *to; /* the result as encoded string */
3015        Py_ssize_t      from_length; /* length of string */
3016        size_t          to_length; /* length of result */
3017        int                     encoding = -1; /* client encoding */
3018
3019        if (PyBytes_Check(data))
3020        {
3021                PyBytes_AsStringAndSize(data, &from, &from_length);
3022        }
3023        else if (PyUnicode_Check(data))
3024        {
3025                encoding = PQclientEncoding(self->cnx);
3026                tmp_obj = get_encoded_string(data, encoding);
3027                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3028                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
3029        }
3030        else
3031        {
3032                PyErr_SetString(PyExc_TypeError,
3033                        "Method escape_bytea() expects a string as argument");
3034                return NULL;
3035        }
3036
3037        to = (char *)PQescapeByteaConn(self->cnx,
3038                (unsigned char *)from, (size_t)from_length, &to_length);
3039
3040        Py_XDECREF(tmp_obj);
3041
3042        if (encoding == -1)
3043                to_obj = PyBytes_FromStringAndSize(to, to_length - 1);
3044        else
3045                to_obj = get_decoded_string(to, to_length - 1, encoding);
3046        if (to)
3047                PQfreemem(to);
3048        return to_obj;
3049}
3050
3051#ifdef LARGE_OBJECTS
3052/* creates large object */
3053static char connCreateLO__doc__[] =
3054"locreate(mode) -- create a new large object in the database";
3055
3056static PyObject *
3057connCreateLO(connObject *self, PyObject *args)
3058{
3059        int                     mode;
3060        Oid                     lo_oid;
3061
3062        /* checks validity */
3063        if (!check_cnx_obj(self))
3064                return NULL;
3065
3066        /* gets arguments */
3067        if (!PyArg_ParseTuple(args, "i", &mode))
3068        {
3069                PyErr_SetString(PyExc_TypeError,
3070                        "Method locreate() takes an integer argument");
3071                return NULL;
3072        }
3073
3074        /* creates large object */
3075        lo_oid = lo_creat(self->cnx, mode);
3076        if (lo_oid == 0)
3077        {
3078                set_error_msg(OperationalError, "Can't create large object");
3079                return NULL;
3080        }
3081
3082        return (PyObject *) largeNew(self, lo_oid);
3083}
3084
3085/* init from already known oid */
3086static char connGetLO__doc__[] =
3087"getlo(oid) -- create a large object instance for the specified oid";
3088
3089static PyObject *
3090connGetLO(connObject *self, PyObject *args)
3091{
3092        int                     lo_oid;
3093
3094        /* checks validity */
3095        if (!check_cnx_obj(self))
3096                return NULL;
3097
3098        /* gets arguments */
3099        if (!PyArg_ParseTuple(args, "i", &lo_oid))
3100        {
3101                PyErr_SetString(PyExc_TypeError,
3102                        "Method getlo() takes an integer argument");
3103                return NULL;
3104        }
3105
3106        if (!lo_oid)
3107        {
3108                PyErr_SetString(PyExc_ValueError, "The object oid can't be null");
3109                return NULL;
3110        }
3111
3112        /* creates object */
3113        return (PyObject *) largeNew(self, lo_oid);
3114}
3115
3116/* import unix file */
3117static char connImportLO__doc__[] =
3118"loimport(name) -- create a new large object from specified file";
3119
3120static PyObject *
3121connImportLO(connObject *self, PyObject *args)
3122{
3123        char   *name;
3124        Oid             lo_oid;
3125
3126        /* checks validity */
3127        if (!check_cnx_obj(self))
3128                return NULL;
3129
3130        /* gets arguments */
3131        if (!PyArg_ParseTuple(args, "s", &name))
3132        {
3133                PyErr_SetString(PyExc_TypeError,
3134                        "Method loimport() takes a string argument");
3135                return NULL;
3136        }
3137
3138        /* imports file and checks result */
3139        lo_oid = lo_import(self->cnx, name);
3140        if (lo_oid == 0)
3141        {
3142                set_error_msg(OperationalError, "Can't create large object");
3143                return NULL;
3144        }
3145
3146        return (PyObject *) largeNew(self, lo_oid);
3147}
3148#endif /* LARGE_OBJECTS */
3149
3150/* resets connection */
3151static char connReset__doc__[] =
3152"reset() -- reset connection with current parameters\n\n"
3153"All derived queries and large objects derived from this connection\n"
3154"will not be usable after this call.\n";
3155
3156static PyObject *
3157connReset(connObject *self, PyObject *noargs)
3158{
3159        if (!self->cnx)
3160        {
3161                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3162                return NULL;
3163        }
3164
3165        /* resets the connection */
3166        PQreset(self->cnx);
3167        Py_INCREF(Py_None);
3168        return Py_None;
3169}
3170
3171/* cancels current command */
3172static char connCancel__doc__[] =
3173"cancel() -- abandon processing of the current command";
3174
3175static PyObject *
3176connCancel(connObject *self, PyObject *noargs)
3177{
3178        if (!self->cnx)
3179        {
3180                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3181                return NULL;
3182        }
3183
3184        /* request that the server abandon processing of the current command */
3185        return PyInt_FromLong((long) PQrequestCancel(self->cnx));
3186}
3187
3188/* get connection socket */
3189static char connFileno__doc__[] =
3190"fileno() -- return database connection socket file handle";
3191
3192static PyObject *
3193connFileno(connObject *self, PyObject *noargs)
3194{
3195        if (!self->cnx)
3196        {
3197                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3198                return NULL;
3199        }
3200
3201#ifdef NO_PQSOCKET
3202        return PyInt_FromLong((long) self->cnx->sock);
3203#else
3204        return PyInt_FromLong((long) PQsocket(self->cnx));
3205#endif
3206}
3207
3208/* set external typecast callback function */
3209static char connSetCastHook__doc__[] =
3210"set_cast_hook(func) -- set a fallback typecast function";
3211
3212static PyObject *
3213connSetCastHook(connObject *self, PyObject *func)
3214{
3215        PyObject *ret = NULL;
3216
3217        if (func == Py_None)
3218        {
3219                Py_XDECREF(self->cast_hook);
3220                self->cast_hook = NULL;
3221                Py_INCREF(Py_None); ret = Py_None;
3222        }
3223        else if (PyCallable_Check(func))
3224        {
3225                Py_XINCREF(func); Py_XDECREF(self->cast_hook);
3226                self->cast_hook = func;
3227                Py_INCREF(Py_None); ret = Py_None;
3228        }
3229        else
3230                PyErr_SetString(PyExc_TypeError,
3231                        "Method set_cast_hook() expects"
3232                         " a callable or None as argument");
3233
3234        return ret;
3235}
3236
3237/* get notice receiver callback function */
3238static char connGetCastHook__doc__[] =
3239"get_cast_hook() -- get the fallback typecast function";
3240
3241static PyObject *
3242connGetCastHook(connObject *self, PyObject *noargs)
3243{
3244        PyObject *ret = self->cast_hook;;
3245
3246        if (!ret)
3247                ret = Py_None;
3248        Py_INCREF(ret);
3249
3250        return ret;
3251}
3252
3253/* set notice receiver callback function */
3254static char connSetNoticeReceiver__doc__[] =
3255"set_notice_receiver(func) -- set the current notice receiver";
3256
3257static PyObject *
3258connSetNoticeReceiver(connObject *self, PyObject *func)
3259{
3260        PyObject *ret = NULL;
3261
3262        if (func == Py_None)
3263        {
3264                Py_XDECREF(self->notice_receiver);
3265                self->notice_receiver = NULL;
3266                Py_INCREF(Py_None); ret = Py_None;
3267        }
3268        else if (PyCallable_Check(func))
3269        {
3270                Py_XINCREF(func); Py_XDECREF(self->notice_receiver);
3271                self->notice_receiver = func;
3272                PQsetNoticeReceiver(self->cnx, notice_receiver, self);
3273                Py_INCREF(Py_None); ret = Py_None;
3274        }
3275        else
3276                PyErr_SetString(PyExc_TypeError,
3277                        "Method set_notice_receiver() expects"
3278                         " a callable or None as argument");
3279
3280        return ret;
3281}
3282
3283/* get notice receiver callback function */
3284static char connGetNoticeReceiver__doc__[] =
3285"get_notice_receiver() -- get the current notice receiver";
3286
3287static PyObject *
3288connGetNoticeReceiver(connObject *self, PyObject *noargs)
3289{
3290        PyObject *ret = self->notice_receiver;
3291
3292        if (!ret)
3293                ret = Py_None;
3294        Py_INCREF(ret);
3295
3296        return ret;
3297}
3298
3299/* close without deleting */
3300static char connClose__doc__[] =
3301"close() -- close connection\n\n"
3302"All instances of the connection object and derived objects\n"
3303"(queries and large objects) can no longer be used after this call.\n";
3304
3305static PyObject *
3306connClose(connObject *self, PyObject *noargs)
3307{
3308        /* connection object cannot already be closed */
3309        if (!self->cnx)
3310        {
3311                set_error_msg(InternalError, "Connection already closed");
3312                return NULL;
3313        }
3314
3315        Py_BEGIN_ALLOW_THREADS
3316        PQfinish(self->cnx);
3317        Py_END_ALLOW_THREADS
3318
3319        self->cnx = NULL;
3320        Py_INCREF(Py_None);
3321        return Py_None;
3322}
3323
3324/* gets asynchronous notify */
3325static char connGetNotify__doc__[] =
3326"getnotify() -- get database notify for this connection";
3327
3328static PyObject *
3329connGetNotify(connObject *self, PyObject *noargs)
3330{
3331        PGnotify   *notify;
3332
3333        if (!self->cnx)
3334        {
3335                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3336                return NULL;
3337        }
3338
3339        /* checks for NOTIFY messages */
3340        PQconsumeInput(self->cnx);
3341
3342        if (!(notify = PQnotifies(self->cnx)))
3343        {
3344                Py_INCREF(Py_None);
3345                return Py_None;
3346        }
3347        else
3348        {
3349                PyObject   *notify_result,
3350                                   *temp;
3351
3352                if (!(temp = PyStr_FromString(notify->relname)))
3353                        return NULL;
3354
3355                if (!(notify_result = PyTuple_New(3)))
3356                        return NULL;
3357
3358                PyTuple_SET_ITEM(notify_result, 0, temp);
3359
3360                if (!(temp = PyInt_FromLong(notify->be_pid)))
3361                {
3362                        Py_DECREF(notify_result);
3363                        return NULL;
3364                }
3365
3366                PyTuple_SET_ITEM(notify_result, 1, temp);
3367
3368                /* extra exists even in old versions that did not support it */
3369                if (!(temp = PyStr_FromString(notify->extra)))
3370                {
3371                        Py_DECREF(notify_result);
3372                        return NULL;
3373                }
3374
3375                PyTuple_SET_ITEM(notify_result, 2, temp);
3376
3377                PQfreemem(notify);
3378
3379                return notify_result;
3380        }
3381}
3382
3383/* get the list of connection attributes */
3384static PyObject *
3385connDir(connObject *self, PyObject *noargs)
3386{
3387        PyObject *attrs;
3388
3389        attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
3390        PyObject_CallMethod(attrs, "extend", "[sssssssss]",
3391                "host", "port", "db", "options", "error", "status", "user",
3392                "protocol_version", "server_version");
3393
3394        return attrs;
3395}
3396
3397/* connection object methods */
3398static struct PyMethodDef connMethods[] = {
3399        {"__dir__", (PyCFunction) connDir,  METH_NOARGS, NULL},
3400
3401        {"source", (PyCFunction) connSource, METH_NOARGS, connSource__doc__},
3402        {"query", (PyCFunction) connQuery, METH_VARARGS, connQuery__doc__},
3403        {"reset", (PyCFunction) connReset, METH_NOARGS, connReset__doc__},
3404        {"cancel", (PyCFunction) connCancel, METH_NOARGS, connCancel__doc__},
3405        {"close", (PyCFunction) connClose, METH_NOARGS, connClose__doc__},
3406        {"fileno", (PyCFunction) connFileno, METH_NOARGS, connFileno__doc__},
3407        {"get_cast_hook", (PyCFunction) connGetCastHook, METH_NOARGS,
3408                        connGetCastHook__doc__},
3409        {"set_cast_hook", (PyCFunction) connSetCastHook, METH_O,
3410                        connSetCastHook__doc__},
3411        {"get_notice_receiver", (PyCFunction) connGetNoticeReceiver, METH_NOARGS,
3412                        connGetNoticeReceiver__doc__},
3413        {"set_notice_receiver", (PyCFunction) connSetNoticeReceiver, METH_O,
3414                        connSetNoticeReceiver__doc__},
3415        {"getnotify", (PyCFunction) connGetNotify, METH_NOARGS,
3416                        connGetNotify__doc__},
3417        {"inserttable", (PyCFunction) connInsertTable, METH_VARARGS,
3418                        connInsertTable__doc__},
3419        {"transaction", (PyCFunction) connTransaction, METH_NOARGS,
3420                        connTransaction__doc__},
3421        {"parameter", (PyCFunction) connParameter, METH_VARARGS,
3422                        connParameter__doc__},
3423        {"date_format", (PyCFunction) connDateFormat, METH_NOARGS,
3424                        connDateFormat__doc__},
3425
3426#ifdef ESCAPING_FUNCS
3427        {"escape_literal", (PyCFunction) connEscapeLiteral, METH_O,
3428                        connEscapeLiteral__doc__},
3429        {"escape_identifier", (PyCFunction) connEscapeIdentifier, METH_O,
3430                        connEscapeIdentifier__doc__},
3431#endif  /* ESCAPING_FUNCS */
3432        {"escape_string", (PyCFunction) connEscapeString, METH_O,
3433                        connEscapeString__doc__},
3434        {"escape_bytea", (PyCFunction) connEscapeBytea, METH_O,
3435                        connEscapeBytea__doc__},
3436
3437#ifdef DIRECT_ACCESS
3438        {"putline", (PyCFunction) connPutLine, METH_VARARGS, connPutLine__doc__},
3439        {"getline", (PyCFunction) connGetLine, METH_NOARGS, connGetLine__doc__},
3440        {"endcopy", (PyCFunction) connEndCopy, METH_NOARGS, connEndCopy__doc__},
3441#endif /* DIRECT_ACCESS */
3442
3443#ifdef LARGE_OBJECTS
3444        {"locreate", (PyCFunction) connCreateLO, METH_VARARGS, connCreateLO__doc__},
3445        {"getlo", (PyCFunction) connGetLO, METH_VARARGS, connGetLO__doc__},
3446        {"loimport", (PyCFunction) connImportLO, METH_VARARGS, connImportLO__doc__},
3447#endif /* LARGE_OBJECTS */
3448
3449        {NULL, NULL} /* sentinel */
3450};
3451
3452/* gets connection attributes */
3453static PyObject *
3454connGetAttr(connObject *self, PyObject *nameobj)
3455{
3456        const char *name = PyStr_AsString(nameobj);
3457
3458        /*
3459         * Although we could check individually, there are only a few
3460         * attributes that don't require a live connection and unless someone
3461         * has an urgent need, this will have to do
3462         */
3463
3464        /* first exception - close which returns a different error */
3465        if (strcmp(name, "close") && !self->cnx)
3466        {
3467                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3468                return NULL;
3469        }
3470
3471        /* list PostgreSQL connection fields */
3472
3473        /* postmaster host */
3474        if (!strcmp(name, "host"))
3475        {
3476                char *r = PQhost(self->cnx);
3477                if (!r)
3478                        r = "localhost";
3479                return PyStr_FromString(r);
3480        }
3481
3482        /* postmaster port */
3483        if (!strcmp(name, "port"))
3484                return PyInt_FromLong(atol(PQport(self->cnx)));
3485
3486        /* selected database */
3487        if (!strcmp(name, "db"))
3488                return PyStr_FromString(PQdb(self->cnx));
3489
3490        /* selected options */
3491        if (!strcmp(name, "options"))
3492                return PyStr_FromString(PQoptions(self->cnx));
3493
3494        /* error (status) message */
3495        if (!strcmp(name, "error"))
3496                return PyStr_FromString(PQerrorMessage(self->cnx));
3497
3498        /* connection status : 1 - OK, 0 - BAD */
3499        if (!strcmp(name, "status"))
3500                return PyInt_FromLong(PQstatus(self->cnx) == CONNECTION_OK ? 1 : 0);
3501
3502        /* provided user name */
3503        if (!strcmp(name, "user"))
3504                return PyStr_FromString(PQuser(self->cnx));
3505
3506        /* protocol version */
3507        if (!strcmp(name, "protocol_version"))
3508                return PyInt_FromLong(PQprotocolVersion(self->cnx));
3509
3510        /* backend version */
3511        if (!strcmp(name, "server_version"))
3512                return PyInt_FromLong(PQserverVersion(self->cnx));
3513
3514        return PyObject_GenericGetAttr((PyObject *) self, nameobj);
3515}
3516
3517/* connection type definition */
3518static PyTypeObject connType = {
3519        PyVarObject_HEAD_INIT(NULL, 0)
3520        "pg.Connection",                        /* tp_name */
3521        sizeof(connObject),                     /* tp_basicsize */
3522        0,                                                      /* tp_itemsize */
3523        (destructor) connDelete,        /* tp_dealloc */
3524        0,                                                      /* tp_print */
3525        0,                                                      /* tp_getattr */
3526        0,                                                      /* tp_setattr */
3527        0,                                                      /* tp_reserved */
3528        0,                                                      /* tp_repr */
3529        0,                                                      /* tp_as_number */
3530        0,                                                      /* tp_as_sequence */
3531        0,                                                      /* tp_as_mapping */
3532        0,                                                      /* tp_hash */
3533        0,                                                      /* tp_call */
3534        0,                                                      /* tp_str */
3535        (getattrofunc) connGetAttr,     /* tp_getattro */
3536        0,                                                      /* tp_setattro */
3537        0,                                                      /* tp_as_buffer */
3538        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
3539        0,                                                      /* tp_doc */
3540        0,                                                      /* tp_traverse */
3541        0,                                                      /* tp_clear */
3542        0,                                                      /* tp_richcompare */
3543        0,                                                      /* tp_weaklistoffset */
3544        0,                                                      /* tp_iter */
3545        0,                                                      /* tp_iternext */
3546        connMethods,                            /* tp_methods */
3547};
3548
3549/* --------------------------------------------------------------------- */
3550/* source object                                                                                                                 */
3551/* --------------------------------------------------------------------- */
3552/* checks source object validity */
3553static int
3554check_source_obj(sourceObject *self, int level)
3555{
3556        if (!self->valid)
3557        {
3558                set_error_msg(OperationalError, "Object has been closed");
3559                return 0;
3560        }
3561
3562        if ((level & CHECK_RESULT) && !self->result)
3563        {
3564                set_error_msg(DatabaseError, "No result");
3565                return 0;
3566        }
3567
3568        if ((level & CHECK_DQL) && self->result_type != RESULT_DQL)
3569        {
3570                set_error_msg(DatabaseError, "Last query did not return tuples");
3571                return 0;
3572        }
3573
3574        if ((level & CHECK_CNX) && !check_cnx_obj(self->pgcnx))
3575                return 0;
3576
3577        return 1;
3578}
3579
3580/* destructor */
3581static void
3582sourceDealloc(sourceObject *self)
3583{
3584        if (self->result)
3585                PQclear(self->result);
3586
3587        Py_XDECREF(self->pgcnx);
3588        PyObject_Del(self);
3589}
3590
3591/* closes object */
3592static char sourceClose__doc__[] =
3593"close() -- close query object without deleting it\n\n"
3594"All instances of the query object can no longer be used after this call.\n";
3595
3596static PyObject *
3597sourceClose(sourceObject *self, PyObject *noargs)
3598{
3599        /* frees result if necessary and invalidates object */
3600        if (self->result)
3601        {
3602                PQclear(self->result);
3603                self->result_type = RESULT_EMPTY;
3604                self->result = NULL;
3605        }
3606
3607        self->valid = 0;
3608
3609        /* return None */
3610        Py_INCREF(Py_None);
3611        return Py_None;
3612}
3613
3614/* database query */
3615static char sourceExecute__doc__[] =
3616"execute(sql) -- execute a SQL statement (string)\n\n"
3617"On success, this call returns the number of affected rows, or None\n"
3618"for DQL (SELECT, ...) statements.  The fetch (fetch(), fetchone()\n"
3619"and fetchall()) methods can be used to get result rows.\n";
3620
3621static PyObject *
3622sourceExecute(sourceObject *self, PyObject *sql)
3623{
3624        PyObject   *tmp_obj = NULL; /* auxiliary string object */
3625        char       *query;
3626        int                     encoding;
3627
3628        /* checks validity */
3629        if (!check_source_obj(self, CHECK_CNX))
3630                return NULL;
3631
3632        /* make sure that the connection object is valid */
3633        if (!self->pgcnx->cnx)
3634                return NULL;
3635
3636        encoding = PQclientEncoding(self->pgcnx->cnx);
3637
3638        if (PyBytes_Check(sql))
3639        {
3640                query = PyBytes_AsString(sql);
3641        }
3642        else if (PyUnicode_Check(sql))
3643        {
3644                tmp_obj = get_encoded_string(sql, encoding);
3645                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3646                query = PyBytes_AsString(tmp_obj);
3647        }
3648        else
3649        {
3650                PyErr_SetString(PyExc_TypeError,
3651                        "Method execute() expects a string as argument");
3652                return NULL;
3653        }
3654
3655        /* frees previous result */
3656        if (self->result)
3657        {
3658                PQclear(self->result);
3659                self->result = NULL;
3660        }
3661        self->max_row = 0;
3662        self->current_row = 0;
3663        self->num_fields = 0;
3664        self->encoding = encoding;
3665
3666        /* gets result */
3667        Py_BEGIN_ALLOW_THREADS
3668        self->result = PQexec(self->pgcnx->cnx, query);
3669        Py_END_ALLOW_THREADS
3670
3671        /* we don't need the auxiliary string any more */
3672        Py_XDECREF(tmp_obj);
3673
3674        /* checks result validity */
3675        if (!self->result)
3676        {
3677                PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->pgcnx->cnx));
3678                return NULL;
3679        }
3680
3681        /* this may have changed the datestyle, so we reset the date format
3682           in order to force fetching it newly when next time requested */
3683        self->pgcnx->date_format = date_format; /* this is normally NULL */
3684
3685        /* checks result status */
3686        switch (PQresultStatus(self->result))
3687        {
3688                long    num_rows;
3689                char   *temp;
3690
3691                /* query succeeded */
3692                case PGRES_TUPLES_OK:   /* DQL: returns None (DB-SIG compliant) */
3693                        self->result_type = RESULT_DQL;
3694                        self->max_row = PQntuples(self->result);
3695                        self->num_fields = PQnfields(self->result);
3696                        Py_INCREF(Py_None);
3697                        return Py_None;
3698                case PGRES_COMMAND_OK:  /* other requests */
3699                case PGRES_COPY_OUT:
3700                case PGRES_COPY_IN:
3701                        self->result_type = RESULT_DDL;
3702                        temp = PQcmdTuples(self->result);
3703                        num_rows = -1;
3704                        if (temp[0])
3705                        {
3706                                self->result_type = RESULT_DML;
3707                                num_rows = atol(temp);
3708                        }
3709                        return PyInt_FromLong(num_rows);
3710
3711                /* query failed */
3712                case PGRES_EMPTY_QUERY:
3713                        PyErr_SetString(PyExc_ValueError, "Empty query");
3714                        break;
3715                case PGRES_BAD_RESPONSE:
3716                case PGRES_FATAL_ERROR:
3717                case PGRES_NONFATAL_ERROR:
3718                        set_error(ProgrammingError, "Cannot execute command",
3719                                self->pgcnx->cnx, self->result);
3720                        break;
3721                default:
3722                        set_error_msg(InternalError, "Internal error: "
3723                                "unknown result status");
3724        }
3725
3726        /* frees result and returns error */
3727        PQclear(self->result);
3728        self->result = NULL;
3729        self->result_type = RESULT_EMPTY;
3730        return NULL;
3731}
3732
3733/* gets oid status for last query (valid for INSERTs, 0 for other) */
3734static char sourceStatusOID__doc__[] =
3735"oidstatus() -- return oid of last inserted row (if available)";
3736
3737static PyObject *
3738sourceStatusOID(sourceObject *self, PyObject *noargs)
3739{
3740        Oid                     oid;
3741
3742        /* checks validity */
3743        if (!check_source_obj(self, CHECK_RESULT))
3744                return NULL;
3745
3746        /* retrieves oid status */
3747        if ((oid = PQoidValue(self->result)) == InvalidOid)
3748        {
3749                Py_INCREF(Py_None);
3750                return Py_None;
3751        }
3752
3753        return PyInt_FromLong(oid);
3754}
3755
3756/* fetches rows from last result */
3757static char sourceFetch__doc__[] =
3758"fetch(num) -- return the next num rows from the last result in a list\n\n"
3759"If num parameter is omitted arraysize attribute value is used.\n"
3760"If size equals -1, all rows are fetched.\n";
3761
3762static PyObject *
3763sourceFetch(sourceObject *self, PyObject *args)
3764{
3765        PyObject   *reslist;
3766        int                     i,
3767                                k;
3768        long            size;
3769#if IS_PY3
3770        int                     encoding;
3771#endif
3772
3773        /* checks validity */
3774        if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
3775                return NULL;
3776
3777        /* checks args */
3778        size = self->arraysize;
3779        if (!PyArg_ParseTuple(args, "|l", &size))
3780        {
3781                PyErr_SetString(PyExc_TypeError,
3782                        "fetch(num), with num (integer, optional)");
3783                return NULL;
3784        }
3785
3786        /* seeks last line */
3787        /* limit size to be within the amount of data we actually have */
3788        if (size == -1 || (self->max_row - self->current_row) < size)
3789                size = self->max_row - self->current_row;
3790
3791        /* allocate list for result */
3792        if (!(reslist = PyList_New(0))) return NULL;
3793
3794#if IS_PY3
3795        encoding = self->encoding;
3796#endif
3797
3798        /* builds result */
3799        for (i = 0, k = self->current_row; i < size; ++i, ++k)
3800        {
3801                PyObject   *rowtuple;
3802                int                     j;
3803
3804                if (!(rowtuple = PyTuple_New(self->num_fields)))
3805                {
3806                        Py_DECREF(reslist); return NULL;
3807                }
3808
3809                for (j = 0; j < self->num_fields; ++j)
3810                {
3811                        PyObject   *str;
3812
3813                        if (PQgetisnull(self->result, k, j))
3814                        {
3815                                Py_INCREF(Py_None);
3816                                str = Py_None;
3817                        }
3818                        else
3819                        {
3820                                char *s = PQgetvalue(self->result, k, j);
3821                                Py_ssize_t size = PQgetlength(self->result, k, j);
3822#if IS_PY3
3823                                if (PQfformat(self->result, j) == 0) /* textual format */
3824                                {
3825                                        str = get_decoded_string(s, size, encoding);
3826                                        if (!str) /* cannot decode */
3827                                                str = PyBytes_FromStringAndSize(s, size);
3828                                }
3829                                else
3830#endif
3831                                str = PyBytes_FromStringAndSize(s, size);
3832                        }
3833                        PyTuple_SET_ITEM(rowtuple, j, str);
3834                }
3835
3836                if (PyList_Append(reslist, rowtuple))
3837                {
3838                        Py_DECREF(rowtuple); Py_DECREF(reslist); return NULL;
3839                }
3840                Py_DECREF(rowtuple);
3841        }
3842
3843        self->current_row = k;
3844        return reslist;
3845}
3846
3847/* changes current row (internal wrapper for all "move" methods) */
3848static PyObject *
3849pgsource_move(sourceObject *self, int move)
3850{
3851        /* checks validity */
3852        if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
3853                return NULL;
3854
3855        /* changes the current row */
3856        switch (move)
3857        {
3858                case QUERY_MOVEFIRST:
3859                        self->current_row = 0;
3860                        break;
3861                case QUERY_MOVELAST:
3862                        self->current_row = self->max_row - 1;
3863                        break;
3864                case QUERY_MOVENEXT:
3865                        if (self->current_row != self->max_row)
3866                                ++self->current_row;
3867                        break;
3868                case QUERY_MOVEPREV:
3869                        if (self->current_row > 0)
3870                                self->current_row--;
3871                        break;
3872        }
3873
3874        Py_INCREF(Py_None);
3875        return Py_None;
3876}
3877
3878/* move to first result row */
3879static char sourceMoveFirst__doc__[] =
3880"movefirst() -- move to first result row";
3881
3882static PyObject *
3883sourceMoveFirst(sourceObject *self, PyObject *noargs)
3884{
3885        return pgsource_move(self, QUERY_MOVEFIRST);
3886}
3887
3888/* move to last result row */
3889static char sourceMoveLast__doc__[] =
3890"movelast() -- move to last valid result row";
3891
3892static PyObject *
3893sourceMoveLast(sourceObject *self, PyObject *noargs)
3894{
3895        return pgsource_move(self, QUERY_MOVELAST);
3896}
3897
3898/* move to next result row */
3899static char sourceMoveNext__doc__[] =
3900"movenext() -- move to next result row";
3901
3902static PyObject *
3903sourceMoveNext(sourceObject *self, PyObject *noargs)
3904{
3905        return pgsource_move(self, QUERY_MOVENEXT);
3906}
3907
3908/* move to previous result row */
3909static char sourceMovePrev__doc__[] =
3910"moveprev() -- move to previous result row";
3911
3912static PyObject *
3913sourceMovePrev(sourceObject *self, PyObject *noargs)
3914{
3915        return pgsource_move(self, QUERY_MOVEPREV);
3916}
3917
3918/* put copy data */
3919static char sourcePutData__doc__[] =
3920"putdata(buffer) -- send data to server during copy from stdin";
3921
3922static PyObject *
3923sourcePutData(sourceObject *self, PyObject *buffer)
3924{
3925        PyObject   *tmp_obj = NULL; /* an auxiliary object */
3926        char       *buf; /* the buffer as encoded string */
3927        Py_ssize_t      nbytes; /* length of string */
3928        char       *errormsg = NULL; /* error message */
3929        int                     res; /* direct result of the operation */
3930        PyObject   *ret; /* return value */
3931
3932        /* checks validity */
3933        if (!check_source_obj(self, CHECK_CNX))
3934                return NULL;
3935
3936        /* make sure that the connection object is valid */
3937        if (!self->pgcnx->cnx)
3938                return NULL;
3939
3940        if (buffer == Py_None)
3941        {
3942                /* pass None for terminating the operation */
3943                buf = errormsg = NULL;
3944        }
3945        else if (PyBytes_Check(buffer))
3946        {
3947                /* or pass a byte string */
3948                PyBytes_AsStringAndSize(buffer, &buf, &nbytes);
3949        }
3950        else if (PyUnicode_Check(buffer))
3951        {
3952                /* or pass a unicode string */
3953                tmp_obj = get_encoded_string(
3954                        buffer, PQclientEncoding(self->pgcnx->cnx));
3955                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3956                PyBytes_AsStringAndSize(tmp_obj, &buf, &nbytes);
3957        }
3958        else if (PyErr_GivenExceptionMatches(buffer, PyExc_BaseException))
3959        {
3960                /* or pass a Python exception for sending an error message */
3961                tmp_obj = PyObject_Str(buffer);
3962                if (PyUnicode_Check(tmp_obj))
3963                {
3964                        PyObject *obj = tmp_obj;
3965                        tmp_obj = get_encoded_string(
3966                                obj, PQclientEncoding(self->pgcnx->cnx));
3967                        Py_DECREF(obj);
3968                        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3969                }
3970                errormsg = PyBytes_AsString(tmp_obj);
3971                buf = NULL;
3972        }
3973        else
3974        {
3975                PyErr_SetString(PyExc_TypeError,
3976                        "Method putdata() expects a buffer, None"
3977                         " or an exception as argument");
3978                return NULL;
3979        }
3980
3981        /* checks validity */
3982        if (!check_source_obj(self, CHECK_CNX | CHECK_RESULT) ||
3983                        !self->pgcnx->cnx ||
3984                        PQresultStatus(self->result) != PGRES_COPY_IN)
3985        {
3986                PyErr_SetString(PyExc_IOError,
3987                        "Connection is invalid or not in copy_in state");
3988                Py_XDECREF(tmp_obj);
3989                return NULL;
3990        }
3991
3992        if (buf)
3993        {
3994                res = nbytes ? PQputCopyData(self->pgcnx->cnx, buf, (int)nbytes) : 1;
3995        }
3996        else
3997        {
3998                res = PQputCopyEnd(self->pgcnx->cnx, errormsg);
3999        }
4000
4001        Py_XDECREF(tmp_obj);
4002
4003        if (res != 1)
4004        {
4005                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->pgcnx->cnx));
4006                return NULL;
4007        }
4008
4009        if (buf) /* buffer has been sent */
4010        {
4011                ret = Py_None;
4012                Py_INCREF(ret);
4013        }
4014        else /* copy is done */
4015        {
4016                PGresult   *result; /* final result of the operation */
4017
4018                Py_BEGIN_ALLOW_THREADS;
4019                result = PQgetResult(self->pgcnx->cnx);
4020                Py_END_ALLOW_THREADS;
4021
4022                if (PQresultStatus(result) == PGRES_COMMAND_OK)
4023                {
4024                        char   *temp;
4025                        long    num_rows;
4026
4027                        temp = PQcmdTuples(result);
4028                        num_rows = temp[0] ? atol(temp) : -1;
4029                        ret = PyInt_FromLong(num_rows);
4030                }
4031                else
4032                {
4033                        if (!errormsg) errormsg = PQerrorMessage(self->pgcnx->cnx);
4034                        PyErr_SetString(PyExc_IOError, errormsg);
4035                        ret = NULL;
4036                }
4037
4038                PQclear(self->result);
4039                self->result = NULL;
4040                self->result_type = RESULT_EMPTY;
4041        }
4042
4043        return ret; /* None or number of rows */
4044}
4045
4046/* get copy data */
4047static char sourceGetData__doc__[] =
4048"getdata(decode) -- receive data to server during copy to stdout";
4049
4050static PyObject *
4051sourceGetData(sourceObject *self, PyObject *args)
4052{
4053        int                *decode = 0; /* decode flag */
4054        char       *buffer; /* the copied buffer as encoded byte string */
4055        Py_ssize_t      nbytes; /* length of the byte string */
4056        PyObject   *ret; /* return value */
4057
4058        /* checks validity */
4059        if (!check_source_obj(self, CHECK_CNX))
4060                return NULL;
4061
4062        /* make sure that the connection object is valid */
4063        if (!self->pgcnx->cnx)
4064                return NULL;
4065
4066        if (!PyArg_ParseTuple(args, "|i", &decode))
4067                return NULL;
4068
4069        /* checks validity */
4070        if (!check_source_obj(self, CHECK_CNX | CHECK_RESULT) ||
4071                        !self->pgcnx->cnx ||
4072                        PQresultStatus(self->result) != PGRES_COPY_OUT)
4073        {
4074                PyErr_SetString(PyExc_IOError,
4075                        "Connection is invalid or not in copy_out state");
4076                return NULL;
4077        }
4078
4079        nbytes = PQgetCopyData(self->pgcnx->cnx, &buffer, 0);
4080
4081        if (!nbytes || nbytes < -1) /* an error occurred */
4082        {
4083                PyErr_SetString(PyExc_IOError, PQerrorMessage(self->pgcnx->cnx));
4084                return NULL;
4085        }
4086
4087        if (nbytes == -1) /* copy is done */
4088        {
4089                PGresult   *result; /* final result of the operation */
4090
4091                Py_BEGIN_ALLOW_THREADS;
4092                result = PQgetResult(self->pgcnx->cnx);
4093                Py_END_ALLOW_THREADS;
4094
4095                if (PQresultStatus(result) == PGRES_COMMAND_OK)
4096                {
4097                        char   *temp;
4098                        long    num_rows;
4099
4100                        temp = PQcmdTuples(result);
4101                        num_rows = temp[0] ? atol(temp) : -1;
4102                        ret = PyInt_FromLong(num_rows);
4103                }
4104                else
4105                {
4106                        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->pgcnx->cnx));
4107                        ret = NULL;
4108                }
4109
4110                PQclear(self->result);
4111                self->result = NULL;
4112                self->result_type = RESULT_EMPTY;
4113        }
4114        else /* a row has been returned */
4115        {
4116                ret = decode ? get_decoded_string(
4117                                buffer, nbytes, PQclientEncoding(self->pgcnx->cnx)) :
4118                        PyBytes_FromStringAndSize(buffer, nbytes);
4119                PQfreemem(buffer);
4120        }
4121
4122        return ret; /* buffer or number of rows */
4123}
4124
4125/* finds field number from string/integer (internal use only) */
4126static int
4127sourceFieldindex(sourceObject *self, PyObject *param, const char *usage)
4128{
4129        int                     num;
4130
4131        /* checks validity */
4132        if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
4133                return -1;
4134
4135        /* gets field number */
4136        if (PyStr_Check(param))
4137                num = PQfnumber(self->result, PyBytes_AsString(param));
4138        else if (PyInt_Check(param))
4139                num = PyInt_AsLong(param);
4140        else
4141        {
4142                PyErr_SetString(PyExc_TypeError, usage);
4143                return -1;
4144        }
4145
4146        /* checks field validity */
4147        if (num < 0 || num >= self->num_fields)
4148        {
4149                PyErr_SetString(PyExc_ValueError, "Unknown field");
4150                return -1;
4151        }
4152
4153        return num;
4154}
4155
4156/* builds field information from position (internal use only) */
4157static PyObject *
4158pgsource_buildinfo(sourceObject *self, int num)
4159{
4160        PyObject *result;
4161
4162        /* allocates tuple */
4163        result = PyTuple_New(5);
4164        if (!result)
4165                return NULL;
4166
4167        /* affects field information */
4168        PyTuple_SET_ITEM(result, 0, PyInt_FromLong(num));
4169        PyTuple_SET_ITEM(result, 1,
4170                PyStr_FromString(PQfname(self->result, num)));
4171        PyTuple_SET_ITEM(result, 2,
4172                PyInt_FromLong(PQftype(self->result, num)));
4173        PyTuple_SET_ITEM(result, 3,
4174                PyInt_FromLong(PQfsize(self->result, num)));
4175        PyTuple_SET_ITEM(result, 4,
4176                PyInt_FromLong(PQfmod(self->result, num)));
4177
4178        return result;
4179}
4180
4181/* lists fields info */
4182static char sourceListInfo__doc__[] =
4183"listinfo() -- get information for all fields (position, name, type oid)";
4184
4185static PyObject *
4186sourceListInfo(sourceObject *self, PyObject *noargs)
4187{
4188        int                     i;
4189        PyObject   *result,
4190                           *info;
4191
4192        /* checks validity */
4193        if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
4194                return NULL;
4195
4196        /* builds result */
4197        if (!(result = PyTuple_New(self->num_fields)))
4198                return NULL;
4199
4200        for (i = 0; i < self->num_fields; ++i)
4201        {
4202                info = pgsource_buildinfo(self, i);
4203                if (!info)
4204                {
4205                        Py_DECREF(result);
4206                        return NULL;
4207                }
4208                PyTuple_SET_ITEM(result, i, info);
4209        }
4210
4211        /* returns result */
4212        return result;
4213};
4214
4215/* list fields information for last result */
4216static char sourceFieldInfo__doc__[] =
4217"fieldinfo(desc) -- get specified field info (position, name, type oid)";
4218
4219static PyObject *
4220sourceFieldInfo(sourceObject *self, PyObject *desc)
4221{
4222        int                     num;
4223
4224        /* checks args and validity */
4225        if ((num = sourceFieldindex(self, desc,
4226                        "Method fieldinfo() needs a string or integer as argument")) == -1)
4227                return NULL;
4228
4229        /* returns result */
4230        return pgsource_buildinfo(self, num);
4231};
4232
4233/* retrieve field value */
4234static char sourceField__doc__[] =
4235"field(desc) -- return specified field value";
4236
4237static PyObject *
4238sourceField(sourceObject *self, PyObject *desc)
4239{
4240        int                     num;
4241
4242        /* checks args and validity */
4243        if ((num = sourceFieldindex(self, desc,
4244                        "Method field() needs a string or integer as argument")) == -1)
4245                return NULL;
4246
4247        return PyStr_FromString(
4248                PQgetvalue(self->result, self->current_row, num));
4249}
4250
4251/* get the list of source object attributes */
4252static PyObject *
4253sourceDir(connObject *self, PyObject *noargs)
4254{
4255        PyObject *attrs;
4256
4257        attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
4258        PyObject_CallMethod(attrs, "extend", "[sssss]",
4259                "pgcnx", "arraysize", "resulttype", "ntuples", "nfields");
4260
4261        return attrs;
4262}
4263
4264/* source object methods */
4265static PyMethodDef sourceMethods[] = {
4266        {"__dir__", (PyCFunction) sourceDir,  METH_NOARGS, NULL},
4267        {"close", (PyCFunction) sourceClose, METH_NOARGS, sourceClose__doc__},
4268        {"execute", (PyCFunction) sourceExecute, METH_O, sourceExecute__doc__},
4269        {"oidstatus", (PyCFunction) sourceStatusOID, METH_NOARGS,
4270                        sourceStatusOID__doc__},
4271        {"fetch", (PyCFunction) sourceFetch, METH_VARARGS,
4272                        sourceFetch__doc__},
4273        {"movefirst", (PyCFunction) sourceMoveFirst, METH_NOARGS,
4274                        sourceMoveFirst__doc__},
4275        {"movelast", (PyCFunction) sourceMoveLast, METH_NOARGS,
4276                        sourceMoveLast__doc__},
4277        {"movenext", (PyCFunction) sourceMoveNext, METH_NOARGS,
4278                        sourceMoveNext__doc__},
4279        {"moveprev", (PyCFunction) sourceMovePrev, METH_NOARGS,
4280                        sourceMovePrev__doc__},
4281        {"putdata", (PyCFunction) sourcePutData, METH_O, sourcePutData__doc__},
4282        {"getdata", (PyCFunction) sourceGetData, METH_VARARGS,
4283                        sourceGetData__doc__},
4284        {"field", (PyCFunction) sourceField, METH_O,
4285                        sourceField__doc__},
4286        {"fieldinfo", (PyCFunction) sourceFieldInfo, METH_O,
4287                        sourceFieldInfo__doc__},
4288        {"listinfo", (PyCFunction) sourceListInfo, METH_NOARGS,
4289                        sourceListInfo__doc__},
4290        {NULL, NULL}
4291};
4292
4293/* gets source object attributes */
4294static PyObject *
4295sourceGetAttr(sourceObject *self, PyObject *nameobj)
4296{
4297        const char *name = PyStr_AsString(nameobj);
4298
4299        /* pg connection object */
4300        if (!strcmp(name, "pgcnx"))
4301        {
4302                if (check_source_obj(self, 0))
4303                {
4304                        Py_INCREF(self->pgcnx);
4305                        return (PyObject *) (self->pgcnx);
4306                }
4307                Py_INCREF(Py_None);
4308                return Py_None;
4309        }
4310
4311        /* arraysize */
4312        if (!strcmp(name, "arraysize"))
4313                return PyInt_FromLong(self->arraysize);
4314
4315        /* resulttype */
4316        if (!strcmp(name, "resulttype"))
4317                return PyInt_FromLong(self->result_type);
4318
4319        /* ntuples */
4320        if (!strcmp(name, "ntuples"))
4321                return PyInt_FromLong(self->max_row);
4322
4323        /* nfields */
4324        if (!strcmp(name, "nfields"))
4325                return PyInt_FromLong(self->num_fields);
4326
4327        /* seeks name in methods (fallback) */
4328        return PyObject_GenericGetAttr((PyObject *) self, nameobj);
4329}
4330
4331/* sets query object attributes */
4332static int
4333sourceSetAttr(sourceObject *self, char *name, PyObject *v)
4334{
4335        /* arraysize */
4336        if (!strcmp(name, "arraysize"))
4337        {
4338                if (!PyInt_Check(v))
4339                {
4340                        PyErr_SetString(PyExc_TypeError, "arraysize must be integer");
4341                        return -1;
4342                }
4343
4344                self->arraysize = PyInt_AsLong(v);
4345                return 0;
4346        }
4347
4348        /* unknown attribute */
4349        PyErr_SetString(PyExc_TypeError, "Not a writable attribute");
4350        return -1;
4351}
4352
4353/* return source object as string in human readable form */
4354static PyObject *
4355sourceStr(sourceObject *self)
4356{
4357        switch (self->result_type)
4358        {
4359                case RESULT_DQL:
4360                        return format_result(self->result);
4361                case RESULT_DDL:
4362                case RESULT_DML:
4363                        return PyStr_FromString(PQcmdStatus(self->result));
4364                case RESULT_EMPTY:
4365                default:
4366                        return PyStr_FromString("(empty PostgreSQL source object)");
4367        }
4368}
4369
4370static char source__doc__[] = "PyGreSQL source object";
4371
4372/* source type definition */
4373static PyTypeObject sourceType = {
4374        PyVarObject_HEAD_INIT(NULL, 0)
4375        "pgdb.Source",                                  /* tp_name */
4376        sizeof(sourceObject),                   /* tp_basicsize */
4377        0,                                                              /* tp_itemsize */
4378        /* methods */
4379        (destructor) sourceDealloc,             /* tp_dealloc */
4380        0,                                                              /* tp_print */
4381        0,                                                              /* tp_getattr */
4382        (setattrfunc) sourceSetAttr,    /* tp_setattr */
4383        0,                                                              /* tp_compare */
4384        0,                                                              /* tp_repr */
4385        0,                                                              /* tp_as_number */
4386        0,                                                              /* tp_as_sequence */
4387        0,                                                              /* tp_as_mapping */
4388        0,                                                              /* tp_hash */
4389        0,                                                              /* tp_call */
4390        (reprfunc) sourceStr,                   /* tp_str */
4391        (getattrofunc) sourceGetAttr,   /* tp_getattro */
4392        0,                                                              /* tp_setattro */
4393        0,                                                              /* tp_as_buffer */
4394        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
4395        source__doc__,                                  /* tp_doc */
4396        0,                                                              /* tp_traverse */
4397        0,                                                              /* tp_clear */
4398        0,                                                              /* tp_richcompare */
4399        0,                                                              /* tp_weaklistoffset */
4400        0,                                                              /* tp_iter */
4401        0,                                                              /* tp_iternext */
4402        sourceMethods,                                  /* tp_methods */
4403};
4404
4405/* connects to a database */
4406static char pgConnect__doc__[] =
4407"connect(dbname, host, port, opt) -- connect to a PostgreSQL database\n\n"
4408"The connection uses the specified parameters (optional, keywords aware).\n";
4409
4410static PyObject *
4411pgConnect(PyObject *self, PyObject *args, PyObject *dict)
4412{
4413        static const char *kwlist[] = {"dbname", "host", "port", "opt",
4414        "user", "passwd", NULL};
4415
4416        char       *pghost,
4417                           *pgopt,
4418                           *pgdbname,
4419                           *pguser,
4420                           *pgpasswd;
4421        int                     pgport;
4422        char            port_buffer[20];
4423        connObject *npgobj;
4424
4425        pghost = pgopt = pgdbname = pguser = pgpasswd = NULL;
4426        pgport = -1;
4427
4428        /*
4429         * parses standard arguments With the right compiler warnings, this
4430         * will issue a diagnostic. There is really no way around it.  If I
4431         * don't declare kwlist as const char *kwlist[] then it complains when
4432         * I try to assign all those constant strings to it.
4433         */
4434        if (!PyArg_ParseTupleAndKeywords(args, dict, "|zzizzz", (char **) kwlist,
4435                &pgdbname, &pghost, &pgport, &pgopt, &pguser, &pgpasswd))
4436                return NULL;
4437
4438#ifdef DEFAULT_VARS
4439        /* handles defaults variables (for uninitialised vars) */
4440        if ((!pghost) && (pg_default_host != Py_None))
4441                pghost = PyBytes_AsString(pg_default_host);
4442
4443        if ((pgport == -1) && (pg_default_port != Py_None))
4444                pgport = PyInt_AsLong(pg_default_port);
4445
4446        if ((!pgopt) && (pg_default_opt != Py_None))
4447                pgopt = PyBytes_AsString(pg_default_opt);
4448
4449        if ((!pgdbname) && (pg_default_base != Py_None))
4450                pgdbname = PyBytes_AsString(pg_default_base);
4451
4452        if ((!pguser) && (pg_default_user != Py_None))
4453                pguser = PyBytes_AsString(pg_default_user);
4454
4455        if ((!pgpasswd) && (pg_default_passwd != Py_None))
4456                pgpasswd = PyBytes_AsString(pg_default_passwd);
4457#endif /* DEFAULT_VARS */
4458
4459        if (!(npgobj = PyObject_NEW(connObject, &connType)))
4460        {
4461                set_error_msg(InternalError, "Can't create new connection object");
4462                return NULL;
4463        }
4464
4465        npgobj->valid = 1;
4466        npgobj->cnx = NULL;
4467        npgobj->date_format = date_format;
4468        npgobj->cast_hook = NULL;
4469        npgobj->notice_receiver = NULL;
4470
4471        if (pgport != -1)
4472        {
4473                memset(port_buffer, 0, sizeof(port_buffer));
4474                sprintf(port_buffer, "%d", pgport);
4475        }
4476
4477        Py_BEGIN_ALLOW_THREADS
4478        npgobj->cnx = PQsetdbLogin(pghost, pgport == -1 ? NULL : port_buffer,
4479                pgopt, NULL, pgdbname, pguser, pgpasswd);
4480        Py_END_ALLOW_THREADS
4481
4482        if (PQstatus(npgobj->cnx) == CONNECTION_BAD)
4483        {
4484                set_error(InternalError, "Cannot connect", npgobj->cnx, NULL);
4485                Py_XDECREF(npgobj);
4486                return NULL;
4487        }
4488
4489        return (PyObject *) npgobj;
4490}
4491
4492static void
4493queryDealloc(queryObject *self)
4494{
4495        Py_XDECREF(self->pgcnx);
4496        if (self->result)
4497                PQclear(self->result);
4498
4499        PyObject_Del(self);
4500}
4501
4502/* get number of rows */
4503static char queryNTuples__doc__[] =
4504"ntuples() -- return number of tuples returned by query";
4505
4506static PyObject *
4507queryNTuples(queryObject *self, PyObject *noargs)
4508{
4509        return PyInt_FromLong((long) PQntuples(self->result));
4510}
4511
4512/* list fields names from query result */
4513static char queryListFields__doc__[] =
4514"listfields() -- List field names from result";
4515
4516static PyObject *
4517queryListFields(queryObject *self, PyObject *noargs)
4518{
4519        int                     i,
4520                                n;
4521        char       *name;
4522        PyObject   *fieldstuple,
4523                           *str;
4524
4525        /* builds tuple */
4526        n = PQnfields(self->result);
4527        fieldstuple = PyTuple_New(n);
4528
4529        for (i = 0; i < n; ++i)
4530        {
4531                name = PQfname(self->result, i);
4532                str = PyStr_FromString(name);
4533                PyTuple_SET_ITEM(fieldstuple, i, str);
4534        }
4535
4536        return fieldstuple;
4537}
4538
4539/* get field name from last result */
4540static char queryFieldName__doc__[] =
4541"fieldname(num) -- return name of field from result from its position";
4542
4543static PyObject *
4544queryFieldName(queryObject *self, PyObject *args)
4545{
4546        int             i;
4547        char   *name;
4548
4549        /* gets args */
4550        if (!PyArg_ParseTuple(args, "i", &i))
4551        {
4552                PyErr_SetString(PyExc_TypeError,
4553                        "Method fieldname() takes an integer as argument");
4554                return NULL;
4555        }
4556
4557        /* checks number validity */
4558        if (i >= PQnfields(self->result))
4559        {
4560                PyErr_SetString(PyExc_ValueError, "Invalid field number");
4561                return NULL;
4562        }
4563
4564        /* gets fields name and builds object */
4565        name = PQfname(self->result, i);
4566        return PyStr_FromString(name);
4567}
4568
4569/* gets fields number from name in last result */
4570static char queryFieldNumber__doc__[] =
4571"fieldnum(name) -- return position in query for field from its name";
4572
4573static PyObject *
4574queryFieldNumber(queryObject *self, PyObject *args)
4575{
4576        int             num;
4577        char   *name;
4578
4579        /* gets args */
4580        if (!PyArg_ParseTuple(args, "s", &name))
4581        {
4582                PyErr_SetString(PyExc_TypeError,
4583                        "Method fieldnum() takes a string as argument");
4584                return NULL;
4585        }
4586
4587        /* gets field number */
4588        if ((num = PQfnumber(self->result, name)) == -1)
4589        {
4590                PyErr_SetString(PyExc_ValueError, "Unknown field");
4591                return NULL;
4592        }
4593
4594        return PyInt_FromLong(num);
4595}
4596
4597/* retrieves last result */
4598static char queryGetResult__doc__[] =
4599"getresult() -- Get the result of a query\n\n"
4600"The result is returned as a list of rows, each one a tuple of fields\n"
4601"in the order returned by the server.\n";
4602
4603static PyObject *
4604queryGetResult(queryObject *self, PyObject *noargs)
4605{
4606        PyObject   *reslist;
4607        int                     i, m, n, *col_types;
4608        int                     encoding = self->encoding;
4609
4610        /* stores result in tuple */
4611        m = PQntuples(self->result);
4612        n = PQnfields(self->result);
4613        if (!(reslist = PyList_New(m))) return NULL;
4614
4615        if (!(col_types = get_col_types(self->result, n))) return NULL;
4616
4617        for (i = 0; i < m; ++i)
4618        {
4619                PyObject   *rowtuple;
4620                int                     j;
4621
4622                if (!(rowtuple = PyTuple_New(n)))
4623                {
4624                        Py_DECREF(reslist);
4625                        reslist = NULL;
4626                        goto exit;
4627                }
4628
4629                for (j = 0; j < n; ++j)
4630                {
4631                        PyObject * val;
4632
4633                        if (PQgetisnull(self->result, i, j))
4634                        {
4635                                Py_INCREF(Py_None);
4636                                val = Py_None;
4637                        }
4638                        else /* not null */
4639                        {
4640                                /* get the string representation of the value */
4641                                /* note: this is always null-terminated text format */
4642                                char   *s = PQgetvalue(self->result, i, j);
4643                                /* get the PyGreSQL type of the column */
4644                                int             type = col_types[j];
4645
4646                                if (type & PYGRES_ARRAY)
4647                                        val = cast_array(s, PQgetlength(self->result, i, j),
4648                                                encoding, type, NULL, 0);
4649                                else if (type == PYGRES_BYTEA)
4650                                        val = cast_bytea_text(s);
4651                                else if (type == PYGRES_OTHER)
4652                                        val = cast_other(s,
4653                                                PQgetlength(self->result, i, j), encoding,
4654                                                PQftype(self->result, j), self->pgcnx->cast_hook);
4655                                else if (type & PYGRES_TEXT)
4656                                        val = cast_sized_text(s, PQgetlength(self->result, i, j),
4657                                                encoding, type);
4658                                else
4659                                        val = cast_unsized_simple(s, type);
4660                        }
4661
4662                        if (!val)
4663                        {
4664                                Py_DECREF(reslist);
4665                                Py_DECREF(rowtuple);
4666                                reslist = NULL;
4667                                goto exit;
4668                        }
4669
4670                        PyTuple_SET_ITEM(rowtuple, j, val);
4671                }
4672
4673                PyList_SET_ITEM(reslist, i, rowtuple);
4674        }
4675
4676exit:
4677        PyMem_Free(col_types);
4678
4679        /* returns list */
4680        return reslist;
4681}
4682
4683/* retrieves last result as a list of dictionaries*/
4684static char queryDictResult__doc__[] =
4685"dictresult() -- Get the result of a query\n\n"
4686"The result is returned as a list of rows, each one a dictionary with\n"
4687"the field names used as the labels.\n";
4688
4689static PyObject *
4690queryDictResult(queryObject *self, PyObject *noargs)
4691{
4692        PyObject   *reslist;
4693        int                     i,
4694                                m,
4695                                n,
4696                           *col_types;
4697        int                     encoding = self->encoding;
4698
4699        /* stores result in list */
4700        m = PQntuples(self->result);
4701        n = PQnfields(self->result);
4702        if (!(reslist = PyList_New(m))) return NULL;
4703
4704        if (!(col_types = get_col_types(self->result, n))) return NULL;
4705
4706        for (i = 0; i < m; ++i)
4707        {
4708                PyObject   *dict;
4709                int                     j;
4710
4711                if (!(dict = PyDict_New()))
4712                {
4713                        Py_DECREF(reslist);
4714                        reslist = NULL;
4715                        goto exit;
4716                }
4717
4718                for (j = 0; j < n; ++j)
4719                {
4720                        PyObject * val;
4721
4722                        if (PQgetisnull(self->result, i, j))
4723                        {
4724                                Py_INCREF(Py_None);
4725                                val = Py_None;
4726                        }
4727                        else /* not null */
4728                        {
4729                                /* get the string representation of the value */
4730                                /* note: this is always null-terminated text format */
4731                                char   *s = PQgetvalue(self->result, i, j);
4732                                /* get the PyGreSQL type of the column */
4733                                int             type = col_types[j];
4734
4735                                if (type & PYGRES_ARRAY)
4736                                        val = cast_array(s, PQgetlength(self->result, i, j),
4737                                                encoding, type, NULL, 0);
4738                                else if (type == PYGRES_BYTEA)
4739                                        val = cast_bytea_text(s);
4740                                else if (type == PYGRES_OTHER)
4741                                        val = cast_other(s,
4742                                                PQgetlength(self->result, i, j), encoding,
4743                                                PQftype(self->result, j), self->pgcnx->cast_hook);
4744                                else if (type & PYGRES_TEXT)
4745                                        val = cast_sized_text(s, PQgetlength(self->result, i, j),
4746                                                encoding, type);
4747                                else
4748                                        val = cast_unsized_simple(s, type);
4749                        }
4750
4751                        if (!val)
4752                        {
4753                                Py_DECREF(dict);
4754                                Py_DECREF(reslist);
4755                                reslist = NULL;
4756                                goto exit;
4757                        }
4758
4759                        PyDict_SetItemString(dict, PQfname(self->result, j), val);
4760                        Py_DECREF(val);
4761                }
4762
4763                PyList_SET_ITEM(reslist, i, dict);
4764        }
4765
4766exit:
4767        PyMem_Free(col_types);
4768
4769        /* returns list */
4770        return reslist;
4771}
4772
4773/* retrieves last result as named tuples */
4774static char queryNamedResult__doc__[] =
4775"namedresult() -- Get the result of a query\n\n"
4776"The result is returned as a list of rows, each one a tuple of fields\n"
4777"in the order returned by the server.\n";
4778
4779static PyObject *
4780queryNamedResult(queryObject *self, PyObject *noargs)
4781{
4782        PyObject   *ret;
4783
4784        if (namedresult)
4785        {
4786                ret = PyObject_CallFunction(namedresult, "(O)", self);
4787
4788                if (ret == NULL)
4789                        return NULL;
4790                }
4791        else
4792        {
4793                ret = queryGetResult(self, NULL);
4794        }
4795
4796        return ret;
4797}
4798
4799/* gets notice object attributes */
4800static PyObject *
4801noticeGetAttr(noticeObject *self, PyObject *nameobj)
4802{
4803        PGresult const *res = self->res;
4804        const char *name = PyStr_AsString(nameobj);
4805        int fieldcode;
4806
4807        if (!res)
4808        {
4809                PyErr_SetString(PyExc_TypeError, "Cannot get current notice");
4810                return NULL;
4811        }
4812
4813        /* pg connection object */
4814        if (!strcmp(name, "pgcnx"))
4815        {
4816                if (self->pgcnx && check_cnx_obj(self->pgcnx))
4817                {
4818                        Py_INCREF(self->pgcnx);
4819                        return (PyObject *) self->pgcnx;
4820                }
4821                else
4822                {
4823                        Py_INCREF(Py_None);
4824                        return Py_None;
4825                }
4826        }
4827
4828        /* full message */
4829        if (!strcmp(name, "message"))
4830                return PyStr_FromString(PQresultErrorMessage(res));
4831
4832        /* other possible fields */
4833        fieldcode = 0;
4834        if (!strcmp(name, "severity"))
4835                fieldcode = PG_DIAG_SEVERITY;
4836        else if (!strcmp(name, "primary"))
4837                fieldcode = PG_DIAG_MESSAGE_PRIMARY;
4838        else if (!strcmp(name, "detail"))
4839                fieldcode = PG_DIAG_MESSAGE_DETAIL;
4840        else if (!strcmp(name, "hint"))
4841                fieldcode = PG_DIAG_MESSAGE_HINT;
4842        if (fieldcode)
4843        {
4844                char *s = PQresultErrorField(res, fieldcode);
4845                if (s)
4846                        return PyStr_FromString(s);
4847                else
4848                {
4849                        Py_INCREF(Py_None); return Py_None;
4850                }
4851        }
4852
4853        return PyObject_GenericGetAttr((PyObject *) self, nameobj);
4854}
4855
4856/* return notice as string in human readable form */
4857static PyObject *
4858noticeStr(noticeObject *self)
4859{
4860        return noticeGetAttr(self, PyBytes_FromString("message"));
4861}
4862
4863/* get the list of notice attributes */
4864static PyObject *
4865noticeDir(noticeObject *self, PyObject *noargs)
4866{
4867        PyObject *attrs;
4868
4869        attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
4870        PyObject_CallMethod(attrs, "extend", "[ssssss]",
4871                "pgcnx", "severity", "message", "primary", "detail", "hint");
4872
4873        return attrs;
4874}
4875
4876/* notice object methods */
4877static struct PyMethodDef noticeMethods[] = {
4878        {"__dir__", (PyCFunction) noticeDir,  METH_NOARGS, NULL},
4879        {NULL, NULL}
4880};
4881
4882/* notice type definition */
4883static PyTypeObject noticeType = {
4884        PyVarObject_HEAD_INIT(NULL, 0)
4885        "pg.Notice",                                    /* tp_name */
4886        sizeof(noticeObject),                   /* tp_basicsize */
4887        0,                                                              /* tp_itemsize */
4888        /* methods */
4889        0,                                                              /* tp_dealloc */
4890        0,                                                              /* tp_print */
4891        0,                                                              /* tp_getattr */
4892        0,                                                              /* tp_setattr */
4893        0,                                                              /* tp_compare */
4894        0,                                                              /* tp_repr */
4895        0,                                                              /* tp_as_number */
4896        0,                                                              /* tp_as_sequence */
4897        0,                                                              /* tp_as_mapping */
4898        0,                                                              /* tp_hash */
4899        0,                                                              /* tp_call */
4900        (reprfunc) noticeStr,                   /* tp_str */
4901        (getattrofunc) noticeGetAttr,   /* tp_getattro */
4902        PyObject_GenericSetAttr,                /* tp_setattro */
4903        0,                                                              /* tp_as_buffer */
4904        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
4905        0,                                                              /* tp_doc */
4906        0,                                                              /* tp_traverse */
4907        0,                                                              /* tp_clear */
4908        0,                                                              /* tp_richcompare */
4909        0,                                                              /* tp_weaklistoffset */
4910        0,                                                              /* tp_iter */
4911        0,                                                              /* tp_iternext */
4912        noticeMethods,                                  /* tp_methods */
4913};
4914
4915/* query object methods */
4916static struct PyMethodDef queryMethods[] = {
4917        {"getresult", (PyCFunction) queryGetResult, METH_NOARGS,
4918                        queryGetResult__doc__},
4919        {"dictresult", (PyCFunction) queryDictResult, METH_NOARGS,
4920                        queryDictResult__doc__},
4921        {"namedresult", (PyCFunction) queryNamedResult, METH_NOARGS,
4922                        queryNamedResult__doc__},
4923        {"fieldname", (PyCFunction) queryFieldName, METH_VARARGS,
4924                         queryFieldName__doc__},
4925        {"fieldnum", (PyCFunction) queryFieldNumber, METH_VARARGS,
4926                        queryFieldNumber__doc__},
4927        {"listfields", (PyCFunction) queryListFields, METH_NOARGS,
4928                        queryListFields__doc__},
4929        {"ntuples", (PyCFunction) queryNTuples, METH_NOARGS,
4930                        queryNTuples__doc__},
4931        {NULL, NULL}
4932};
4933
4934/* query type definition */
4935static PyTypeObject queryType = {
4936        PyVarObject_HEAD_INIT(NULL, 0)
4937        "pg.Query",                                             /* tp_name */
4938        sizeof(queryObject),                    /* tp_basicsize */
4939        0,                                                              /* tp_itemsize */
4940        /* methods */
4941        (destructor) queryDealloc,              /* tp_dealloc */
4942        0,                                                              /* tp_print */
4943        0,                                                              /* tp_getattr */
4944        0,                                                              /* tp_setattr */
4945        0,                                                              /* tp_compare */
4946        0,                                                              /* tp_repr */
4947        0,                                                              /* tp_as_number */
4948        0,                                                              /* tp_as_sequence */
4949        0,                                                              /* tp_as_mapping */
4950        0,                                                              /* tp_hash */
4951        0,                                                              /* tp_call */
4952        (reprfunc) queryStr,                    /* tp_str */
4953        PyObject_GenericGetAttr,                /* tp_getattro */
4954        0,                                                              /* tp_setattro */
4955        0,                                                              /* tp_as_buffer */
4956        Py_TPFLAGS_DEFAULT,                             /* tp_flags */
4957        0,                                                              /* tp_doc */
4958        0,                                                              /* tp_traverse */
4959        0,                                                              /* tp_clear */
4960        0,                                                              /* tp_richcompare */
4961        0,                                                              /* tp_weaklistoffset */
4962        0,                                                              /* tp_iter */
4963        0,                                                              /* tp_iternext */
4964        queryMethods,                                   /* tp_methods */
4965};
4966
4967/* --------------------------------------------------------------------- */
4968
4969/* MODULE FUNCTIONS */
4970
4971/* escape string */
4972static char pgEscapeString__doc__[] =
4973"escape_string(string) -- escape a string for use within SQL";
4974
4975static PyObject *
4976pgEscapeString(PyObject *self, PyObject *string)
4977{
4978        PyObject   *tmp_obj = NULL, /* auxiliary string object */
4979                           *to_obj; /* string object to return */
4980        char       *from, /* our string argument as encoded string */
4981                           *to; /* the result as encoded string */
4982        Py_ssize_t      from_length; /* length of string */
4983        size_t          to_length; /* length of result */
4984        int                     encoding = -1; /* client encoding */
4985
4986        if (PyBytes_Check(string))
4987        {
4988                PyBytes_AsStringAndSize(string, &from, &from_length);
4989        }
4990        else if (PyUnicode_Check(string))
4991        {
4992                encoding = pg_encoding_ascii;
4993                tmp_obj = get_encoded_string(string, encoding);
4994                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
4995                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
4996        }
4997        else
4998        {
4999                PyErr_SetString(PyExc_TypeError,
5000                        "Method escape_string() expects a string as argument");
5001                return NULL;
5002        }
5003
5004        to_length = 2*from_length + 1;
5005        if ((Py_ssize_t)to_length < from_length) /* overflow */
5006        {
5007                to_length = from_length;
5008                from_length = (from_length - 1)/2;
5009        }
5010        to = (char *)PyMem_Malloc(to_length);
5011        to_length = (int)PQescapeString(to, from, (size_t)from_length);
5012
5013        Py_XDECREF(tmp_obj);
5014
5015        if (encoding == -1)
5016                to_obj = PyBytes_FromStringAndSize(to, to_length);
5017        else
5018                to_obj = get_decoded_string(to, to_length, encoding);
5019        PyMem_Free(to);
5020        return to_obj;
5021}
5022
5023/* escape bytea */
5024static char pgEscapeBytea__doc__[] =
5025"escape_bytea(data) -- escape binary data for use within SQL as type bytea";
5026
5027static PyObject *
5028pgEscapeBytea(PyObject *self, PyObject *data)
5029{
5030        PyObject   *tmp_obj = NULL, /* auxiliary string object */
5031                           *to_obj; /* string object to return */
5032        char       *from, /* our string argument as encoded string */
5033                           *to; /* the result as encoded string */
5034        Py_ssize_t      from_length; /* length of string */
5035        size_t          to_length; /* length of result */
5036        int                     encoding = -1; /* client encoding */
5037
5038        if (PyBytes_Check(data))
5039        {
5040                PyBytes_AsStringAndSize(data, &from, &from_length);
5041        }
5042        else if (PyUnicode_Check(data))
5043        {
5044                encoding = pg_encoding_ascii;
5045                tmp_obj = get_encoded_string(data, encoding);
5046                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
5047                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
5048        }
5049        else
5050        {
5051                PyErr_SetString(PyExc_TypeError,
5052                        "Method escape_bytea() expects a string as argument");
5053                return NULL;
5054        }
5055
5056        to = (char *)PQescapeBytea(
5057                (unsigned char*)from, (size_t)from_length, &to_length);
5058
5059        Py_XDECREF(tmp_obj);
5060
5061        if (encoding == -1)
5062                to_obj = PyBytes_FromStringAndSize(to, to_length - 1);
5063        else
5064                to_obj = get_decoded_string(to, to_length - 1, encoding);
5065        if (to)
5066                PQfreemem(to);
5067        return to_obj;
5068}
5069
5070/* unescape bytea */
5071static char pgUnescapeBytea__doc__[] =
5072"unescape_bytea(string) -- unescape bytea data retrieved as text";
5073
5074static PyObject *
5075pgUnescapeBytea(PyObject *self, PyObject *data)
5076{
5077        PyObject   *tmp_obj = NULL, /* auxiliary string object */
5078                           *to_obj; /* string object to return */
5079        char       *from, /* our string argument as encoded string */
5080                           *to; /* the result as encoded string */
5081        Py_ssize_t      from_length; /* length of string */
5082        size_t          to_length; /* length of result */
5083
5084        if (PyBytes_Check(data))
5085        {
5086                PyBytes_AsStringAndSize(data, &from, &from_length);
5087        }
5088        else if (PyUnicode_Check(data))
5089        {
5090                tmp_obj = get_encoded_string(data, pg_encoding_ascii);
5091                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
5092                PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
5093        }
5094        else
5095        {
5096                PyErr_SetString(PyExc_TypeError,
5097                        "Method unescape_bytea() expects a string as argument");
5098                return NULL;
5099        }
5100
5101        to = (char *)PQunescapeBytea((unsigned char*)from, &to_length);
5102
5103        Py_XDECREF(tmp_obj);
5104
5105        if (!to) return PyErr_NoMemory();
5106
5107        to_obj = PyBytes_FromStringAndSize(to, to_length);
5108        PQfreemem(to);
5109
5110        return to_obj;
5111}
5112
5113/* set fixed datestyle */
5114static char pgSetDatestyle__doc__[] =
5115"set_datestyle(style) -- set which style is assumed";
5116
5117static PyObject *
5118pgSetDatestyle(PyObject *self, PyObject *args)
5119{
5120        const char         *datestyle = NULL;
5121
5122        /* gets arguments */
5123        if (!PyArg_ParseTuple(args, "z", &datestyle))
5124        {
5125                PyErr_SetString(PyExc_TypeError,
5126                        "Function set_datestyle() expects a string or None as argument");
5127                return NULL;
5128        }
5129
5130        date_format = datestyle ? date_style_to_format(datestyle) : NULL;
5131
5132        Py_INCREF(Py_None); return Py_None;
5133}
5134
5135/* get fixed datestyle */
5136static char pgGetDatestyle__doc__[] =
5137"get_datestyle() -- get which date style is assumed";
5138
5139static PyObject *
5140pgGetDatestyle(PyObject *self, PyObject *noargs)
5141{
5142        if (date_format)
5143        {
5144                return PyStr_FromString(date_format_to_style(date_format));
5145        }
5146        else
5147        {
5148                Py_INCREF(Py_None); return Py_None;
5149        }
5150}
5151
5152/* get decimal point */
5153static char pgGetDecimalPoint__doc__[] =
5154"get_decimal_point() -- get decimal point to be used for money values";
5155
5156static PyObject *
5157pgGetDecimalPoint(PyObject *self, PyObject *noargs)
5158{
5159        PyObject *ret;
5160        char s[2];
5161
5162        if (decimal_point)
5163        {
5164                s[0] = decimal_point; s[1] = '\0';
5165                ret = PyStr_FromString(s);
5166        }
5167        else
5168        {
5169                Py_INCREF(Py_None); ret = Py_None;
5170        }
5171
5172        return ret;
5173}
5174
5175/* set decimal point */
5176static char pgSetDecimalPoint__doc__[] =
5177"set_decimal_point(char) -- set decimal point to be used for money values";
5178
5179static PyObject *
5180pgSetDecimalPoint(PyObject *self, PyObject *args)
5181{
5182        PyObject *ret = NULL;
5183        char *s = NULL;
5184
5185        /* gets arguments */
5186        if (PyArg_ParseTuple(args, "z", &s))
5187        {
5188                if (!s)
5189                        s = "\0";
5190                else if (*s && (*(s+1) || !strchr(".,;: '*/_`|", *s)))
5191                        s = NULL;
5192        }
5193
5194        if (s)
5195        {
5196                decimal_point = *s;
5197                Py_INCREF(Py_None); ret = Py_None;
5198        }
5199        else
5200                PyErr_SetString(PyExc_TypeError,
5201                        "Function set_decimal_mark() expects"
5202                        " a decimal mark character as argument");
5203
5204        return ret;
5205}
5206
5207/* get decimal type */
5208static char pgGetDecimal__doc__[] =
5209"get_decimal() -- get the decimal type to be used for numeric values";
5210
5211static PyObject *
5212pgGetDecimal(PyObject *self, PyObject *noargs)
5213{
5214        PyObject *ret;
5215
5216        ret = decimal ? decimal : Py_None;
5217        Py_INCREF(ret);
5218
5219        return ret;
5220}
5221
5222/* set decimal type */
5223static char pgSetDecimal__doc__[] =
5224"set_decimal(cls) -- set a decimal type to be used for numeric values";
5225
5226static PyObject *
5227pgSetDecimal(PyObject *self, PyObject *cls)
5228{
5229        PyObject *ret = NULL;
5230
5231        if (cls == Py_None)
5232        {
5233                Py_XDECREF(decimal); decimal = NULL;
5234                Py_INCREF(Py_None); ret = Py_None;
5235        }
5236        else if (PyCallable_Check(cls))
5237        {
5238                Py_XINCREF(cls); Py_XDECREF(decimal); decimal = cls;
5239                Py_INCREF(Py_None); ret = Py_None;
5240        }
5241        else
5242                PyErr_SetString(PyExc_TypeError,
5243                        "Function set_decimal() expects"
5244                         " a callable or None as argument");
5245
5246        return ret;
5247}
5248
5249/* get usage of bool values */
5250static char pgGetBool__doc__[] =
5251"get_bool() -- check whether boolean values are converted to bool";
5252
5253static PyObject *
5254pgGetBool(PyObject *self, PyObject *noargs)
5255{
5256        PyObject *ret;
5257
5258        ret = bool_as_text ? Py_False : Py_True;
5259        Py_INCREF(ret);
5260
5261        return ret;
5262}
5263
5264/* set usage of bool values */
5265static char pgSetBool__doc__[] =
5266"set_bool(on) -- set whether boolean values should be converted to bool";
5267
5268static PyObject *
5269pgSetBool(PyObject *self, PyObject *args)
5270{
5271        PyObject *ret = NULL;
5272        int                     i;
5273
5274        /* gets arguments */
5275        if (PyArg_ParseTuple(args, "i", &i))
5276        {
5277                bool_as_text = i ? 0 : 1;
5278                Py_INCREF(Py_None); ret = Py_None;
5279        }
5280        else
5281                PyErr_SetString(PyExc_TypeError,
5282                        "Function set_bool() expects a boolean value as argument");
5283
5284        return ret;
5285}
5286
5287/* get conversion of arrays to lists */
5288static char pgGetArray__doc__[] =
5289"get_array() -- check whether arrays are converted as lists";
5290
5291static PyObject *
5292pgGetArray(PyObject *self, PyObject *noargs)
5293{
5294        PyObject *ret;
5295
5296        ret = array_as_text ? Py_False : Py_True;
5297        Py_INCREF(ret);
5298
5299        return ret;
5300}
5301
5302/* set conversion of arrays to lists */
5303static char pgSetArray__doc__[] =
5304"set_array(on) -- set whether arrays should be converted to lists";
5305
5306static PyObject *
5307pgSetArray(PyObject *self, PyObject *args)
5308{
5309        PyObject *ret = NULL;
5310        int                     i;
5311
5312        /* gets arguments */
5313        if (PyArg_ParseTuple(args, "i", &i))
5314        {
5315                array_as_text = i ? 0 : 1;
5316                Py_INCREF(Py_None); ret = Py_None;
5317        }
5318        else
5319                PyErr_SetString(PyExc_TypeError,
5320                        "Function set_array() expects a boolean value as argument");
5321
5322        return ret;
5323}
5324
5325/* check whether bytea values are unescaped */
5326static char pgGetByteaEscaped__doc__[] =
5327"get_bytea_escaped() -- check whether bytea will be returned escaped";
5328
5329static PyObject *
5330pgGetByteaEscaped(PyObject *self, PyObject *noargs)
5331{
5332        PyObject *ret;
5333
5334        ret = bytea_escaped ? Py_True : Py_False;
5335        Py_INCREF(ret);
5336
5337        return ret;
5338}
5339
5340/* set usage of bool values */
5341static char pgSetByteaEscaped__doc__[] =
5342"set_bytea_escaped(on) -- set whether bytea will be returned escaped";
5343
5344static PyObject *
5345pgSetByteaEscaped(PyObject *self, PyObject *args)
5346{
5347        PyObject *ret = NULL;
5348        int                     i;
5349
5350        /* gets arguments */
5351        if (PyArg_ParseTuple(args, "i", &i))
5352        {
5353                bytea_escaped = i ? 1 : 0;
5354                Py_INCREF(Py_None); ret = Py_None;
5355        }
5356        else
5357                PyErr_SetString(PyExc_TypeError,
5358                        "Function set_bytea_escaped() expects a boolean value as argument");
5359
5360        return ret;
5361}
5362
5363/* get named result factory */
5364static char pgGetNamedresult__doc__[] =
5365"get_namedresult() -- get the function used for getting named results";
5366
5367static PyObject *
5368pgGetNamedresult(PyObject *self, PyObject *noargs)
5369{
5370        PyObject *ret;
5371
5372        ret = namedresult ? namedresult : Py_None;
5373        Py_INCREF(ret);
5374
5375        return ret;
5376}
5377
5378/* set named result factory */
5379static char pgSetNamedresult__doc__[] =
5380"set_namedresult(func) -- set a function to be used for getting named results";
5381
5382static PyObject *
5383pgSetNamedresult(PyObject *self, PyObject *func)
5384{
5385        PyObject *ret = NULL;
5386
5387        if (func == Py_None)
5388        {
5389                Py_XDECREF(namedresult); namedresult = NULL;
5390                Py_INCREF(Py_None); ret = Py_None;
5391        }
5392        else if (PyCallable_Check(func))
5393        {
5394                Py_XINCREF(func); Py_XDECREF(namedresult); namedresult = func;
5395                Py_INCREF(Py_None); ret = Py_None;
5396        }
5397        else
5398                PyErr_SetString(PyExc_TypeError,
5399                        "Function set_namedresult() expects"
5400                         " a callable or None as argument");
5401
5402        return ret;
5403}
5404
5405/* get json decode function */
5406static char pgGetJsondecode__doc__[] =
5407"get_jsondecode() -- get the function used for decoding json results";
5408
5409static PyObject *
5410pgGetJsondecode(PyObject *self, PyObject *noargs)
5411{
5412        PyObject *ret;
5413
5414        ret = jsondecode;
5415        if (!ret)
5416                ret = Py_None;
5417        Py_INCREF(ret);
5418
5419        return ret;
5420}
5421
5422/* set json decode function */
5423static char pgSetJsondecode__doc__[] =
5424"set_jsondecode(func) -- set a function to be used for decoding json results";
5425
5426static PyObject *
5427pgSetJsondecode(PyObject *self, PyObject *func)
5428{
5429        PyObject *ret = NULL;
5430
5431        if (func == Py_None)
5432        {
5433                Py_XDECREF(jsondecode); jsondecode = NULL;
5434                Py_INCREF(Py_None); ret = Py_None;
5435        }
5436        else if (PyCallable_Check(func))
5437        {
5438                Py_XINCREF(func); Py_XDECREF(jsondecode); jsondecode = func;
5439                Py_INCREF(Py_None); ret = Py_None;
5440        }
5441        else
5442                PyErr_SetString(PyExc_TypeError,
5443                        "Function jsondecode() expects"
5444                         " a callable or None as argument");
5445
5446        return ret;
5447}
5448
5449#ifdef DEFAULT_VARS
5450
5451/* gets default host */
5452static char pgGetDefHost__doc__[] =
5453"get_defhost() -- return default database host";
5454
5455static PyObject *
5456pgGetDefHost(PyObject *self, PyObject *noargs)
5457{
5458        Py_XINCREF(pg_default_host);
5459        return pg_default_host;
5460}
5461
5462/* sets default host */
5463static char pgSetDefHost__doc__[] =
5464"set_defhost(string) -- set default database host and return previous value";
5465
5466static PyObject *
5467pgSetDefHost(PyObject *self, PyObject *args)
5468{
5469        char       *temp = NULL;
5470        PyObject   *old;
5471
5472        /* gets arguments */
5473        if (!PyArg_ParseTuple(args, "z", &temp))
5474        {
5475                PyErr_SetString(PyExc_TypeError,
5476                        "Function set_defhost() expects a string or None as argument");
5477                return NULL;
5478        }
5479
5480        /* adjusts value */
5481        old = pg_default_host;
5482
5483        if (temp)
5484                pg_default_host = PyStr_FromString(temp);
5485        else
5486        {
5487                Py_INCREF(Py_None);
5488                pg_default_host = Py_None;
5489        }
5490
5491        return old;
5492}
5493
5494/* gets default base */
5495static char pgGetDefBase__doc__[] =
5496"get_defbase() -- return default database name";
5497
5498static PyObject *
5499pgGetDefBase(PyObject *self, PyObject *noargs)
5500{
5501        Py_XINCREF(pg_default_base);
5502        return pg_default_base;
5503}
5504
5505/* sets default base */
5506static char pgSetDefBase__doc__[] =
5507"set_defbase(string) -- set default database name and return previous value";
5508
5509static PyObject *
5510pgSetDefBase(PyObject *self, PyObject *args)
5511{
5512        char       *temp = NULL;
5513        PyObject   *old;
5514
5515        /* gets arguments */
5516        if (!PyArg_ParseTuple(args, "z", &temp))
5517        {
5518                PyErr_SetString(PyExc_TypeError,
5519                        "Function set_defbase() Argument a string or None as argument");
5520                return NULL;
5521        }
5522
5523        /* adjusts value */
5524        old = pg_default_base;
5525
5526        if (temp)
5527                pg_default_base = PyStr_FromString(temp);
5528        else
5529        {
5530                Py_INCREF(Py_None);
5531                pg_default_base = Py_None;
5532        }
5533
5534        return old;
5535}
5536
5537/* gets default options */
5538static char pgGetDefOpt__doc__[] =
5539"get_defopt() -- return default database options";
5540
5541static PyObject *
5542pgGetDefOpt(PyObject *self, PyObject *noargs)
5543{
5544        Py_XINCREF(pg_default_opt);
5545        return pg_default_opt;
5546}
5547
5548/* sets default opt */
5549static char pgSetDefOpt__doc__[] =
5550"set_defopt(string) -- set default options and return previous value";
5551
5552static PyObject *
5553pgSetDefOpt(PyObject *self, PyObject *args)
5554{
5555        char       *temp = NULL;
5556        PyObject   *old;
5557
5558        /* gets arguments */
5559        if (!PyArg_ParseTuple(args, "z", &temp))
5560        {
5561                PyErr_SetString(PyExc_TypeError,
5562                        "Function set_defopt() expects a string or None as argument");
5563                return NULL;
5564        }
5565
5566        /* adjusts value */
5567        old = pg_default_opt;
5568
5569        if (temp)
5570                pg_default_opt = PyStr_FromString(temp);
5571        else
5572        {
5573                Py_INCREF(Py_None);
5574                pg_default_opt = Py_None;
5575        }
5576
5577        return old;
5578}
5579
5580/* gets default username */
5581static char pgGetDefUser__doc__[] =
5582"get_defuser() -- return default database username";
5583
5584static PyObject *
5585pgGetDefUser(PyObject *self, PyObject *noargs)
5586{
5587        Py_XINCREF(pg_default_user);
5588        return pg_default_user;
5589}
5590
5591/* sets default username */
5592
5593static char pgSetDefUser__doc__[] =
5594"set_defuser(name) -- set default username and return previous value";
5595
5596static PyObject *
5597pgSetDefUser(PyObject *self, PyObject *args)
5598{
5599        char       *temp = NULL;
5600        PyObject   *old;
5601
5602        /* gets arguments */
5603        if (!PyArg_ParseTuple(args, "z", &temp))
5604        {
5605                PyErr_SetString(PyExc_TypeError,
5606                        "Function set_defuser() expects a string or None as argument");
5607                return NULL;
5608        }
5609
5610        /* adjusts value */
5611        old = pg_default_user;
5612
5613        if (temp)
5614                pg_default_user = PyStr_FromString(temp);
5615        else
5616        {
5617                Py_INCREF(Py_None);
5618                pg_default_user = Py_None;
5619        }
5620
5621        return old;
5622}
5623
5624/* sets default password */
5625static char pgSetDefPassword__doc__[] =
5626"set_defpasswd(password) -- set default database password";
5627
5628static PyObject *
5629pgSetDefPassword(PyObject *self, PyObject *args)
5630{
5631        char       *temp = NULL;
5632
5633        /* gets arguments */
5634        if (!PyArg_ParseTuple(args, "z", &temp))
5635        {
5636                PyErr_SetString(PyExc_TypeError,
5637                        "Function set_defpasswd() expects a string or None as argument");
5638                return NULL;
5639        }
5640
5641        if (temp)
5642                pg_default_passwd = PyStr_FromString(temp);
5643        else
5644        {
5645                Py_INCREF(Py_None);
5646                pg_default_passwd = Py_None;
5647        }
5648
5649        Py_INCREF(Py_None);
5650        return Py_None;
5651}
5652
5653/* gets default port */
5654static char pgGetDefPort__doc__[] =
5655"get_defport() -- return default database port";
5656
5657static PyObject *
5658pgGetDefPort(PyObject *self, PyObject *noargs)
5659{
5660        Py_XINCREF(pg_default_port);
5661        return pg_default_port;
5662}
5663
5664/* sets default port */
5665static char pgSetDefPort__doc__[] =
5666"set_defport(port) -- set default port and return previous value";
5667
5668static PyObject *
5669pgSetDefPort(PyObject *self, PyObject *args)
5670{
5671        long int        port = -2;
5672        PyObject   *old;
5673
5674        /* gets arguments */
5675        if ((!PyArg_ParseTuple(args, "l", &port)) || (port < -1))
5676        {
5677                PyErr_SetString(PyExc_TypeError,
5678                        "Function set_deport expects"
5679                         " a positive integer or -1 as argument");
5680                return NULL;
5681        }
5682
5683        /* adjusts value */
5684        old = pg_default_port;
5685
5686        if (port != -1)
5687                pg_default_port = PyInt_FromLong(port);
5688        else
5689        {
5690                Py_INCREF(Py_None);
5691                pg_default_port = Py_None;
5692        }
5693
5694        return old;
5695}
5696#endif /* DEFAULT_VARS */
5697
5698/* cast a string with a text representation of an array to a list */
5699static char pgCastArray__doc__[] =
5700"cast_array(string, cast=None, delim=',') -- cast a string as an array";
5701
5702PyObject *
5703pgCastArray(PyObject *self, PyObject *args, PyObject *dict)
5704{
5705        static const char *kwlist[] = {"string", "cast", "delim", NULL};
5706        PyObject   *string_obj, *cast_obj = NULL, *ret;
5707        char       *string, delim = ',';
5708        Py_ssize_t      size;
5709        int                     encoding;
5710
5711        if (!PyArg_ParseTupleAndKeywords(args, dict, "O|Oc",
5712                        (char **) kwlist, &string_obj, &cast_obj, &delim))
5713                return NULL;
5714
5715        if (PyBytes_Check(string_obj))
5716        {
5717                PyBytes_AsStringAndSize(string_obj, &string, &size);
5718                string_obj = NULL;
5719                encoding = pg_encoding_ascii;
5720        }
5721        else if (PyUnicode_Check(string_obj))
5722        {
5723                string_obj = PyUnicode_AsUTF8String(string_obj);
5724                if (!string_obj) return NULL; /* pass the UnicodeEncodeError */
5725                PyBytes_AsStringAndSize(string_obj, &string, &size);
5726                encoding = pg_encoding_utf8;
5727        }
5728        else
5729        {
5730                PyErr_SetString(PyExc_TypeError,
5731                        "Function cast_array() expects a string as first argument");
5732                return NULL;
5733        }
5734
5735        if (!cast_obj || cast_obj == Py_None)
5736        {
5737                if (cast_obj)
5738                {
5739                        Py_DECREF(cast_obj); cast_obj = NULL;
5740                }
5741        }
5742        else if (!PyCallable_Check(cast_obj))
5743        {
5744                PyErr_SetString(PyExc_TypeError,
5745                        "Function cast_array() expects a callable as second argument");
5746                return NULL;
5747        }
5748
5749        ret = cast_array(string, size, encoding, 0, cast_obj, delim);
5750
5751        Py_XDECREF(string_obj);
5752
5753        return ret;
5754}
5755
5756/* cast a string with a text representation of a record to a tuple */
5757static char pgCastRecord__doc__[] =
5758"cast_record(string, cast=None, delim=',') -- cast a string as a record";
5759
5760PyObject *
5761pgCastRecord(PyObject *self, PyObject *args, PyObject *dict)
5762{
5763        static const char *kwlist[] = {"string", "cast", "delim", NULL};
5764        PyObject   *string_obj, *cast_obj = NULL, *ret;
5765        char       *string, delim = ',';
5766        Py_ssize_t      size, len;
5767        int                     encoding;
5768
5769        if (!PyArg_ParseTupleAndKeywords(args, dict, "O|Oc",
5770                        (char **) kwlist, &string_obj, &cast_obj, &delim))
5771                return NULL;
5772
5773        if (PyBytes_Check(string_obj))
5774        {
5775                PyBytes_AsStringAndSize(string_obj, &string, &size);
5776                string_obj = NULL;
5777                encoding = pg_encoding_ascii;
5778        }
5779        else if (PyUnicode_Check(string_obj))
5780        {
5781                string_obj = PyUnicode_AsUTF8String(string_obj);
5782                if (!string_obj) return NULL; /* pass the UnicodeEncodeError */
5783                PyBytes_AsStringAndSize(string_obj, &string, &size);
5784                encoding = pg_encoding_utf8;
5785        }
5786        else
5787        {
5788                PyErr_SetString(PyExc_TypeError,
5789                        "Function cast_record() expects a string as first argument");
5790                return NULL;
5791        }
5792
5793        if (!cast_obj || PyCallable_Check(cast_obj))
5794        {
5795                len = 0;
5796        }
5797        else if (cast_obj == Py_None)
5798        {
5799                Py_DECREF(cast_obj); cast_obj = NULL; len = 0;
5800        }
5801        else if (PyTuple_Check(cast_obj) || PyList_Check(cast_obj))
5802        {
5803                len = PySequence_Size(cast_obj);
5804                if (!len)
5805                {
5806                        Py_DECREF(cast_obj); cast_obj = NULL;
5807                }
5808        }
5809        else
5810        {
5811                PyErr_SetString(PyExc_TypeError,
5812                        "Function cast_record() expects a callable"
5813                         " or tuple or list of callables as second argument");
5814                return NULL;
5815        }
5816
5817        ret = cast_record(string, size, encoding, 0, cast_obj, len, delim);
5818
5819        Py_XDECREF(string_obj);
5820
5821        return ret;
5822}
5823
5824/* cast a string with a text representation of an hstore to a dict */
5825static char pgCastHStore__doc__[] =
5826"cast_hstore(string) -- cast a string as an hstore";
5827
5828PyObject *
5829pgCastHStore(PyObject *self, PyObject *string)
5830{
5831        PyObject   *tmp_obj = NULL, *ret;
5832        char       *s;
5833        Py_ssize_t      size;
5834        int                     encoding;
5835
5836        if (PyBytes_Check(string))
5837        {
5838                PyBytes_AsStringAndSize(string, &s, &size);
5839                encoding = pg_encoding_ascii;
5840        }
5841        else if (PyUnicode_Check(string))
5842        {
5843                tmp_obj = PyUnicode_AsUTF8String(string);
5844                if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
5845                PyBytes_AsStringAndSize(tmp_obj, &s, &size);
5846                encoding = pg_encoding_utf8;
5847        }
5848        else
5849        {
5850                PyErr_SetString(PyExc_TypeError,
5851                        "Function cast_hstore() expects a string as first argument");
5852                return NULL;
5853        }
5854
5855        ret = cast_hstore(s, size, encoding);
5856
5857        Py_XDECREF(tmp_obj);
5858
5859        return ret;
5860}
5861
5862/* List of functions defined in the module */
5863
5864static struct PyMethodDef pgMethods[] = {
5865        {"connect", (PyCFunction) pgConnect, METH_VARARGS|METH_KEYWORDS,
5866                        pgConnect__doc__},
5867        {"escape_string", (PyCFunction) pgEscapeString, METH_O,
5868                        pgEscapeString__doc__},
5869        {"escape_bytea", (PyCFunction) pgEscapeBytea, METH_O,
5870                        pgEscapeBytea__doc__},
5871        {"unescape_bytea", (PyCFunction) pgUnescapeBytea, METH_O,
5872                        pgUnescapeBytea__doc__},
5873        {"get_datestyle", (PyCFunction) pgGetDatestyle, METH_NOARGS,
5874                        pgGetDatestyle__doc__},
5875        {"set_datestyle", (PyCFunction) pgSetDatestyle, METH_VARARGS,
5876                        pgSetDatestyle__doc__},
5877        {"get_decimal_point", (PyCFunction) pgGetDecimalPoint, METH_NOARGS,
5878                        pgGetDecimalPoint__doc__},
5879        {"set_decimal_point", (PyCFunction) pgSetDecimalPoint, METH_VARARGS,
5880                        pgSetDecimalPoint__doc__},
5881        {"get_decimal", (PyCFunction) pgGetDecimal, METH_NOARGS,
5882                        pgGetDecimal__doc__},
5883        {"set_decimal", (PyCFunction) pgSetDecimal, METH_O,
5884                        pgSetDecimal__doc__},
5885        {"get_bool", (PyCFunction) pgGetBool, METH_NOARGS, pgGetBool__doc__},
5886        {"set_bool", (PyCFunction) pgSetBool, METH_VARARGS, pgSetBool__doc__},
5887        {"get_array", (PyCFunction) pgGetArray, METH_NOARGS, pgGetArray__doc__},
5888        {"set_array", (PyCFunction) pgSetArray, METH_VARARGS, pgSetArray__doc__},
5889        {"get_bytea_escaped", (PyCFunction) pgGetByteaEscaped, METH_NOARGS,
5890                pgGetByteaEscaped__doc__},
5891        {"set_bytea_escaped", (PyCFunction) pgSetByteaEscaped, METH_VARARGS,
5892                pgSetByteaEscaped__doc__},
5893        {"get_namedresult", (PyCFunction) pgGetNamedresult, METH_NOARGS,
5894                        pgGetNamedresult__doc__},
5895        {"set_namedresult", (PyCFunction) pgSetNamedresult, METH_O,
5896                        pgSetNamedresult__doc__},
5897        {"get_jsondecode", (PyCFunction) pgGetJsondecode, METH_NOARGS,
5898                        pgGetJsondecode__doc__},
5899        {"set_jsondecode", (PyCFunction) pgSetJsondecode, METH_O,
5900                        pgSetJsondecode__doc__},
5901        {"cast_array", (PyCFunction) pgCastArray, METH_VARARGS|METH_KEYWORDS,
5902                        pgCastArray__doc__},
5903        {"cast_record", (PyCFunction) pgCastRecord, METH_VARARGS|METH_KEYWORDS,
5904                        pgCastRecord__doc__},
5905        {"cast_hstore", (PyCFunction) pgCastHStore, METH_O, pgCastHStore__doc__},
5906
5907#ifdef DEFAULT_VARS
5908        {"get_defhost", pgGetDefHost, METH_NOARGS, pgGetDefHost__doc__},
5909        {"set_defhost", pgSetDefHost, METH_VARARGS, pgSetDefHost__doc__},
5910        {"get_defbase", pgGetDefBase, METH_NOARGS, pgGetDefBase__doc__},
5911        {"set_defbase", pgSetDefBase, METH_VARARGS, pgSetDefBase__doc__},
5912        {"get_defopt", pgGetDefOpt, METH_NOARGS, pgGetDefOpt__doc__},
5913        {"set_defopt", pgSetDefOpt, METH_VARARGS, pgSetDefOpt__doc__},
5914        {"get_defport", pgGetDefPort, METH_NOARGS, pgGetDefPort__doc__},
5915        {"set_defport", pgSetDefPort, METH_VARARGS, pgSetDefPort__doc__},
5916        {"get_defuser", pgGetDefUser, METH_NOARGS, pgGetDefUser__doc__},
5917        {"set_defuser", pgSetDefUser, METH_VARARGS, pgSetDefUser__doc__},
5918        {"set_defpasswd", pgSetDefPassword, METH_VARARGS, pgSetDefPassword__doc__},
5919#endif /* DEFAULT_VARS */
5920        {NULL, NULL} /* sentinel */
5921};
5922
5923static char pg__doc__[] = "Python interface to PostgreSQL DB";
5924
5925static struct PyModuleDef moduleDef = {
5926        PyModuleDef_HEAD_INIT,
5927        "_pg",          /* m_name */
5928        pg__doc__,      /* m_doc */
5929        -1,                     /* m_size */
5930        pgMethods       /* m_methods */
5931};
5932
5933/* Initialization function for the module */
5934MODULE_INIT_FUNC(_pg)
5935{
5936        PyObject   *mod, *dict, *s;
5937
5938        /* Create the module and add the functions */
5939
5940        mod = PyModule_Create(&moduleDef);
5941
5942        /* Initialize here because some Windows platforms get confused otherwise */
5943#if IS_PY3
5944        connType.tp_base = noticeType.tp_base =
5945                queryType.tp_base = sourceType.tp_base = &PyBaseObject_Type;
5946#ifdef LARGE_OBJECTS
5947        largeType.tp_base = &PyBaseObject_Type;
5948#endif
5949#else
5950        connType.ob_type = noticeType.ob_type =
5951                queryType.ob_type = sourceType.ob_type = &PyType_Type;
5952#ifdef LARGE_OBJECTS
5953        largeType.ob_type = &PyType_Type;
5954#endif
5955#endif
5956
5957        if (PyType_Ready(&connType)
5958                || PyType_Ready(&noticeType)
5959                || PyType_Ready(&queryType)
5960                || PyType_Ready(&sourceType)
5961#ifdef LARGE_OBJECTS
5962                || PyType_Ready(&largeType)
5963#endif
5964                ) return NULL;
5965
5966        dict = PyModule_GetDict(mod);
5967
5968        /* Exceptions as defined by DB-API 2.0 */
5969        Error = PyErr_NewException("pg.Error", PyExc_Exception, NULL);
5970        PyDict_SetItemString(dict, "Error", Error);
5971
5972        Warning = PyErr_NewException("pg.Warning", PyExc_Exception, NULL);
5973        PyDict_SetItemString(dict, "Warning", Warning);
5974
5975        InterfaceError = PyErr_NewException("pg.InterfaceError", Error, NULL);
5976        PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
5977
5978        DatabaseError = PyErr_NewException("pg.DatabaseError", Error, NULL);
5979        PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
5980
5981        InternalError = PyErr_NewException("pg.InternalError", DatabaseError, NULL);
5982        PyDict_SetItemString(dict, "InternalError", InternalError);
5983
5984        OperationalError =
5985                PyErr_NewException("pg.OperationalError", DatabaseError, NULL);
5986        PyDict_SetItemString(dict, "OperationalError", OperationalError);
5987
5988        ProgrammingError =
5989                PyErr_NewException("pg.ProgrammingError", DatabaseError, NULL);
5990        PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
5991
5992        IntegrityError =
5993                PyErr_NewException("pg.IntegrityError", DatabaseError, NULL);
5994        PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
5995
5996        DataError = PyErr_NewException("pg.DataError", DatabaseError, NULL);
5997        PyDict_SetItemString(dict, "DataError", DataError);
5998
5999        NotSupportedError =
6000                PyErr_NewException("pg.NotSupportedError", DatabaseError, NULL);
6001        PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
6002
6003        /* Make the version available */
6004        s = PyStr_FromString(PyPgVersion);
6005        PyDict_SetItemString(dict, "version", s);
6006        PyDict_SetItemString(dict, "__version__", s);
6007        Py_DECREF(s);
6008
6009        /* results type for queries */
6010        PyDict_SetItemString(dict, "RESULT_EMPTY", PyInt_FromLong(RESULT_EMPTY));
6011        PyDict_SetItemString(dict, "RESULT_DML", PyInt_FromLong(RESULT_DML));
6012        PyDict_SetItemString(dict, "RESULT_DDL", PyInt_FromLong(RESULT_DDL));
6013        PyDict_SetItemString(dict, "RESULT_DQL", PyInt_FromLong(RESULT_DQL));
6014
6015        /* transaction states */
6016        PyDict_SetItemString(dict,"TRANS_IDLE",PyInt_FromLong(PQTRANS_IDLE));
6017        PyDict_SetItemString(dict,"TRANS_ACTIVE",PyInt_FromLong(PQTRANS_ACTIVE));
6018        PyDict_SetItemString(dict,"TRANS_INTRANS",PyInt_FromLong(PQTRANS_INTRANS));
6019        PyDict_SetItemString(dict,"TRANS_INERROR",PyInt_FromLong(PQTRANS_INERROR));
6020        PyDict_SetItemString(dict,"TRANS_UNKNOWN",PyInt_FromLong(PQTRANS_UNKNOWN));
6021
6022#ifdef LARGE_OBJECTS
6023        /* create mode for large objects */
6024        PyDict_SetItemString(dict, "INV_READ", PyInt_FromLong(INV_READ));
6025        PyDict_SetItemString(dict, "INV_WRITE", PyInt_FromLong(INV_WRITE));
6026
6027        /* position flags for lo_lseek */
6028        PyDict_SetItemString(dict, "SEEK_SET", PyInt_FromLong(SEEK_SET));
6029        PyDict_SetItemString(dict, "SEEK_CUR", PyInt_FromLong(SEEK_CUR));
6030        PyDict_SetItemString(dict, "SEEK_END", PyInt_FromLong(SEEK_END));
6031#endif /* LARGE_OBJECTS */
6032
6033#ifdef DEFAULT_VARS
6034        /* prepares default values */
6035        Py_INCREF(Py_None);
6036        pg_default_host = Py_None;
6037        Py_INCREF(Py_None);
6038        pg_default_base = Py_None;
6039        Py_INCREF(Py_None);
6040        pg_default_opt = Py_None;
6041        Py_INCREF(Py_None);
6042        pg_default_port = Py_None;
6043        Py_INCREF(Py_None);
6044        pg_default_user = Py_None;
6045        Py_INCREF(Py_None);
6046        pg_default_passwd = Py_None;
6047#endif /* DEFAULT_VARS */
6048
6049        /* store common pg encoding ids */
6050
6051        pg_encoding_utf8 = pg_char_to_encoding("UTF8");
6052        pg_encoding_latin1 = pg_char_to_encoding("LATIN1");
6053        pg_encoding_ascii = pg_char_to_encoding("SQL_ASCII");
6054
6055        /* Check for errors */
6056        if (PyErr_Occurred())
6057                return NULL;
6058
6059        return mod;
6060}
Note: See TracBrowser for help on using the repository browser.