source: trunk/module/pgmodule.c @ 703

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

One more cast to avoid a compiler warning with MSVC.

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