void conn_notifies_process(connectionObject *self) { PGnotify *pgn = NULL; PyObject *notify = NULL; PyObject *pid = NULL, *channel = NULL, *payload = NULL; PyObject *tmp = NULL; static PyObject *append; if (!append) { if (!(append = Text_FromUTF8("append"))) { goto error; } } while ((pgn = PQnotifies(self->pgconn)) != NULL) { Dprintf("conn_notifies_process: got NOTIFY from pid %d, msg = %s", (int) pgn->be_pid, pgn->relname); if (!(pid = PyInt_FromLong((long)pgn->be_pid))) { goto error; } if (!(channel = conn_text_from_chars(self, pgn->relname))) { goto error; } if (!(payload = conn_text_from_chars(self, pgn->extra))) { goto error; } if (!(notify = PyObject_CallFunctionObjArgs((PyObject *)¬ifyType, pid, channel, payload, NULL))) { goto error; } Py_DECREF(pid); pid = NULL; Py_DECREF(channel); channel = NULL; Py_DECREF(payload); payload = NULL; if (!(tmp = PyObject_CallMethodObjArgs( self->notifies, append, notify, NULL))) { goto error; } Py_DECREF(tmp); tmp = NULL; Py_DECREF(notify); notify = NULL; PQfreemem(pgn); pgn = NULL; } return; /* no error */ error: if (pgn) { PQfreemem(pgn); } Py_XDECREF(tmp); Py_XDECREF(notify); Py_XDECREF(pid); Py_XDECREF(channel); Py_XDECREF(payload); /* TODO: callers currently don't expect an error from us */ PyErr_Clear(); }
/* Expose the notices received as Python objects. * * The function should be called with the connection lock and the GIL. */ void conn_notice_process(connectionObject *self) { struct connectionObject_notice *notice; PyObject *msg = NULL; PyObject *tmp = NULL; static PyObject *append; if (NULL == self->notice_pending) { return; } if (!append) { if (!(append = Text_FromUTF8("append"))) { goto error; } } notice = self->notice_pending; while (notice != NULL) { Dprintf("conn_notice_process: %s", notice->message); if (!(msg = conn_text_from_chars(self, notice->message))) { goto error; } if (!(tmp = PyObject_CallMethodObjArgs( self->notice_list, append, msg, NULL))) { goto error; } Py_DECREF(tmp); tmp = NULL; Py_DECREF(msg); msg = NULL; notice = notice->next; } /* Remove the oldest item if the queue is getting too long. */ if (PyList_Check(self->notice_list)) { Py_ssize_t nnotices; nnotices = PyList_GET_SIZE(self->notice_list); if (nnotices > CONN_NOTICES_LIMIT) { if (-1 == PySequence_DelSlice(self->notice_list, 0, nnotices - CONN_NOTICES_LIMIT)) { PyErr_Clear(); } } } conn_notice_clean(self); return; error: Py_XDECREF(tmp); Py_XDECREF(msg); conn_notice_clean(self); /* TODO: the caller doesn't expects errors from us */ PyErr_Clear(); }
RAISES void psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg, const char *pgerror, const char *pgcode) { PyObject *t; PyObject *pymsg; PyObject *err = NULL; connectionObject *conn = NULL; if (curs) { conn = ((cursorObject *)curs)->conn; } if ((pymsg = conn_text_from_chars(conn, msg))) { err = PyObject_CallFunctionObjArgs(exc, pymsg, NULL); Py_DECREF(pymsg); } else { /* what's better than an error in an error handler in the morning? * Anyway, some error was set, refcount is ok... get outta here. */ return; } if (err) { if (curs) { PyObject_SetAttrString(err, "cursor", (PyObject *)curs); } if (pgerror) { if ((t = conn_text_from_chars(conn, pgerror))) { PyObject_SetAttrString(err, "pgerror", t); Py_DECREF(t); } } if (pgcode) { if ((t = conn_text_from_chars(conn, pgcode))) { PyObject_SetAttrString(err, "pgcode", t); Py_DECREF(t); } } PyErr_SetObject(exc, err); Py_DECREF(err); } }
static PyObject * psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs) { #if PG_VERSION_NUM >= 90000 PyObject *ident = NULL, *obj = NULL, *result = NULL; connectionObject *conn; const char *str; char *quoted = NULL; static char *kwlist[] = {"ident", "scope", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &ident, &obj)) { return NULL; } if (PyObject_TypeCheck(obj, &cursorType)) { conn = ((cursorObject*)obj)->conn; } else if (PyObject_TypeCheck(obj, &connectionType)) { conn = (connectionObject*)obj; } else { PyErr_SetString(PyExc_TypeError, "argument 2 must be a connection or a cursor"); return NULL; } Py_INCREF(ident); /* for ensure_bytes */ if (!(ident = psycopg_ensure_bytes(ident))) { goto exit; } str = Bytes_AS_STRING(ident); quoted = PQescapeIdentifier(conn->pgconn, str, strlen(str)); if (!quoted) { PyErr_NoMemory(); goto exit; } result = conn_text_from_chars(conn, quoted); exit: PQfreemem(quoted); Py_XDECREF(ident); return result; #else PyErr_SetString(NotSupportedError, "PQescapeIdentifier not available in libpq < 9.0"); return NULL; #endif }
static PyObject * psyco_conn_get_parameter_status(connectionObject *self, PyObject *args) { const char *param = NULL; const char *val = NULL; EXC_IF_CONN_CLOSED(self); if (!PyArg_ParseTuple(args, "s", ¶m)) return NULL; val = PQparameterStatus(self->pgconn, param); if (!val) { Py_RETURN_NONE; } return conn_text_from_chars(self, val); }
/* Expose the notices received as Python objects. * * The function should be called with the connection lock and the GIL. */ void conn_notice_process(connectionObject *self) { struct connectionObject_notice *notice; Py_ssize_t nnotices; if (NULL == self->notice_pending) { return; } notice = self->notice_pending; nnotices = PyList_GET_SIZE(self->notice_list); while (notice != NULL) { PyObject *msg; msg = conn_text_from_chars(self, notice->message); Dprintf("conn_notice_process: %s", notice->message); /* Respect the order in which notices were produced, because in notice_list they are reversed (see ticket #9) */ if (msg) { PyList_Insert(self->notice_list, nnotices, msg); Py_DECREF(msg); } else { /* We don't really have a way to report errors, so gulp it. * The function should only fail for out of memory, so we are * likely going to die anyway. */ PyErr_Clear(); } notice = notice->next; } /* Remove the oldest item if the queue is getting too long. */ nnotices = PyList_GET_SIZE(self->notice_list); if (nnotices > CONN_NOTICES_LIMIT) { PySequence_DelSlice(self->notice_list, 0, nnotices - CONN_NOTICES_LIMIT); } conn_notice_clean(self); }
static PyObject * psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *ident = NULL, *obj = NULL, *result = NULL; connectionObject *conn; char *quoted = NULL; static char *kwlist[] = {"ident", "scope", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &ident, &obj)) { return NULL; } if (PyObject_TypeCheck(obj, &cursorType)) { conn = ((cursorObject*)obj)->conn; } else if (PyObject_TypeCheck(obj, &connectionType)) { conn = (connectionObject*)obj; } else { PyErr_SetString(PyExc_TypeError, "argument 2 must be a connection or a cursor"); return NULL; } Py_INCREF(ident); /* for ensure_bytes */ if (!(ident = psycopg_ensure_bytes(ident))) { goto exit; } if (!(quoted = psycopg_escape_identifier(conn, Bytes_AS_STRING(ident), Bytes_GET_SIZE(ident)))) { goto exit; } result = conn_text_from_chars(conn, quoted); exit: PQfreemem(quoted); Py_XDECREF(ident); return result; }
/* TODO: may have been changed to BORROWED */ RAISES PyObject * psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg) { PyObject *pymsg; PyObject *err = NULL; connectionObject *conn = NULL; if (curs) { conn = ((cursorObject *)curs)->conn; } if ((pymsg = conn_text_from_chars(conn, msg))) { err = PyObject_CallFunctionObjArgs(exc, pymsg, NULL); Py_DECREF(pymsg); } else { /* what's better than an error in an error handler in the morning? * Anyway, some error was set, refcount is ok... get outta here. */ return NULL; } if (err && PyObject_TypeCheck(err, &errorType)) { errorObject *perr = (errorObject *)err; if (curs) { Py_CLEAR(perr->cursor); Py_INCREF(curs); perr->cursor = curs; } } if (err) { PyErr_SetObject(exc, err); Py_DECREF(err); } return err; }