예제 #1
0
VALUE db_postgres_statement_execute(int argc, VALUE *argv, VALUE self) {
    PGresult *result;
    PGconn *connection;
    char **bind_args_data = 0;
    int n, *bind_args_size = 0, *bind_args_fmt = 0;
    VALUE bind, data, typecast_bind;

    Statement *s = db_postgres_statement_handle_safe(self);
    connection   = db_postgres_adapter_handle_safe(s->adapter)->connection;

    rb_scan_args(argc, argv, "00*", &bind);

    typecast_bind = rb_ary_new();
    rb_gc_register_address(&typecast_bind);
    rb_gc_register_address(&bind);

    if (RARRAY_LEN(bind) > 0) {
        bind_args_size = (int   *) malloc(sizeof(int)    * RARRAY_LEN(bind));
        bind_args_fmt  = (int   *) malloc(sizeof(int)    * RARRAY_LEN(bind));
        bind_args_data = (char **) malloc(sizeof(char *) * RARRAY_LEN(bind));

        for (n = 0; n < RARRAY_LEN(bind); n++) {
            data = rb_ary_entry(bind, n);
            if (NIL_P(data)) {
                bind_args_size[n] = 0;
                bind_args_data[n] = 0;
                bind_args_fmt[n]  = 0;
            }
            else {
                if (rb_obj_is_kind_of(data, rb_cIO) || rb_obj_is_kind_of(data, cStringIO))
                    bind_args_fmt[n] = 1;
                else
                    bind_args_fmt[n] = 0;
                data = typecast_to_string(data);
                rb_ary_push(typecast_bind, data);
                bind_args_size[n] = RSTRING_LEN(data);
                bind_args_data[n] = RSTRING_PTR(data);
            }
        }

        Query q = {
            .connection = connection,
            .command    = s->id,
            .n_args     = RARRAY_LEN(bind),
            .data       = bind_args_data,
            .size       = bind_args_size,
            .format     = bind_args_fmt
        };

        result = (PGresult *)GVL_NOLOCK(nogvl_pq_exec_prepared, &q, RUBY_UBF_IO, 0);
        free(bind_args_fmt);
        free(bind_args_size);
        free(bind_args_data);
    }
    else {
예제 #2
0
VALUE db_postgres_adapter_execute(int argc, VALUE *argv, VALUE self) {
    char **bind_args_data = 0;
    int n, *bind_args_size = 0, *bind_args_fmt = 0;
    PGresult *result;
    VALUE sql, bind, data;
    Adapter *a = db_postgres_adapter_handle_safe(self);

    rb_scan_args(argc, argv, "10*", &sql, &bind);
    if (!a->native)
        sql = db_postgres_normalized_sql(sql);

    if (RARRAY_LEN(bind) > 0) {
        bind_args_size = (int   *) malloc(sizeof(int)    * RARRAY_LEN(bind));
        bind_args_fmt  = (int   *) malloc(sizeof(int)    * RARRAY_LEN(bind));
        bind_args_data = (char **) malloc(sizeof(char *) * RARRAY_LEN(bind));

        rb_gc_register_address(&bind);
        for (n = 0; n < RARRAY_LEN(bind); n++) {
            data = rb_ary_entry(bind, n);
            if (NIL_P(data)) {
                bind_args_size[n] = 0;
                bind_args_data[n] = 0;
                bind_args_fmt[n]  = 0;
            }
            else {
                if (rb_obj_is_kind_of(data, rb_cIO) || rb_obj_is_kind_of(data, cStringIO))
                    bind_args_fmt[n] = 1;
                else
                    bind_args_fmt[n] = 0;

                data = typecast_to_string(data);
                bind_args_size[n] = RSTRING_LEN(data);
                bind_args_data[n] = RSTRING_PTR(data);
            }
        }

        Query q = {
            .connection = a->connection,
            .command    = CSTRING(sql),
            .n_args     = RARRAY_LEN(bind),
            .data       = bind_args_data,
            .size       = bind_args_size,
            .format     = bind_args_fmt
        };

        result = (PGresult *)rb_thread_blocking_region(nogvl_pq_exec_params, &q, RUBY_UBF_IO, 0);
        rb_gc_unregister_address(&bind);
        free(bind_args_size);
        free(bind_args_data);
        free(bind_args_fmt);
    }
    else {
예제 #3
0
VALUE db_postgres_statement_initialize(VALUE self, VALUE adapter, VALUE sql) {
    PGresult *result;
    Statement *s = db_postgres_statement_handle(self);
    Adapter *a   = db_postgres_adapter_handle_safe(adapter);

    snprintf(s->id, 128, "s%s", CSTRING(rb_uuid_string()));
    s->adapter = adapter;

    if (!a->native)
        sql = db_postgres_normalized_sql(sql);

    result = PQprepare(a->connection, s->id, CSTRING(sql), 0, 0);
    db_postgres_check_result(result);
    PQclear(result);
    return self;
}
예제 #4
0
VALUE db_postgres_statement_release(VALUE self) {
    char command[256];
    PGresult *result;
    PGconn *connection;

    Statement *s = db_postgres_statement_handle_safe(self);
    connection   = db_postgres_adapter_handle_safe(s->adapter)->connection;

    if (connection && PQstatus(connection) == CONNECTION_OK) {
        snprintf(command, 256, "deallocate %s", s->id);
        result = PQexec(connection, command);
        db_postgres_check_result(result);
        PQclear(result);
        return Qtrue;
    }

    return Qfalse;
}