/*
* call-seq:
* conn.transaction { |conn| ... } -> nil
*
* Executes a +BEGIN+ at the start of the block,
* and a +COMMIT+ at the end of the block, or
* +ROLLBACK+ if any exception occurs.
*/
static VALUE
pgconn_transaction(VALUE self)
{
PGconn *conn = get_pgconn(self);
PGresult *result;
VALUE rb_pgresult;
int status;
if (rb_block_given_p()) {
result = PQexec(conn, "BEGIN");
rb_pgresult = new_pgresult(result);
pgresult_check(self, rb_pgresult);
rb_protect(rb_yield, self, &status);
if(status == 0) {
result = PQexec(conn, "COMMIT");
rb_pgresult = new_pgresult(result);
pgresult_check(self, rb_pgresult);
}
else {
/* exception occurred, ROLLBACK and re-raise */
result = PQexec(conn, "ROLLBACK");
rb_pgresult = new_pgresult(result);
pgresult_check(self, rb_pgresult);
rb_jump_tag(status);
}
}
else {
/* no block supplied? */
rb_raise(rb_eArgError, "Must supply block for PGconn#transaction");
}
return Qnil;
}