source: trunk/pgmodule.c @ 715

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

Use the original header file from PG instead of pgfs.h

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