source: trunk/pgmodule.c @ 781

Last change on this file since 781 was 781, checked in by cito, 3 years ago

Add full support for PostgreSQL array types

At the core of this patch is a fast parser for the peculiar syntax of
literal array expressions in PostgreSQL that was added to the C module.
This is not trivial, because PostgreSQL arrays can be multidimensional
and the syntax is different from Python and SQL expressions.

The Python pg and pgdb modules make use of this parser so that they can
return database columns containing PostgreSQL arrays to Python as lists.
Also added quoting methods that allow passing PostgreSQL arrays as lists
to insert()/update() and execute/executemany(). These methods are simpler
and were implemented in Python but needed support from the regex module.

The patch also adds makes getresult() in pg automatically return bytea
values in unescaped form as bytes strings. Before, it was necessary to
call unescape_bytea manually. The pgdb module did this already.

The patch includes some more refactorings and simplifications regarding
the quoting and casting in pg and pgdb.

Some references to antique PostgreSQL types that are not used any more
in the supported PostgreSQL versions have been removed.

Also added documentation and tests for the new features.

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