/* call-seq:
 *    busy_handler { |count| ... }
 *    busy_handler(Class.new { def call count; end }.new)
 *
 * Register a busy handler with this database instance. When a requested
 * resource is busy, this handler will be invoked. If the handler returns
 * +false+, the operation will be aborted; otherwise, the resource will
 * be requested again.
 *
 * The handler will be invoked with the name of the resource that was
 * busy, and the number of times it has been retried.
 *
 * See also the mutually exclusive #busy_timeout.
 */
static VALUE busy_handler(int argc, VALUE *argv, VALUE self)
{
  sqlite3RubyPtr ctx;
  VALUE block;
  int status;

  Data_Get_Struct(self, sqlite3Ruby, ctx);
  REQUIRE_OPEN_DB(ctx);

  rb_scan_args(argc, argv, "01", &block);

  if(NIL_P(block) && rb_block_given_p()) block = rb_block_proc();

  rb_iv_set(self, "@busy_handler", block);

  status = sqlite3_busy_handler(
      ctx->db, NIL_P(block) ? NULL : rb_sqlite3_busy_handler, (void *)self);

  CHECK(ctx->db, status);

  return self;
}