VALUE db_sqlite3_statement_execute(int argc, VALUE *argv, VALUE self) {
    int expect, n;
    VALUE bind, result;

    Statement *s = db_sqlite3_statement_handle_safe(self);

    sqlite3_reset(s->s);
    sqlite3_clear_bindings(s->s);

    rb_scan_args(argc, argv, "00*", &bind);
    expect = sqlite3_bind_parameter_count(s->s);
    if (expect != RARRAY_LEN(bind))
        rb_raise(eSwiftArgumentError, "expected %d bind values got %d", expect, (int)RARRAY_LEN(bind));

    rb_gc_register_address(&bind);
    for (n = 0; n < expect; n++) {
        VALUE value = rb_ary_entry(bind, n);
        if (NIL_P(value))
            sqlite3_bind_null(s->s, n + 1);
        else {
            VALUE text = typecast_to_string(value);
            sqlite3_bind_text(s->s, n + 1, RSTRING_PTR(text), RSTRING_LEN(text), 0);
        }
    }

    result = db_sqlite3_result_allocate(cDSR);
    db_sqlite3_result_initialize(result, self);
    db_sqlite3_result_consume(result);
    rb_gc_unregister_address(&bind);
    return result;
}
Exemple #2
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 {
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 {
Exemple #4
0
/* NOTE: very naive, no regex etc. */
VALUE db_mysql_bind_sql(VALUE adapter, VALUE sql, VALUE bind) {
    VALUE value;
    size_t size = 4096;
    char *ptr, *buffer;
    size_t i = 0, j = 0, n = 0;

    buffer = (char *)malloc(size);
    ptr    = RSTRING_PTR(sql);

    while (i < (size_t)RSTRING_LEN(sql)) {
        if (*ptr == '?') {
            if (n < (size_t)RARRAY_LEN(bind)) {
                value = rb_ary_entry(bind, n++);
                if (NIL_P(value)) {
                    size = db_mysql_buffer_adjust(&buffer, size, j, 4);
                    j   += sprintf(buffer + j, "NULL");
                }
                else {
                    value = db_mysql_adapter_escape(adapter, typecast_to_string(value));
                    size  = db_mysql_buffer_adjust(&buffer, size, j, RSTRING_LEN(value) + 2);
                    j    += sprintf(buffer + j, "'%s'", RSTRING_PTR(value));
                }
            }
            else {
                buffer[j++] = *ptr;
                n++;
            }
        }
        else {
            buffer[j++] = *ptr;
        }

        i++;
        ptr++;

        if (j >= size)
            buffer = realloc(buffer, size += 4096);
    }

    sql = rb_str_new(buffer, j);
    free(buffer);

    if (n != (size_t)RARRAY_LEN(bind))
        rb_raise(eSwiftArgumentError, "expected %d bind arguments got %d instead", n, RARRAY_LEN(bind));
    return sql;
}