ext/duckdb/prepared_statement.c in duckdb-0.3.1.0 vs ext/duckdb/prepared_statement.c in duckdb-0.3.2.0

- old
+ new

@@ -1,25 +1,56 @@ #include "ruby-duckdb.h" static VALUE cDuckDBPreparedStatement; -static void deallocate(void *ctx) -{ +static void deallocate(void *ctx); +static VALUE allocate(VALUE klass); +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); +static VALUE duckdb_prepared_statement_bind_int8(VALUE self, VALUE vidx, VALUE val); +static VALUE duckdb_prepared_statement_bind_int16(VALUE self, VALUE vidx, VALUE val); +static VALUE duckdb_prepared_statement_bind_int32(VALUE self, VALUE vidx, VALUE val); +static VALUE duckdb_prepared_statement_bind_int64(VALUE self, VALUE vidx, VALUE val); +static VALUE duckdb_prepared_statement_bind_float(VALUE self, VALUE vidx, VALUE val); +static VALUE duckdb_prepared_statement_bind_double(VALUE self, VALUE vidx, VALUE val); +static VALUE duckdb_prepared_statement_bind_varchar(VALUE self, VALUE vidx, VALUE str); +static VALUE duckdb_prepared_statement_bind_blob(VALUE self, VALUE vidx, VALUE blob); +static VALUE duckdb_prepared_statement_bind_null(VALUE self, VALUE vidx); + +#ifdef HAVE_DUCKDB_BIND_DATE +static VALUE duckdb_prepared_statement__bind_date(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day); +#endif + +#ifdef HAVE_DUCKDB_BIND_TIME +static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE hour, VALUE min, VALUE sec, VALUE micros); +#endif + +#ifdef HAVE_DUCKDB_BIND_TIMESTAMP +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); +#endif + +#ifdef HAVE_DUCKDB_BIND_INTERVAL +static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VALUE months, VALUE days, VALUE micros); +#endif + + +static void deallocate(void *ctx) { rubyDuckDBPreparedStatement *p = (rubyDuckDBPreparedStatement *)ctx; duckdb_destroy_prepare(&(p->prepared_statement)); xfree(p); } -static VALUE allocate(VALUE klass) -{ +static VALUE allocate(VALUE klass) { rubyDuckDBPreparedStatement *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBPreparedStatement)); return Data_Wrap_Struct(klass, NULL, deallocate, ctx); } -static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE query) -{ +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"); @@ -38,12 +69,11 @@ #endif } return self; } -static VALUE duckdb_prepared_statement_nparams(VALUE self) -{ +static VALUE duckdb_prepared_statement_nparams(VALUE self) { rubyDuckDBPreparedStatement *ctx; Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx); #ifdef HAVE_DUCKDB_NPARAMS_029 return rb_int2big(duckdb_nparams(ctx->prepared_statement)); #else @@ -53,35 +83,32 @@ return rb_int2big(ctx->nparams); #endif } -static VALUE duckdb_prepared_statement_execute(VALUE self) -{ +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); if (duckdb_execute_prepared(ctx->prepared_statement, &(ctxr->result)) == DuckDBError) { - rb_raise(eDuckDBError, "%s", ctxr->result.error_message); + rb_raise(eDuckDBError, "%s", duckdb_result_error(&(ctxr->result))); } return result; } -static idx_t check_index(VALUE vidx) -{ +static idx_t check_index(VALUE vidx) { idx_t idx = FIX2INT(vidx); if (idx <= 0) { rb_raise(rb_eArgError, "index of parameter must be greater than 0"); } return idx; } -static VALUE duckdb_prepared_statement_bind_bool(VALUE self, VALUE vidx, VALUE val) -{ +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); if (val != Qtrue && val != Qfalse) { @@ -92,12 +119,11 @@ rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } -static VALUE duckdb_prepared_statement_bind_int8(VALUE self, VALUE vidx, VALUE val) -{ +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); @@ -106,12 +132,11 @@ rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } -static VALUE duckdb_prepared_statement_bind_int16(VALUE self, VALUE vidx, VALUE val) -{ +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); @@ -120,12 +145,11 @@ rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } -static VALUE duckdb_prepared_statement_bind_int32(VALUE self, VALUE vidx, VALUE val) -{ +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); @@ -134,12 +158,11 @@ rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } -static VALUE duckdb_prepared_statement_bind_int64(VALUE self, VALUE vidx, VALUE val) -{ +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); @@ -148,12 +171,11 @@ rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } -static VALUE duckdb_prepared_statement_bind_float(VALUE self, VALUE vidx, VALUE val) -{ +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); @@ -162,12 +184,11 @@ rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } -static VALUE duckdb_prepared_statement_bind_double(VALUE self, VALUE vidx, VALUE val) -{ +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); @@ -176,50 +197,109 @@ rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } -static VALUE duckdb_prepared_statement_bind_varchar(VALUE self, VALUE vidx, VALUE str) -{ +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); 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; } -#ifdef HAVE_DUCKDB_VALUE_BLOB -static VALUE duckdb_prepared_statement_bind_blob(VALUE self, VALUE vidx, VALUE blob) -{ +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); 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; } -#endif /* HAVE_DUCKDB_VALUE_BLOB */ -static VALUE duckdb_prepared_statement_bind_null(VALUE self, VALUE vidx) -{ +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); if (duckdb_bind_null(ctx->prepared_statement, idx) == DuckDBError) { rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); } return self; } -void init_duckdb_prepared_statement(void) -{ +#ifdef HAVE_DUCKDB_BIND_DATE +static VALUE duckdb_prepared_statement__bind_date(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day) { + rubyDuckDBPreparedStatement *ctx; + duckdb_date dt; + idx_t idx = check_index(vidx); + + dt = to_duckdb_date_from_value(year, month, day); + + Data_Get_Struct(self, rubyDuckDBPreparedStatement, 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; +} +#endif + +#ifdef HAVE_DUCKDB_BIND_TIME +static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE hour, VALUE min, VALUE sec, VALUE micros){ + rubyDuckDBPreparedStatement *ctx; + duckdb_time time; + + idx_t idx = check_index(vidx); + + time = to_duckdb_time_from_value(hour, min, sec, micros); + + Data_Get_Struct(self, rubyDuckDBPreparedStatement, 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; +} +#endif + +#ifdef HAVE_DUCKDB_BIND_TIMESTAMP +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); + + if (duckdb_bind_timestamp(ctx->prepared_statement, idx, timestamp) == DuckDBError) { + rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); + } + return self; +} +#endif + +#ifdef HAVE_DUCKDB_BIND_INTERVAL +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); + 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); + } + return self; +} +#endif + +void init_duckdb_prepared_statement(void) { cDuckDBPreparedStatement = rb_define_class_under(mDuckDB, "PreparedStatement", rb_cObject); rb_define_alloc_func(cDuckDBPreparedStatement, allocate); rb_define_method(cDuckDBPreparedStatement, "initialize", duckdb_prepared_statement_initialize, 2); @@ -231,10 +311,18 @@ rb_define_method(cDuckDBPreparedStatement, "bind_int32", duckdb_prepared_statement_bind_int32, 2); rb_define_method(cDuckDBPreparedStatement, "bind_int64", duckdb_prepared_statement_bind_int64, 2); rb_define_method(cDuckDBPreparedStatement, "bind_float", duckdb_prepared_statement_bind_float, 2); rb_define_method(cDuckDBPreparedStatement, "bind_double", duckdb_prepared_statement_bind_double, 2); rb_define_method(cDuckDBPreparedStatement, "bind_varchar", duckdb_prepared_statement_bind_varchar, 2); -#ifdef HAVE_DUCKDB_VALUE_BLOB rb_define_method(cDuckDBPreparedStatement, "bind_blob", duckdb_prepared_statement_bind_blob, 2); -#endif /* HAVE_DUCKDB_VALUE_BLOB */ rb_define_method(cDuckDBPreparedStatement, "bind_null", duckdb_prepared_statement_bind_null, 1); + rb_define_private_method(cDuckDBPreparedStatement, "_bind_date", duckdb_prepared_statement__bind_date, 4); +#ifdef HAVE_DUCKDB_BIND_TIME + rb_define_private_method(cDuckDBPreparedStatement, "_bind_time", duckdb_prepared_statement__bind_time, 5); +#endif +#ifdef HAVE_DUCKDB_BIND_TIMESTAMP + rb_define_private_method(cDuckDBPreparedStatement, "_bind_timestamp", duckdb_prepared_statement__bind_timestamp, 8); +#endif +#ifdef HAVE_DUCKDB_BIND_INTERVAL + rb_define_private_method(cDuckDBPreparedStatement, "_bind_interval", duckdb_prepared_statement__bind_interval, 4); +#endif }