source: trunk/pgmodule.c @ 740

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

Reformat some error messages and docstrings

Try to achieve a somewhat consistent style of docstrings and error
messages in the trunk. The docstrings use PEP 257, with a slight
variation between C code and Python code. The error messages are
capitalized and do not end with a period. (I prefer the periods,
but most Python code I have seen doesn't use them.)

(I know, a foolish consistency is the hobgoblin of little minds.)

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