duckdb 1.1.3.0 → 1.2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/make_documents.yml +34 -0
- data/.github/workflows/test_on_macos.yml +2 -2
- data/.github/workflows/test_on_ubuntu.yml +2 -2
- data/.github/workflows/test_on_windows.yml +2 -2
- data/.gitignore +1 -0
- data/.rdoc_options +22 -0
- data/CHANGELOG.md +49 -0
- data/Dockerfile +20 -9
- data/Gemfile.lock +23 -11
- data/README.md +17 -3
- data/duckdb.gemspec +1 -0
- data/ext/duckdb/appender.c +113 -78
- data/ext/duckdb/blob.c +3 -0
- data/ext/duckdb/column.c +33 -3
- data/ext/duckdb/config.c +3 -0
- data/ext/duckdb/connection.c +6 -0
- data/ext/duckdb/database.c +6 -0
- data/ext/duckdb/duckdb.c +1 -0
- data/ext/duckdb/error.c +3 -0
- data/ext/duckdb/extconf.rb +0 -3
- data/ext/duckdb/extracted_statements.c +3 -0
- data/ext/duckdb/logical_type.c +187 -0
- data/ext/duckdb/logical_type.h +13 -0
- data/ext/duckdb/pending_result.c +5 -0
- data/ext/duckdb/prepared_statement.c +46 -8
- data/ext/duckdb/result.c +16 -44
- data/ext/duckdb/ruby-duckdb.h +2 -0
- data/lib/duckdb/appender.rb +211 -48
- data/lib/duckdb/column.rb +0 -2
- data/lib/duckdb/connection.rb +1 -12
- data/lib/duckdb/database.rb +1 -6
- data/lib/duckdb/interval.rb +12 -10
- data/lib/duckdb/library_version.rb +2 -0
- data/lib/duckdb/logical_type.rb +22 -0
- data/lib/duckdb/pending_result.rb +1 -1
- data/lib/duckdb/result.rb +16 -16
- data/lib/duckdb/version.rb +1 -1
- data/lib/duckdb.rb +1 -0
- metadata +9 -6
@@ -0,0 +1,187 @@
|
|
1
|
+
#include "ruby-duckdb.h"
|
2
|
+
|
3
|
+
static VALUE cDuckDBLogicalType;
|
4
|
+
|
5
|
+
static void deallocate(void *ctx);
|
6
|
+
static VALUE allocate(VALUE klass);
|
7
|
+
static size_t memsize(const void *p);
|
8
|
+
static VALUE duckdb_logical_type__type(VALUE self);
|
9
|
+
static VALUE duckdb_logical_type_width(VALUE self);
|
10
|
+
static VALUE duckdb_logical_type_scale(VALUE self);
|
11
|
+
static VALUE duckdb_logical_type_child_type(VALUE self);
|
12
|
+
static VALUE duckdb_logical_type_size(VALUE self);
|
13
|
+
static VALUE duckdb_logical_type_key_type(VALUE self);
|
14
|
+
static VALUE duckdb_logical_type_value_type(VALUE self);
|
15
|
+
|
16
|
+
static const rb_data_type_t logical_type_data_type = {
|
17
|
+
"DuckDB/LogicalType",
|
18
|
+
{NULL, deallocate, memsize,},
|
19
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
20
|
+
};
|
21
|
+
|
22
|
+
static void deallocate(void *ctx) {
|
23
|
+
rubyDuckDBLogicalType *p = (rubyDuckDBLogicalType *)ctx;
|
24
|
+
|
25
|
+
if (p->logical_type) {
|
26
|
+
duckdb_destroy_logical_type(&(p->logical_type));
|
27
|
+
}
|
28
|
+
|
29
|
+
xfree(p);
|
30
|
+
}
|
31
|
+
|
32
|
+
static VALUE allocate(VALUE klass) {
|
33
|
+
rubyDuckDBLogicalType *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBLogicalType));
|
34
|
+
return TypedData_Wrap_Struct(klass, &logical_type_data_type, ctx);
|
35
|
+
}
|
36
|
+
|
37
|
+
static size_t memsize(const void *p) {
|
38
|
+
return sizeof(rubyDuckDBLogicalType);
|
39
|
+
}
|
40
|
+
|
41
|
+
/*
|
42
|
+
* call-seq:
|
43
|
+
* decimal_col.logical_type.type -> Symbol
|
44
|
+
*
|
45
|
+
* Returns the logical type's type symbol.
|
46
|
+
*
|
47
|
+
*/
|
48
|
+
static VALUE duckdb_logical_type__type(VALUE self) {
|
49
|
+
rubyDuckDBLogicalType *ctx;
|
50
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
51
|
+
return INT2FIX(duckdb_get_type_id(ctx->logical_type));
|
52
|
+
}
|
53
|
+
|
54
|
+
/*
|
55
|
+
* call-seq:
|
56
|
+
* decimal_col.logical_type.width -> Integer
|
57
|
+
*
|
58
|
+
* Returns the width of the decimal column.
|
59
|
+
*
|
60
|
+
*/
|
61
|
+
static VALUE duckdb_logical_type_width(VALUE self) {
|
62
|
+
rubyDuckDBLogicalType *ctx;
|
63
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
64
|
+
return INT2FIX(duckdb_decimal_width(ctx->logical_type));
|
65
|
+
}
|
66
|
+
|
67
|
+
/*
|
68
|
+
* call-seq:
|
69
|
+
* decimal_col.logical_type.scale -> Integer
|
70
|
+
*
|
71
|
+
* Returns the scale of the decimal column.
|
72
|
+
*
|
73
|
+
*/
|
74
|
+
static VALUE duckdb_logical_type_scale(VALUE self) {
|
75
|
+
rubyDuckDBLogicalType *ctx;
|
76
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
77
|
+
return INT2FIX(duckdb_decimal_scale(ctx->logical_type));
|
78
|
+
}
|
79
|
+
|
80
|
+
/*
|
81
|
+
* call-seq:
|
82
|
+
* list_col.logical_type.child_type -> DuckDB::LogicalType
|
83
|
+
*
|
84
|
+
* Returns the child logical type for list and map types, otherwise nil.
|
85
|
+
*
|
86
|
+
*/
|
87
|
+
static VALUE duckdb_logical_type_child_type(VALUE self) {
|
88
|
+
rubyDuckDBLogicalType *ctx;
|
89
|
+
duckdb_type type_id;
|
90
|
+
duckdb_logical_type child_logical_type;
|
91
|
+
VALUE logical_type = Qnil;
|
92
|
+
|
93
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
94
|
+
type_id = duckdb_get_type_id(ctx->logical_type);
|
95
|
+
|
96
|
+
switch(type_id) {
|
97
|
+
case DUCKDB_TYPE_LIST:
|
98
|
+
case DUCKDB_TYPE_MAP:
|
99
|
+
child_logical_type = duckdb_list_type_child_type(ctx->logical_type);
|
100
|
+
logical_type = rbduckdb_create_logical_type(child_logical_type);
|
101
|
+
break;
|
102
|
+
case DUCKDB_TYPE_ARRAY:
|
103
|
+
child_logical_type = duckdb_array_type_child_type(ctx->logical_type);
|
104
|
+
logical_type = rbduckdb_create_logical_type(child_logical_type);
|
105
|
+
break;
|
106
|
+
default:
|
107
|
+
logical_type = Qnil;
|
108
|
+
}
|
109
|
+
return logical_type;
|
110
|
+
}
|
111
|
+
|
112
|
+
/*
|
113
|
+
* call-seq:
|
114
|
+
* list_col.logical_type.size -> Integer
|
115
|
+
*
|
116
|
+
* Returns the size of the array column, otherwise 0.
|
117
|
+
*
|
118
|
+
*/
|
119
|
+
static VALUE duckdb_logical_type_size(VALUE self) {
|
120
|
+
rubyDuckDBLogicalType *ctx;
|
121
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
122
|
+
return INT2FIX(duckdb_array_type_array_size(ctx->logical_type));
|
123
|
+
}
|
124
|
+
|
125
|
+
/*
|
126
|
+
* call-seq:
|
127
|
+
* map_col.logical_type.key_type -> DuckDB::LogicalType
|
128
|
+
*
|
129
|
+
* Returns the key logical type for map type, otherwise nil.
|
130
|
+
*
|
131
|
+
*/
|
132
|
+
static VALUE duckdb_logical_type_key_type(VALUE self) {
|
133
|
+
rubyDuckDBLogicalType *ctx;
|
134
|
+
duckdb_logical_type key_logical_type;
|
135
|
+
VALUE logical_type = Qnil;
|
136
|
+
|
137
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
138
|
+
key_logical_type = duckdb_map_type_key_type(ctx->logical_type);
|
139
|
+
logical_type = rbduckdb_create_logical_type(key_logical_type);
|
140
|
+
return logical_type;
|
141
|
+
}
|
142
|
+
|
143
|
+
/*
|
144
|
+
* call-seq:
|
145
|
+
* map_col.logical_type.value_type -> DuckDB::LogicalType
|
146
|
+
*
|
147
|
+
* Returns the value logical type for map type, otherwise nil.
|
148
|
+
*
|
149
|
+
*/
|
150
|
+
static VALUE duckdb_logical_type_value_type(VALUE self) {
|
151
|
+
rubyDuckDBLogicalType *ctx;
|
152
|
+
duckdb_logical_type value_logical_type;
|
153
|
+
VALUE logical_type = Qnil;
|
154
|
+
|
155
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
156
|
+
value_logical_type = duckdb_map_type_value_type(ctx->logical_type);
|
157
|
+
logical_type = rbduckdb_create_logical_type(value_logical_type);
|
158
|
+
return logical_type;
|
159
|
+
}
|
160
|
+
|
161
|
+
VALUE rbduckdb_create_logical_type(duckdb_logical_type logical_type) {
|
162
|
+
VALUE obj;
|
163
|
+
rubyDuckDBLogicalType *ctx;
|
164
|
+
|
165
|
+
obj = allocate(cDuckDBLogicalType);
|
166
|
+
TypedData_Get_Struct(obj, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
167
|
+
|
168
|
+
ctx->logical_type = logical_type;
|
169
|
+
|
170
|
+
return obj;
|
171
|
+
}
|
172
|
+
|
173
|
+
void rbduckdb_init_duckdb_logical_type(void) {
|
174
|
+
#if 0
|
175
|
+
VALUE mDuckDB = rb_define_module("DuckDB");
|
176
|
+
#endif
|
177
|
+
cDuckDBLogicalType = rb_define_class_under(mDuckDB, "LogicalType", rb_cObject);
|
178
|
+
rb_define_alloc_func(cDuckDBLogicalType, allocate);
|
179
|
+
|
180
|
+
rb_define_private_method(cDuckDBLogicalType, "_type", duckdb_logical_type__type, 0);
|
181
|
+
rb_define_method(cDuckDBLogicalType, "width", duckdb_logical_type_width, 0);
|
182
|
+
rb_define_method(cDuckDBLogicalType, "scale", duckdb_logical_type_scale, 0);
|
183
|
+
rb_define_method(cDuckDBLogicalType, "child_type", duckdb_logical_type_child_type, 0);
|
184
|
+
rb_define_method(cDuckDBLogicalType, "size", duckdb_logical_type_size, 0);
|
185
|
+
rb_define_method(cDuckDBLogicalType, "key_type", duckdb_logical_type_key_type, 0);
|
186
|
+
rb_define_method(cDuckDBLogicalType, "value_type", duckdb_logical_type_value_type, 0);
|
187
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#ifndef RUBY_DUCKDB_LOGICAL_TYPE_H
|
2
|
+
#define RUBY_DUCKDB_LOGICAL_TYPE_H
|
3
|
+
|
4
|
+
struct _rubyDuckDBLogicalType {
|
5
|
+
duckdb_logical_type logical_type;
|
6
|
+
};
|
7
|
+
|
8
|
+
typedef struct _rubyDuckDBLogicalType rubyDuckDBLogicalType;
|
9
|
+
|
10
|
+
void rbduckdb_init_duckdb_logical_type(void);
|
11
|
+
VALUE rbduckdb_create_logical_type(duckdb_logical_type logical_type);
|
12
|
+
|
13
|
+
#endif
|
data/ext/duckdb/pending_result.c
CHANGED
@@ -124,11 +124,13 @@ static VALUE duckdb_pending_result_execute_pending(VALUE self) {
|
|
124
124
|
return result;
|
125
125
|
}
|
126
126
|
|
127
|
+
/* :nodoc: */
|
127
128
|
static VALUE duckdb_pending_result__state(VALUE self) {
|
128
129
|
rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
|
129
130
|
return INT2FIX(ctx->state);
|
130
131
|
}
|
131
132
|
|
133
|
+
/* :nodoc: */
|
132
134
|
static VALUE duckdb_pending_result__execute_check_state(VALUE self) {
|
133
135
|
rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
|
134
136
|
return INT2FIX(duckdb_pending_execute_check_state(ctx->pending_result));
|
@@ -141,6 +143,9 @@ rubyDuckDBPendingResult *get_struct_pending_result(VALUE obj) {
|
|
141
143
|
}
|
142
144
|
|
143
145
|
void rbduckdb_init_duckdb_pending_result(void) {
|
146
|
+
#if 0
|
147
|
+
VALUE mDuckDB = rb_define_module("DuckDB");
|
148
|
+
#endif
|
144
149
|
cDuckDBPendingResult = rb_define_class_under(mDuckDB, "PendingResult", rb_cObject);
|
145
150
|
rb_define_alloc_func(cDuckDBPendingResult, allocate);
|
146
151
|
|
@@ -72,7 +72,8 @@ VALUE rbduckdb_prepared_statement_new(duckdb_connection con, duckdb_extracted_st
|
|
72
72
|
TypedData_Get_Struct(obj, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
|
73
73
|
|
74
74
|
if (duckdb_prepare_extracted_statement(con, extracted_statements, index, &(ctx->prepared_statement)) == DuckDBError) {
|
75
|
-
|
75
|
+
const char *error = duckdb_prepare_error(ctx->prepared_statement);
|
76
|
+
rb_raise(eDuckDBError, "%s", error ? error : "Failed to create DuckDB::PreparedStatement object.");
|
76
77
|
}
|
77
78
|
return obj;
|
78
79
|
}
|
@@ -90,7 +91,7 @@ static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE q
|
|
90
91
|
|
91
92
|
if (duckdb_prepare(ctxcon->con, StringValuePtr(query), &(ctx->prepared_statement)) == DuckDBError) {
|
92
93
|
const char *error = duckdb_prepare_error(ctx->prepared_statement);
|
93
|
-
rb_raise(eDuckDBError, "%s", error);
|
94
|
+
rb_raise(eDuckDBError, "%s", error ? error : "Failed to prepare statement(Database connection closed?).");
|
94
95
|
}
|
95
96
|
return self;
|
96
97
|
}
|
@@ -101,21 +102,47 @@ static VALUE duckdb_prepared_statement_nparams(VALUE self) {
|
|
101
102
|
return ULL2NUM(duckdb_nparams(ctx->prepared_statement));
|
102
103
|
}
|
103
104
|
|
105
|
+
/* :nodoc: */
|
106
|
+
typedef struct {
|
107
|
+
duckdb_prepared_statement prepared_statement;
|
108
|
+
duckdb_result *out_result;
|
109
|
+
duckdb_state retval;
|
110
|
+
} duckdb_prepared_statement_execute_nogvl_args;
|
111
|
+
|
112
|
+
/* :nodoc: */
|
113
|
+
static void duckdb_prepared_statement_execute_nogvl(void *ptr) {
|
114
|
+
duckdb_prepared_statement_execute_nogvl_args *args = (duckdb_prepared_statement_execute_nogvl_args *)ptr;
|
115
|
+
|
116
|
+
args->retval = duckdb_execute_prepared(args->prepared_statement, args->out_result);
|
117
|
+
}
|
118
|
+
|
104
119
|
static VALUE duckdb_prepared_statement_execute(VALUE self) {
|
105
120
|
rubyDuckDBPreparedStatement *ctx;
|
106
121
|
rubyDuckDBResult *ctxr;
|
122
|
+
const char *error;
|
107
123
|
VALUE result = rbduckdb_create_result();
|
108
|
-
const char *p = NULL;
|
109
124
|
|
110
125
|
TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
|
111
126
|
ctxr = get_struct_result(result);
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
127
|
+
|
128
|
+
duckdb_prepared_statement_execute_nogvl_args args = {
|
129
|
+
.prepared_statement = ctx->prepared_statement,
|
130
|
+
.out_result = &(ctxr->result),
|
131
|
+
.retval = DuckDBError,
|
132
|
+
};
|
133
|
+
|
134
|
+
rb_thread_call_without_gvl((void *)duckdb_prepared_statement_execute_nogvl, &args, RUBY_UBF_IO, 0);
|
135
|
+
duckdb_state state = args.retval;
|
136
|
+
|
137
|
+
if (state == DuckDBError) {
|
138
|
+
error = duckdb_result_error(args.out_result);
|
139
|
+
if (error == NULL) {
|
140
|
+
error = duckdb_prepare_error(args.prepared_statement);
|
116
141
|
}
|
117
|
-
|
142
|
+
|
143
|
+
rb_raise(eDuckDBError, "%s", error ? error : "Failed to execute prepared statement.");
|
118
144
|
}
|
145
|
+
|
119
146
|
return result;
|
120
147
|
}
|
121
148
|
|
@@ -315,18 +342,21 @@ static VALUE duckdb_prepared_statement_bind_null(VALUE self, VALUE vidx) {
|
|
315
342
|
return self;
|
316
343
|
}
|
317
344
|
|
345
|
+
/* :nodoc: */
|
318
346
|
static VALUE duckdb_prepared_statement__statement_type(VALUE self) {
|
319
347
|
rubyDuckDBPreparedStatement *ctx;
|
320
348
|
TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
|
321
349
|
return INT2FIX(duckdb_prepared_statement_type(ctx->prepared_statement));
|
322
350
|
}
|
323
351
|
|
352
|
+
/* :nodoc: */
|
324
353
|
static VALUE duckdb_prepared_statement__param_type(VALUE self, VALUE vidx) {
|
325
354
|
rubyDuckDBPreparedStatement *ctx;
|
326
355
|
TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
|
327
356
|
return INT2FIX(duckdb_param_type(ctx->prepared_statement, NUM2ULL(vidx)));
|
328
357
|
}
|
329
358
|
|
359
|
+
/* :nodoc: */
|
330
360
|
static VALUE duckdb_prepared_statement__bind_date(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day) {
|
331
361
|
rubyDuckDBPreparedStatement *ctx;
|
332
362
|
duckdb_date dt;
|
@@ -343,6 +373,7 @@ static VALUE duckdb_prepared_statement__bind_date(VALUE self, VALUE vidx, VALUE
|
|
343
373
|
return self;
|
344
374
|
}
|
345
375
|
|
376
|
+
/* :nodoc: */
|
346
377
|
static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE hour, VALUE min, VALUE sec, VALUE micros){
|
347
378
|
rubyDuckDBPreparedStatement *ctx;
|
348
379
|
duckdb_time time;
|
@@ -360,6 +391,7 @@ static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE
|
|
360
391
|
return self;
|
361
392
|
}
|
362
393
|
|
394
|
+
/* :nodoc: */
|
363
395
|
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) {
|
364
396
|
duckdb_timestamp timestamp;
|
365
397
|
rubyDuckDBPreparedStatement *ctx;
|
@@ -374,6 +406,7 @@ static VALUE duckdb_prepared_statement__bind_timestamp(VALUE self, VALUE vidx, V
|
|
374
406
|
return self;
|
375
407
|
}
|
376
408
|
|
409
|
+
/* :nodoc: */
|
377
410
|
static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VALUE months, VALUE days, VALUE micros) {
|
378
411
|
duckdb_interval interval;
|
379
412
|
rubyDuckDBPreparedStatement *ctx;
|
@@ -389,6 +422,7 @@ static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VA
|
|
389
422
|
return self;
|
390
423
|
}
|
391
424
|
|
425
|
+
/* :nodoc: */
|
392
426
|
static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper) {
|
393
427
|
duckdb_hugeint hugeint;
|
394
428
|
rubyDuckDBPreparedStatement *ctx;
|
@@ -405,6 +439,7 @@ static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VAL
|
|
405
439
|
return self;
|
406
440
|
}
|
407
441
|
|
442
|
+
/* :nodoc: */
|
408
443
|
static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale) {
|
409
444
|
duckdb_hugeint hugeint;
|
410
445
|
duckdb_decimal decimal;
|
@@ -432,6 +467,9 @@ rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self) {
|
|
432
467
|
}
|
433
468
|
|
434
469
|
void rbduckdb_init_duckdb_prepared_statement(void) {
|
470
|
+
#if 0
|
471
|
+
VALUE mDuckDB = rb_define_module("DuckDB");
|
472
|
+
#endif
|
435
473
|
cDuckDBPreparedStatement = rb_define_class_under(mDuckDB, "PreparedStatement", rb_cObject);
|
436
474
|
|
437
475
|
rb_define_alloc_func(cDuckDBPreparedStatement, allocate);
|
data/ext/duckdb/result.c
CHANGED
@@ -24,12 +24,11 @@ static void deallocate(void *ctx);
|
|
24
24
|
static VALUE allocate(VALUE klass);
|
25
25
|
static size_t memsize(const void *p);
|
26
26
|
static VALUE duckdb_result_column_count(VALUE oDuckDBResult);
|
27
|
-
static VALUE duckdb_result_row_count(VALUE oDuckDBResult);
|
28
27
|
static VALUE duckdb_result_rows_changed(VALUE oDuckDBResult);
|
29
28
|
static VALUE duckdb_result_columns(VALUE oDuckDBResult);
|
30
29
|
static VALUE duckdb_result_streaming_p(VALUE oDuckDBResult);
|
31
30
|
static VALUE destroy_data_chunk(VALUE arg);
|
32
|
-
static VALUE
|
31
|
+
static VALUE duckdb_result__chunk_each(VALUE oDuckDBResult);
|
33
32
|
|
34
33
|
static VALUE duckdb_result__chunk_stream(VALUE oDuckDBResult);
|
35
34
|
static VALUE yield_rows(VALUE arg);
|
@@ -147,36 +146,6 @@ static VALUE duckdb_result_column_count(VALUE oDuckDBResult) {
|
|
147
146
|
return LL2NUM(duckdb_column_count(&(ctx->result)));
|
148
147
|
}
|
149
148
|
|
150
|
-
/*
|
151
|
-
* call-seq:
|
152
|
-
* result.row_count -> Integer
|
153
|
-
*
|
154
|
-
* Returns the column size of the result.
|
155
|
-
*
|
156
|
-
* DuckDB::Database.open do |db|
|
157
|
-
* db.connect do |con|
|
158
|
-
* r = con.query('CREATE TABLE t2 (id INT, name VARCHAR(128))')
|
159
|
-
* r = con.query("INSERT INTO t2 VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Catherine')")
|
160
|
-
* r = con.query('SELECT * FROM t2')
|
161
|
-
* r.row_count # => 3
|
162
|
-
* r = con.query('SELECT * FROM t2 where id = 1')
|
163
|
-
* r.row_count # => 1
|
164
|
-
* end
|
165
|
-
* end
|
166
|
-
*
|
167
|
-
*/
|
168
|
-
static VALUE duckdb_result_row_count(VALUE oDuckDBResult) {
|
169
|
-
|
170
|
-
#ifdef DUCKDB_API_NO_DEPRECATED
|
171
|
-
return Qnil;
|
172
|
-
#else
|
173
|
-
rubyDuckDBResult *ctx;
|
174
|
-
rb_warn("`row_count` will be deprecated in the future.");
|
175
|
-
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
176
|
-
return LL2NUM(duckdb_row_count(&(ctx->result)));
|
177
|
-
#endif
|
178
|
-
}
|
179
|
-
|
180
149
|
/*
|
181
150
|
* call-seq:
|
182
151
|
* result.columns -> DuckDB::Column[]
|
@@ -200,11 +169,7 @@ static VALUE duckdb_result_columns(VALUE oDuckDBResult) {
|
|
200
169
|
}
|
201
170
|
|
202
171
|
/*
|
203
|
-
*
|
204
|
-
* result.streaming? -> Boolean
|
205
|
-
*
|
206
|
-
* Returns true if the result is streaming, otherwise false.
|
207
|
-
*
|
172
|
+
* :nodoc:
|
208
173
|
*/
|
209
174
|
static VALUE duckdb_result_streaming_p(VALUE oDuckDBResult) {
|
210
175
|
rubyDuckDBResult *ctx;
|
@@ -212,6 +177,7 @@ static VALUE duckdb_result_streaming_p(VALUE oDuckDBResult) {
|
|
212
177
|
#ifdef DUCKDB_API_NO_DEPRECATED
|
213
178
|
return Qtrue;
|
214
179
|
#else
|
180
|
+
rb_warn("`DuckDB::Result#streaming?` will be deprecated in the future.");
|
215
181
|
/* FIXME streaming is allways true. so this method is not useful and deprecated. */
|
216
182
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
217
183
|
return duckdb_result_is_streaming(ctx->result) ? Qtrue : Qfalse;
|
@@ -224,7 +190,8 @@ static VALUE destroy_data_chunk(VALUE arg) {
|
|
224
190
|
return Qnil;
|
225
191
|
}
|
226
192
|
|
227
|
-
|
193
|
+
/* :nodoc: */
|
194
|
+
static VALUE duckdb_result__chunk_each(VALUE oDuckDBResult) {
|
228
195
|
/*
|
229
196
|
#ifdef HAVE_DUCKDB_H_GE_V1_0_0
|
230
197
|
return duckdb_result__chunk_stream(oDuckDBResult);
|
@@ -258,6 +225,7 @@ static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult) {
|
|
258
225
|
*/
|
259
226
|
}
|
260
227
|
|
228
|
+
/* :nodoc: */
|
261
229
|
static VALUE duckdb_result__chunk_stream(VALUE oDuckDBResult) {
|
262
230
|
rubyDuckDBResult *ctx;
|
263
231
|
struct chunk_arg arg;
|
@@ -268,11 +236,7 @@ static VALUE duckdb_result__chunk_stream(VALUE oDuckDBResult) {
|
|
268
236
|
|
269
237
|
arg.col_count = duckdb_column_count(&(ctx->result));
|
270
238
|
|
271
|
-
#ifdef HAVE_DUCKDB_H_GE_V1_0_0
|
272
239
|
while((arg.chunk = duckdb_fetch_chunk(ctx->result)) != NULL) {
|
273
|
-
#else
|
274
|
-
while((arg.chunk = duckdb_stream_fetch_chunk(ctx->result)) != NULL) {
|
275
|
-
#endif
|
276
240
|
rb_ensure(yield_rows, (VALUE)&arg, destroy_data_chunk, (VALUE)&arg);
|
277
241
|
}
|
278
242
|
return Qnil;
|
@@ -301,12 +265,14 @@ static VALUE yield_rows(VALUE arg) {
|
|
301
265
|
return Qnil;
|
302
266
|
}
|
303
267
|
|
268
|
+
/* :nodoc: */
|
304
269
|
static VALUE duckdb_result__column_type(VALUE oDuckDBResult, VALUE col_idx) {
|
305
270
|
rubyDuckDBResult *ctx;
|
306
271
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
307
272
|
return LL2NUM(duckdb_column_type(&(ctx->result), NUM2LL(col_idx)));
|
308
273
|
}
|
309
274
|
|
275
|
+
/* :nodoc: */
|
310
276
|
static VALUE duckdb_result__return_type(VALUE oDuckDBResult) {
|
311
277
|
rubyDuckDBResult *ctx;
|
312
278
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
@@ -320,12 +286,14 @@ static VALUE duckdb_result__return_type(VALUE oDuckDBResult) {
|
|
320
286
|
#endif
|
321
287
|
}
|
322
288
|
|
289
|
+
/* :nodoc: */
|
323
290
|
static VALUE duckdb_result__statement_type(VALUE oDuckDBResult) {
|
324
291
|
rubyDuckDBResult *ctx;
|
325
292
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
326
293
|
return INT2FIX(duckdb_result_statement_type(ctx->result));
|
327
294
|
}
|
328
295
|
|
296
|
+
/* :nodoc: */
|
329
297
|
static VALUE duckdb_result__enum_internal_type(VALUE oDuckDBResult, VALUE col_idx) {
|
330
298
|
rubyDuckDBResult *ctx;
|
331
299
|
VALUE type = Qnil;
|
@@ -340,6 +308,7 @@ static VALUE duckdb_result__enum_internal_type(VALUE oDuckDBResult, VALUE col_id
|
|
340
308
|
return type;
|
341
309
|
}
|
342
310
|
|
311
|
+
/* :nodoc: */
|
343
312
|
static VALUE duckdb_result__enum_dictionary_size(VALUE oDuckDBResult, VALUE col_idx) {
|
344
313
|
rubyDuckDBResult *ctx;
|
345
314
|
VALUE size = Qnil;
|
@@ -354,6 +323,7 @@ static VALUE duckdb_result__enum_dictionary_size(VALUE oDuckDBResult, VALUE col_
|
|
354
323
|
return size;
|
355
324
|
}
|
356
325
|
|
326
|
+
/* :nodoc: */
|
357
327
|
static VALUE duckdb_result__enum_dictionary_value(VALUE oDuckDBResult, VALUE col_idx, VALUE idx) {
|
358
328
|
rubyDuckDBResult *ctx;
|
359
329
|
VALUE value = Qnil;
|
@@ -884,6 +854,9 @@ static VALUE vector_value(duckdb_vector vector, idx_t row_idx) {
|
|
884
854
|
}
|
885
855
|
|
886
856
|
void rbduckdb_init_duckdb_result(void) {
|
857
|
+
#if 0
|
858
|
+
VALUE mDuckDB = rb_define_module("DuckDB");
|
859
|
+
#endif
|
887
860
|
cDuckDBResult = rb_define_class_under(mDuckDB, "Result", rb_cObject);
|
888
861
|
id__to_date = rb_intern("_to_date");
|
889
862
|
id__to_time = rb_intern("_to_time");
|
@@ -902,11 +875,10 @@ void rbduckdb_init_duckdb_result(void) {
|
|
902
875
|
rb_define_alloc_func(cDuckDBResult, allocate);
|
903
876
|
|
904
877
|
rb_define_method(cDuckDBResult, "column_count", duckdb_result_column_count, 0);
|
905
|
-
rb_define_method(cDuckDBResult, "row_count", duckdb_result_row_count, 0); /* deprecated */
|
906
878
|
rb_define_method(cDuckDBResult, "rows_changed", duckdb_result_rows_changed, 0);
|
907
879
|
rb_define_method(cDuckDBResult, "columns", duckdb_result_columns, 0);
|
908
880
|
rb_define_method(cDuckDBResult, "streaming?", duckdb_result_streaming_p, 0);
|
909
|
-
|
881
|
+
rb_define_private_method(cDuckDBResult, "_chunk_each", duckdb_result__chunk_each, 0);
|
910
882
|
rb_define_private_method(cDuckDBResult, "_chunk_stream", duckdb_result__chunk_stream, 0);
|
911
883
|
rb_define_private_method(cDuckDBResult, "_column_type", duckdb_result__column_type, 1);
|
912
884
|
rb_define_private_method(cDuckDBResult, "_return_type", duckdb_result__return_type, 0);
|
data/ext/duckdb/ruby-duckdb.h
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
#define DUCKDB_NO_EXTENSION_FUNCTIONS // disable extension C-functions
|
6
6
|
|
7
7
|
#include "ruby.h"
|
8
|
+
#include "ruby/thread.h"
|
8
9
|
#include <duckdb.h>
|
9
10
|
|
10
11
|
#ifdef HAVE_DUCKDB_FETCH_CHUNK
|
@@ -24,6 +25,7 @@
|
|
24
25
|
#include "./connection.h"
|
25
26
|
#include "./result.h"
|
26
27
|
#include "./column.h"
|
28
|
+
#include "./logical_type.h"
|
27
29
|
#include "./prepared_statement.h"
|
28
30
|
#include "./extracted_statements.h"
|
29
31
|
#include "./pending_result.h"
|