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