duckdb 1.2.0.0 → 1.2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ed07310471afbddcd5b4facd1720eeae0868af7d2682754a30361bafdf45b5a
4
- data.tar.gz: 984fd1ac1d47a72c0d20a2b1225656baf8838a47c70c3edc54d58bde0490cf25
3
+ metadata.gz: d8003b16f724b8a5c4863dbc507476601992e002767aa3cf7cfd7d87583265bc
4
+ data.tar.gz: a82ef0f5617349c568dd2be3cb8ad1deb5bdee8796483e376eaabc266232f280
5
5
  SHA512:
6
- metadata.gz: 5e85e65243f72ac9d1d8bab1ec44a18b7ac31dccba3cfd12dc81c075f44ea79592b7357dde7f30b4276fda2eee769aa93986ca216061ea2aa497a7e7038872df
7
- data.tar.gz: ee8db3baf4385b71e4c4d4765200baacef1df273702281e33809d2b4037bc25b4bae008e0501c178f615ba22f5a1b99021a22d15d5982054dbe675a769ca1cd8
6
+ metadata.gz: 8220ad5939d4c60819636488a783118ba8040429348ad157515ea1801fe9462ad20e2fff12440ce3e1ffae642f3d6fca0a02b43b4ed8958a105cfd079f85de47
7
+ data.tar.gz: f221a85106b80b654750faeb855c51ff760d82082cb86d7c77834c20194ab71b21feff55d883f1d2d13b1dac699bb50ff6fc5473a04db0e50f4dbbfcb1cd5d22
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: macos-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['3.1.6', '3.2.6', '3.3.6', '3.4.2', 'head']
19
- duckdb: ['1.2.0', '1.1.3', '1.1.1', '1.0.0']
18
+ ruby: ['3.1.6', '3.2.7', '3.3.7', '3.4.2', 'head']
19
+ duckdb: ['1.2.1', '1.1.3', '1.1.1']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v4
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: ubuntu-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['3.1.6', '3.2.6', '3.3.6', '3.4.2', 'head']
19
- duckdb: ['1.2.0', '1.1.3', '1.1.1', '1.0.0']
18
+ ruby: ['3.1.6', '3.2.7', '3.3.7', '3.4.2', 'head']
19
+ duckdb: ['1.2.1', '1.1.3', '1.1.1']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v4
@@ -16,7 +16,7 @@ jobs:
16
16
  strategy:
17
17
  matrix:
18
18
  ruby: ['3.1.6', '3.2.6', '3.3.6', '3.4.1', 'ucrt', 'mingw', 'mswin', 'head']
19
- duckdb: ['1.2.0', '1.1.3', '1.1.1', '1.0.0']
19
+ duckdb: ['1.2.1', '1.1.3', '1.1.1']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v4
data/CHANGELOG.md CHANGED
@@ -3,6 +3,24 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  # Unreleased
5
5
 
6
+ # 1.2.1.0 - 2025-03-30
7
+ - bump duckdb v1.2.1 on CI.
8
+ - drop duckdb v1.0.0.
9
+ - add `DuckDB::LogicalType` class.
10
+ - `DuckDB::LogicalType` class is under construction. `DuckDB::LogicalType#member_count`,
11
+ `DuckDB::LogicalType#member_name_at`, `DuckDB::LogicalType#member_type_at`,
12
+ `DuckDB::LogicalType#each_member_name`, `DuckDB::LogicalType#each_member_type`,
13
+ `DuckDB::LogicalType#child_count`, `DuckDB::LogicalType#child_name_at`,
14
+ `DuckDB::LogicalType#child_type_at`, `DuckDB::LogicalType#each_child_name`, and
15
+ `DuckDB::LogicalType#each_child_type` are available.
16
+ - fix error message when `DuckDB::Appender#append_uint16`, `DuckDB::Appender#append_uint32`,
17
+ `DuckDB::Appender#append_uint64`, `DuckDB::Appender#append_float`, `DuckDB::Appender#append_double`,
18
+ `DuckDB::Appender#append_varchar`, `DuckDB::Appender#append_varchar_length`,
19
+ `DuckDB::Appender#append_blob`, `DuckDB::Appender#append_null`, `DuckDB::Appender#append_default`,
20
+ `DuckDB::Appender#append_date`, `DuckDB::Appender#append_interval`, `DuckDB::Appender#append_time`,
21
+ `DuckDB::Appender#append_timestamp`, `DuckDB::Appender#append_hugeint` failed.
22
+ - add `DuckDB::PreparedStatement#bind_uhugeint`.
23
+
6
24
  # 1.2.0.0 - 2025-02-24
7
25
  - bump duckdb to 1.2.0.
8
26
  - add `DuckDB::LogicalType` class(Thanks to @otegami).
data/Dockerfile CHANGED
@@ -1,7 +1,7 @@
1
1
  ARG RUBY_VERSION=3.4.2
2
2
  FROM ruby:${RUBY_VERSION}
3
3
 
4
- ARG DUCKDB_VERSION=1.2.0
4
+ ARG DUCKDB_VERSION=1.2.1
5
5
  ARG VALGRIND_VERSION=3.21.0
6
6
 
7
7
  RUN apt update -qq && \
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (1.2.0.0)
4
+ duckdb (1.2.1.0)
5
5
  bigdecimal (>= 3.1.4)
6
6
 
7
7
  GEM
@@ -10,19 +10,19 @@ GEM
10
10
  benchmark-ips (2.14.0)
11
11
  bigdecimal (3.1.9)
12
12
  mini_portile2 (2.8.8)
13
- minitest (5.25.4)
14
- nokogiri (1.18.3)
13
+ minitest (5.25.5)
14
+ nokogiri (1.18.6)
15
15
  mini_portile2 (~> 2.8.2)
16
16
  racc (~> 1.4)
17
- nokogiri (1.18.3-aarch64-linux-gnu)
17
+ nokogiri (1.18.6-aarch64-linux-gnu)
18
18
  racc (~> 1.4)
19
- nokogiri (1.18.3-arm-linux-gnu)
19
+ nokogiri (1.18.6-arm-linux-gnu)
20
20
  racc (~> 1.4)
21
- nokogiri (1.18.3-arm64-darwin)
21
+ nokogiri (1.18.6-arm64-darwin)
22
22
  racc (~> 1.4)
23
- nokogiri (1.18.3-x86_64-darwin)
23
+ nokogiri (1.18.6-x86_64-darwin)
24
24
  racc (~> 1.4)
25
- nokogiri (1.18.3-x86_64-linux-gnu)
25
+ nokogiri (1.18.6-x86_64-linux-gnu)
26
26
  racc (~> 1.4)
27
27
  racc (1.8.1)
28
28
  rake (13.2.1)
@@ -13,20 +13,16 @@ static VALUE appender__append_int16(VALUE self, VALUE val);
13
13
  static VALUE appender__append_int32(VALUE self, VALUE val);
14
14
  static VALUE appender__append_int64(VALUE self, VALUE val);
15
15
  static VALUE appender__append_uint8(VALUE self, VALUE val);
16
- static VALUE appender_append_uint16(VALUE self, VALUE val);
17
- static VALUE appender_append_uint32(VALUE self, VALUE val);
18
- static VALUE appender_append_uint64(VALUE self, VALUE val);
19
- static VALUE appender_append_float(VALUE self, VALUE val);
20
- static VALUE appender_append_double(VALUE self, VALUE val);
21
- static VALUE appender_append_varchar(VALUE self, VALUE val);
22
- static VALUE appender_append_varchar_length(VALUE self, VALUE val, VALUE len);
23
- static VALUE appender_append_blob(VALUE self, VALUE val);
24
- static VALUE appender_append_null(VALUE self);
25
-
26
- #ifdef HAVE_DUCKDB_H_GE_V1_1_0
27
- static VALUE appender_append_default(VALUE self);
28
- #endif
29
-
16
+ static VALUE appender__append_uint16(VALUE self, VALUE val);
17
+ static VALUE appender__append_uint32(VALUE self, VALUE val);
18
+ static VALUE appender__append_uint64(VALUE self, VALUE val);
19
+ static VALUE appender__append_float(VALUE self, VALUE val);
20
+ static VALUE appender__append_double(VALUE self, VALUE val);
21
+ static VALUE appender__append_varchar(VALUE self, VALUE val);
22
+ static VALUE appender__append_varchar_length(VALUE self, VALUE val, VALUE len);
23
+ static VALUE appender__append_blob(VALUE self, VALUE val);
24
+ static VALUE appender__append_null(VALUE self);
25
+ static VALUE appender__append_default(VALUE self);
30
26
  static VALUE appender__end_row(VALUE self);
31
27
  static VALUE appender__append_date(VALUE self, VALUE yearval, VALUE monthval, VALUE dayval);
32
28
  static VALUE appender__append_interval(VALUE self, VALUE months, VALUE days, VALUE micros);
@@ -177,79 +173,68 @@ static VALUE appender__append_uint8(VALUE self, VALUE val) {
177
173
  return duckdb_state_to_bool_value(duckdb_append_uint8(ctx->appender, ui8val));
178
174
  }
179
175
 
180
- static VALUE appender_append_uint16(VALUE self, VALUE val) {
176
+ /* :nodoc: */
177
+ static VALUE appender__append_uint16(VALUE self, VALUE val) {
181
178
  rubyDuckDBAppender *ctx;
182
179
  uint16_t ui16val = (uint16_t)NUM2UINT(val);
183
180
 
184
181
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
185
182
 
186
- if (duckdb_append_uint16(ctx->appender, ui16val) == DuckDBError) {
187
- rb_raise(eDuckDBError, "failed to append uint16");
188
- }
189
- return self;
183
+ return duckdb_state_to_bool_value(duckdb_append_uint16(ctx->appender, ui16val));
190
184
  }
191
185
 
192
- static VALUE appender_append_uint32(VALUE self, VALUE val) {
186
+ /* :nodoc: */
187
+ static VALUE appender__append_uint32(VALUE self, VALUE val) {
193
188
  rubyDuckDBAppender *ctx;
194
189
  uint32_t ui32val = (uint32_t)NUM2UINT(val);
195
190
 
196
191
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
197
192
 
198
- if (duckdb_append_uint32(ctx->appender, ui32val) == DuckDBError) {
199
- rb_raise(eDuckDBError, "failed to append uint32");
200
- }
201
- return self;
193
+ return duckdb_state_to_bool_value(duckdb_append_uint32(ctx->appender, ui32val));
202
194
  }
203
195
 
204
- static VALUE appender_append_uint64(VALUE self, VALUE val) {
196
+ /* :nodoc: */
197
+ static VALUE appender__append_uint64(VALUE self, VALUE val) {
205
198
  rubyDuckDBAppender *ctx;
206
199
  uint64_t ui64val = (uint64_t)NUM2ULL(val);
207
200
 
208
201
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
209
202
 
210
- if (duckdb_append_uint64(ctx->appender, ui64val) == DuckDBError) {
211
- rb_raise(eDuckDBError, "failed to append uint64");
212
- }
213
- return self;
203
+ return duckdb_state_to_bool_value(duckdb_append_uint64(ctx->appender, ui64val));
214
204
  }
215
205
 
216
- static VALUE appender_append_float(VALUE self, VALUE val) {
206
+ /* :nodoc: */
207
+ static VALUE appender__append_float(VALUE self, VALUE val) {
217
208
  rubyDuckDBAppender *ctx;
218
209
  float fval = (float)NUM2DBL(val);
219
210
 
220
211
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
221
212
 
222
- if (duckdb_append_float(ctx->appender, fval) == DuckDBError) {
223
- rb_raise(eDuckDBError, "failed to append float");
224
- }
225
- return self;
213
+ return duckdb_state_to_bool_value(duckdb_append_float(ctx->appender, fval));
226
214
  }
227
215
 
228
- static VALUE appender_append_double(VALUE self, VALUE val) {
216
+ /* :nodoc: */
217
+ static VALUE appender__append_double(VALUE self, VALUE val) {
229
218
  rubyDuckDBAppender *ctx;
230
219
  double dval = NUM2DBL(val);
231
220
 
232
221
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
233
222
 
234
- if (duckdb_append_double(ctx->appender, dval) == DuckDBError) {
235
- rb_raise(eDuckDBError, "failed to append double");
236
- }
237
- return self;
223
+ return duckdb_state_to_bool_value(duckdb_append_double(ctx->appender, dval));
238
224
  }
239
225
 
240
- static VALUE appender_append_varchar(VALUE self, VALUE val) {
226
+ /* :nodoc: */
227
+ static VALUE appender__append_varchar(VALUE self, VALUE val) {
241
228
  rubyDuckDBAppender *ctx;
242
229
  char *pval = StringValuePtr(val);
243
230
 
244
231
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
245
232
 
246
- if (duckdb_append_varchar(ctx->appender, pval) == DuckDBError) {
247
- rb_raise(eDuckDBError, "failed to append varchar");
248
- }
249
- return self;
233
+ return duckdb_state_to_bool_value(duckdb_append_varchar(ctx->appender, pval));
250
234
  }
251
235
 
252
- static VALUE appender_append_varchar_length(VALUE self, VALUE val, VALUE len) {
236
+ /* :nodoc: */
237
+ static VALUE appender__append_varchar_length(VALUE self, VALUE val, VALUE len) {
253
238
  rubyDuckDBAppender *ctx;
254
239
 
255
240
  char *pval = StringValuePtr(val);
@@ -257,13 +242,11 @@ static VALUE appender_append_varchar_length(VALUE self, VALUE val, VALUE len) {
257
242
 
258
243
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
259
244
 
260
- if (duckdb_append_varchar_length(ctx->appender, pval, length) == DuckDBError) {
261
- rb_raise(eDuckDBError, "failed to append varchar with length");
262
- }
263
- return self;
245
+ return duckdb_state_to_bool_value(duckdb_append_varchar_length(ctx->appender, pval, length));
264
246
  }
265
247
 
266
- static VALUE appender_append_blob(VALUE self, VALUE val) {
248
+ /* :nodoc: */
249
+ static VALUE appender__append_blob(VALUE self, VALUE val) {
267
250
  rubyDuckDBAppender *ctx;
268
251
 
269
252
  char *pval = StringValuePtr(val);
@@ -271,33 +254,24 @@ static VALUE appender_append_blob(VALUE self, VALUE val) {
271
254
 
272
255
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
273
256
 
274
- if (duckdb_append_blob(ctx->appender, (void *)pval, length) == DuckDBError) {
275
- rb_raise(eDuckDBError, "failed to append blob");
276
- }
277
- return self;
257
+ return duckdb_state_to_bool_value(duckdb_append_blob(ctx->appender, (void *)pval, length));
278
258
  }
279
259
 
280
- static VALUE appender_append_null(VALUE self) {
260
+ /* :nodoc: */
261
+ static VALUE appender__append_null(VALUE self) {
281
262
  rubyDuckDBAppender *ctx;
282
263
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
283
264
 
284
- if (duckdb_append_null(ctx->appender) == DuckDBError) {
285
- rb_raise(eDuckDBError, "failed to append null");
286
- }
287
- return self;
265
+ return duckdb_state_to_bool_value(duckdb_append_null(ctx->appender));
288
266
  }
289
267
 
290
- #ifdef HAVE_DUCKDB_H_GE_V1_1_0
291
- static VALUE appender_append_default(VALUE self) {
268
+ /* :nodoc: */
269
+ static VALUE appender__append_default(VALUE self) {
292
270
  rubyDuckDBAppender *ctx;
293
271
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
294
272
 
295
- if (duckdb_append_default(ctx->appender) == DuckDBError) {
296
- rb_raise(eDuckDBError, "failed to append default");
297
- }
298
- return self;
273
+ return duckdb_state_to_bool_value(duckdb_append_default(ctx->appender));
299
274
  }
300
- #endif
301
275
 
302
276
  /* :nodoc: */
303
277
  static VALUE appender__append_date(VALUE self, VALUE year, VALUE month, VALUE day) {
@@ -307,10 +281,7 @@ static VALUE appender__append_date(VALUE self, VALUE year, VALUE month, VALUE da
307
281
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
308
282
  dt = rbduckdb_to_duckdb_date_from_value(year, month, day);
309
283
 
310
- if (duckdb_append_date(ctx->appender, dt) == DuckDBError) {
311
- rb_raise(eDuckDBError, "failed to append date");
312
- }
313
- return self;
284
+ return duckdb_state_to_bool_value(duckdb_append_date(ctx->appender, dt));
314
285
  }
315
286
 
316
287
  /* :nodoc: */
@@ -321,10 +292,7 @@ static VALUE appender__append_interval(VALUE self, VALUE months, VALUE days, VAL
321
292
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
322
293
  rbduckdb_to_duckdb_interval_from_value(&interval, months, days, micros);
323
294
 
324
- if (duckdb_append_interval(ctx->appender, interval) == DuckDBError) {
325
- rb_raise(eDuckDBError, "failed to append interval");
326
- }
327
- return self;
295
+ return duckdb_state_to_bool_value(duckdb_append_interval(ctx->appender, interval));
328
296
  }
329
297
 
330
298
  /* :nodoc: */
@@ -335,10 +303,7 @@ static VALUE appender__append_time(VALUE self, VALUE hour, VALUE min, VALUE sec,
335
303
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
336
304
  time = rbduckdb_to_duckdb_time_from_value(hour, min, sec, micros);
337
305
 
338
- if (duckdb_append_time(ctx->appender, time) == DuckDBError) {
339
- rb_raise(eDuckDBError, "failed to append time");
340
- }
341
- return self;
306
+ return duckdb_state_to_bool_value(duckdb_append_time(ctx->appender, time));
342
307
  }
343
308
 
344
309
  /* :nodoc: */
@@ -351,10 +316,7 @@ static VALUE appender__append_timestamp(VALUE self, VALUE year, VALUE month, VAL
351
316
 
352
317
  timestamp = rbduckdb_to_duckdb_timestamp_from_value(year, month, day, hour, min, sec, micros);
353
318
 
354
- if (duckdb_append_timestamp(ctx->appender, timestamp) == DuckDBError) {
355
- rb_raise(eDuckDBError, "failed to append timestamp");
356
- }
357
- return self;
319
+ return duckdb_state_to_bool_value(duckdb_append_timestamp(ctx->appender, timestamp));
358
320
  }
359
321
 
360
322
  /* :nodoc: */
@@ -367,10 +329,8 @@ static VALUE appender__append_hugeint(VALUE self, VALUE lower, VALUE upper) {
367
329
  rubyDuckDBAppender *ctx;
368
330
 
369
331
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
370
- if (duckdb_append_hugeint(ctx->appender, hugeint) == DuckDBError) {
371
- rb_raise(eDuckDBError, "failed to append hugeint");
372
- }
373
- return self;
332
+
333
+ return duckdb_state_to_bool_value(duckdb_append_hugeint(ctx->appender, hugeint));
374
334
  }
375
335
 
376
336
  /* :nodoc: */
@@ -383,10 +343,8 @@ static VALUE appender__append_uhugeint(VALUE self, VALUE lower, VALUE upper) {
383
343
  rubyDuckDBAppender *ctx;
384
344
 
385
345
  TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
386
- if (duckdb_append_uhugeint(ctx->appender, uhugeint) == DuckDBError) {
387
- rb_raise(eDuckDBError, "failed to append uhugeint");
388
- }
389
- return self;
346
+
347
+ return duckdb_state_to_bool_value(duckdb_append_uhugeint(ctx->appender, uhugeint));
390
348
  }
391
349
 
392
350
  /* :nodoc: */
@@ -420,20 +378,6 @@ void rbduckdb_init_duckdb_appender(void) {
420
378
  rb_define_alloc_func(cDuckDBAppender, allocate);
421
379
  rb_define_method(cDuckDBAppender, "initialize", appender_initialize, 3);
422
380
  rb_define_method(cDuckDBAppender, "error_message", appender_error_message, 0);
423
- rb_define_method(cDuckDBAppender, "append_uint16", appender_append_uint16, 1);
424
- rb_define_method(cDuckDBAppender, "append_uint32", appender_append_uint32, 1);
425
- rb_define_method(cDuckDBAppender, "append_uint64", appender_append_uint64, 1);
426
- rb_define_method(cDuckDBAppender, "append_float", appender_append_float, 1);
427
- rb_define_method(cDuckDBAppender, "append_double", appender_append_double, 1);
428
- rb_define_method(cDuckDBAppender, "append_varchar", appender_append_varchar, 1);
429
- rb_define_method(cDuckDBAppender, "append_varchar_length", appender_append_varchar_length, 2);
430
- rb_define_method(cDuckDBAppender, "append_blob", appender_append_blob, 1);
431
- rb_define_method(cDuckDBAppender, "append_null", appender_append_null, 0);
432
-
433
- #ifdef HAVE_DUCKDB_H_GE_V1_1_0
434
- rb_define_method(cDuckDBAppender, "append_default", appender_append_default, 0);
435
- #endif
436
-
437
381
  rb_define_private_method(cDuckDBAppender, "_end_row", appender__end_row, 0);
438
382
  rb_define_private_method(cDuckDBAppender, "_flush", appender__flush, 0);
439
383
  rb_define_private_method(cDuckDBAppender, "_close", appender__close, 0);
@@ -443,6 +387,16 @@ void rbduckdb_init_duckdb_appender(void) {
443
387
  rb_define_private_method(cDuckDBAppender, "_append_int32", appender__append_int32, 1);
444
388
  rb_define_private_method(cDuckDBAppender, "_append_int64", appender__append_int64, 1);
445
389
  rb_define_private_method(cDuckDBAppender, "_append_uint8", appender__append_uint8, 1);
390
+ rb_define_private_method(cDuckDBAppender, "_append_uint16", appender__append_uint16, 1);
391
+ rb_define_private_method(cDuckDBAppender, "_append_uint32", appender__append_uint32, 1);
392
+ rb_define_private_method(cDuckDBAppender, "_append_uint64", appender__append_uint64, 1);
393
+ rb_define_private_method(cDuckDBAppender, "_append_float", appender__append_float, 1);
394
+ rb_define_private_method(cDuckDBAppender, "_append_double", appender__append_double, 1);
395
+ rb_define_private_method(cDuckDBAppender, "_append_varchar", appender__append_varchar, 1);
396
+ rb_define_private_method(cDuckDBAppender, "_append_varchar_length", appender__append_varchar_length, 2);
397
+ rb_define_private_method(cDuckDBAppender, "_append_blob", appender__append_blob, 1);
398
+ rb_define_private_method(cDuckDBAppender, "_append_null", appender__append_null, 0);
399
+ rb_define_private_method(cDuckDBAppender, "_append_default", appender__append_default, 0);
446
400
  rb_define_private_method(cDuckDBAppender, "_append_date", appender__append_date, 3);
447
401
  rb_define_private_method(cDuckDBAppender, "_append_interval", appender__append_interval, 3);
448
402
  rb_define_private_method(cDuckDBAppender, "_append_time", appender__append_time, 4);
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'mkmf'
4
4
 
5
- DUCKDB_REQUIRED_VERSION = '1.0.0'
5
+ DUCKDB_REQUIRED_VERSION = '1.1.0'
6
6
 
7
7
  def check_duckdb_header(header, version)
8
8
  found = find_header(
@@ -56,14 +56,14 @@ end
56
56
  dir_config('duckdb')
57
57
 
58
58
  check_duckdb_header('duckdb.h', DUCKDB_REQUIRED_VERSION)
59
- check_duckdb_library('duckdb', 'duckdb_appender_column_count', DUCKDB_REQUIRED_VERSION)
60
-
61
- # check duckdb >= 1.0.0
62
- have_func('duckdb_fetch_chunk', 'duckdb.h')
59
+ check_duckdb_library('duckdb', 'duckdb_result_error_type', DUCKDB_REQUIRED_VERSION)
63
60
 
64
61
  # check duckdb >= 1.1.0
65
62
  have_func('duckdb_result_error_type', 'duckdb.h')
66
63
 
64
+ # check duckdb >= 1.2.0
65
+ have_func('duckdb_create_instance_cache', 'duckdb.h')
66
+
67
67
  # Building with enabled DUCKDB_API_NO_DEPRECATED is failed with DuckDB v1.1.0 only.
68
68
  # DuckDB v1.1.1 is fixed this issue https://github.com/duckdb/duckdb/issues/13872.
69
69
  have_const('DUCKDB_TYPE_SQLNULL', 'duckdb.h')
@@ -8,10 +8,16 @@ static size_t memsize(const void *p);
8
8
  static VALUE duckdb_logical_type__type(VALUE self);
9
9
  static VALUE duckdb_logical_type_width(VALUE self);
10
10
  static VALUE duckdb_logical_type_scale(VALUE self);
11
+ static VALUE duckdb_logical_type_child_count(VALUE self);
12
+ static VALUE duckdb_logical_type_child_name_at(VALUE self, VALUE cidx);
11
13
  static VALUE duckdb_logical_type_child_type(VALUE self);
14
+ static VALUE duckdb_logical_type_child_type_at(VALUE self, VALUE cidx);
12
15
  static VALUE duckdb_logical_type_size(VALUE self);
13
16
  static VALUE duckdb_logical_type_key_type(VALUE self);
14
17
  static VALUE duckdb_logical_type_value_type(VALUE self);
18
+ static VALUE duckdb_logical_type_member_count(VALUE self);
19
+ static VALUE duckdb_logical_type_member_name_at(VALUE self, VALUE midx);
20
+ static VALUE duckdb_logical_type_member_type_at(VALUE self, VALUE midx);
15
21
 
16
22
  static const rb_data_type_t logical_type_data_type = {
17
23
  "DuckDB/LogicalType",
@@ -77,6 +83,43 @@ static VALUE duckdb_logical_type_scale(VALUE self) {
77
83
  return INT2FIX(duckdb_decimal_scale(ctx->logical_type));
78
84
  }
79
85
 
86
+ /*
87
+ * call-seq:
88
+ * struct_col.logical_type.child_count -> Integer
89
+ *
90
+ * Returns the number of children of a struct type, otherwise 0.
91
+ *
92
+ */
93
+ static VALUE duckdb_logical_type_child_count(VALUE self) {
94
+ rubyDuckDBLogicalType *ctx;
95
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
96
+ return INT2FIX(duckdb_struct_type_child_count(ctx->logical_type));
97
+ }
98
+
99
+ /*
100
+ * call-seq:
101
+ * struct_col.logical_type.child_name(index) -> String
102
+ *
103
+ * Returns the name of the struct child at the specified index.
104
+ *
105
+ */
106
+ static VALUE duckdb_logical_type_child_name_at(VALUE self, VALUE cidx) {
107
+ rubyDuckDBLogicalType *ctx;
108
+ VALUE cname;
109
+ const char *child_name;
110
+ idx_t idx = NUM2ULL(cidx);
111
+
112
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
113
+
114
+ child_name = duckdb_struct_type_child_name(ctx->logical_type, idx);
115
+ if (child_name == NULL) {
116
+ rb_raise(eDuckDBError, "fail to get name of %llu child", (unsigned long long)idx);
117
+ }
118
+ cname = rb_str_new_cstr(child_name);
119
+ duckdb_free((void *)child_name);
120
+ return cname;
121
+ }
122
+
80
123
  /*
81
124
  * call-seq:
82
125
  * list_col.logical_type.child_type -> DuckDB::LogicalType
@@ -109,6 +152,31 @@ static VALUE duckdb_logical_type_child_type(VALUE self) {
109
152
  return logical_type;
110
153
  }
111
154
 
155
+ /*
156
+ * call-seq:
157
+ * struct_col.logical_type.child_type_at(index) -> DuckDB::LogicalType
158
+ *
159
+ * Returns the child logical type for struct types at the specified index as a
160
+ * DuckDB::LogicalType object.
161
+ *
162
+ */
163
+ static VALUE duckdb_logical_type_child_type_at(VALUE self, VALUE cidx) {
164
+ rubyDuckDBLogicalType *ctx;
165
+ duckdb_logical_type struct_child_type;
166
+ idx_t idx = NUM2ULL(cidx);
167
+
168
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
169
+
170
+ struct_child_type = duckdb_struct_type_child_type(ctx->logical_type, idx);
171
+ if (struct_child_type == NULL) {
172
+ rb_raise(eDuckDBError,
173
+ "Failed to get the struct child type at index %llu",
174
+ (unsigned long long)idx);
175
+ }
176
+
177
+ return rbduckdb_create_logical_type(struct_child_type);
178
+ }
179
+
112
180
  /*
113
181
  * call-seq:
114
182
  * list_col.logical_type.size -> Integer
@@ -158,6 +226,68 @@ static VALUE duckdb_logical_type_value_type(VALUE self) {
158
226
  return logical_type;
159
227
  }
160
228
 
229
+ /*
230
+ * call-seq:
231
+ * member_col.logical_type.member_count -> Integer
232
+ *
233
+ * Returns the member count of union type, otherwise 0.
234
+ *
235
+ */
236
+ static VALUE duckdb_logical_type_member_count(VALUE self) {
237
+ rubyDuckDBLogicalType *ctx;
238
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
239
+ return INT2FIX(duckdb_union_type_member_count(ctx->logical_type));
240
+ }
241
+
242
+ /*
243
+ * call-seq:
244
+ * union_col.logical_type.member_name_at(index) -> String
245
+ *
246
+ * Returns the name of the union member at the specified index.
247
+ *
248
+ */
249
+ static VALUE duckdb_logical_type_member_name_at(VALUE self, VALUE midx) {
250
+ rubyDuckDBLogicalType *ctx;
251
+ VALUE mname;
252
+ const char *member_name;
253
+ idx_t idx = NUM2ULL(midx);
254
+
255
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
256
+
257
+ member_name = duckdb_union_type_member_name(ctx->logical_type, idx);
258
+ if (member_name == NULL) {
259
+ rb_raise(eDuckDBError, "fail to get name of %llu member", (unsigned long long)idx);
260
+ }
261
+ mname = rb_str_new_cstr(member_name);
262
+ duckdb_free((void *)member_name);
263
+ return mname;
264
+ }
265
+
266
+ /*
267
+ * call-seq:
268
+ * union_col.logical_type.member_type_at(index) -> DuckDB::LogicalType
269
+ *
270
+ * Returns the logical type of the union member at the specified index as a
271
+ * DuckDB::LogicalType object.
272
+ *
273
+ */
274
+ static VALUE duckdb_logical_type_member_type_at(VALUE self, VALUE midx) {
275
+ rubyDuckDBLogicalType *ctx;
276
+ duckdb_logical_type union_member_type;
277
+ idx_t idx = NUM2ULL(midx);
278
+
279
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
280
+
281
+ union_member_type = duckdb_union_type_member_type(ctx->logical_type, idx);
282
+ if (union_member_type == NULL) {
283
+ rb_raise(eDuckDBError,
284
+ "Failed to get the union member type at index %llu",
285
+ (unsigned long long)idx);
286
+ }
287
+
288
+ return rbduckdb_create_logical_type(union_member_type);
289
+ }
290
+
161
291
  VALUE rbduckdb_create_logical_type(duckdb_logical_type logical_type) {
162
292
  VALUE obj;
163
293
  rubyDuckDBLogicalType *ctx;
@@ -180,8 +310,14 @@ void rbduckdb_init_duckdb_logical_type(void) {
180
310
  rb_define_private_method(cDuckDBLogicalType, "_type", duckdb_logical_type__type, 0);
181
311
  rb_define_method(cDuckDBLogicalType, "width", duckdb_logical_type_width, 0);
182
312
  rb_define_method(cDuckDBLogicalType, "scale", duckdb_logical_type_scale, 0);
313
+ rb_define_method(cDuckDBLogicalType, "child_count", duckdb_logical_type_child_count, 0);
314
+ rb_define_method(cDuckDBLogicalType, "child_name_at", duckdb_logical_type_child_name_at, 1);
183
315
  rb_define_method(cDuckDBLogicalType, "child_type", duckdb_logical_type_child_type, 0);
316
+ rb_define_method(cDuckDBLogicalType, "child_type_at", duckdb_logical_type_child_type_at, 1);
184
317
  rb_define_method(cDuckDBLogicalType, "size", duckdb_logical_type_size, 0);
185
318
  rb_define_method(cDuckDBLogicalType, "key_type", duckdb_logical_type_key_type, 0);
186
319
  rb_define_method(cDuckDBLogicalType, "value_type", duckdb_logical_type_value_type, 0);
320
+ rb_define_method(cDuckDBLogicalType, "member_count", duckdb_logical_type_member_count, 0);
321
+ rb_define_method(cDuckDBLogicalType, "member_name_at", duckdb_logical_type_member_name_at, 1);
322
+ rb_define_method(cDuckDBLogicalType, "member_type_at", duckdb_logical_type_member_type_at, 1);
187
323
  }
@@ -32,6 +32,7 @@ static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE
32
32
  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);
33
33
  static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VALUE months, VALUE days, VALUE micros);
34
34
  static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper);
35
+ static VALUE duckdb_prepared_statement__bind_uhugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper);
35
36
  static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale);
36
37
 
37
38
  static const rb_data_type_t prepared_statement_data_type = {
@@ -121,6 +122,7 @@ static VALUE duckdb_prepared_statement_execute(VALUE self) {
121
122
  rubyDuckDBResult *ctxr;
122
123
  const char *error;
123
124
  VALUE result = rbduckdb_create_result();
125
+ VALUE msg;
124
126
 
125
127
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
126
128
  ctxr = get_struct_result(result);
@@ -135,12 +137,13 @@ static VALUE duckdb_prepared_statement_execute(VALUE self) {
135
137
  duckdb_state state = args.retval;
136
138
 
137
139
  if (state == DuckDBError) {
138
- error = duckdb_result_error(args.out_result);
140
+ error = duckdb_prepare_error(args.prepared_statement);
139
141
  if (error == NULL) {
140
- error = duckdb_prepare_error(args.prepared_statement);
142
+ error = duckdb_result_error(args.out_result);
141
143
  }
144
+ msg = rb_str_new2(error ? error : "Failed to execute prepared statement.");
142
145
 
143
- rb_raise(eDuckDBError, "%s", error ? error : "Failed to execute prepared statement.");
146
+ rb_raise(eDuckDBError, "%s", StringValuePtr(msg));
144
147
  }
145
148
 
146
149
  return result;
@@ -439,6 +442,23 @@ static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VAL
439
442
  return self;
440
443
  }
441
444
 
445
+ /* :nodoc: */
446
+ static VALUE duckdb_prepared_statement__bind_uhugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper) {
447
+ duckdb_uhugeint uhugeint;
448
+ rubyDuckDBPreparedStatement *ctx;
449
+ idx_t idx = check_index(vidx);
450
+
451
+ TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
452
+ uhugeint.lower = NUM2ULL(lower);
453
+ uhugeint.upper = NUM2ULL(upper);
454
+
455
+ if (duckdb_bind_uhugeint(ctx->prepared_statement, idx, uhugeint) == DuckDBError) {
456
+ rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx);
457
+ }
458
+
459
+ return self;
460
+ }
461
+
442
462
  /* :nodoc: */
443
463
  static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale) {
444
464
  duckdb_hugeint hugeint;
@@ -498,5 +518,6 @@ void rbduckdb_init_duckdb_prepared_statement(void) {
498
518
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_timestamp", duckdb_prepared_statement__bind_timestamp, 8);
499
519
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_interval", duckdb_prepared_statement__bind_interval, 4);
500
520
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_hugeint", duckdb_prepared_statement__bind_hugeint, 3);
521
+ rb_define_private_method(cDuckDBPreparedStatement, "_bind_uhugeint", duckdb_prepared_statement__bind_uhugeint, 3);
501
522
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_decimal", duckdb_prepared_statement__bind_decimal, 5);
502
523
  }
data/ext/duckdb/result.c CHANGED
@@ -279,7 +279,7 @@ static VALUE duckdb_result__return_type(VALUE oDuckDBResult) {
279
279
  /*
280
280
  * remove this #if ... #else statement when dropping duckdb 1.1.0.
281
281
  */
282
- #if !defined(HAVE_DUCKDB_H_GE_V1_1_1) && defined(HAVE_DUCKDB_H_GE_V1_1_0) && defined(DUCKDB_API_NO_DEPRECATED)
282
+ #if !defined(HAVE_DUCKDB_H_GE_V1_1_1) && defined(DUCKDB_API_NO_DEPRECATED)
283
283
  rb_raise(eDuckDBError, "duckdb_result_return_type C-API is not available with duckdb v1.1.0 with enabled DUCKDB_API_NO_DEPRECATED.");
284
284
  #else
285
285
  return INT2FIX(duckdb_result_return_type(ctx->result));
@@ -8,18 +8,14 @@
8
8
  #include "ruby/thread.h"
9
9
  #include <duckdb.h>
10
10
 
11
- #ifdef HAVE_DUCKDB_FETCH_CHUNK
12
- #define HAVE_DUCKDB_H_GE_V1_0_0 1
13
- #endif
14
-
15
- #ifdef HAVE_DUCKDB_RESULT_ERROR_TYPE
16
- #define HAVE_DUCKDB_H_GE_V1_1_0 1
17
- #endif
18
-
19
11
  #ifdef HAVE_CONST_DUCKDB_TYPE_SQLNULL
20
12
  #define HAVE_DUCKDB_H_GE_V1_1_1 1
21
13
  #endif
22
14
 
15
+ #ifdef HAVE_DUCKDB_CREATE_INSTANCE_CACHE
16
+ #define HAVE_DUCKDB_H_GE_V1_2_0 1
17
+ #endif
18
+
23
19
  #include "./error.h"
24
20
  #include "./database.h"
25
21
  #include "./connection.h"
@@ -203,27 +203,235 @@ module DuckDB
203
203
  end
204
204
 
205
205
  # call-seq:
206
- # appender.append_uint8(val) -> self
206
+ # appender.append_uint8(val) -> self
207
207
  #
208
208
  # Appends an uint8 value to the current row in the appender.
209
209
  #
210
- # require 'duckdb'
211
- # db = DuckDB::Database.open
212
- # con = db.connect
213
- # con.query('CREATE TABLE users (id INTEGER, age UTINYINT)')
214
- # appender = con.appender('users')
215
- # appender
216
- # .append_int32(1)
217
- # .append_uint8(20)
218
- # .end_row
219
- # .flush
210
+ # require 'duckdb'
211
+ # db = DuckDB::Database.open
212
+ # con = db.connect
213
+ # con.query('CREATE TABLE users (id INTEGER, age UTINYINT)')
214
+ # appender = con.appender('users')
215
+ # appender
216
+ # .append_int32(1)
217
+ # .append_uint8(20)
218
+ # .end_row
219
+ # .flush
220
220
  def append_uint8(value)
221
221
  return self if _append_uint8(value)
222
222
 
223
223
  raise_appender_error('failed to append_uint8')
224
224
  end
225
225
 
226
- # appends huge int value.
226
+ # call-seq:
227
+ # appender.append_uint16(val) -> self
228
+ #
229
+ # Appends an uint16 value to the current row in the appender.
230
+ #
231
+ # require 'duckdb'
232
+ # db = DuckDB::Database.open
233
+ # con = db.connect
234
+ # con.query('CREATE TABLE users (id INTEGER, age USMALLINT)')
235
+ # appender = con.appender('users')
236
+ # appender
237
+ # .append_int32(1)
238
+ # .append_uint16(20)
239
+ # .end_row
240
+ # .flush
241
+ def append_uint16(value)
242
+ return self if _append_uint16(value)
243
+
244
+ raise_appender_error('failed to append_uint16')
245
+ end
246
+
247
+ # call-seq:
248
+ # appender.append_uint32(val) -> self
249
+ #
250
+ # Appends an uint32 value to the current row in the appender.
251
+ #
252
+ # require 'duckdb'
253
+ # db = DuckDB::Database.open
254
+ # con = db.connect
255
+ # con.query('CREATE TABLE users (id INTEGER, age UINTEGER)')
256
+ # appender = con.appender('users')
257
+ # appender
258
+ # .append_int32(1)
259
+ # .append_uint32(20)
260
+ # .end_row
261
+ # .flush
262
+ def append_uint32(value)
263
+ return self if _append_uint32(value)
264
+
265
+ raise_appender_error('failed to append_uint32')
266
+ end
267
+
268
+ # call-seq:
269
+ # appender.append_uint64(val) -> self
270
+ #
271
+ # Appends an uint64 value to the current row in the appender.
272
+ #
273
+ # require 'duckdb'
274
+ # db = DuckDB::Database.open
275
+ # con = db.connect
276
+ # con.query('CREATE TABLE users (id INTEGER, age UBIGINT)')
277
+ # appender = con.appender('users')
278
+ # Appender
279
+ # .append_int32(1)
280
+ # .append_uint64(20)
281
+ # .end_row
282
+ # .flush
283
+ def append_uint64(value)
284
+ return self if _append_uint64(value)
285
+
286
+ raise_appender_error('failed to append_uint64')
287
+ end
288
+
289
+ # call-seq:
290
+ # appender.append_float(val) -> self
291
+ #
292
+ # Appends a float value to the current row in the appender.
293
+ #
294
+ # require 'duckdb'
295
+ # db = DuckDB::Database.open
296
+ # con = db.connect
297
+ # con.query('CREATE TABLE numbers (num FLOAT)')
298
+ # appender = con.appender('numbers')
299
+ # appender
300
+ # .append_float(1.23)
301
+ # .end_row
302
+ # .flush
303
+ def append_float(value)
304
+ return self if _append_float(value)
305
+
306
+ raise_appender_error('failed to append_float')
307
+ end
308
+
309
+ # call-seq:
310
+ # appender.append_double(val) -> self
311
+ #
312
+ # Appends a double value to the current row in the appender.
313
+ #
314
+ # require 'duckdb'
315
+ # db = DuckDB::Database.open
316
+ # con = db.connect
317
+ # con.query('CREATE TABLE numbers (num DOUBLE)')
318
+ # appender = con.appender('numbers')
319
+ # appender
320
+ # .append_double(1.23)
321
+ # .end_row
322
+ # .flush
323
+ def append_double(value)
324
+ return self if _append_double(value)
325
+
326
+ raise_appender_error('failed to append_double')
327
+ end
328
+
329
+ # call-seq:
330
+ # appender.append_varchar(val) -> self
331
+ #
332
+ # Appends a varchar value to the current row in the appender.
333
+ #
334
+ # require 'duckdb'
335
+ # db = DuckDB::Database.open
336
+ # con = db.connect
337
+ # con.query('CREATE TABLE names (name VARCHAR)')
338
+ # appender = con.appender('names')
339
+ # appender
340
+ # .append_varchar('Alice')
341
+ # .end_row
342
+ # .flush
343
+ def append_varchar(value)
344
+ return self if _append_varchar(value)
345
+
346
+ raise_appender_error('failed to append_varchar')
347
+ end
348
+
349
+ # call-seq:
350
+ # appender.append_varchar_length(val, len) -> self
351
+ #
352
+ # Appends a varchar value to the current row in the appender.
353
+ #
354
+ # require 'duckdb'
355
+ # db = DuckDB::Database.open
356
+ # con = db.connect
357
+ # con.query('CREATE TABLE names (name VARCHAR)')
358
+ # appender = con.appender('names')
359
+ # appender
360
+ # .append_varchar_length('Alice', 5)
361
+ # .end_row
362
+ # .flush
363
+ def append_varchar_length(value, length)
364
+ return self if _append_varchar_length(value, length)
365
+
366
+ raise_appender_error('failed to append_varchar_length')
367
+ end
368
+
369
+ # call-seq:
370
+ # appender.append_blob(val) -> self
371
+ #
372
+ # Appends a varchar value to the current row in the appender.
373
+ #
374
+ # require 'duckdb'
375
+ # db = DuckDB::Database.open
376
+ # con = db.connect
377
+ # con.query('CREATE TABLE values (value BLOB)')
378
+ # appender = con.appender('values')
379
+ # appender
380
+ # .append('\0\1\2\3\4\5'.encode(Encoding::BINARY))
381
+ # .end_row
382
+ # .flush
383
+ def append_blob(value)
384
+ return self if _append_blob(value)
385
+
386
+ raise_appender_error('failed to append_blob')
387
+ end
388
+
389
+ # call-seq:
390
+ # appender.append_null -> self
391
+ #
392
+ # Appends a NULL value to the current row in the appender.
393
+ #
394
+ # require 'duckdb'
395
+ # db = DuckDB::Database.open
396
+ # con = db.connect
397
+ # con.query('CREATE TABLE values (value INTEGER)')
398
+ # appender = con.appender('values')
399
+ # appender
400
+ # .append_null
401
+ # .end_row
402
+ # .flush
403
+ def append_null
404
+ return self if _append_null
405
+
406
+ raise_appender_error('failed to append_null')
407
+ end
408
+
409
+ # call-seq:
410
+ # appender.append_default -> self
411
+ #
412
+ # Appends a default value to the current row in the appender.
413
+ # If the column does not have a default value, this method
414
+ # appends a NULL value.
415
+ #
416
+ # require 'duckdb'
417
+ # db = DuckDB::Database.open
418
+ # con = db.connect
419
+ # con.query('CREATE TABLE values (value INTEGER DEFAULT 1)')
420
+ # appender = con.appender('values')
421
+ # appender
422
+ # .append_default
423
+ # .end_row
424
+ # .flush
425
+ def append_default
426
+ return self if _append_default
427
+
428
+ raise_appender_error('failed to append_default')
429
+ end
430
+
431
+ # call-seq:
432
+ # appender.append_hugeint(val) -> self
433
+ #
434
+ # Appends a huge int value to the current row in the appender.
227
435
  #
228
436
  # require 'duckdb'
229
437
  # db = DuckDB::Database.open
@@ -233,12 +441,19 @@ module DuckDB
233
441
  # appender
234
442
  # .append_hugeint(-170_141_183_460_469_231_731_687_303_715_884_105_727)
235
443
  # .end_row
444
+ # .flush
236
445
  def append_hugeint(value)
237
446
  lower, upper = integer_to_hugeint(value)
238
- _append_hugeint(lower, upper)
447
+
448
+ return self if _append_hugeint(lower, upper)
449
+
450
+ raise_appender_error('failed to append_hugeint')
239
451
  end
240
452
 
241
- # appends unsigned huge int value.
453
+ # call-seq:
454
+ # appender.append_uhugeint(val) -> self
455
+ #
456
+ # Appends an unsigned huge int value to the current row in the appender.
242
457
  #
243
458
  # require 'duckdb'
244
459
  # db = DuckDB::Database.open
@@ -248,12 +463,19 @@ module DuckDB
248
463
  # appender
249
464
  # .append_hugeint(340_282_366_920_938_463_463_374_607_431_768_211_455)
250
465
  # .end_row
466
+ # .flush
251
467
  def append_uhugeint(value)
252
468
  lower, upper = integer_to_hugeint(value)
253
- _append_uhugeint(lower, upper)
469
+
470
+ return self if _append_uhugeint(lower, upper)
471
+
472
+ raise_appender_error('failed to append_uhugeint')
254
473
  end
255
474
 
256
- # appends date value.
475
+ # call-seq:
476
+ # appender.append_date(val) -> self
477
+ #
478
+ # Appends a date value to the current row in the appender.
257
479
  #
258
480
  # require 'duckdb'
259
481
  # db = DuckDB::Database.open
@@ -269,10 +491,15 @@ module DuckDB
269
491
  def append_date(value)
270
492
  date = _parse_date(value)
271
493
 
272
- _append_date(date.year, date.month, date.day)
494
+ return self if _append_date(date.year, date.month, date.day)
495
+
496
+ raise_appender_error('failed to append_date')
273
497
  end
274
498
 
275
- # appends time value.
499
+ # call-seq:
500
+ # appender.append_time(val) -> self
501
+ #
502
+ # Appends a time value to the current row in the appender.
276
503
  #
277
504
  # require 'duckdb'
278
505
  # db = DuckDB::Database.open
@@ -287,10 +514,15 @@ module DuckDB
287
514
  def append_time(value)
288
515
  time = _parse_time(value)
289
516
 
290
- _append_time(time.hour, time.min, time.sec, time.usec)
517
+ return self if _append_time(time.hour, time.min, time.sec, time.usec)
518
+
519
+ raise_appender_error('failed to append_time')
291
520
  end
292
521
 
293
- # appends timestamp value.
522
+ # call-seq:
523
+ # appender.append_timestamp(val) -> self
524
+ #
525
+ # Appends a timestamp value to the current row in the appender.
294
526
  #
295
527
  # require 'duckdb'
296
528
  # db = DuckDB::Database.open
@@ -306,12 +538,16 @@ module DuckDB
306
538
  def append_timestamp(value)
307
539
  time = to_time(value)
308
540
 
309
- _append_timestamp(time.year, time.month, time.day, time.hour, time.min, time.sec, time.nsec / 1000)
541
+ return self if _append_timestamp(time.year, time.month, time.day, time.hour, time.min, time.sec, time.nsec / 1000)
542
+
543
+ raise_appender_error('failed to append_timestamp')
310
544
  end
311
545
 
312
- # appends interval.
546
+ # call-seq:
547
+ # appender.append_interval(val) -> self
548
+ #
549
+ # Appends an interval value to the current row in the appender.
313
550
  # The argument must be ISO8601 duration format.
314
- # WARNING: This method is expremental.
315
551
  #
316
552
  # require 'duckdb'
317
553
  # db = DuckDB::Database.open
@@ -324,7 +560,10 @@ module DuckDB
324
560
  # .flush
325
561
  def append_interval(value)
326
562
  value = Interval.to_interval(value)
327
- _append_interval(value.interval_months, value.interval_days, value.interval_micros)
563
+
564
+ return self if _append_interval(value.interval_months, value.interval_days, value.interval_micros)
565
+
566
+ raise_appender_error('failed to append_interval')
328
567
  end
329
568
 
330
569
  # appends value.
@@ -18,5 +18,93 @@ module DuckDB
18
18
  type_id = _type
19
19
  DuckDB::Converter::IntToSym.type_to_sym(type_id)
20
20
  end
21
+
22
+ # Iterates over each union member name.
23
+ #
24
+ # When a block is provided, this method yields each union member name in
25
+ # order. It also returns the total number of members yielded.
26
+ #
27
+ # union_logical_type.each_member_name do |name|
28
+ # puts "Union member: #{name}"
29
+ # end
30
+ #
31
+ # If no block is given, an Enumerator is returned, which can be used to
32
+ # retrieve all member names.
33
+ #
34
+ # names = union_logical_type.each_member_name.to_a
35
+ # # => ["member1", "member2"]
36
+ def each_member_name
37
+ return to_enum(__method__) {member_count} unless block_given?
38
+
39
+ member_count.times do |i|
40
+ yield member_name_at(i)
41
+ end
42
+ end
43
+
44
+ # Iterates over each union member type.
45
+ #
46
+ # When a block is provided, this method yields each union member logical
47
+ # type in order. It also returns the total number of members yielded.
48
+ #
49
+ # union_logical_type.each_member_type do |logical_type|
50
+ # puts "Union member: #{logical_type.type}"
51
+ # end
52
+ #
53
+ # If no block is given, an Enumerator is returned, which can be used to
54
+ # retrieve all member logical types.
55
+ #
56
+ # names = union_logical_type.each_member_type.map(&:type)
57
+ # # => [:varchar, :integer]
58
+ def each_member_type
59
+ return to_enum(__method__) {member_count} unless block_given?
60
+
61
+ member_count.times do |i|
62
+ yield member_type_at(i)
63
+ end
64
+ end
65
+
66
+ # Iterates over each struct child name.
67
+ #
68
+ # When a block is provided, this method yields each struct child name in
69
+ # order. It also returns the total number of children yielded.
70
+ #
71
+ # struct_logical_type.each_child_name do |name|
72
+ # puts "Struct child: #{name}"
73
+ # end
74
+ #
75
+ # If no block is given, an Enumerator is returned, which can be used to
76
+ # retrieve all child names.
77
+ #
78
+ # names = struct_logical_type.each_child_name.to_a
79
+ # # => ["child1", "child2"]
80
+ def each_child_name
81
+ return to_enum(__method__) {child_count} unless block_given?
82
+
83
+ child_count.times do |i|
84
+ yield child_name_at(i)
85
+ end
86
+ end
87
+
88
+ # Iterates over each struct child type.
89
+ #
90
+ # When a block is provided, this method yields each struct child type in
91
+ # order. It also returns the total number of children yielded.
92
+ #
93
+ # struct_logical_type.each_child_type do |logical_type|
94
+ # puts "Struct child type: #{logical_type.type}"
95
+ # end
96
+ #
97
+ # If no block is given, an Enumerator is returned, which can be used to
98
+ # retrieve all child logical types.
99
+ #
100
+ # types = struct_logical_type.each_child_type.map(&:type)
101
+ # # => [:integer, :varchar]
102
+ def each_child_type
103
+ return to_enum(__method__) {child_count} unless block_given?
104
+
105
+ child_count.times do |i|
106
+ yield child_type_at(i)
107
+ end
108
+ end
21
109
  end
22
110
  end
@@ -135,7 +135,7 @@ module DuckDB
135
135
  # require 'duckdb'
136
136
  # db = DuckDB::Database.open('duckdb_database')
137
137
  # con = db.connect
138
- # sql ='SELECT name FROM users WHERE bigint_col = ?'
138
+ # sql ='SELECT name FROM users WHERE hugeint_col = ?'
139
139
  # stmt = PreparedStatement.new(con, sql)
140
140
  # stmt.bind_hugeint_internal(1, 1_234_567_890_123_456_789_012_345)
141
141
  def bind_hugeint_internal(index, value)
@@ -143,6 +143,23 @@ module DuckDB
143
143
  _bind_hugeint(index, lower, upper)
144
144
  end
145
145
 
146
+ # binds i-th parameter with SQL prepared statement.
147
+ # The first argument is index of parameter.
148
+ # The index of first parameter is 1 not 0.
149
+ # The second argument value must be Integer value.
150
+ # This method uses duckdb_bind_uhugeint internally.
151
+ #
152
+ # require 'duckdb'
153
+ # db = DuckDB::Database.open('duckdb_database')
154
+ # con = db.connect
155
+ # sql ='SELECT name FROM users WHERE uhugeint_col = ?'
156
+ # stmt = PreparedStatement.new(con, sql)
157
+ # stmt.bind_uhugeint(1, (2**128) - 1)
158
+ def bind_uhugeint(index, value)
159
+ lower, upper = integer_to_hugeint(value)
160
+ _bind_uhugeint(index, lower, upper)
161
+ end
162
+
146
163
  # binds i-th parameter with SQL prepared statement.
147
164
  # The first argument is index of parameter.
148
165
  # The index of first parameter is 1 not 0.
@@ -3,5 +3,5 @@
3
3
  module DuckDB
4
4
  # The version string of ruby-duckdb.
5
5
  # Currently, ruby-duckdb is NOT semantic versioning.
6
- VERSION = '1.2.0.0'
6
+ VERSION = '1.2.1.0'
7
7
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duckdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0.0
4
+ version: 1.2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaki Suketa
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-02-23 00:00:00.000000000 Z
10
+ date: 2025-03-29 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bigdecimal