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