source: trunk/pgconn.c

Last change on this file was 1002, checked in by cito, 3 months ago

Use same prefix for all C files

So that they are not scattered among the other files
in the root directory.

File size: 44.3 KB
Line 
1/*
2 * $Id: pgconn.c 985 2019-04-22 22:07:43Z cito $
3 *
4 * PyGreSQL - a Python interface for the PostgreSQL database.
5 *
6 * The connection object - this file is part a of 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/* Deallocate connection object. */
15static void
16conn_dealloc(connObject *self)
17{
18    if (self->cnx) {
19        Py_BEGIN_ALLOW_THREADS
20        PQfinish(self->cnx);
21        Py_END_ALLOW_THREADS
22    }
23    Py_XDECREF(self->cast_hook);
24    Py_XDECREF(self->notice_receiver);
25    PyObject_Del(self);
26}
27
28/* Get connection attributes. */
29static PyObject *
30conn_getattr(connObject *self, PyObject *nameobj)
31{
32    const char *name = PyStr_AsString(nameobj);
33
34    /*
35     * Although we could check individually, there are only a few
36     * attributes that don't require a live connection and unless someone
37     * has an urgent need, this will have to do.
38     */
39
40    /* first exception - close which returns a different error */
41    if (strcmp(name, "close") && !self->cnx) {
42        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
43        return NULL;
44    }
45
46    /* list PostgreSQL connection fields */
47
48    /* postmaster host */
49    if (!strcmp(name, "host")) {
50        char *r = PQhost(self->cnx);
51        if (!r || r[0] == '/') /* Pg >= 9.6 can return a Unix socket path */
52            r = "localhost";
53        return PyStr_FromString(r);
54    }
55
56    /* postmaster port */
57    if (!strcmp(name, "port"))
58        return PyInt_FromLong(atol(PQport(self->cnx)));
59
60    /* selected database */
61    if (!strcmp(name, "db"))
62        return PyStr_FromString(PQdb(self->cnx));
63
64    /* selected options */
65    if (!strcmp(name, "options"))
66        return PyStr_FromString(PQoptions(self->cnx));
67
68    /* error (status) message */
69    if (!strcmp(name, "error"))
70        return PyStr_FromString(PQerrorMessage(self->cnx));
71
72    /* connection status : 1 - OK, 0 - BAD */
73    if (!strcmp(name, "status"))
74        return PyInt_FromLong(PQstatus(self->cnx) == CONNECTION_OK ? 1 : 0);
75
76    /* provided user name */
77    if (!strcmp(name, "user"))
78        return PyStr_FromString(PQuser(self->cnx));
79
80    /* protocol version */
81    if (!strcmp(name, "protocol_version"))
82        return PyInt_FromLong(PQprotocolVersion(self->cnx));
83
84    /* backend version */
85    if (!strcmp(name, "server_version"))
86        return PyInt_FromLong(PQserverVersion(self->cnx));
87
88    /* descriptor number of connection socket */
89    if (!strcmp(name, "socket")) {
90        return PyInt_FromLong(PQsocket(self->cnx));
91    }
92
93    /* PID of backend process */
94    if (!strcmp(name, "backend_pid")) {
95        return PyInt_FromLong(PQbackendPID(self->cnx));
96    }
97
98    /* whether the connection uses SSL */
99    if (!strcmp(name, "ssl_in_use")) {
100#ifdef SSL_INFO
101        if (PQsslInUse(self->cnx)) {
102            Py_INCREF(Py_True); return Py_True;
103        }
104        else {
105            Py_INCREF(Py_False); return Py_False;
106        }
107#else
108        set_error_msg(NotSupportedError, "SSL info functions not supported");
109        return NULL;
110#endif
111    }
112
113    /* SSL attributes */
114    if (!strcmp(name, "ssl_attributes")) {
115#ifdef SSL_INFO
116        return get_ssl_attributes(self->cnx);
117#else
118        set_error_msg(NotSupportedError, "SSL info functions not supported");
119        return NULL;
120#endif
121    }
122
123    return PyObject_GenericGetAttr((PyObject *) self, nameobj);
124}
125
126/* Check connection validity. */
127static int
128_check_cnx_obj(connObject *self)
129{
130    if (!self || !self->valid || !self->cnx) {
131        set_error_msg(OperationalError, "Connection has been closed");
132        return 0;
133    }
134    return 1;
135}
136
137/* Create source object. */
138static char conn_source__doc__[] =
139"source() -- create a new source object for this connection";
140
141static PyObject *
142conn_source(connObject *self, PyObject *noargs)
143{
144    sourceObject *source_obj;
145
146    /* checks validity */
147    if (!_check_cnx_obj(self)) {
148        return NULL;
149    }
150
151    /* allocates new query object */
152    if (!(source_obj = PyObject_NEW(sourceObject, &sourceType))) {
153        return NULL;
154    }
155
156    /* initializes internal parameters */
157    Py_XINCREF(self);
158    source_obj->pgcnx = self;
159    source_obj->result = NULL;
160    source_obj->valid = 1;
161    source_obj->arraysize = PG_ARRAYSIZE;
162
163    return (PyObject *) source_obj;
164}
165
166/* Base method for execution of both unprepared and prepared queries */
167static PyObject *
168_conn_query(connObject *self, PyObject *args, int prepared)
169{
170    PyObject *query_str_obj, *param_obj = NULL;
171    PGresult* result;
172    queryObject* query_obj;
173    char *query;
174    int encoding, status, nparms = 0;
175
176    if (!self->cnx) {
177        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
178        return NULL;
179    }
180
181    /* get query args */
182    if (!PyArg_ParseTuple(args, "O|O", &query_str_obj, &param_obj)) {
183        return NULL;
184    }
185
186    encoding = PQclientEncoding(self->cnx);
187
188    if (PyBytes_Check(query_str_obj)) {
189        query = PyBytes_AsString(query_str_obj);
190        query_str_obj = NULL;
191    }
192    else if (PyUnicode_Check(query_str_obj)) {
193        query_str_obj = get_encoded_string(query_str_obj, encoding);
194        if (!query_str_obj) return NULL; /* pass the UnicodeEncodeError */
195        query = PyBytes_AsString(query_str_obj);
196    }
197    else {
198        PyErr_SetString(PyExc_TypeError,
199                        "Method query() expects a string as first argument");
200        return NULL;
201    }
202
203    /* If param_obj is passed, ensure it's a non-empty tuple. We want to treat
204     * an empty tuple the same as no argument since we'll get that when the
205     * caller passes no arguments to db.query(), and historic behaviour was
206     * to call PQexec() in that case, which can execute multiple commands. */
207    if (param_obj) {
208        param_obj = PySequence_Fast(
209            param_obj, "Method query() expects a sequence as second argument");
210        if (!param_obj) {
211            Py_XDECREF(query_str_obj);
212            return NULL;
213        }
214        nparms = (int) PySequence_Fast_GET_SIZE(param_obj);
215
216        /* if there's a single argument and it's a list or tuple, it
217         * contains the positional arguments. */
218        if (nparms == 1) {
219            PyObject *first_obj = PySequence_Fast_GET_ITEM(param_obj, 0);
220            if (PyList_Check(first_obj) || PyTuple_Check(first_obj)) {
221                Py_DECREF(param_obj);
222                param_obj = PySequence_Fast(first_obj, NULL);
223                nparms = (int) PySequence_Fast_GET_SIZE(param_obj);
224            }
225        }
226    }
227
228    /* gets result */
229    if (nparms) {
230        /* prepare arguments */
231        PyObject **str, **s;
232        const char **parms, **p;
233        register int i;
234
235        str = (PyObject **) PyMem_Malloc(nparms * sizeof(*str));
236        parms = (const char **) PyMem_Malloc(nparms * sizeof(*parms));
237        if (!str || !parms) {
238            PyMem_Free((void *) parms); PyMem_Free(str);
239            Py_XDECREF(query_str_obj); Py_XDECREF(param_obj);
240            return PyErr_NoMemory();
241        }
242
243        /* convert optional args to a list of strings -- this allows
244         * the caller to pass whatever they like, and prevents us
245         * from having to map types to OIDs */
246        for (i = 0, s = str, p = parms; i < nparms; ++i, ++p) {
247            PyObject *obj = PySequence_Fast_GET_ITEM(param_obj, i);
248
249            if (obj == Py_None) {
250                *p = NULL;
251            }
252            else if (PyBytes_Check(obj)) {
253                *p = PyBytes_AsString(obj);
254            }
255            else if (PyUnicode_Check(obj)) {
256                PyObject *str_obj = get_encoded_string(obj, encoding);
257                if (!str_obj) {
258                    PyMem_Free((void *) parms);
259                    while (s != str) { s--; Py_DECREF(*s); }
260                    PyMem_Free(str);
261                    Py_XDECREF(query_str_obj);
262                    Py_XDECREF(param_obj);
263                    /* pass the UnicodeEncodeError */
264                    return NULL;
265                }
266                *s++ = str_obj;
267                *p = PyBytes_AsString(str_obj);
268            }
269            else {
270                PyObject *str_obj = PyObject_Str(obj);
271                if (!str_obj) {
272                    PyMem_Free((void *) parms);
273                    while (s != str) { s--; Py_DECREF(*s); }
274                    PyMem_Free(str);
275                    Py_XDECREF(query_str_obj);
276                    Py_XDECREF(param_obj);
277                    PyErr_SetString(
278                        PyExc_TypeError,
279                        "Query parameter has no string representation");
280                    return NULL;
281                }
282                *s++ = str_obj;
283                *p = PyStr_AsString(str_obj);
284            }
285        }
286
287        Py_BEGIN_ALLOW_THREADS
288        result = prepared ?
289            PQexecPrepared(self->cnx, query, nparms,
290                parms, NULL, NULL, 0) :
291            PQexecParams(self->cnx, query, nparms,
292                NULL, parms, NULL, NULL, 0);
293        Py_END_ALLOW_THREADS
294
295        PyMem_Free((void *) parms);
296        while (s != str) { s--; Py_DECREF(*s); }
297        PyMem_Free(str);
298    }
299    else {
300        Py_BEGIN_ALLOW_THREADS
301        result = prepared ?
302            PQexecPrepared(self->cnx, query, 0,
303                NULL, NULL, NULL, 0) :
304            PQexec(self->cnx, query);
305        Py_END_ALLOW_THREADS
306    }
307
308    /* we don't need the query and its params any more */
309    Py_XDECREF(query_str_obj);
310    Py_XDECREF(param_obj);
311
312    /* checks result validity */
313    if (!result) {
314        PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->cnx));
315        return NULL;
316    }
317
318    /* this may have changed the datestyle, so we reset the date format
319       in order to force fetching it newly when next time requested */
320    self->date_format = date_format; /* this is normally NULL */
321
322    /* checks result status */
323    if ((status = PQresultStatus(result)) != PGRES_TUPLES_OK) {
324        switch (status) {
325            case PGRES_EMPTY_QUERY:
326                PyErr_SetString(PyExc_ValueError, "Empty query");
327                break;
328            case PGRES_BAD_RESPONSE:
329            case PGRES_FATAL_ERROR:
330            case PGRES_NONFATAL_ERROR:
331                set_error(ProgrammingError, "Cannot execute query",
332                    self->cnx, result);
333                break;
334            case PGRES_COMMAND_OK:
335                {   /* INSERT, UPDATE, DELETE */
336                    Oid oid = PQoidValue(result);
337
338                    if (oid == InvalidOid) {  /* not a single insert */
339                        char *ret = PQcmdTuples(result);
340
341                        if (ret[0]) {  /* return number of rows affected */
342                            PyObject *obj = PyStr_FromString(ret);
343                            PQclear(result);
344                            return obj;
345                        }
346                        PQclear(result);
347                        Py_INCREF(Py_None);
348                        return Py_None;
349                    }
350                    /* for a single insert, return the oid */
351                    PQclear(result);
352                    return PyInt_FromLong(oid);
353                }
354            case PGRES_COPY_OUT: /* no data will be received */
355            case PGRES_COPY_IN:
356                PQclear(result);
357                Py_INCREF(Py_None);
358                return Py_None;
359            default:
360                set_error_msg(InternalError, "Unknown result status");
361        }
362
363        PQclear(result);
364        return NULL; /* error detected on query */
365    }
366
367    if (!(query_obj = PyObject_NEW(queryObject, &queryType)))
368        return PyErr_NoMemory();
369
370    /* stores result and returns object */
371    Py_XINCREF(self);
372    query_obj->pgcnx = self;
373    query_obj->result = result;
374    query_obj->encoding = encoding;
375    query_obj->current_row = 0;
376    query_obj->max_row = PQntuples(result);
377    query_obj->num_fields = PQnfields(result);
378    query_obj->col_types = get_col_types(result, query_obj->num_fields);
379    if (!query_obj->col_types) {
380        Py_DECREF(query_obj);
381        Py_DECREF(self);
382        return NULL;
383    }
384
385    return (PyObject *) query_obj;
386}
387
388/* Database query */
389static char conn_query__doc__[] =
390"query(sql, [arg]) -- create a new query object for this connection\n\n"
391"You must pass the SQL (string) request and you can optionally pass\n"
392"a tuple with positional parameters.\n";
393
394static PyObject *
395conn_query(connObject *self, PyObject *args)
396{
397    return _conn_query(self, args, 0);
398}
399
400/* Execute prepared statement. */
401static char conn_query_prepared__doc__[] =
402"query_prepared(name, [arg]) -- execute a prepared statement\n\n"
403"You must pass the name (string) of the prepared statement and you can\n"
404"optionally pass a tuple with positional parameters.\n";
405
406static PyObject *
407conn_query_prepared(connObject *self, PyObject *args)
408{
409    return _conn_query(self, args, 1);
410}
411
412/* Create prepared statement. */
413static char conn_prepare__doc__[] =
414"prepare(name, sql) -- create a prepared statement\n\n"
415"You must pass the name (string) of the prepared statement and the\n"
416"SQL (string) request for later execution.\n";
417
418static PyObject *
419conn_prepare(connObject *self, PyObject *args)
420{
421    char *name, *query;
422    int name_length, query_length;
423    PGresult *result;
424
425    if (!self->cnx) {
426        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
427        return NULL;
428    }
429
430    /* reads args */
431    if (!PyArg_ParseTuple(args, "s#s#",
432        &name, &name_length, &query, &query_length))
433    {
434        PyErr_SetString(PyExc_TypeError,
435                        "Method prepare() takes two string arguments");
436        return NULL;
437    }
438
439    /* create prepared statement */
440    Py_BEGIN_ALLOW_THREADS
441    result = PQprepare(self->cnx, name, query, 0, NULL);
442    Py_END_ALLOW_THREADS
443    if (result && PQresultStatus(result) == PGRES_COMMAND_OK) {
444        PQclear(result);
445        Py_INCREF(Py_None);
446        return Py_None; /* success */
447    }
448    set_error(ProgrammingError, "Cannot create prepared statement",
449        self->cnx, result);
450    if (result)
451        PQclear(result);
452    return NULL; /* error */
453}
454
455/* Describe prepared statement. */
456static char conn_describe_prepared__doc__[] =
457"describe_prepared(name) -- describe a prepared statement\n\n"
458"You must pass the name (string) of the prepared statement.\n";
459
460static PyObject *
461conn_describe_prepared(connObject *self, PyObject *args)
462{
463    char *name;
464    int name_length;
465    PGresult *result;
466
467    if (!self->cnx) {
468        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
469        return NULL;
470    }
471
472    /* reads args */
473    if (!PyArg_ParseTuple(args, "s#", &name, &name_length)) {
474        PyErr_SetString(PyExc_TypeError,
475                        "Method prepare() takes a string argument");
476        return NULL;
477    }
478
479    /* describe prepared statement */
480    Py_BEGIN_ALLOW_THREADS
481    result = PQdescribePrepared(self->cnx, name);
482    Py_END_ALLOW_THREADS
483    if (result && PQresultStatus(result) == PGRES_COMMAND_OK) {
484        queryObject *query_obj = PyObject_NEW(queryObject, &queryType);
485        if (!query_obj)
486            return PyErr_NoMemory();
487        Py_XINCREF(self);
488        query_obj->pgcnx = self;
489        query_obj->result = result;
490        query_obj->encoding = PQclientEncoding(self->cnx);
491        query_obj->current_row = 0;
492        query_obj->max_row = PQntuples(result);
493        query_obj->num_fields = PQnfields(result);
494        query_obj->col_types = get_col_types(result, query_obj->num_fields);
495        return (PyObject *) query_obj;
496    }
497    set_error(ProgrammingError, "Cannot describe prepared statement",
498        self->cnx, result);
499    if (result)
500        PQclear(result);
501    return NULL; /* error */
502}
503
504#ifdef DIRECT_ACCESS
505static char conn_putline__doc__[] =
506"putline(line) -- send a line directly to the backend";
507
508/* Direct access function: putline. */
509static PyObject *
510conn_putline(connObject *self, PyObject *args)
511{
512    char *line;
513    int line_length;
514
515    if (!self->cnx) {
516        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
517        return NULL;
518    }
519
520    /* reads args */
521    if (!PyArg_ParseTuple(args, "s#", &line, &line_length)) {
522        PyErr_SetString(PyExc_TypeError,
523                        "Method putline() takes a string argument");
524        return NULL;
525    }
526
527    /* sends line to backend */
528    if (PQputline(self->cnx, line)) {
529        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
530        return NULL;
531    }
532    Py_INCREF(Py_None);
533    return Py_None;
534}
535
536/* Direct access function: getline. */
537static char conn_getline__doc__[] =
538"getline() -- get a line directly from the backend";
539
540static PyObject *
541conn_getline(connObject *self, PyObject *noargs)
542{
543    char line[MAX_BUFFER_SIZE];
544    PyObject *str = NULL;     /* GCC */
545
546    if (!self->cnx) {
547        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
548        return NULL;
549    }
550
551    /* gets line */
552    switch (PQgetline(self->cnx, line, MAX_BUFFER_SIZE)) {
553        case 0:
554            str = PyStr_FromString(line);
555            break;
556        case 1:
557            PyErr_SetString(PyExc_MemoryError, "Buffer overflow");
558            str = NULL;
559            break;
560        case EOF:
561            Py_INCREF(Py_None);
562            str = Py_None;
563            break;
564    }
565
566    return str;
567}
568
569/* Direct access function: end copy. */
570static char conn_endcopy__doc__[] =
571"endcopy() -- synchronize client and server";
572
573static PyObject *
574conn_endcopy(connObject *self, PyObject *noargs)
575{
576    if (!self->cnx) {
577        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
578        return NULL;
579    }
580
581    /* ends direct copy */
582    if (PQendcopy(self->cnx)) {
583        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
584        return NULL;
585    }
586    Py_INCREF(Py_None);
587    return Py_None;
588}
589#endif /* DIRECT_ACCESS */
590
591
592/* Insert table */
593static char conn_inserttable__doc__[] =
594"inserttable(table, data) -- insert list into table\n\n"
595"The fields in the list must be in the same order as in the table.\n";
596
597static PyObject *
598conn_inserttable(connObject *self, PyObject *args)
599{
600    PGresult *result;
601    char *table, *buffer, *bufpt;
602    int encoding;
603    size_t bufsiz;
604    PyObject *list, *sublist, *item;
605    PyObject *(*getitem) (PyObject *, Py_ssize_t);
606    PyObject *(*getsubitem) (PyObject *, Py_ssize_t);
607    Py_ssize_t i, j, m, n;
608
609    if (!self->cnx) {
610        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
611        return NULL;
612    }
613
614    /* gets arguments */
615    if (!PyArg_ParseTuple(args, "sO:filter", &table, &list)) {
616        PyErr_SetString(
617            PyExc_TypeError,
618            "Method inserttable() expects a string and a list as arguments");
619        return NULL;
620    }
621
622    /* checks list type */
623    if (PyList_Check(list)) {
624        m = PyList_Size(list);
625        getitem = PyList_GetItem;
626    }
627    else if (PyTuple_Check(list)) {
628        m = PyTuple_Size(list);
629        getitem = PyTuple_GetItem;
630    }
631    else {
632        PyErr_SetString(
633            PyExc_TypeError,
634            "Method inserttable() expects a list or a tuple"
635            " as second argument");
636        return NULL;
637    }
638
639    /* allocate buffer */
640    if (!(buffer = PyMem_Malloc(MAX_BUFFER_SIZE)))
641        return PyErr_NoMemory();
642
643    /* starts query */
644    sprintf(buffer, "copy %s from stdin", table);
645
646    Py_BEGIN_ALLOW_THREADS
647    result = PQexec(self->cnx, buffer);
648    Py_END_ALLOW_THREADS
649
650    if (!result) {
651        PyMem_Free(buffer);
652        PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->cnx));
653        return NULL;
654    }
655
656    encoding = PQclientEncoding(self->cnx);
657
658    PQclear(result);
659
660    n = 0; /* not strictly necessary but avoids warning */
661
662    /* feed table */
663    for (i = 0; i < m; ++i) {
664        sublist = getitem(list, i);
665        if (PyTuple_Check(sublist)) {
666            j = PyTuple_Size(sublist);
667            getsubitem = PyTuple_GetItem;
668        }
669        else if (PyList_Check(sublist)) {
670            j = PyList_Size(sublist);
671            getsubitem = PyList_GetItem;
672        }
673        else {
674            PyErr_SetString(
675                PyExc_TypeError,
676                "The second argument must contain a tuple or a list");
677            return NULL;
678        }
679        if (i) {
680            if (j != n) {
681                PyMem_Free(buffer);
682                PyErr_SetString(
683                    PyExc_TypeError,
684                    "Arrays contained in second arg must have same size");
685                return NULL;
686            }
687        }
688        else {
689            n = j; /* never used before this assignment */
690        }
691
692        /* builds insert line */
693        bufpt = buffer;
694        bufsiz = MAX_BUFFER_SIZE - 1;
695
696        for (j = 0; j < n; ++j) {
697            if (j) {
698                *bufpt++ = '\t'; --bufsiz;
699            }
700
701            item = getsubitem(sublist, j);
702
703            /* convert item to string and append to buffer */
704            if (item == Py_None) {
705                if (bufsiz > 2) {
706                    *bufpt++ = '\\'; *bufpt++ = 'N';
707                    bufsiz -= 2;
708                }
709                else
710                    bufsiz = 0;
711            }
712            else if (PyBytes_Check(item)) {
713                const char* t = PyBytes_AsString(item);
714
715                while (*t && bufsiz) {
716                    if (*t == '\\' || *t == '\t' || *t == '\n') {
717                        *bufpt++ = '\\'; --bufsiz;
718                        if (!bufsiz) break;
719                    }
720                    *bufpt++ = *t++; --bufsiz;
721                }
722            }
723            else if (PyUnicode_Check(item)) {
724                PyObject *s = get_encoded_string(item, encoding);
725                if (!s) {
726                    PyMem_Free(buffer);
727                    return NULL; /* pass the UnicodeEncodeError */
728                }
729                else {
730                    const char* t = PyBytes_AsString(s);
731
732                    while (*t && bufsiz) {
733                        if (*t == '\\' || *t == '\t' || *t == '\n') {
734                            *bufpt++ = '\\'; --bufsiz;
735                            if (!bufsiz) break;
736                        }
737                        *bufpt++ = *t++; --bufsiz;
738                    }
739                    Py_DECREF(s);
740                }
741            }
742            else if (PyInt_Check(item) || PyLong_Check(item)) {
743                PyObject* s = PyObject_Str(item);
744                const char* t = PyStr_AsString(s);
745
746                while (*t && bufsiz) {
747                    *bufpt++ = *t++; --bufsiz;
748                }
749                Py_DECREF(s);
750            }
751            else {
752                PyObject* s = PyObject_Repr(item);
753                const char* t = PyStr_AsString(s);
754
755                while (*t && bufsiz) {
756                    if (*t == '\\' || *t == '\t' || *t == '\n') {
757                        *bufpt++ = '\\'; --bufsiz;
758                        if (!bufsiz) break;
759                    }
760                    *bufpt++ = *t++; --bufsiz;
761                }
762                Py_DECREF(s);
763            }
764
765            if (bufsiz <= 0) {
766                PyMem_Free(buffer); return PyErr_NoMemory();
767            }
768
769        }
770
771        *bufpt++ = '\n'; *bufpt = '\0';
772
773        /* sends data */
774        if (PQputline(self->cnx, buffer)) {
775            PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
776            PQendcopy(self->cnx);
777            PyMem_Free(buffer);
778            return NULL;
779        }
780    }
781
782    /* ends query */
783    if (PQputline(self->cnx, "\\.\n")) {
784        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
785        PQendcopy(self->cnx);
786        PyMem_Free(buffer);
787        return NULL;
788    }
789
790    if (PQendcopy(self->cnx)) {
791        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
792        PyMem_Free(buffer);
793        return NULL;
794    }
795
796    PyMem_Free(buffer);
797
798    /* no error : returns nothing */
799    Py_INCREF(Py_None);
800    return Py_None;
801}
802
803/* Get transaction state. */
804static char conn_transaction__doc__[] =
805"transaction() -- return the current transaction status";
806
807static PyObject *
808conn_transaction(connObject *self, PyObject *noargs)
809{
810    if (!self->cnx) {
811        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
812        return NULL;
813    }
814
815    return PyInt_FromLong(PQtransactionStatus(self->cnx));
816}
817
818/* Get parameter setting. */
819static char conn_parameter__doc__[] =
820"parameter(name) -- look up a current parameter setting";
821
822static PyObject *
823conn_parameter(connObject *self, PyObject *args)
824{
825    const char *name;
826
827    if (!self->cnx) {
828        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
829        return NULL;
830    }
831
832    /* get query args */
833    if (!PyArg_ParseTuple(args, "s", &name)) {
834        PyErr_SetString(PyExc_TypeError,
835                        "Method parameter() takes a string as argument");
836        return NULL;
837    }
838
839    name = PQparameterStatus(self->cnx, name);
840
841    if (name)
842        return PyStr_FromString(name);
843
844    /* unknown parameter, return None */
845    Py_INCREF(Py_None);
846    return Py_None;
847}
848
849/* Get current date format. */
850static char conn_date_format__doc__[] =
851"date_format() -- return the current date format";
852
853static PyObject *
854conn_date_format(connObject *self, PyObject *noargs)
855{
856    const char *fmt;
857
858    if (!self->cnx) {
859        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
860        return NULL;
861    }
862
863    /* check if the date format is cached in the connection */
864    fmt = self->date_format;
865    if (!fmt) {
866        fmt = date_style_to_format(PQparameterStatus(self->cnx, "DateStyle"));
867        self->date_format = fmt; /* cache the result */
868    }
869
870    return PyStr_FromString(fmt);
871}
872
873#ifdef ESCAPING_FUNCS
874
875/* Escape literal */
876static char conn_escape_literal__doc__[] =
877"escape_literal(str) -- escape a literal constant for use within SQL";
878
879static PyObject *
880conn_escape_literal(connObject *self, PyObject *string)
881{
882    PyObject *tmp_obj = NULL,  /* auxiliary string object */
883             *to_obj;          /* string object to return */
884    char *from,  /* our string argument as encoded string */
885         *to;    /* the result as encoded string */
886    Py_ssize_t from_length;    /* length of string */
887    size_t to_length;          /* length of result */
888    int encoding = -1;         /* client encoding */
889
890    if (PyBytes_Check(string)) {
891        PyBytes_AsStringAndSize(string, &from, &from_length);
892    }
893    else if (PyUnicode_Check(string)) {
894        encoding = PQclientEncoding(self->cnx);
895        tmp_obj = get_encoded_string(string, encoding);
896        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
897        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
898    }
899    else {
900        PyErr_SetString(
901            PyExc_TypeError,
902            "Method escape_literal() expects a string as argument");
903        return NULL;
904    }
905
906    to = PQescapeLiteral(self->cnx, from, (size_t) from_length);
907    to_length = strlen(to);
908
909    Py_XDECREF(tmp_obj);
910
911    if (encoding == -1)
912        to_obj = PyBytes_FromStringAndSize(to, to_length);
913    else
914        to_obj = get_decoded_string(to, to_length, encoding);
915    if (to)
916        PQfreemem(to);
917    return to_obj;
918}
919
920/* Escape identifier */
921static char conn_escape_identifier__doc__[] =
922"escape_identifier(str) -- escape an identifier for use within SQL";
923
924static PyObject *
925conn_escape_identifier(connObject *self, PyObject *string)
926{
927    PyObject *tmp_obj = NULL,  /* auxiliary string object */
928             *to_obj;          /* string object to return */
929    char *from,  /* our string argument as encoded string */
930         *to;    /* the result as encoded string */
931    Py_ssize_t from_length;    /* length of string */
932    size_t to_length;          /* length of result */
933    int encoding = -1;         /* client encoding */
934
935    if (PyBytes_Check(string)) {
936        PyBytes_AsStringAndSize(string, &from, &from_length);
937    }
938    else if (PyUnicode_Check(string)) {
939        encoding = PQclientEncoding(self->cnx);
940        tmp_obj = get_encoded_string(string, encoding);
941        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
942        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
943    }
944    else {
945        PyErr_SetString(
946            PyExc_TypeError,
947            "Method escape_identifier() expects a string as argument");
948        return NULL;
949    }
950
951    to = PQescapeIdentifier(self->cnx, from, (size_t) from_length);
952    to_length = strlen(to);
953
954    Py_XDECREF(tmp_obj);
955
956    if (encoding == -1)
957        to_obj = PyBytes_FromStringAndSize(to, to_length);
958    else
959        to_obj = get_decoded_string(to, to_length, encoding);
960    if (to)
961        PQfreemem(to);
962    return to_obj;
963}
964
965#endif /* ESCAPING_FUNCS */
966
967/* Escape string */
968static char conn_escape_string__doc__[] =
969"escape_string(str) -- escape a string for use within SQL";
970
971static PyObject *
972conn_escape_string(connObject *self, PyObject *string)
973{
974    PyObject *tmp_obj = NULL,  /* auxiliary string object */
975             *to_obj;          /* string object to return */
976    char *from,  /* our string argument as encoded string */
977         *to;    /* the result as encoded string */
978    Py_ssize_t from_length;    /* length of string */
979    size_t to_length;          /* length of result */
980    int encoding = -1;         /* client encoding */
981
982    if (PyBytes_Check(string)) {
983        PyBytes_AsStringAndSize(string, &from, &from_length);
984    }
985    else if (PyUnicode_Check(string)) {
986        encoding = PQclientEncoding(self->cnx);
987        tmp_obj = get_encoded_string(string, encoding);
988        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
989        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
990    }
991    else {
992        PyErr_SetString(
993            PyExc_TypeError,
994            "Method escape_string() expects a string as argument");
995        return NULL;
996    }
997
998    to_length = 2*from_length + 1;
999    if ((Py_ssize_t) to_length < from_length) { /* overflow */
1000        to_length = from_length;
1001        from_length = (from_length - 1)/2;
1002    }
1003    to = (char *) PyMem_Malloc(to_length);
1004    to_length = PQescapeStringConn(self->cnx,
1005        to, from, (size_t) from_length, NULL);
1006
1007    Py_XDECREF(tmp_obj);
1008
1009    if (encoding == -1)
1010        to_obj = PyBytes_FromStringAndSize(to, to_length);
1011    else
1012        to_obj = get_decoded_string(to, to_length, encoding);
1013    PyMem_Free(to);
1014    return to_obj;
1015}
1016
1017/* Escape bytea */
1018static char conn_escape_bytea__doc__[] =
1019"escape_bytea(data) -- escape binary data for use within SQL as type bytea";
1020
1021static PyObject *
1022conn_escape_bytea(connObject *self, PyObject *data)
1023{
1024    PyObject *tmp_obj = NULL,  /* auxiliary string object */
1025             *to_obj;          /* string object to return */
1026    char *from,  /* our string argument as encoded string */
1027         *to;    /* the result as encoded string */
1028    Py_ssize_t from_length;    /* length of string */
1029    size_t to_length;          /* length of result */
1030    int encoding = -1;         /* client encoding */
1031
1032    if (PyBytes_Check(data)) {
1033        PyBytes_AsStringAndSize(data, &from, &from_length);
1034    }
1035    else if (PyUnicode_Check(data)) {
1036        encoding = PQclientEncoding(self->cnx);
1037        tmp_obj = get_encoded_string(data, encoding);
1038        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
1039        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
1040    }
1041    else {
1042        PyErr_SetString(
1043            PyExc_TypeError,
1044            "Method escape_bytea() expects a string as argument");
1045        return NULL;
1046    }
1047
1048    to = (char *) PQescapeByteaConn(self->cnx,
1049        (unsigned char *) from, (size_t) from_length, &to_length);
1050
1051    Py_XDECREF(tmp_obj);
1052
1053    if (encoding == -1)
1054        to_obj = PyBytes_FromStringAndSize(to, to_length - 1);
1055    else
1056        to_obj = get_decoded_string(to, to_length - 1, encoding);
1057    if (to)
1058        PQfreemem(to);
1059    return to_obj;
1060}
1061
1062#ifdef LARGE_OBJECTS
1063
1064/* Constructor for large objects (internal use only) */
1065static largeObject *
1066large_new(connObject *pgcnx, Oid oid)
1067{
1068    largeObject *large_obj;
1069
1070    if (!(large_obj = PyObject_NEW(largeObject, &largeType))) {
1071        return NULL;
1072    }
1073
1074    Py_XINCREF(pgcnx);
1075    large_obj->pgcnx = pgcnx;
1076    large_obj->lo_fd = -1;
1077    large_obj->lo_oid = oid;
1078
1079    return large_obj;
1080}
1081
1082/* Create large object. */
1083static char conn_locreate__doc__[] =
1084"locreate(mode) -- create a new large object in the database";
1085
1086static PyObject *
1087conn_locreate(connObject *self, PyObject *args)
1088{
1089    int mode;
1090    Oid lo_oid;
1091
1092    /* checks validity */
1093    if (!_check_cnx_obj(self)) {
1094        return NULL;
1095    }
1096
1097    /* gets arguments */
1098    if (!PyArg_ParseTuple(args, "i", &mode)) {
1099        PyErr_SetString(PyExc_TypeError,
1100                        "Method locreate() takes an integer argument");
1101        return NULL;
1102    }
1103
1104    /* creates large object */
1105    lo_oid = lo_creat(self->cnx, mode);
1106    if (lo_oid == 0) {
1107        set_error_msg(OperationalError, "Can't create large object");
1108        return NULL;
1109    }
1110
1111    return (PyObject *) large_new(self, lo_oid);
1112}
1113
1114/* Init from already known oid. */
1115static char conn_getlo__doc__[] =
1116"getlo(oid) -- create a large object instance for the specified oid";
1117
1118static PyObject *
1119conn_getlo(connObject *self, PyObject *args)
1120{
1121    int oid;
1122    Oid lo_oid;
1123
1124    /* checks validity */
1125    if (!_check_cnx_obj(self)) {
1126        return NULL;
1127    }
1128
1129    /* gets arguments */
1130    if (!PyArg_ParseTuple(args, "i", &oid)) {
1131        PyErr_SetString(PyExc_TypeError,
1132                        "Method getlo() takes an integer argument");
1133        return NULL;
1134    }
1135
1136    lo_oid = (Oid) oid;
1137    if (lo_oid == 0) {
1138        PyErr_SetString(PyExc_ValueError, "The object oid can't be null");
1139        return NULL;
1140    }
1141
1142    /* creates object */
1143    return (PyObject *) large_new(self, lo_oid);
1144}
1145
1146/* Import unix file. */
1147static char conn_loimport__doc__[] =
1148"loimport(name) -- create a new large object from specified file";
1149
1150static PyObject *
1151conn_loimport(connObject *self, PyObject *args)
1152{
1153    char *name;
1154    Oid lo_oid;
1155
1156    /* checks validity */
1157    if (!_check_cnx_obj(self)) {
1158        return NULL;
1159    }
1160
1161    /* gets arguments */
1162    if (!PyArg_ParseTuple(args, "s", &name)) {
1163        PyErr_SetString(PyExc_TypeError,
1164                        "Method loimport() takes a string argument");
1165        return NULL;
1166    }
1167
1168    /* imports file and checks result */
1169    lo_oid = lo_import(self->cnx, name);
1170    if (lo_oid == 0) {
1171        set_error_msg(OperationalError, "Can't create large object");
1172        return NULL;
1173    }
1174
1175    return (PyObject *) large_new(self, lo_oid);
1176}
1177
1178#endif /* LARGE_OBJECTS */
1179
1180/* Reset connection. */
1181static char conn_reset__doc__[] =
1182"reset() -- reset connection with current parameters\n\n"
1183"All derived queries and large objects derived from this connection\n"
1184"will not be usable after this call.\n";
1185
1186static PyObject *
1187conn_reset(connObject *self, PyObject *noargs)
1188{
1189    if (!self->cnx) {
1190        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
1191        return NULL;
1192    }
1193
1194    /* resets the connection */
1195    PQreset(self->cnx);
1196    Py_INCREF(Py_None);
1197    return Py_None;
1198}
1199
1200/* Cancel current command. */
1201static char conn_cancel__doc__[] =
1202"cancel() -- abandon processing of the current command";
1203
1204static PyObject *
1205conn_cancel(connObject *self, PyObject *noargs)
1206{
1207    if (!self->cnx) {
1208        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
1209        return NULL;
1210    }
1211
1212    /* request that the server abandon processing of the current command */
1213    return PyInt_FromLong((long) PQrequestCancel(self->cnx));
1214}
1215
1216/* Get connection socket. */
1217static char conn_fileno__doc__[] =
1218"fileno() -- return database connection socket file handle";
1219
1220static PyObject *
1221conn_fileno(connObject *self, PyObject *noargs)
1222{
1223    if (!self->cnx) {
1224        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
1225        return NULL;
1226    }
1227
1228#ifdef NO_PQSOCKET
1229    return PyInt_FromLong((long) self->cnx->sock);
1230#else
1231    return PyInt_FromLong((long) PQsocket(self->cnx));
1232#endif
1233}
1234
1235/* Set external typecast callback function. */
1236static char conn_set_cast_hook__doc__[] =
1237"set_cast_hook(func) -- set a fallback typecast function";
1238
1239static PyObject *
1240conn_set_cast_hook(connObject *self, PyObject *func)
1241{
1242    PyObject *ret = NULL;
1243
1244    if (func == Py_None) {
1245        Py_XDECREF(self->cast_hook);
1246        self->cast_hook = NULL;
1247        Py_INCREF(Py_None); ret = Py_None;
1248    }
1249    else if (PyCallable_Check(func)) {
1250        Py_XINCREF(func); Py_XDECREF(self->cast_hook);
1251        self->cast_hook = func;
1252        Py_INCREF(Py_None); ret = Py_None;
1253    }
1254    else {
1255        PyErr_SetString(PyExc_TypeError,
1256                        "Method set_cast_hook() expects"
1257                        " a callable or None as argument");
1258    }
1259
1260    return ret;
1261}
1262
1263/* Get notice receiver callback function. */
1264static char conn_get_cast_hook__doc__[] =
1265"get_cast_hook() -- get the fallback typecast function";
1266
1267static PyObject *
1268conn_get_cast_hook(connObject *self, PyObject *noargs)
1269{
1270    PyObject *ret = self->cast_hook;;
1271
1272    if (!ret)
1273        ret = Py_None;
1274    Py_INCREF(ret);
1275
1276    return ret;
1277}
1278
1279/* Set notice receiver callback function. */
1280static char conn_set_notice_receiver__doc__[] =
1281"set_notice_receiver(func) -- set the current notice receiver";
1282
1283static PyObject *
1284conn_set_notice_receiver(connObject *self, PyObject *func)
1285{
1286    PyObject *ret = NULL;
1287
1288    if (func == Py_None) {
1289        Py_XDECREF(self->notice_receiver);
1290        self->notice_receiver = NULL;
1291        Py_INCREF(Py_None); ret = Py_None;
1292    }
1293    else if (PyCallable_Check(func)) {
1294        Py_XINCREF(func); Py_XDECREF(self->notice_receiver);
1295        self->notice_receiver = func;
1296        PQsetNoticeReceiver(self->cnx, notice_receiver, self);
1297        Py_INCREF(Py_None); ret = Py_None;
1298    }
1299    else {
1300        PyErr_SetString(PyExc_TypeError,
1301                        "Method set_notice_receiver() expects"
1302                        " a callable or None as argument");
1303    }
1304
1305    return ret;
1306}
1307
1308/* Get notice receiver callback function. */
1309static char conn_get_notice_receiver__doc__[] =
1310"get_notice_receiver() -- get the current notice receiver";
1311
1312static PyObject *
1313conn_get_notice_receiver(connObject *self, PyObject *noargs)
1314{
1315    PyObject *ret = self->notice_receiver;
1316
1317    if (!ret)
1318        ret = Py_None;
1319    Py_INCREF(ret);
1320
1321    return ret;
1322}
1323
1324/* Close without deleting. */
1325static char conn_close__doc__[] =
1326"close() -- close connection\n\n"
1327"All instances of the connection object and derived objects\n"
1328"(queries and large objects) can no longer be used after this call.\n";
1329
1330static PyObject *
1331conn_close(connObject *self, PyObject *noargs)
1332{
1333    /* connection object cannot already be closed */
1334    if (!self->cnx) {
1335        set_error_msg(InternalError, "Connection already closed");
1336        return NULL;
1337    }
1338
1339    Py_BEGIN_ALLOW_THREADS
1340    PQfinish(self->cnx);
1341    Py_END_ALLOW_THREADS
1342
1343    self->cnx = NULL;
1344    Py_INCREF(Py_None);
1345    return Py_None;
1346}
1347
1348/* Get asynchronous notify. */
1349static char conn_get_notify__doc__[] =
1350"getnotify() -- get database notify for this connection";
1351
1352static PyObject *
1353conn_get_notify(connObject *self, PyObject *noargs)
1354{
1355    PGnotify *notify;
1356
1357    if (!self->cnx) {
1358        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
1359        return NULL;
1360    }
1361
1362    /* checks for NOTIFY messages */
1363    PQconsumeInput(self->cnx);
1364
1365    if (!(notify = PQnotifies(self->cnx))) {
1366        Py_INCREF(Py_None);
1367        return Py_None;
1368    }
1369    else {
1370        PyObject *notify_result, *tmp;
1371
1372        if (!(tmp = PyStr_FromString(notify->relname))) {
1373            return NULL;
1374        }
1375
1376        if (!(notify_result = PyTuple_New(3))) {
1377            return NULL;
1378        }
1379
1380        PyTuple_SET_ITEM(notify_result, 0, tmp);
1381
1382        if (!(tmp = PyInt_FromLong(notify->be_pid))) {
1383            Py_DECREF(notify_result);
1384            return NULL;
1385        }
1386
1387        PyTuple_SET_ITEM(notify_result, 1, tmp);
1388
1389        /* extra exists even in old versions that did not support it */
1390        if (!(tmp = PyStr_FromString(notify->extra))) {
1391            Py_DECREF(notify_result);
1392            return NULL;
1393        }
1394
1395        PyTuple_SET_ITEM(notify_result, 2, tmp);
1396
1397        PQfreemem(notify);
1398
1399        return notify_result;
1400    }
1401}
1402
1403/* Get the list of connection attributes. */
1404static PyObject *
1405conn_dir(connObject *self, PyObject *noargs)
1406{
1407    PyObject *attrs;
1408
1409    attrs = PyObject_Dir(PyObject_Type((PyObject *) self));
1410    PyObject_CallMethod(
1411        attrs, "extend", "[sssssssssssss]",
1412        "host", "port", "db", "options", "error", "status", "user",
1413        "protocol_version", "server_version", "socket", "backend_pid",
1414        "ssl_in_use", "ssl_attributes");
1415
1416    return attrs;
1417}
1418
1419/* Connection object methods */
1420static struct PyMethodDef conn_methods[] = {
1421    {"__dir__", (PyCFunction) conn_dir,  METH_NOARGS, NULL},
1422
1423    {"source", (PyCFunction) conn_source,
1424        METH_NOARGS, conn_source__doc__},
1425    {"query", (PyCFunction) conn_query,
1426        METH_VARARGS, conn_query__doc__},
1427    {"query_prepared", (PyCFunction) conn_query_prepared,
1428        METH_VARARGS, conn_query_prepared__doc__},
1429    {"prepare", (PyCFunction) conn_prepare,
1430        METH_VARARGS, conn_prepare__doc__},
1431    {"describe_prepared", (PyCFunction) conn_describe_prepared,
1432        METH_VARARGS, conn_describe_prepared__doc__},
1433    {"reset", (PyCFunction) conn_reset,
1434        METH_NOARGS, conn_reset__doc__},
1435    {"cancel", (PyCFunction) conn_cancel,
1436        METH_NOARGS, conn_cancel__doc__},
1437    {"close", (PyCFunction) conn_close,
1438        METH_NOARGS, conn_close__doc__},
1439    {"fileno", (PyCFunction) conn_fileno,
1440        METH_NOARGS, conn_fileno__doc__},
1441    {"get_cast_hook", (PyCFunction) conn_get_cast_hook,
1442        METH_NOARGS, conn_get_cast_hook__doc__},
1443    {"set_cast_hook", (PyCFunction) conn_set_cast_hook,
1444        METH_O, conn_set_cast_hook__doc__},
1445    {"get_notice_receiver", (PyCFunction) conn_get_notice_receiver,
1446        METH_NOARGS, conn_get_notice_receiver__doc__},
1447    {"set_notice_receiver", (PyCFunction) conn_set_notice_receiver,
1448        METH_O, conn_set_notice_receiver__doc__},
1449    {"getnotify", (PyCFunction) conn_get_notify,
1450        METH_NOARGS, conn_get_notify__doc__},
1451    {"inserttable", (PyCFunction) conn_inserttable,
1452        METH_VARARGS, conn_inserttable__doc__},
1453    {"transaction", (PyCFunction) conn_transaction,
1454        METH_NOARGS, conn_transaction__doc__},
1455    {"parameter", (PyCFunction) conn_parameter,
1456        METH_VARARGS, conn_parameter__doc__},
1457    {"date_format", (PyCFunction) conn_date_format,
1458        METH_NOARGS, conn_date_format__doc__},
1459
1460#ifdef ESCAPING_FUNCS
1461    {"escape_literal", (PyCFunction) conn_escape_literal,
1462        METH_O, conn_escape_literal__doc__},
1463    {"escape_identifier", (PyCFunction) conn_escape_identifier,
1464        METH_O, conn_escape_identifier__doc__},
1465#endif /* ESCAPING_FUNCS */
1466    {"escape_string", (PyCFunction) conn_escape_string,
1467        METH_O, conn_escape_string__doc__},
1468    {"escape_bytea", (PyCFunction) conn_escape_bytea,
1469        METH_O, conn_escape_bytea__doc__},
1470
1471#ifdef DIRECT_ACCESS
1472    {"putline", (PyCFunction) conn_putline,
1473        METH_VARARGS, conn_putline__doc__},
1474    {"getline", (PyCFunction) conn_getline,
1475        METH_NOARGS, conn_getline__doc__},
1476    {"endcopy", (PyCFunction) conn_endcopy,
1477        METH_NOARGS, conn_endcopy__doc__},
1478#endif /* DIRECT_ACCESS */
1479
1480#ifdef LARGE_OBJECTS
1481    {"locreate", (PyCFunction) conn_locreate,
1482        METH_VARARGS, conn_locreate__doc__},
1483    {"getlo", (PyCFunction) conn_getlo,
1484        METH_VARARGS, conn_getlo__doc__},
1485    {"loimport", (PyCFunction) conn_loimport,
1486        METH_VARARGS, conn_loimport__doc__},
1487#endif /* LARGE_OBJECTS */
1488
1489    {NULL, NULL} /* sentinel */
1490};
1491
1492static char conn__doc__[] = "PostgreSQL connection object";
1493
1494/* Connection type definition */
1495static PyTypeObject connType = {
1496    PyVarObject_HEAD_INIT(NULL, 0)
1497    "pg.Connection",              /* tp_name */
1498    sizeof(connObject),           /* tp_basicsize */
1499    0,                            /* tp_itemsize */
1500    (destructor) conn_dealloc,    /* tp_dealloc */
1501    0,                            /* tp_print */
1502    0,                            /* tp_getattr */
1503    0,                            /* tp_setattr */
1504    0,                            /* tp_reserved */
1505    0,                            /* tp_repr */
1506    0,                            /* tp_as_number */
1507    0,                            /* tp_as_sequence */
1508    0,                            /* tp_as_mapping */
1509    0,                            /* tp_hash */
1510    0,                            /* tp_call */
1511    0,                            /* tp_str */
1512    (getattrofunc) conn_getattr,  /* tp_getattro */
1513    0,                            /* tp_setattro */
1514    0,                            /* tp_as_buffer */
1515    Py_TPFLAGS_DEFAULT,           /* tp_flags */
1516    conn__doc__,                  /* tp_doc */
1517    0,                            /* tp_traverse */
1518    0,                            /* tp_clear */
1519    0,                            /* tp_richcompare */
1520    0,                            /* tp_weaklistoffset */
1521    0,                            /* tp_iter */
1522    0,                            /* tp_iternext */
1523    conn_methods,                 /* tp_methods */
1524};
Note: See TracBrowser for help on using the repository browser.