source: trunk/module/pgmodule.c @ 680

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

Remove the deprecated tty parameter and attribute

This parameter has been ignored by PostgreSQL since version 7.4.

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