source: trunk/pgmodule.c @ 804

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

Make the automatic conversion to arrays configurable

The automatic conversion of arrays to lists can now be
disabled with the set_array() method.

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