source: trunk/pgmodule.c @ 817

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

Support the hstore data type

Added adaptation and typecasting of the hstore type as Python dictionaries.
For the typecasting, a fast parser has been added to the C extension.

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