source: trunk/pgmodule.c @ 711

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

Flatten the directory structure of the project

Simplified the directory structure by flattening the "module" subdirectory out
to the root directory. That way, the setup.py script can now also access the
top-level docs subdirectory, so it could also install or build the docs.
There was nothing else in the root directory anyway, except the mkdocs and
mktar scripts which could be made unnecessary through setup.py.

Also made the setup script a bit clearer. Removed the note about MinGW for
Windows since the Microsoft compiler for Python 2.7 and Visual Studio Community
are now freely available including 64bit compilers, and produce less problems.

Note that the usual structure would have been to use a "pygresql" package
directory instead of the "module" directory. But since we install PyGreSQL
as two top-level modules "pg" and "pgdb" instead of a package "pygresql",
the flattened structure reflects that much better. For historical reasons
and people don't want to rewrite import statements, we will keep it that way.

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