source: trunk/pgmodule.c @ 910

Last change on this file since 910 was 910, checked in by cito, 2 years ago

Cleaner handling of oid parameter in getlo() method

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