source: trunk/pgmodule.c @ 844

Last change on this file since 844 was 844, checked in by cito, 3 years ago

New connection attribute "closed" in pgdb

This can be useful when implementing connection pools, e.g. in SQLAlchemy.

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