duckdb 1.1.3.1 → 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.
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 duckdb_result_chunk_each(VALUE oDuckDBResult);
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
- * call-seq:
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
- static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult) {
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
- rb_define_method(cDuckDBResult, "chunk_each", duckdb_result_chunk_each, 0);
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);
@@ -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"
@@ -13,15 +13,216 @@ module DuckDB
13
13
  # con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
14
14
  # appender = con.appender('users')
15
15
  # appender.append_row(1, 'Alice')
16
- #
17
16
  class Appender
18
17
  include DuckDB::Converter
19
18
 
19
+ # :stopdoc:
20
20
  RANGE_INT16 = -32_768..32_767
21
21
  RANGE_INT32 = -2_147_483_648..2_147_483_647
22
22
  RANGE_INT64 = -9_223_372_036_854_775_808..9_223_372_036_854_775_807
23
+ private_constant :RANGE_INT16, :RANGE_INT32, :RANGE_INT64
24
+ # :startdoc:
25
+
26
+ # :call-seq:
27
+ # appender.begin_row -> self
28
+ # A nop method, provided for backwards compatibility reasons.
29
+ # Does nothing. Only `end_row` is required.
30
+ def begin_row
31
+ self
32
+ end
33
+
34
+ # call-seq:
35
+ # appender.end_row -> self
36
+ #
37
+ # Finish the current row of appends. After end_row is called, the next row can be appended.
38
+ # require 'duckdb'
39
+ # db = DuckDB::Database.open
40
+ # con = db.connect
41
+ # con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
42
+ # appender = con.appender('users')
43
+ # appender
44
+ # .append_int32(1)
45
+ # .append_varchar('Alice')
46
+ # .end_row
47
+ def end_row
48
+ return self if _end_row
49
+
50
+ raise_appender_error('failed to end_row')
51
+ end
52
+
53
+ # :call-seq:
54
+ # appender.flush -> self
55
+ #
56
+ # Flushes the appender to the table, forcing the cache of the appender to be cleared.
57
+ # If flushing the data triggers a constraint violation or any other error, then all
58
+ # data is invalidated, and this method raises DuckDB::Error.
59
+ #
60
+ # require 'duckdb'
61
+ # db = DuckDB::Database.open
62
+ # con = db.connect
63
+ # con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
64
+ # appender = con.appender('users')
65
+ # appender
66
+ # .append_int32(1)
67
+ # .append_varchar('Alice')
68
+ # .end_row
69
+ # .flush
70
+ def flush
71
+ return self if _flush
72
+
73
+ raise_appender_error('failed to flush')
74
+ end
75
+
76
+ # :call-seq:
77
+ # appender.close -> self
78
+ #
79
+ # Closes the appender by flushing all intermediate states and closing it for further appends.
80
+ # If flushing the data triggers a constraint violation or any other error, then all data is
81
+ # invalidated, and this method raises DuckDB::Error.
82
+ #
83
+ # require 'duckdb'
84
+ # db = DuckDB::Database.open
85
+ # con = db.connect
86
+ # con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
87
+ # appender = con.appender('users')
88
+ # appender
89
+ # .append_int32(1)
90
+ # .append_varchar('Alice')
91
+ # .end_row
92
+ # .close
93
+ def close
94
+ return self if _close
95
+
96
+ raise_appender_error('failed to close')
97
+ end
98
+
99
+ # call-seq:
100
+ # appender.append_bool(val) -> self
101
+ #
102
+ # Appends a boolean value to the current row in the appender.
103
+ #
104
+ # require 'duckdb'
105
+ # db = DuckDB::Database.open
106
+ # con = db.connect
107
+ # con.query('CREATE TABLE users (id INTEGER, active BOOLEAN)')
108
+ # appender = con.appender('users')
109
+ # appender
110
+ # .append_int32(1)
111
+ # .append_bool(true)
112
+ # .end_row
113
+ # .flush
114
+ def append_bool(value)
115
+ return self if _append_bool(value)
116
+
117
+ raise_appender_error('failed to append_bool')
118
+ end
119
+
120
+ # call-seq:
121
+ # appender.append_int8(val) -> self
122
+ #
123
+ # Appends an int8(TINYINT) value to the current row in the appender.
124
+ #
125
+ # require 'duckdb'
126
+ # db = DuckDB::Database.open
127
+ # con = db.connect
128
+ # con.query('CREATE TABLE users (id INTEGER, age TINYINT)')
129
+ # appender = con.appender('users')
130
+ # appender
131
+ # .append_int32(1)
132
+ # .append_int8(20)
133
+ # .end_row
134
+ # .flush
135
+ #
136
+ def append_int8(value)
137
+ return self if _append_int8(value)
138
+
139
+ raise_appender_error('failed to append_int8')
140
+ end
23
141
 
142
+ # call-seq:
143
+ # appender.append_int16(val) -> self
24
144
  #
145
+ # Appends an int16(SMALLINT) value to the current row in the appender.
146
+ #
147
+ # require 'duckdb'
148
+ # db = DuckDB::Database.open
149
+ # con = db.connect
150
+ # con.query('CREATE TABLE users (id INTEGER, age SMALLINT)')
151
+ # appender = con.appender('users')
152
+ # appender
153
+ # .append_int32(1)
154
+ # .append_int16(20)
155
+ # .end_row
156
+ # .flush
157
+ def append_int16(value)
158
+ return self if _append_int16(value)
159
+
160
+ raise_appender_error('failed to append_int16')
161
+ end
162
+
163
+ # call-seq:
164
+ # appender.append_int32(val) -> self
165
+ #
166
+ # Appends an int32(INTEGER) value to the current row in the appender.
167
+ #
168
+ # require 'duckdb'
169
+ # db = DuckDB::Database.open
170
+ # con = db.connect
171
+ # con.query('CREATE TABLE users (id INTEGER, age INTEGER)')
172
+ # appender = con.appender('users')
173
+ # appender
174
+ # .append_int32(1)
175
+ # .append_int32(20)
176
+ # .end_row
177
+ # .flush
178
+ def append_int32(value)
179
+ return self if _append_int32(value)
180
+
181
+ raise_appender_error('failed to append_int32')
182
+ end
183
+
184
+ # call-seq:
185
+ # appender.append_int64(val) -> self
186
+ #
187
+ # Appends an int64(BIGINT) value to the current row in the appender.
188
+ #
189
+ # require 'duckdb'
190
+ # db = DuckDB::Database.open
191
+ # con = db.connect
192
+ # con.query('CREATE TABLE users (id INTEGER, age BIGINT)')
193
+ # appender = con.appender('users')
194
+ # appender
195
+ # .append_int32(1)
196
+ # .append_int64(20)
197
+ # .end_row
198
+ # .flush
199
+ def append_int64(value)
200
+ return self if _append_int64(value)
201
+
202
+ raise_appender_error('failed to append_int64')
203
+ end
204
+
205
+ # call-seq:
206
+ # appender.append_uint8(val) -> self
207
+ #
208
+ # Appends an uint8 value to the current row in the appender.
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
220
+ def append_uint8(value)
221
+ return self if _append_uint8(value)
222
+
223
+ raise_appender_error('failed to append_uint8')
224
+ end
225
+
25
226
  # appends huge int value.
26
227
  #
27
228
  # require 'duckdb'
@@ -30,16 +231,13 @@ module DuckDB
30
231
  # con.query('CREATE TABLE numbers (num HUGEINT)')
31
232
  # appender = con.appender('numbers')
32
233
  # appender
33
- # .begin_row
34
234
  # .append_hugeint(-170_141_183_460_469_231_731_687_303_715_884_105_727)
35
235
  # .end_row
36
- #
37
236
  def append_hugeint(value)
38
237
  lower, upper = integer_to_hugeint(value)
39
238
  _append_hugeint(lower, upper)
40
239
  end
41
240
 
42
- #
43
241
  # appends unsigned huge int value.
44
242
  #
45
243
  # require 'duckdb'
@@ -48,16 +246,13 @@ module DuckDB
48
246
  # con.query('CREATE TABLE numbers (num UHUGEINT)')
49
247
  # appender = con.appender('numbers')
50
248
  # appender
51
- # .begin_row
52
249
  # .append_hugeint(340_282_366_920_938_463_463_374_607_431_768_211_455)
53
250
  # .end_row
54
- #
55
251
  def append_uhugeint(value)
56
252
  lower, upper = integer_to_hugeint(value)
57
253
  _append_uhugeint(lower, upper)
58
254
  end
59
255
 
60
- #
61
256
  # appends date value.
62
257
  #
63
258
  # require 'duckdb'
@@ -65,21 +260,18 @@ module DuckDB
65
260
  # con = db.connect
66
261
  # con.query('CREATE TABLE dates (date_value DATE)')
67
262
  # appender = con.appender('dates')
68
- # appender.begin_row
69
263
  # appender.append_date(Date.today)
70
264
  # # or
71
265
  # # appender.append_date(Time.now)
72
266
  # # appender.append_date('2021-10-10')
73
267
  # appender.end_row
74
268
  # appender.flush
75
- #
76
269
  def append_date(value)
77
- date = to_date(value)
270
+ date = _parse_date(value)
78
271
 
79
272
  _append_date(date.year, date.month, date.day)
80
273
  end
81
274
 
82
- #
83
275
  # appends time value.
84
276
  #
85
277
  # require 'duckdb'
@@ -87,20 +279,17 @@ module DuckDB
87
279
  # con = db.connect
88
280
  # con.query('CREATE TABLE times (time_value TIME)')
89
281
  # appender = con.appender('times')
90
- # appender.begin_row
91
282
  # appender.append_time(Time.now)
92
283
  # # or
93
284
  # # appender.append_time('01:01:01')
94
285
  # appender.end_row
95
286
  # appender.flush
96
- #
97
287
  def append_time(value)
98
288
  time = _parse_time(value)
99
289
 
100
290
  _append_time(time.hour, time.min, time.sec, time.usec)
101
291
  end
102
292
 
103
- #
104
293
  # appends timestamp value.
105
294
  #
106
295
  # require 'duckdb'
@@ -108,21 +297,18 @@ module DuckDB
108
297
  # con = db.connect
109
298
  # con.query('CREATE TABLE timestamps (timestamp_value TIMESTAMP)')
110
299
  # appender = con.appender('timestamps')
111
- # appender.begin_row
112
300
  # appender.append_time(Time.now)
113
301
  # # or
114
302
  # # appender.append_time(Date.today)
115
303
  # # appender.append_time('2021-08-01 01:01:01')
116
304
  # appender.end_row
117
305
  # appender.flush
118
- #
119
306
  def append_timestamp(value)
120
307
  time = to_time(value)
121
308
 
122
309
  _append_timestamp(time.year, time.month, time.day, time.hour, time.min, time.sec, time.nsec / 1000)
123
310
  end
124
311
 
125
- #
126
312
  # appends interval.
127
313
  # The argument must be ISO8601 duration format.
128
314
  # WARNING: This method is expremental.
@@ -133,17 +319,14 @@ module DuckDB
133
319
  # con.query('CREATE TABLE intervals (interval_value INTERVAL)')
134
320
  # appender = con.appender('intervals')
135
321
  # appender
136
- # .begin_row
137
322
  # .append_interval('P1Y2D') # => append 1 year 2 days interval.
138
323
  # .end_row
139
324
  # .flush
140
- #
141
325
  def append_interval(value)
142
326
  value = Interval.to_interval(value)
143
327
  _append_interval(value.interval_months, value.interval_days, value.interval_micros)
144
328
  end
145
329
 
146
- #
147
330
  # appends value.
148
331
  #
149
332
  # require 'duckdb'
@@ -151,11 +334,9 @@ module DuckDB
151
334
  # con = db.connect
152
335
  # con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
153
336
  # appender = con.appender('users')
154
- # appender.begin_row
155
337
  # appender.append(1)
156
338
  # appender.append('Alice')
157
339
  # appender.end_row
158
- #
159
340
  def append(value)
160
341
  case value
161
342
  when NilClass
@@ -188,20 +369,16 @@ module DuckDB
188
369
  end
189
370
  end
190
371
 
191
- #
192
372
  # append a row.
193
373
  #
194
374
  # appender.append_row(1, 'Alice')
195
375
  #
196
376
  # is same as:
197
377
  #
198
- # appender.begin_row
199
- # appender.append(1)
378
+ # appender.append(2)
200
379
  # appender.append('Alice')
201
380
  # appender.end_row
202
- #
203
381
  def append_row(*args)
204
- begin_row
205
382
  args.each do |arg|
206
383
  append(arg)
207
384
  end
@@ -210,35 +387,21 @@ module DuckDB
210
387
 
211
388
  private
212
389
 
213
- def blob?(value)
214
- value.instance_of?(DuckDB::Blob) || value.encoding == Encoding::BINARY
390
+ def raise_appender_error(default_message) # :nodoc:
391
+ message = error_message
392
+ raise DuckDB::Error, message || default_message
215
393
  end
216
394
 
217
- def to_date(value)
218
- case value
219
- when Date, Time
220
- value
221
- else
222
- begin
223
- Date.parse(value)
224
- rescue StandardError
225
- raise(ArgumentError, "Cannot parse argument `#{value}` to Date.")
226
- end
227
- end
395
+ def blob?(value) # :nodoc:
396
+ value.instance_of?(DuckDB::Blob) || value.encoding == Encoding::BINARY
228
397
  end
229
398
 
230
- def to_time(value)
399
+ def to_time(value) # :nodoc:
231
400
  case value
232
- when Time
233
- value
234
401
  when Date
235
402
  value.to_time
236
403
  else
237
- begin
238
- Time.parse(value)
239
- rescue StandardError
240
- raise(ArgumentError, "Cannot parse argument `#{value}` to Time or Date.")
241
- end
404
+ _parse_time(value)
242
405
  end
243
406
  end
244
407
  end
data/lib/duckdb/column.rb CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  module DuckDB
4
4
  class Column
5
- #
6
5
  # returns column type symbol
7
6
  # `:unknown` means that the column type is unknown/unsupported by ruby-duckdb.
8
7
  # `:invalid` means that the column type is invalid in duckdb.
@@ -15,7 +14,6 @@ module DuckDB
15
14
  # users = con.query('SELECT * FROM users')
16
15
  # columns = users.columns
17
16
  # columns.first.type #=> :integer
18
- #
19
17
  def type
20
18
  type_id = _type
21
19
  DuckDB::Converter::IntToSym.type_to_sym(type_id)
@@ -24,11 +24,11 @@ module DuckDB
24
24
  # con.query('CREATE TABLE intervals (interval_value INTERVAL)')
25
25
  # appender = con.appender('intervals')
26
26
  # appender
27
- # .begin_row
28
27
  # .append_interval(interval)
29
28
  # .end_row
30
29
  # .flush
31
30
  class Interval
31
+ # :stopdoc:
32
32
  ISO8601_REGEXP = Regexp.compile(
33
33
  '(?<negativ>-{0,1})P
34
34
  (?<year>-{0,1}\d+Y){0,1}
@@ -40,6 +40,8 @@ module DuckDB
40
40
  ((?<sec>-{0,1}\d+)\.{0,1}(?<usec>\d*)S){0,1}',
41
41
  Regexp::EXTENDED
42
42
  )
43
+ private_constant :ISO8601_REGEXP
44
+ # :startdoc:
43
45
 
44
46
  class << self
45
47
  # parses the ISO8601 format string and return the Interval object.
@@ -93,7 +95,7 @@ module DuckDB
93
95
 
94
96
  private
95
97
 
96
- def matched_to_i(matched)
98
+ def matched_to_i(matched) # :nodoc:
97
99
  sign = to_sign(matched)
98
100
  sec = to_sec(matched)
99
101
  usec = to_usec(matched)
@@ -104,35 +106,35 @@ module DuckDB
104
106
  sign.positive? ? value : value.map { |v| v * sign }
105
107
  end
106
108
 
107
- def to_sign(matched)
109
+ def to_sign(matched) # :nodoc:
108
110
  matched[:negativ] == '-' ? -1 : 1
109
111
  end
110
112
 
111
- def to_year(matched)
113
+ def to_year(matched) # :nodoc:
112
114
  matched[:year].to_i
113
115
  end
114
116
 
115
- def to_month(matched)
117
+ def to_month(matched) # :nodoc:
116
118
  matched[:month].to_i
117
119
  end
118
120
 
119
- def to_day(matched)
121
+ def to_day(matched) # :nodoc:
120
122
  matched[:day].to_i
121
123
  end
122
124
 
123
- def to_hour(matched)
125
+ def to_hour(matched) # :nodoc:
124
126
  matched[:hour].to_i
125
127
  end
126
128
 
127
- def to_min(matched)
129
+ def to_min(matched) # :nodoc:
128
130
  matched[:min].to_i
129
131
  end
130
132
 
131
- def to_sec(matched)
133
+ def to_sec(matched) # :nodoc:
132
134
  matched[:sec].to_i
133
135
  end
134
136
 
135
- def to_usec(matched)
137
+ def to_usec(matched) # :nodoc:
136
138
  matched[:usec].to_s.ljust(6, '0')[0, 6].to_i
137
139
  end
138
140
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DuckDB
4
+ class LogicalType
5
+ # returns logical type's type symbol
6
+ # `:unknown` means that the logical type's type is unknown/unsupported by ruby-duckdb.
7
+ # `:invalid` means that the logical type's type is invalid in duckdb.
8
+ #
9
+ # require 'duckdb'
10
+ # db = DuckDB::Database.open
11
+ # con = db.connect
12
+ # con.query('CREATE TABLE climates (id INTEGER, temperature DECIMAIL)')
13
+ #
14
+ # users = con.query('SELECT * FROM climates')
15
+ # columns = users.columns
16
+ # columns.second.logical_type.type #=> :decimal
17
+ def type
18
+ type_id = _type
19
+ DuckDB::Converter::IntToSym.type_to_sym(type_id)
20
+ end
21
+ end
22
+ end