source: trunk/pgmodule.c

Last change on this file was 1021, checked in by cito, 2 weeks ago

Fix deprecation warning issue with Python 3.8

  • Property svn:keywords set to Id
File size: 38.6 KB
Line 
1/*
2 * $Id: pgmodule.c 1021 2019-10-03 18:34:54Z cito $
3 *
4 * PyGreSQL - a Python interface for the PostgreSQL database.
5 *
6 * This is the main file for the C extension module.
7 *
8 * Copyright (c) 2019 by the PyGreSQL Development Team
9 *
10 * Please see the LICENSE.TXT file for specific restrictions.
11 *
12 */
13
14/* Note: This should be linked against the same C runtime lib as Python */
15
16#define PY_SSIZE_T_CLEAN
17#include <Python.h>
18
19#include <libpq-fe.h>
20#include <libpq/libpq-fs.h>
21
22/* The type definitions from <server/catalog/pg_type.h> */
23#include "pgtypes.h"
24
25/* Macros for single-source Python 2/3 compatibility */
26#include "py3c.h"
27
28static PyObject *Error, *Warning, *InterfaceError, *DatabaseError,
29                *InternalError, *OperationalError, *ProgrammingError,
30                *IntegrityError, *DataError, *NotSupportedError,
31                *InvalidResultError, *NoResultError, *MultipleResultsError;
32
33#define _TOSTRING(x) #x
34#define TOSTRING(x) _TOSTRING(x)
35static const char *PyPgVersion = TOSTRING(PYGRESQL_VERSION);
36
37#if SIZEOF_SIZE_T != SIZEOF_INT
38#define Py_InitModule4 Py_InitModule4_64
39#endif
40
41/* Default values */
42#define PG_ARRAYSIZE 1
43
44/* Flags for object validity checks */
45#define CHECK_OPEN   1
46#define CHECK_CLOSE  2
47#define CHECK_CNX    4
48#define CHECK_RESULT 8
49#define CHECK_DQL   16
50
51/* Query result types */
52#define RESULT_EMPTY 1
53#define RESULT_DML   2
54#define RESULT_DDL   3
55#define RESULT_DQL   4
56
57/* Flags for move methods */
58#define QUERY_MOVEFIRST 1
59#define QUERY_MOVELAST  2
60#define QUERY_MOVENEXT  3
61#define QUERY_MOVEPREV  4
62
63#define MAX_BUFFER_SIZE 8192  /* maximum transaction size */
64#define MAX_ARRAY_DEPTH 16    /* maximum allowed depth of an array */
65
66/* MODULE GLOBAL VARIABLES */
67
68#ifdef DEFAULT_VARS
69static PyObject *pg_default_host;   /* default database host */
70static PyObject *pg_default_base;   /* default database name */
71static PyObject *pg_default_opt;    /* default connection options */
72static PyObject *pg_default_port;   /* default connection port */
73static PyObject *pg_default_user;   /* default username */
74static PyObject *pg_default_passwd; /* default password */
75#endif  /* DEFAULT_VARS */
76
77static PyObject *decimal = NULL,    /* decimal type */
78                *dictiter = NULL,   /* function for getting named results */
79                *namediter = NULL,  /* function for getting named results */
80                *namednext = NULL,  /* function for getting one named result */
81                *scalariter = NULL, /* function for getting scalar results */
82                *jsondecode = NULL; /* function for decoding json strings */
83static const char *date_format = NULL; /* date format that is always assumed */
84static char decimal_point = '.';    /* decimal point used in money values */
85static int bool_as_text = 0;   /* whether bool shall be returned as text */
86static int array_as_text = 0;  /* whether arrays shall be returned as text */
87static int bytea_escaped = 0;  /* whether bytea shall be returned escaped */
88
89static int pg_encoding_utf8 = 0;
90static int pg_encoding_latin1 = 0;
91static int pg_encoding_ascii = 0;
92
93/*
94OBJECTS
95=======
96
97  Each object has a number of elements.  The naming scheme will be based on
98  the object type.  Here are the elements using example object type "foo".
99   - fooType: Type definition for object.
100   - fooObject: A structure to hold local object information.
101   - foo_methods: Methods declaration.
102   - foo_method_name: Object methods.
103
104  The objects that we need to create:
105   - pg: The module itself.
106   - conn: Connection object returned from pg.connect().
107   - notice: Notice object returned from pg.notice().
108   - large: Large object returned by pg.conn.locreate() and pg.conn.loimport().
109   - query: Query object returned by pg.conn.query().
110   - source: Source object returned by pg.conn.source().
111*/
112
113/* Forward declarations for types */
114static PyTypeObject connType, sourceType, queryType, noticeType, largeType;
115
116/* Forward static declarations */
117static void notice_receiver(void *, const PGresult *);
118
119/* Object declarations */
120
121typedef struct
122{
123    PyObject_HEAD
124    int        valid;             /* validity flag */
125    PGconn     *cnx;              /* Postgres connection handle */
126    const char *date_format;      /* date format derived from datestyle */
127    PyObject   *cast_hook;        /* external typecast method */
128    PyObject   *notice_receiver;  /* current notice receiver */
129}   connObject;
130#define is_connObject(v) (PyType(v) == &connType)
131
132typedef struct
133{
134    PyObject_HEAD
135    int        valid;        /* validity flag */
136    connObject *pgcnx;       /* parent connection object */
137    PGresult   *result;      /* result content */
138    int        encoding;     /* client encoding */
139    int        result_type;  /* result type (DDL/DML/DQL) */
140    long       arraysize;    /* array size for fetch method */
141    int        current_row;  /* currently selected row */
142    int        max_row;      /* number of rows in the result */
143    int        num_fields;   /* number of fields in each row */
144}   sourceObject;
145#define is_sourceObject(v) (PyType(v) == &sourceType)
146
147typedef struct
148{
149    PyObject_HEAD
150    connObject *pgcnx;    /* parent connection object */
151    PGresult const *res;  /* an error or warning */
152}   noticeObject;
153#define is_noticeObject(v) (PyType(v) == &noticeType)
154
155typedef struct
156{
157    PyObject_HEAD
158    connObject *pgcnx;       /* parent connection object */
159    PGresult   *result;      /* result content */
160    int        encoding;     /* client encoding */
161    int        current_row;  /* currently selected row */
162    int        max_row;      /* number of rows in the result */
163    int        num_fields;   /* number of fields in each row */
164    int        *col_types;   /* PyGreSQL column types */
165}   queryObject;
166#define is_queryObject(v) (PyType(v) == &queryType)
167
168#ifdef LARGE_OBJECTS
169typedef struct
170{
171    PyObject_HEAD
172    connObject *pgcnx;  /* parent connection object */
173    Oid lo_oid;         /* large object oid */
174    int lo_fd;          /* large object fd */
175}   largeObject;
176#define is_largeObject(v) (PyType(v) == &largeType)
177#endif /* LARGE_OBJECTS */
178
179/* Internal functions */
180#include "pginternal.c"
181
182/* Connection object */
183#include "pgconn.c"
184
185/* Query object */
186#include "pgquery.c"
187
188/* Source object */
189#include "pgsource.c"
190
191/* Notice object */
192#include "pgnotice.c"
193
194/* Large objects */
195#ifdef LARGE_OBJECTS
196#include "pglarge.c"
197#endif
198
199/* MODULE FUNCTIONS */
200
201/* Connect to a database. */
202static char pg_connect__doc__[] =
203"connect(dbname, host, port, opt) -- connect to a PostgreSQL database\n\n"
204"The connection uses the specified parameters (optional, keywords aware).\n";
205
206static PyObject *
207pg_connect(PyObject *self, PyObject *args, PyObject *dict)
208{
209    static const char *kwlist[] =
210    {
211        "dbname", "host", "port", "opt", "user", "passwd", NULL
212    };
213
214    char *pghost, *pgopt, *pgdbname, *pguser, *pgpasswd;
215    int pgport;
216    char port_buffer[20];
217    connObject *conn_obj;
218
219    pghost = pgopt = pgdbname = pguser = pgpasswd = NULL;
220    pgport = -1;
221
222    /*
223     * parses standard arguments With the right compiler warnings, this
224     * will issue a diagnostic. There is really no way around it.  If I
225     * don't declare kwlist as const char *kwlist[] then it complains when
226     * I try to assign all those constant strings to it.
227     */
228    if (!PyArg_ParseTupleAndKeywords(
229        args, dict, "|zzizzz", (char**)kwlist,
230        &pgdbname, &pghost, &pgport, &pgopt, &pguser, &pgpasswd))
231    {
232        return NULL;
233    }
234
235#ifdef DEFAULT_VARS
236    /* handles defaults variables (for uninitialised vars) */
237    if ((!pghost) && (pg_default_host != Py_None))
238        pghost = PyBytes_AsString(pg_default_host);
239
240    if ((pgport == -1) && (pg_default_port != Py_None))
241        pgport = (int) PyInt_AsLong(pg_default_port);
242
243    if ((!pgopt) && (pg_default_opt != Py_None))
244        pgopt = PyBytes_AsString(pg_default_opt);
245
246    if ((!pgdbname) && (pg_default_base != Py_None))
247        pgdbname = PyBytes_AsString(pg_default_base);
248
249    if ((!pguser) && (pg_default_user != Py_None))
250        pguser = PyBytes_AsString(pg_default_user);
251
252    if ((!pgpasswd) && (pg_default_passwd != Py_None))
253        pgpasswd = PyBytes_AsString(pg_default_passwd);
254#endif /* DEFAULT_VARS */
255
256    if (!(conn_obj = PyObject_NEW(connObject, &connType))) {
257        set_error_msg(InternalError, "Can't create new connection object");
258        return NULL;
259    }
260
261    conn_obj->valid = 1;
262    conn_obj->cnx = NULL;
263    conn_obj->date_format = date_format;
264    conn_obj->cast_hook = NULL;
265    conn_obj->notice_receiver = NULL;
266
267    if (pgport != -1) {
268        memset(port_buffer, 0, sizeof(port_buffer));
269        sprintf(port_buffer, "%d", pgport);
270    }
271
272    Py_BEGIN_ALLOW_THREADS
273    conn_obj->cnx = PQsetdbLogin(pghost, pgport == -1 ? NULL : port_buffer,
274        pgopt, NULL, pgdbname, pguser, pgpasswd);
275    Py_END_ALLOW_THREADS
276
277    if (PQstatus(conn_obj->cnx) == CONNECTION_BAD) {
278        set_error(InternalError, "Cannot connect", conn_obj->cnx, NULL);
279        Py_XDECREF(conn_obj);
280        return NULL;
281    }
282
283    return (PyObject *) conn_obj;
284}
285
286/* Escape string */
287static char pg_escape_string__doc__[] =
288"escape_string(string) -- escape a string for use within SQL";
289
290static PyObject *
291pg_escape_string(PyObject *self, PyObject *string)
292{
293    PyObject *tmp_obj = NULL,  /* auxiliary string object */
294             *to_obj;          /* string object to return */
295    char *from,  /* our string argument as encoded string */
296         *to;    /* the result as encoded string */
297    Py_ssize_t from_length;    /* length of string */
298    size_t to_length;          /* length of result */
299    int encoding = -1;         /* client encoding */
300
301    if (PyBytes_Check(string)) {
302        PyBytes_AsStringAndSize(string, &from, &from_length);
303    }
304    else if (PyUnicode_Check(string)) {
305        encoding = pg_encoding_ascii;
306        tmp_obj = get_encoded_string(string, encoding);
307        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
308        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
309    }
310    else {
311        PyErr_SetString(PyExc_TypeError,
312                        "Method escape_string() expects a string as argument");
313        return NULL;
314    }
315
316    to_length = 2*from_length + 1;
317    if ((Py_ssize_t ) to_length < from_length) { /* overflow */
318        to_length = from_length;
319        from_length = (from_length - 1)/2;
320    }
321    to = (char *) PyMem_Malloc(to_length);
322    to_length = (int) PQescapeString(to, from, (size_t) from_length);
323
324    Py_XDECREF(tmp_obj);
325
326    if (encoding == -1)
327        to_obj = PyBytes_FromStringAndSize(to, to_length);
328    else
329        to_obj = get_decoded_string(to, to_length, encoding);
330    PyMem_Free(to);
331    return to_obj;
332}
333
334/* Escape bytea */
335static char pg_escape_bytea__doc__[] =
336"escape_bytea(data) -- escape binary data for use within SQL as type bytea";
337
338static PyObject *
339pg_escape_bytea(PyObject *self, PyObject *data)
340{
341    PyObject *tmp_obj = NULL,  /* auxiliary string object */
342             *to_obj;          /* string object to return */
343    char *from,  /* our string argument as encoded string */
344         *to;    /* the result as encoded string */
345    Py_ssize_t from_length;    /* length of string */
346    size_t to_length;          /* length of result */
347    int encoding = -1;         /* client encoding */
348
349    if (PyBytes_Check(data)) {
350        PyBytes_AsStringAndSize(data, &from, &from_length);
351    }
352    else if (PyUnicode_Check(data)) {
353        encoding = pg_encoding_ascii;
354        tmp_obj = get_encoded_string(data, encoding);
355        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
356        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
357    }
358    else {
359        PyErr_SetString(PyExc_TypeError,
360                        "Method escape_bytea() expects a string as argument");
361        return NULL;
362    }
363
364    to = (char *) PQescapeBytea(
365        (unsigned char*) from, (size_t) from_length, &to_length);
366
367    Py_XDECREF(tmp_obj);
368
369    if (encoding == -1)
370        to_obj = PyBytes_FromStringAndSize(to, to_length - 1);
371    else
372        to_obj = get_decoded_string(to, to_length - 1, encoding);
373    if (to)
374        PQfreemem(to);
375    return to_obj;
376}
377
378/* Unescape bytea */
379static char pg_unescape_bytea__doc__[] =
380"unescape_bytea(string) -- unescape bytea data retrieved as text";
381
382static PyObject *
383pg_unescape_bytea(PyObject *self, PyObject *data)
384{
385    PyObject *tmp_obj = NULL,  /* auxiliary string object */
386             *to_obj;          /* string object to return */
387    char *from,  /* our string argument as encoded string */
388         *to;    /* the result as encoded string */
389    Py_ssize_t from_length;    /* length of string */
390    size_t to_length;          /* length of result */
391
392    if (PyBytes_Check(data)) {
393        PyBytes_AsStringAndSize(data, &from, &from_length);
394    }
395    else if (PyUnicode_Check(data)) {
396        tmp_obj = get_encoded_string(data, pg_encoding_ascii);
397        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
398        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
399    }
400    else {
401        PyErr_SetString(
402            PyExc_TypeError,
403            "Method unescape_bytea() expects a string as argument");
404        return NULL;
405    }
406
407    to = (char *) PQunescapeBytea((unsigned char*) from, &to_length);
408
409    Py_XDECREF(tmp_obj);
410
411    if (!to) return PyErr_NoMemory();
412
413    to_obj = PyBytes_FromStringAndSize(to, to_length);
414    PQfreemem(to);
415
416    return to_obj;
417}
418
419/* Set fixed datestyle. */
420static char pg_set_datestyle__doc__[] =
421"set_datestyle(style) -- set which style is assumed";
422
423static PyObject *
424pg_set_datestyle(PyObject *self, PyObject *args)
425{
426    const char *datestyle = NULL;
427
428    /* gets arguments */
429    if (!PyArg_ParseTuple(args, "z", &datestyle)) {
430        PyErr_SetString(
431            PyExc_TypeError,
432            "Function set_datestyle() expects a string or None as argument");
433        return NULL;
434    }
435
436    date_format = datestyle ? date_style_to_format(datestyle) : NULL;
437
438    Py_INCREF(Py_None); return Py_None;
439}
440
441/* Get fixed datestyle. */
442static char pg_get_datestyle__doc__[] =
443"get_datestyle() -- get which date style is assumed";
444
445static PyObject *
446pg_get_datestyle(PyObject *self, PyObject *noargs)
447{
448    if (date_format) {
449        return PyStr_FromString(date_format_to_style(date_format));
450    }
451    else {
452        Py_INCREF(Py_None); return Py_None;
453    }
454}
455
456/* Get decimal point. */
457static char pg_get_decimal_point__doc__[] =
458"get_decimal_point() -- get decimal point to be used for money values";
459
460static PyObject *
461pg_get_decimal_point(PyObject *self, PyObject *noargs)
462{
463    PyObject *ret;
464    char s[2];
465
466    if (decimal_point) {
467        s[0] = decimal_point; s[1] = '\0';
468        ret = PyStr_FromString(s);
469    }
470    else {
471        Py_INCREF(Py_None); ret = Py_None;
472    }
473
474    return ret;
475}
476
477/* Set decimal point. */
478static char pg_set_decimal_point__doc__[] =
479"set_decimal_point(char) -- set decimal point to be used for money values";
480
481static PyObject *
482pg_set_decimal_point(PyObject *self, PyObject *args)
483{
484    PyObject *ret = NULL;
485    char *s = NULL;
486
487    /* gets arguments */
488    if (PyArg_ParseTuple(args, "z", &s)) {
489        if (!s)
490            s = "\0";
491        else if (*s && (*(s+1) || !strchr(".,;: '*/_`|", *s)))
492            s = NULL;
493    }
494
495    if (s) {
496        decimal_point = *s;
497        Py_INCREF(Py_None); ret = Py_None;
498    }
499    else {
500        PyErr_SetString(PyExc_TypeError,
501                        "Function set_decimal_mark() expects"
502                        " a decimal mark character as argument");
503    }
504    return ret;
505}
506
507/* Get decimal type. */
508static char pg_get_decimal__doc__[] =
509"get_decimal() -- get the decimal type to be used for numeric values";
510
511static PyObject *
512pg_get_decimal(PyObject *self, PyObject *noargs)
513{
514    PyObject *ret;
515
516    ret = decimal ? decimal : Py_None;
517    Py_INCREF(ret);
518
519    return ret;
520}
521
522/* Set decimal type. */
523static char pg_set_decimal__doc__[] =
524"set_decimal(cls) -- set a decimal type to be used for numeric values";
525
526static PyObject *
527pg_set_decimal(PyObject *self, PyObject *cls)
528{
529    PyObject *ret = NULL;
530
531    if (cls == Py_None) {
532        Py_XDECREF(decimal); decimal = NULL;
533        Py_INCREF(Py_None); ret = Py_None;
534    }
535    else if (PyCallable_Check(cls)) {
536        Py_XINCREF(cls); Py_XDECREF(decimal); decimal = cls;
537        Py_INCREF(Py_None); ret = Py_None;
538    }
539    else {
540        PyErr_SetString(PyExc_TypeError,
541                        "Function set_decimal() expects"
542                        " a callable or None as argument");
543    }
544
545    return ret;
546}
547
548/* Get usage of bool values. */
549static char pg_get_bool__doc__[] =
550"get_bool() -- check whether boolean values are converted to bool";
551
552static PyObject *
553pg_get_bool(PyObject *self, PyObject *noargs)
554{
555    PyObject *ret;
556
557    ret = bool_as_text ? Py_False : Py_True;
558    Py_INCREF(ret);
559
560    return ret;
561}
562
563/* Set usage of bool values. */
564static char pg_set_bool__doc__[] =
565"set_bool(on) -- set whether boolean values should be converted to bool";
566
567static PyObject *
568pg_set_bool(PyObject *self, PyObject *args)
569{
570    PyObject *ret = NULL;
571    int i;
572
573    /* gets arguments */
574    if (PyArg_ParseTuple(args, "i", &i)) {
575        bool_as_text = i ? 0 : 1;
576        Py_INCREF(Py_None); ret = Py_None;
577    }
578    else {
579        PyErr_SetString(
580            PyExc_TypeError,
581            "Function set_bool() expects a boolean value as argument");
582    }
583
584    return ret;
585}
586
587/* Get conversion of arrays to lists. */
588static char pg_get_array__doc__[] =
589"get_array() -- check whether arrays are converted as lists";
590
591static PyObject *
592pg_get_array(PyObject *self, PyObject *noargs)
593{
594    PyObject *ret;
595
596    ret = array_as_text ? Py_False : Py_True;
597    Py_INCREF(ret);
598
599    return ret;
600}
601
602/* Set conversion of arrays to lists. */
603static char pg_set_array__doc__[] =
604"set_array(on) -- set whether arrays should be converted to lists";
605
606static PyObject *
607pg_set_array(PyObject* self, PyObject* args)
608{
609    PyObject* ret = NULL;
610    int i;
611
612    /* gets arguments */
613    if (PyArg_ParseTuple(args, "i", &i)) {
614        array_as_text = i ? 0 : 1;
615        Py_INCREF(Py_None); ret = Py_None;
616    }
617    else {
618        PyErr_SetString(
619            PyExc_TypeError,
620            "Function set_array() expects a boolean value as argument");
621    }
622
623    return ret;
624}
625
626/* Check whether bytea values are unescaped. */
627static char pg_get_bytea_escaped__doc__[] =
628"get_bytea_escaped() -- check whether bytea will be returned escaped";
629
630static PyObject *
631pg_get_bytea_escaped(PyObject *self, PyObject *noargs)
632{
633    PyObject *ret;
634
635    ret = bytea_escaped ? Py_True : Py_False;
636    Py_INCREF(ret);
637
638    return ret;
639}
640
641/* Set usage of bool values. */
642static char pg_set_bytea_escaped__doc__[] =
643"set_bytea_escaped(on) -- set whether bytea will be returned escaped";
644
645static PyObject *
646pg_set_bytea_escaped(PyObject *self, PyObject *args)
647{
648    PyObject *ret = NULL;
649    int i;
650
651    /* gets arguments */
652    if (PyArg_ParseTuple(args, "i", &i)) {
653        bytea_escaped = i ? 1 : 0;
654        Py_INCREF(Py_None); ret = Py_None;
655    }
656    else {
657        PyErr_SetString(PyExc_TypeError,
658                        "Function set_bytea_escaped() expects"
659                        " a boolean value as argument");
660    }
661
662    return ret;
663}
664
665/* set query helper functions (not part of public API) */
666
667static char pg_set_query_helpers__doc__[] =
668"set_query_helpers(*helpers) -- set internal query helper functions";
669
670static PyObject *
671pg_set_query_helpers(PyObject *self, PyObject *args)
672{
673    /* gets arguments */
674    if (!PyArg_ParseTuple(args, "O!O!O!O!",
675        &PyFunction_Type, &dictiter,
676        &PyFunction_Type, &namediter,
677        &PyFunction_Type, &namednext,
678        &PyFunction_Type, &scalariter))
679    {
680        return NULL;
681    }
682
683    Py_INCREF(Py_None);
684    return Py_None;
685}
686
687/* Get json decode function. */
688static char pg_get_jsondecode__doc__[] =
689"get_jsondecode() -- get the function used for decoding json results";
690
691static PyObject *
692pg_get_jsondecode(PyObject *self, PyObject *noargs)
693{
694    PyObject *ret;
695
696    ret = jsondecode;
697    if (!ret)
698        ret = Py_None;
699    Py_INCREF(ret);
700
701    return ret;
702}
703
704/* Set json decode function. */
705static char pg_set_jsondecode__doc__[] =
706"set_jsondecode(func) -- set a function to be used for decoding json results";
707
708static PyObject *
709pg_set_jsondecode(PyObject *self, PyObject *func)
710{
711    PyObject *ret = NULL;
712
713    if (func == Py_None) {
714        Py_XDECREF(jsondecode); jsondecode = NULL;
715        Py_INCREF(Py_None); ret = Py_None;
716    }
717    else if (PyCallable_Check(func)) {
718        Py_XINCREF(func); Py_XDECREF(jsondecode); jsondecode = func;
719        Py_INCREF(Py_None); ret = Py_None;
720    }
721    else {
722        PyErr_SetString(PyExc_TypeError,
723                        "Function jsondecode() expects"
724                        " a callable or None as argument");
725    }
726
727    return ret;
728}
729
730#ifdef DEFAULT_VARS
731
732/* Get default host. */
733static char pg_get_defhost__doc__[] =
734"get_defhost() -- return default database host";
735
736static PyObject *
737pg_get_defhost(PyObject *self, PyObject *noargs)
738{
739    Py_XINCREF(pg_default_host);
740    return pg_default_host;
741}
742
743/* Set default host. */
744static char pg_set_defhost__doc__[] =
745"set_defhost(string) -- set default database host and return previous value";
746
747static PyObject *
748pg_set_defhost(PyObject *self, PyObject *args)
749{
750    char *tmp = NULL;
751    PyObject *old;
752
753    /* gets arguments */
754    if (!PyArg_ParseTuple(args, "z", &tmp)) {
755        PyErr_SetString(
756            PyExc_TypeError,
757            "Function set_defhost() expects a string or None as argument");
758        return NULL;
759    }
760
761    /* adjusts value */
762    old = pg_default_host;
763
764    if (tmp) {
765        pg_default_host = PyStr_FromString(tmp);
766    }
767    else {
768        Py_INCREF(Py_None);
769        pg_default_host = Py_None;
770    }
771
772    return old;
773}
774
775/* Get default database. */
776static char pg_get_defbase__doc__[] =
777"get_defbase() -- return default database name";
778
779static PyObject *
780pg_get_defbase(PyObject *self, PyObject *noargs)
781{
782    Py_XINCREF(pg_default_base);
783    return pg_default_base;
784}
785
786/* Set default database. */
787static char pg_set_defbase__doc__[] =
788"set_defbase(string) -- set default database name and return previous value";
789
790static PyObject *
791pg_set_defbase(PyObject *self, PyObject *args)
792{
793    char *tmp = NULL;
794    PyObject *old;
795
796    /* gets arguments */
797    if (!PyArg_ParseTuple(args, "z", &tmp)) {
798        PyErr_SetString(
799            PyExc_TypeError,
800            "Function set_defbase() Argument a string or None as argument");
801        return NULL;
802    }
803
804    /* adjusts value */
805    old = pg_default_base;
806
807    if (tmp) {
808        pg_default_base = PyStr_FromString(tmp);
809    }
810    else {
811        Py_INCREF(Py_None);
812        pg_default_base = Py_None;
813    }
814
815    return old;
816}
817
818/* Get default options. */
819static char pg_get_defopt__doc__[] =
820"get_defopt() -- return default database options";
821
822static PyObject *
823pg_get_defopt(PyObject *self, PyObject *noargs)
824{
825    Py_XINCREF(pg_default_opt);
826    return pg_default_opt;
827}
828
829/* Set default options. */
830static char pg_set_defopt__doc__[] =
831"set_defopt(string) -- set default options and return previous value";
832
833static PyObject *
834pg_setdefopt(PyObject *self, PyObject *args)
835{
836    char *tmp = NULL;
837    PyObject *old;
838
839    /* gets arguments */
840    if (!PyArg_ParseTuple(args, "z", &tmp)) {
841        PyErr_SetString(
842            PyExc_TypeError,
843            "Function set_defopt() expects a string or None as argument");
844        return NULL;
845    }
846
847    /* adjusts value */
848    old = pg_default_opt;
849
850    if (tmp) {
851        pg_default_opt = PyStr_FromString(tmp);
852    }
853    else {
854        Py_INCREF(Py_None);
855        pg_default_opt = Py_None;
856    }
857
858    return old;
859}
860
861/* Get default username. */
862static char pg_get_defuser__doc__[] =
863"get_defuser() -- return default database username";
864
865static PyObject *
866pg_get_defuser(PyObject *self, PyObject *noargs)
867{
868    Py_XINCREF(pg_default_user);
869    return pg_default_user;
870}
871
872/* Set default username. */
873
874static char pg_set_defuser__doc__[] =
875"set_defuser(name) -- set default username and return previous value";
876
877static PyObject *
878pg_set_defuser(PyObject *self, PyObject *args)
879{
880    char *tmp = NULL;
881    PyObject *old;
882
883    /* gets arguments */
884    if (!PyArg_ParseTuple(args, "z", &tmp)) {
885        PyErr_SetString(
886            PyExc_TypeError,
887            "Function set_defuser() expects a string or None as argument");
888        return NULL;
889    }
890
891    /* adjusts value */
892    old = pg_default_user;
893
894    if (tmp) {
895        pg_default_user = PyStr_FromString(tmp);
896    }
897    else {
898        Py_INCREF(Py_None);
899        pg_default_user = Py_None;
900    }
901
902    return old;
903}
904
905/* Set default password. */
906static char pg_set_defpasswd__doc__[] =
907"set_defpasswd(password) -- set default database password";
908
909static PyObject *
910pg_set_defpasswd(PyObject *self, PyObject *args)
911{
912    char *tmp = NULL;
913
914    /* gets arguments */
915    if (!PyArg_ParseTuple(args, "z", &tmp)) {
916        PyErr_SetString(
917            PyExc_TypeError,
918            "Function set_defpasswd() expects a string or None as argument");
919        return NULL;
920    }
921
922    if (tmp) {
923        pg_default_passwd = PyStr_FromString(tmp);
924    }
925    else {
926        Py_INCREF(Py_None);
927        pg_default_passwd = Py_None;
928    }
929
930    Py_INCREF(Py_None);
931    return Py_None;
932}
933
934/* Get default port. */
935static char pg_get_defport__doc__[] =
936"get_defport() -- return default database port";
937
938static PyObject *
939pg_get_defport(PyObject *self, PyObject *noargs)
940{
941    Py_XINCREF(pg_default_port);
942    return pg_default_port;
943}
944
945/* Set default port. */
946static char pg_set_defport__doc__[] =
947"set_defport(port) -- set default port and return previous value";
948
949static PyObject *
950pg_set_defport(PyObject *self, PyObject *args)
951{
952    long int port = -2;
953    PyObject *old;
954
955    /* gets arguments */
956    if ((!PyArg_ParseTuple(args, "l", &port)) || (port < -1)) {
957        PyErr_SetString(PyExc_TypeError,
958                        "Function set_deport expects"
959                        " a positive integer or -1 as argument");
960        return NULL;
961    }
962
963    /* adjusts value */
964    old = pg_default_port;
965
966    if (port != -1) {
967        pg_default_port = PyInt_FromLong(port);
968    }
969    else {
970        Py_INCREF(Py_None);
971        pg_default_port = Py_None;
972    }
973
974    return old;
975}
976#endif /* DEFAULT_VARS */
977
978/* Cast a string with a text representation of an array to a list. */
979static char pg_cast_array__doc__[] =
980"cast_array(string, cast=None, delim=',') -- cast a string as an array";
981
982PyObject *
983pg_cast_array(PyObject *self, PyObject *args, PyObject *dict)
984{
985    static const char *kwlist[] = {"string", "cast", "delim", NULL};
986    PyObject *string_obj, *cast_obj = NULL, *ret;
987    char *string, delim = ',';
988    Py_ssize_t size;
989    int encoding;
990
991    if (!PyArg_ParseTupleAndKeywords(
992        args, dict, "O|Oc",
993        (char**) kwlist, &string_obj, &cast_obj, &delim))
994    {
995        return NULL;
996    }
997
998    if (PyBytes_Check(string_obj)) {
999        PyBytes_AsStringAndSize(string_obj, &string, &size);
1000        string_obj = NULL;
1001        encoding = pg_encoding_ascii;
1002    }
1003    else if (PyUnicode_Check(string_obj)) {
1004        string_obj = PyUnicode_AsUTF8String(string_obj);
1005        if (!string_obj) return NULL; /* pass the UnicodeEncodeError */
1006        PyBytes_AsStringAndSize(string_obj, &string, &size);
1007        encoding = pg_encoding_utf8;
1008    }
1009    else {
1010        PyErr_SetString(
1011            PyExc_TypeError,
1012            "Function cast_array() expects a string as first argument");
1013        return NULL;
1014    }
1015
1016    if (!cast_obj || cast_obj == Py_None) {
1017        if (cast_obj) {
1018            Py_DECREF(cast_obj); cast_obj = NULL;
1019        }
1020    }
1021    else if (!PyCallable_Check(cast_obj)) {
1022        PyErr_SetString(
1023            PyExc_TypeError,
1024            "Function cast_array() expects a callable as second argument");
1025        return NULL;
1026    }
1027
1028    ret = cast_array(string, size, encoding, 0, cast_obj, delim);
1029
1030    Py_XDECREF(string_obj);
1031
1032    return ret;
1033}
1034
1035/* Cast a string with a text representation of a record to a tuple. */
1036static char pg_cast_record__doc__[] =
1037"cast_record(string, cast=None, delim=',') -- cast a string as a record";
1038
1039PyObject *
1040pg_cast_record(PyObject *self, PyObject *args, PyObject *dict)
1041{
1042    static const char *kwlist[] = {"string", "cast", "delim", NULL};
1043    PyObject *string_obj, *cast_obj = NULL, *ret;
1044    char *string, delim = ',';
1045    Py_ssize_t size, len;
1046    int encoding;
1047
1048    if (!PyArg_ParseTupleAndKeywords(
1049        args, dict, "O|Oc",
1050        (char**) kwlist, &string_obj, &cast_obj, &delim))
1051    {
1052        return NULL;
1053    }
1054
1055    if (PyBytes_Check(string_obj)) {
1056        PyBytes_AsStringAndSize(string_obj, &string, &size);
1057        string_obj = NULL;
1058        encoding = pg_encoding_ascii;
1059    }
1060    else if (PyUnicode_Check(string_obj)) {
1061        string_obj = PyUnicode_AsUTF8String(string_obj);
1062        if (!string_obj) return NULL; /* pass the UnicodeEncodeError */
1063        PyBytes_AsStringAndSize(string_obj, &string, &size);
1064        encoding = pg_encoding_utf8;
1065    }
1066    else {
1067        PyErr_SetString(
1068            PyExc_TypeError,
1069            "Function cast_record() expects a string as first argument");
1070        return NULL;
1071    }
1072
1073    if (!cast_obj || PyCallable_Check(cast_obj)) {
1074        len = 0;
1075    }
1076    else if (cast_obj == Py_None) {
1077        Py_DECREF(cast_obj); cast_obj = NULL; len = 0;
1078    }
1079    else if (PyTuple_Check(cast_obj) || PyList_Check(cast_obj)) {
1080        len = PySequence_Size(cast_obj);
1081        if (!len) {
1082            Py_DECREF(cast_obj); cast_obj = NULL;
1083        }
1084    }
1085    else {
1086        PyErr_SetString(PyExc_TypeError,
1087                        "Function cast_record() expects a callable"
1088                        " or tuple or list of callables as second argument");
1089        return NULL;
1090    }
1091
1092    ret = cast_record(string, size, encoding, 0, cast_obj, len, delim);
1093
1094    Py_XDECREF(string_obj);
1095
1096    return ret;
1097}
1098
1099/* Cast a string with a text representation of an hstore to a dict. */
1100static char pg_cast_hstore__doc__[] =
1101"cast_hstore(string) -- cast a string as an hstore";
1102
1103PyObject *
1104pg_cast_hstore(PyObject *self, PyObject *string)
1105{
1106    PyObject *tmp_obj = NULL, *ret;
1107    char *s;
1108    Py_ssize_t size;
1109    int encoding;
1110
1111    if (PyBytes_Check(string)) {
1112        PyBytes_AsStringAndSize(string, &s, &size);
1113        encoding = pg_encoding_ascii;
1114    }
1115    else if (PyUnicode_Check(string)) {
1116        tmp_obj = PyUnicode_AsUTF8String(string);
1117        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
1118        PyBytes_AsStringAndSize(tmp_obj, &s, &size);
1119        encoding = pg_encoding_utf8;
1120    }
1121    else {
1122        PyErr_SetString(
1123            PyExc_TypeError,
1124            "Function cast_hstore() expects a string as first argument");
1125        return NULL;
1126    }
1127
1128    ret = cast_hstore(s, size, encoding);
1129
1130    Py_XDECREF(tmp_obj);
1131
1132    return ret;
1133}
1134
1135/* The list of functions defined in the module */
1136
1137static struct PyMethodDef pg_methods[] = {
1138    {"connect", (PyCFunction) pg_connect,
1139        METH_VARARGS|METH_KEYWORDS, pg_connect__doc__},
1140    {"escape_string", (PyCFunction) pg_escape_string,
1141        METH_O, pg_escape_string__doc__},
1142    {"escape_bytea", (PyCFunction) pg_escape_bytea,
1143        METH_O, pg_escape_bytea__doc__},
1144    {"unescape_bytea", (PyCFunction) pg_unescape_bytea,
1145        METH_O, pg_unescape_bytea__doc__},
1146    {"get_datestyle", (PyCFunction) pg_get_datestyle,
1147        METH_NOARGS, pg_get_datestyle__doc__},
1148    {"set_datestyle", (PyCFunction) pg_set_datestyle,
1149        METH_VARARGS, pg_set_datestyle__doc__},
1150    {"get_decimal_point", (PyCFunction) pg_get_decimal_point,
1151        METH_NOARGS, pg_get_decimal_point__doc__},
1152    {"set_decimal_point", (PyCFunction) pg_set_decimal_point,
1153        METH_VARARGS, pg_set_decimal_point__doc__},
1154    {"get_decimal", (PyCFunction) pg_get_decimal,
1155        METH_NOARGS, pg_get_decimal__doc__},
1156    {"set_decimal", (PyCFunction) pg_set_decimal,
1157        METH_O, pg_set_decimal__doc__},
1158    {"get_bool", (PyCFunction) pg_get_bool,
1159        METH_NOARGS, pg_get_bool__doc__},
1160    {"set_bool", (PyCFunction) pg_set_bool,
1161        METH_VARARGS, pg_set_bool__doc__},
1162    {"get_array", (PyCFunction) pg_get_array,
1163        METH_NOARGS, pg_get_array__doc__},
1164    {"set_array", (PyCFunction) pg_set_array,
1165        METH_VARARGS, pg_set_array__doc__},
1166    {"set_query_helpers", (PyCFunction) pg_set_query_helpers,
1167        METH_VARARGS, pg_set_query_helpers__doc__},
1168    {"get_bytea_escaped", (PyCFunction) pg_get_bytea_escaped,
1169        METH_NOARGS, pg_get_bytea_escaped__doc__},
1170    {"set_bytea_escaped", (PyCFunction) pg_set_bytea_escaped,
1171        METH_VARARGS, pg_set_bytea_escaped__doc__},
1172    {"get_jsondecode", (PyCFunction) pg_get_jsondecode,
1173        METH_NOARGS, pg_get_jsondecode__doc__},
1174    {"set_jsondecode", (PyCFunction) pg_set_jsondecode,
1175        METH_O, pg_set_jsondecode__doc__},
1176    {"cast_array", (PyCFunction) pg_cast_array,
1177        METH_VARARGS|METH_KEYWORDS, pg_cast_array__doc__},
1178    {"cast_record", (PyCFunction) pg_cast_record,
1179        METH_VARARGS|METH_KEYWORDS, pg_cast_record__doc__},
1180    {"cast_hstore", (PyCFunction) pg_cast_hstore,
1181        METH_O, pg_cast_hstore__doc__},
1182
1183#ifdef DEFAULT_VARS
1184    {"get_defhost", pg_get_defhost, METH_NOARGS, pg_get_defhost__doc__},
1185    {"set_defhost", pg_set_defhost, METH_VARARGS, pg_set_defhost__doc__},
1186    {"get_defbase", pg_get_defbase, METH_NOARGS, pg_get_defbase__doc__},
1187    {"set_defbase", pg_set_defbase, METH_VARARGS, pg_set_defbase__doc__},
1188    {"get_defopt", pg_get_defopt, METH_NOARGS, pg_get_defopt__doc__},
1189    {"set_defopt", pg_setdefopt, METH_VARARGS, pg_set_defopt__doc__},
1190    {"get_defport", pg_get_defport, METH_NOARGS, pg_get_defport__doc__},
1191    {"set_defport", pg_set_defport, METH_VARARGS, pg_set_defport__doc__},
1192    {"get_defuser", pg_get_defuser, METH_NOARGS, pg_get_defuser__doc__},
1193    {"set_defuser", pg_set_defuser, METH_VARARGS, pg_set_defuser__doc__},
1194    {"set_defpasswd", pg_set_defpasswd, METH_VARARGS, pg_set_defpasswd__doc__},
1195#endif /* DEFAULT_VARS */
1196    {NULL, NULL} /* sentinel */
1197};
1198
1199static char pg__doc__[] = "Python interface to PostgreSQL DB";
1200
1201static struct PyModuleDef moduleDef = {
1202    PyModuleDef_HEAD_INIT,
1203    "_pg",     /* m_name */
1204    pg__doc__, /* m_doc */
1205    -1,        /* m_size */
1206    pg_methods /* m_methods */
1207};
1208
1209/* Initialization function for the module */
1210MODULE_INIT_FUNC(_pg)
1211{
1212    PyObject *mod, *dict, *s;
1213
1214    /* Create the module and add the functions */
1215
1216    mod = PyModule_Create(&moduleDef);
1217
1218    /* Initialize here because some Windows platforms get confused otherwise */
1219#if IS_PY3
1220    connType.tp_base = noticeType.tp_base =
1221        queryType.tp_base = sourceType.tp_base = &PyBaseObject_Type;
1222#ifdef LARGE_OBJECTS
1223    largeType.tp_base = &PyBaseObject_Type;
1224#endif
1225#else
1226    connType.ob_type = noticeType.ob_type =
1227        queryType.ob_type = sourceType.ob_type = &PyType_Type;
1228#ifdef LARGE_OBJECTS
1229    largeType.ob_type = &PyType_Type;
1230#endif
1231#endif
1232
1233    if (PyType_Ready(&connType)
1234        || PyType_Ready(&noticeType)
1235        || PyType_Ready(&queryType)
1236        || PyType_Ready(&sourceType)
1237#ifdef LARGE_OBJECTS
1238        || PyType_Ready(&largeType)
1239#endif
1240        )
1241    {
1242        return NULL;
1243    }
1244
1245    dict = PyModule_GetDict(mod);
1246
1247    /* Exceptions as defined by DB-API 2.0 */
1248    Error = PyErr_NewException("pg.Error", PyExc_Exception, NULL);
1249    PyDict_SetItemString(dict, "Error", Error);
1250
1251    Warning = PyErr_NewException("pg.Warning", PyExc_Exception, NULL);
1252    PyDict_SetItemString(dict, "Warning", Warning);
1253
1254    InterfaceError = PyErr_NewException(
1255        "pg.InterfaceError", Error, NULL);
1256    PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
1257
1258    DatabaseError = PyErr_NewException(
1259        "pg.DatabaseError", Error, NULL);
1260    PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
1261
1262    InternalError = PyErr_NewException(
1263        "pg.InternalError", DatabaseError, NULL);
1264    PyDict_SetItemString(dict, "InternalError", InternalError);
1265
1266    OperationalError = PyErr_NewException(
1267        "pg.OperationalError", DatabaseError, NULL);
1268    PyDict_SetItemString(dict, "OperationalError", OperationalError);
1269
1270    ProgrammingError = PyErr_NewException(
1271        "pg.ProgrammingError", DatabaseError, NULL);
1272    PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
1273
1274    IntegrityError = PyErr_NewException(
1275        "pg.IntegrityError", DatabaseError, NULL);
1276    PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
1277
1278    DataError = PyErr_NewException(
1279        "pg.DataError", DatabaseError, NULL);
1280    PyDict_SetItemString(dict, "DataError", DataError);
1281
1282    NotSupportedError = PyErr_NewException(
1283        "pg.NotSupportedError", DatabaseError, NULL);
1284    PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
1285
1286    InvalidResultError = PyErr_NewException(
1287        "pg.InvalidResultError", DataError, NULL);
1288    PyDict_SetItemString(dict, "InvalidResultError", InvalidResultError);
1289
1290    NoResultError = PyErr_NewException(
1291        "pg.NoResultError", InvalidResultError, NULL);
1292    PyDict_SetItemString(dict, "NoResultError", NoResultError);
1293
1294    MultipleResultsError = PyErr_NewException(
1295        "pg.MultipleResultsError", InvalidResultError, NULL);
1296    PyDict_SetItemString(dict, "MultipleResultsError", MultipleResultsError);
1297
1298    /* Make the version available */
1299    s = PyStr_FromString(PyPgVersion);
1300    PyDict_SetItemString(dict, "version", s);
1301    PyDict_SetItemString(dict, "__version__", s);
1302    Py_DECREF(s);
1303
1304    /* Result types for queries */
1305    PyDict_SetItemString(dict, "RESULT_EMPTY", PyInt_FromLong(RESULT_EMPTY));
1306    PyDict_SetItemString(dict, "RESULT_DML", PyInt_FromLong(RESULT_DML));
1307    PyDict_SetItemString(dict, "RESULT_DDL", PyInt_FromLong(RESULT_DDL));
1308    PyDict_SetItemString(dict, "RESULT_DQL", PyInt_FromLong(RESULT_DQL));
1309
1310    /* Transaction states */
1311    PyDict_SetItemString(dict,"TRANS_IDLE",PyInt_FromLong(PQTRANS_IDLE));
1312    PyDict_SetItemString(dict,"TRANS_ACTIVE",PyInt_FromLong(PQTRANS_ACTIVE));
1313    PyDict_SetItemString(dict,"TRANS_INTRANS",PyInt_FromLong(PQTRANS_INTRANS));
1314    PyDict_SetItemString(dict,"TRANS_INERROR",PyInt_FromLong(PQTRANS_INERROR));
1315    PyDict_SetItemString(dict,"TRANS_UNKNOWN",PyInt_FromLong(PQTRANS_UNKNOWN));
1316
1317#ifdef LARGE_OBJECTS
1318    /* Create mode for large objects */
1319    PyDict_SetItemString(dict, "INV_READ", PyInt_FromLong(INV_READ));
1320    PyDict_SetItemString(dict, "INV_WRITE", PyInt_FromLong(INV_WRITE));
1321
1322    /* Position flags for lo_lseek */
1323    PyDict_SetItemString(dict, "SEEK_SET", PyInt_FromLong(SEEK_SET));
1324    PyDict_SetItemString(dict, "SEEK_CUR", PyInt_FromLong(SEEK_CUR));
1325    PyDict_SetItemString(dict, "SEEK_END", PyInt_FromLong(SEEK_END));
1326#endif /* LARGE_OBJECTS */
1327
1328#ifdef DEFAULT_VARS
1329    /* Prepare default values */
1330    Py_INCREF(Py_None);
1331    pg_default_host = Py_None;
1332    Py_INCREF(Py_None);
1333    pg_default_base = Py_None;
1334    Py_INCREF(Py_None);
1335    pg_default_opt = Py_None;
1336    Py_INCREF(Py_None);
1337    pg_default_port = Py_None;
1338    Py_INCREF(Py_None);
1339    pg_default_user = Py_None;
1340    Py_INCREF(Py_None);
1341    pg_default_passwd = Py_None;
1342#endif /* DEFAULT_VARS */
1343
1344    /* Store common pg encoding ids */
1345
1346    pg_encoding_utf8 = pg_char_to_encoding("UTF8");
1347    pg_encoding_latin1 = pg_char_to_encoding("LATIN1");
1348    pg_encoding_ascii = pg_char_to_encoding("SQL_ASCII");
1349
1350    /* Check for errors */
1351    if (PyErr_Occurred()) {
1352        return NULL;
1353    }
1354
1355    return mod;
1356}
Note: See TracBrowser for help on using the repository browser.