source: trunk/pgmodule.c @ 802

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

Make the unescaping of bytea configurable

By default, bytea is returned unescaped in 5.0, but the old
behavior can now be restored with set_escaped_bytea().

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