source: trunk/pgmodule.c @ 785

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

Make all tests run again with Python 3

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