source: trunk/module/pgmodule.c @ 655

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

Fix garbage collection issues

This patch fixes memory management problems, particularly on Windows.

The query() method and the handling of object references inside the method has
been greatly simplified and corrected. Note that we don't calculate and pass
the paramLengths any more since this is only needed when also passing info about
binary data in paramFormats. We also use PyMem_Malloc() instead of malloc() to
allocate memory to make sure the memory is allocated in the Python heap.

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