source: trunk/pgmodule.c @ 791

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

Add support for composite types

Added a fast parser for the composite type input/output syntax, which is
similar to the already existing parser for the array input/output syntax.

The pgdb module now makes use of this parser, converting in both directions
between PostgreSQL records (composite types) and Python (named) tuples.

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