source: trunk/pgmodule.c @ 798

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

Port type cache and typecasting from pgdb to pg

So far, the typecasting in the classic module was been only done by
the C extension module and was not extensible through typecasting
functions in Python. This has now been made extensible by adding
a cast hook to the C extension module which has been hooked up to
a new type cache object that holds information on the types and the
associated typecast functions. All of this works very similar to the
pgdb module now, except that the basic types are still handled by
the C extension module and the Python typecast functions are only
called via the hook for types which are not supported internally.

Also added tests and a chapter on the type cache in the documentation,
and cleaned up the error messages in the C extension module.

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