/* * call-seq: * conn.async_exec( sql ) * * Sends an asyncrhonous SQL query request specified by _sql_ to the PostgreSQL. * Returns a PGresult instance on success. * On failure, it raises a PGError exception. */ static VALUE pgconn_async_exec(obj, str) VALUE obj, str; { PGconn *conn = get_pgconn(obj); PGresult *result; int status; char *msg; int cs; int ret; fd_set rset; Check_Type(str, T_STRING); while(result = PQgetResult(conn)) { PQclear(result); } if (!PQsendQuery(conn, RSTRING(str)->ptr)) { rb_raise(rb_ePGError, PQerrorMessage(conn)); } cs = PQsocket(conn); for(;;) { FD_ZERO(&rset); FD_SET(cs, &rset); ret = rb_thread_select(cs + 1, &rset, NULL, NULL, NULL); if (ret < 0) { rb_sys_fail(0); } if (ret == 0) { continue; } if (PQconsumeInput(conn) == 0) { rb_raise(rb_ePGError, PQerrorMessage(conn)); } if (PQisBusy(conn) == 0) { break; } } result = PQgetResult(conn); if (!result) { rb_raise(rb_ePGError, PQerrorMessage(conn)); } status = PQresultStatus(result); switch (status) { case PGRES_TUPLES_OK: case PGRES_COPY_OUT: case PGRES_COPY_IN: case PGRES_EMPTY_QUERY: case PGRES_COMMAND_OK: /* no data will be received */ return pgresult_new(result); case PGRES_BAD_RESPONSE: case PGRES_FATAL_ERROR: case PGRES_NONFATAL_ERROR: msg = PQerrorMessage(conn); break; default: msg = "internal error : unknown result status."; break; } PQclear(result); rb_raise(rb_ePGError, msg); }