ext/duckdb/prepared_statement.c in duckdb-0.3.4.0 vs ext/duckdb/prepared_statement.c in duckdb-0.5.0

- old
+ new

@@ -2,10 +2,11 @@ static VALUE cDuckDBPreparedStatement; static void deallocate(void *ctx); static VALUE allocate(VALUE klass); +static size_t memsize(const void *p); static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE query); static VALUE duckdb_prepared_statement_nparams(VALUE self); static VALUE duckdb_prepared_statement_execute(VALUE self); static idx_t check_index(VALUE vidx); static VALUE duckdb_prepared_statement_bind_bool(VALUE self, VALUE vidx, VALUE val); @@ -21,59 +22,64 @@ static VALUE duckdb_prepared_statement__bind_date(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day); static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE hour, VALUE min, VALUE sec, VALUE micros); static VALUE duckdb_prepared_statement__bind_timestamp(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros); static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VALUE months, VALUE days, VALUE micros); +static const rb_data_type_t prepared_statement_data_type = { + "DuckDB/PreparedStatement", + {NULL, deallocate, memsize,}, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY +}; + static void deallocate(void *ctx) { rubyDuckDBPreparedStatement *p = (rubyDuckDBPreparedStatement *)ctx; duckdb_destroy_prepare(&(p->prepared_statement)); xfree(p); } static VALUE allocate(VALUE klass) { rubyDuckDBPreparedStatement *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBPreparedStatement)); - return Data_Wrap_Struct(klass, NULL, deallocate, ctx); + return TypedData_Wrap_Struct(klass, &prepared_statement_data_type, ctx); } +static size_t memsize(const void *p) { + return sizeof(rubyDuckDBPreparedStatement); +} + static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE query) { rubyDuckDBConnection *ctxcon; rubyDuckDBPreparedStatement *ctx; if (!rb_obj_is_kind_of(con, cDuckDBConnection)) { rb_raise(rb_eTypeError, "1st argument should be instance of DackDB::Connection"); } - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); - Data_Get_Struct(con, rubyDuckDBConnection, ctxcon); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); + ctxcon = get_struct_connection(con); if (duckdb_prepare(ctxcon->con, StringValuePtr(query), &(ctx->prepared_statement)) == DuckDBError) { -#ifdef HAVE_DUCKDB_PREPARE_ERROR const char *error = duckdb_prepare_error(ctx->prepared_statement); rb_raise(eDuckDBError, "%s", error); -#else - /* TODO: include query parameter information in error message. */ - rb_raise(eDuckDBError, "failed to prepare statement"); -#endif } return self; } static VALUE duckdb_prepared_statement_nparams(VALUE self) { rubyDuckDBPreparedStatement *ctx; - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); return rb_int2big(duckdb_nparams(ctx->prepared_statement)); } static VALUE duckdb_prepared_statement_execute(VALUE self) { rubyDuckDBPreparedStatement *ctx; rubyDuckDBResult *ctxr; VALUE result = create_result(); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); - Data_Get_Struct(result, rubyDuckDBResult, ctxr); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); + ctxr = get_struct_result(result); if (duckdb_execute_prepared(ctx->prepared_statement, &(ctxr->result)) == DuckDBError) { rb_raise(eDuckDBError, "%s", duckdb_result_error(&(ctxr->result))); } return result; } @@ -88,11 +94,11 @@ static VALUE duckdb_prepared_statement_bind_bool(VALUE self, VALUE vidx, VALUE val) { rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); if (val != Qtrue && val != Qfalse) { rb_raise(rb_eArgError, "binding value must be boolean"); } if (duckdb_bind_boolean(ctx->prepared_statement, idx, (val == Qtrue)) == DuckDBError) { @@ -104,11 +110,11 @@ static VALUE duckdb_prepared_statement_bind_int8(VALUE self, VALUE vidx, VALUE val) { rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); int8_t i8val = (int8_t)NUM2INT(val); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); if (duckdb_bind_int8(ctx->prepared_statement, idx, i8val) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; @@ -117,11 +123,11 @@ static VALUE duckdb_prepared_statement_bind_int16(VALUE self, VALUE vidx, VALUE val) { rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); int16_t i16val = NUM2INT(val); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); if (duckdb_bind_int16(ctx->prepared_statement, idx, i16val) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; @@ -130,11 +136,11 @@ static VALUE duckdb_prepared_statement_bind_int32(VALUE self, VALUE vidx, VALUE val) { rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); int32_t i32val = NUM2INT(val); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); if (duckdb_bind_int32(ctx->prepared_statement, idx, i32val) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; @@ -143,11 +149,11 @@ static VALUE duckdb_prepared_statement_bind_int64(VALUE self, VALUE vidx, VALUE val) { rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); int64_t i64val = NUM2LL(val); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); if (duckdb_bind_int64(ctx->prepared_statement, idx, i64val) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; @@ -156,11 +162,11 @@ static VALUE duckdb_prepared_statement_bind_float(VALUE self, VALUE vidx, VALUE val) { rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); double dbl = NUM2DBL(val); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); if (duckdb_bind_float(ctx->prepared_statement, idx, (float)dbl) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; @@ -169,11 +175,11 @@ static VALUE duckdb_prepared_statement_bind_double(VALUE self, VALUE vidx, VALUE val) { rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); double dbl = NUM2DBL(val); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); if (duckdb_bind_double(ctx->prepared_statement, idx, dbl) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; @@ -181,33 +187,36 @@ static VALUE duckdb_prepared_statement_bind_varchar(VALUE self, VALUE vidx, VALUE str) { rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); + if (duckdb_bind_varchar(ctx->prepared_statement, idx, StringValuePtr(str)) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } static VALUE duckdb_prepared_statement_bind_blob(VALUE self, VALUE vidx, VALUE blob) { rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); + if (duckdb_bind_blob(ctx->prepared_statement, idx, (const void *)StringValuePtr(blob), (idx_t)RSTRING_LEN(blob)) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } static VALUE duckdb_prepared_statement_bind_null(VALUE self, VALUE vidx) { rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); + if (duckdb_bind_null(ctx->prepared_statement, idx) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } @@ -217,14 +226,16 @@ duckdb_date dt; idx_t idx = check_index(vidx); dt = to_duckdb_date_from_value(year, month, day); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); + if (duckdb_bind_date(ctx->prepared_statement, idx, dt) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } + return self; } static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE hour, VALUE min, VALUE sec, VALUE micros){ rubyDuckDBPreparedStatement *ctx; @@ -232,24 +243,26 @@ idx_t idx = check_index(vidx); time = to_duckdb_time_from_value(hour, min, sec, micros); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); + if (duckdb_bind_time(ctx->prepared_statement, idx, time) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } + return self; } static VALUE duckdb_prepared_statement__bind_timestamp(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros) { duckdb_timestamp timestamp; rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); timestamp = to_duckdb_timestamp_from_value(year, month, day, hour, min, sec, micros); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); if (duckdb_bind_timestamp(ctx->prepared_statement, idx, timestamp) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; @@ -258,10 +271,11 @@ static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VALUE months, VALUE days, VALUE micros) { duckdb_interval interval; rubyDuckDBPreparedStatement *ctx; idx_t idx = check_index(vidx); - Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); + to_duckdb_interval_from_value(&interval, months, days, micros); if (duckdb_bind_interval(ctx->prepared_statement, idx, interval) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); }