source: trunk/pgmodule.c @ 794

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

Fix regarding reference counting in typecast call

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