コード例 #1
0
ファイル: green.c プロジェクト: kikin/watchlrsite
/* Replacement for PQexec using the user-provided wait function.
 *
 * The function should be called helding the connection lock, and
 * the GIL because some Python code is expected to be called.
 *
 * If PGresult is NULL, there may have been either a libpq error
 * or an exception raised by Python code: before raising an exception
 * check if there is already one using `PyErr_Occurred()` */
PGresult *
psyco_exec_green(connectionObject *conn, const char *command)
{
    PGresult *result = NULL;

    /* Send the query asynchronously */
    if (0 == pq_send_query(conn, command)) {
        goto end;
    }

    /* Enter the poll loop with a write. When writing is finished the poll
       implementation will set the status to ASYNC_READ without exiting the
       loop. If read is finished the status is finally set to ASYNC_DONE.
    */
    conn->async_status = ASYNC_WRITE;

    if (0 != psyco_wait(conn)) {
        psyco_clear_result_blocking(conn);
        goto end;
    }

    /* Now we can read the data without fear of blocking. */
    result = pq_get_last_result(conn);

end:
    conn->async_status = ASYNC_DONE;
    return result;
}
コード例 #2
0
static int
_conn_sync_connect(connectionObject *self)
{
    PGconn *pgconn;
    int green;

    /* store this value to prevent inconsistencies due to a change
     * in the middle of the function. */
    green = psyco_green();
    if (!green) {
        Py_BEGIN_ALLOW_THREADS;
        self->pgconn = pgconn = PQconnectdb(self->dsn);
        Py_END_ALLOW_THREADS;
        Dprintf("conn_connect: new postgresql connection at %p", pgconn);
    }
    else {
        Py_BEGIN_ALLOW_THREADS;
        self->pgconn = pgconn = PQconnectStart(self->dsn);
        Py_END_ALLOW_THREADS;
        Dprintf("conn_connect: new green postgresql connection at %p", pgconn);
    }

    if (pgconn == NULL)
    {
        Dprintf("conn_connect: PQconnectdb(%s) FAILED", self->dsn);
        PyErr_SetString(OperationalError, "PQconnectdb() failed");
        return -1;
    }
    else if (PQstatus(pgconn) == CONNECTION_BAD)
    {
        Dprintf("conn_connect: PQconnectdb(%s) returned BAD", self->dsn);
        PyErr_SetString(OperationalError, PQerrorMessage(pgconn));
        return -1;
    }

    PQsetNoticeProcessor(pgconn, conn_notice_callback, (void*)self);

    /* if the connection is green, wait to finish connection */
    if (green) {
        if (0 > pq_set_non_blocking(self, 1)) {
            return -1;
        }
        if (0 != psyco_wait(self)) {
            return -1;
        }
    }

    /* From here the connection is considered ready: with the new status,
     * poll() will use PQisBusy instead of PQconnectPoll.
     */
    self->status = CONN_STATUS_READY;

    if (conn_setup(self, self->pgconn) == -1) {
        return -1;
    }

    return 0;
}
コード例 #3
0
/* Replacement for PQexec using the user-provided wait function.
 *
 * The function should be called helding the connection lock, and
 * the GIL because some Python code is expected to be called.
 *
 * If PGresult is NULL, there may have been either a libpq error
 * or an exception raised by Python code: before raising an exception
 * check if there is already one using `PyErr_Occurred()` */
PGresult *
psyco_exec_green(connectionObject *conn, const char *command)
{
    PGresult *result = NULL;

    /* Check that there is a single concurrently executing query */
    if (conn->async_cursor) {
        PyErr_SetString(ProgrammingError,
            "a single async query can be executed on the same connection");
        goto end;
    }
    /* we don't care about which cursor is executing the query, and
     * it may also be that no cursor is involved at all and this is
     * an internal query. So just store anything in the async_cursor,
     * respecting the code expecting it to be a weakref */
    if (!(conn->async_cursor = PyWeakref_NewRef((PyObject*)conn, NULL))) {
        goto end;
    }

    /* Send the query asynchronously */
    if (0 == pq_send_query(conn, command)) {
        goto end;
    }

    /* Enter the poll loop with a write. When writing is finished the poll
       implementation will set the status to ASYNC_READ without exiting the
       loop. If read is finished the status is finally set to ASYNC_DONE.
    */
    conn->async_status = ASYNC_WRITE;

    if (0 != psyco_wait(conn)) {
        psyco_clear_result_blocking(conn);
        goto end;
    }

    /* Now we can read the data without fear of blocking. */
    result = pq_get_last_result(conn);

end:
    conn->async_status = ASYNC_DONE;
    Py_CLEAR(conn->async_cursor);
    return result;
}