/*
* 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;
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));
}
switch (PQresultStatus(result)) {
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 = RSTRING(rb_str_new2(PQresultErrorMessage(result)))->ptr;
break;
default:
msg = "internal error : unknown result status.";
break;
}
PQclear(result);
rb_raise(rb_ePGError, msg);
}