source: trunk/pgmodule.c @ 774

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

Add support for JSON and JSONB to pg and pgdb

This adds all necessary functions to make PyGreSQL automatically
convert between JSON columns and Python objects representing them.

The documentation has also been updated, see there for the details.

Also, tuples automatically bind to ROW expressions in pgdb now.

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