Esempio n. 1
0
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 *)&notifyType,
                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();

}
Esempio n. 2
0
/* 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();
}
Esempio n. 3
0
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);
    }
}
Esempio n. 4
0
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
}
Esempio n. 5
0
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", &param)) return NULL;

    val = PQparameterStatus(self->pgconn, param);
    if (!val) {
        Py_RETURN_NONE;
    }
    return conn_text_from_chars(self, val);
}
Esempio n. 6
0
/* 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);
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
/* 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;
}