/*
* call-seq:
* conn.exec(sql, *bind_values)
*
* Sends SQL query request specified by _sql_ to the PostgreSQL.
* Returns a PGresult instance on success.
* On failure, it raises a PGError exception.
*
* +bind_values+ represents values for the PostgreSQL bind parameters found in the +sql+. PostgreSQL bind parameters are presented as $1, $1, $2, etc.
*/
static VALUE
pgconn_exec(argc, argv, obj)
int argc;
VALUE *argv;
VALUE obj;
{
PGconn *conn = get_pgconn(obj);
PGresult *result = NULL;
VALUE command, params;
char *msg;
rb_scan_args(argc, argv, "1*", &command, ¶ms);
Check_Type(command, T_STRING);
if (RARRAY(params)->len <= 0) {
result = PQexec(conn, StringValuePtr(command));
}
else {
int len = RARRAY(params)->len;
int i;
#ifdef HAVE_PQEXECPARAMS
VALUE* ptr = RARRAY(params)->ptr;
char const** values = ALLOCA_N(char const*, len);
int* lengths = ALLOCA_N(int, len);
int* formats = ALLOCA_N(int, len);
for (i = 0; i < len; i++, ptr++) {
translate_to_pg(*ptr, values+i, lengths+i, formats+i);
}
result = PQexecParams(conn, StringValuePtr(command), len, NULL, values, lengths, formats, 0);
#else
for (i = 0; i < len; i++) {
rb_ary_store(params, i, pgconn_s_quote(rb_cPGconn, rb_ary_entry(params, i)));
}
result = PQexecParams_compat(conn, command, params);
#endif
}
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: {
VALUE pg_result = pgresult_new(result);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, pg_result, pgresult_clear, pg_result);
}
else {
return pg_result;
}
}
case PGRES_BAD_RESPONSE:
case PGRES_FATAL_ERROR:
case PGRES_NONFATAL_ERROR:
msg = RSTRING_PTR(rb_str_new2(PQresultErrorMessage(result)));
break;
default:
msg = "internal error : unknown result status.";
break;
}
PQclear(result);
rb_raise(rb_ePGError, msg);
}