source: branches/4.x/module/pgmodule.c @ 549

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

Add tests for large object support.

Also fix some minor issues in the C code and docs.
Particularly, type checks in large object support
should always be done before checking the object status.

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