source: trunk/pgmodule.c @ 823

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

Raise the proper subclasses of DatabaseError?

Particularly, we raise IntegrityError? instead of ProgrammingError? for
duplicate keys. This also makes PyGreSQL more useable with SQLAlchemy.

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