source: branches/4.x/pgmodule.c @ 711

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

Flatten the directory structure of the project

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

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

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

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