source: trunk/pgmodule.c @ 780

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

Refactoring of the decoding of columns

Add a helper function cast_value() and use that to cast
values to Python objects in both getresult() and dictresult().

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