duckdb 1.1.3.1 → 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 +4 -4
- data/.github/workflows/make_documents.yml +34 -0
- data/.github/workflows/test_on_macos.yml +2 -3
- 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 +63 -0
- data/Dockerfile +2 -2
- data/Gemfile.lock +14 -12
- data/README.md +2 -1
- data/duckdb.gemspec +1 -0
- data/ext/duckdb/appender.c +140 -173
- 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 +5 -8
- data/ext/duckdb/extracted_statements.c +3 -0
- data/ext/duckdb/logical_type.c +323 -0
- data/ext/duckdb/logical_type.h +13 -0
- data/ext/duckdb/pending_result.c +5 -0
- data/ext/duckdb/prepared_statement.c +64 -6
- data/ext/duckdb/result.c +17 -45
- data/ext/duckdb/ruby-duckdb.h +6 -8
- data/lib/duckdb/appender.rb +458 -56
- data/lib/duckdb/column.rb +0 -2
- data/lib/duckdb/interval.rb +12 -10
- data/lib/duckdb/logical_type.rb +110 -0
- data/lib/duckdb/pending_result.rb +1 -1
- data/lib/duckdb/prepared_statement.rb +18 -1
- data/lib/duckdb/result.rb +16 -16
- data/lib/duckdb/version.rb +1 -1
- data/lib/duckdb.rb +1 -0
- metadata +9 -6
data/lib/duckdb/appender.rb
CHANGED
@@ -13,16 +13,425 @@ 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
|
141
|
+
|
142
|
+
# call-seq:
|
143
|
+
# appender.append_int16(val) -> self
|
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
|
+
|
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
|
23
427
|
|
428
|
+
raise_appender_error('failed to append_default')
|
429
|
+
end
|
430
|
+
|
431
|
+
# call-seq:
|
432
|
+
# appender.append_hugeint(val) -> self
|
24
433
|
#
|
25
|
-
#
|
434
|
+
# Appends a huge int value to the current row in the appender.
|
26
435
|
#
|
27
436
|
# require 'duckdb'
|
28
437
|
# db = DuckDB::Database.open
|
@@ -30,17 +439,21 @@ module DuckDB
|
|
30
439
|
# con.query('CREATE TABLE numbers (num HUGEINT)')
|
31
440
|
# appender = con.appender('numbers')
|
32
441
|
# appender
|
33
|
-
# .begin_row
|
34
442
|
# .append_hugeint(-170_141_183_460_469_231_731_687_303_715_884_105_727)
|
35
443
|
# .end_row
|
36
|
-
#
|
444
|
+
# .flush
|
37
445
|
def append_hugeint(value)
|
38
446
|
lower, upper = integer_to_hugeint(value)
|
39
|
-
|
447
|
+
|
448
|
+
return self if _append_hugeint(lower, upper)
|
449
|
+
|
450
|
+
raise_appender_error('failed to append_hugeint')
|
40
451
|
end
|
41
452
|
|
453
|
+
# call-seq:
|
454
|
+
# appender.append_uhugeint(val) -> self
|
42
455
|
#
|
43
|
-
#
|
456
|
+
# Appends an unsigned huge int value to the current row in the appender.
|
44
457
|
#
|
45
458
|
# require 'duckdb'
|
46
459
|
# db = DuckDB::Database.open
|
@@ -48,84 +461,93 @@ module DuckDB
|
|
48
461
|
# con.query('CREATE TABLE numbers (num UHUGEINT)')
|
49
462
|
# appender = con.appender('numbers')
|
50
463
|
# appender
|
51
|
-
# .begin_row
|
52
464
|
# .append_hugeint(340_282_366_920_938_463_463_374_607_431_768_211_455)
|
53
465
|
# .end_row
|
54
|
-
#
|
466
|
+
# .flush
|
55
467
|
def append_uhugeint(value)
|
56
468
|
lower, upper = integer_to_hugeint(value)
|
57
|
-
|
469
|
+
|
470
|
+
return self if _append_uhugeint(lower, upper)
|
471
|
+
|
472
|
+
raise_appender_error('failed to append_uhugeint')
|
58
473
|
end
|
59
474
|
|
475
|
+
# call-seq:
|
476
|
+
# appender.append_date(val) -> self
|
60
477
|
#
|
61
|
-
#
|
478
|
+
# Appends a date value to the current row in the appender.
|
62
479
|
#
|
63
480
|
# require 'duckdb'
|
64
481
|
# db = DuckDB::Database.open
|
65
482
|
# con = db.connect
|
66
483
|
# con.query('CREATE TABLE dates (date_value DATE)')
|
67
484
|
# appender = con.appender('dates')
|
68
|
-
# appender.begin_row
|
69
485
|
# appender.append_date(Date.today)
|
70
486
|
# # or
|
71
487
|
# # appender.append_date(Time.now)
|
72
488
|
# # appender.append_date('2021-10-10')
|
73
489
|
# appender.end_row
|
74
490
|
# appender.flush
|
75
|
-
#
|
76
491
|
def append_date(value)
|
77
|
-
date =
|
492
|
+
date = _parse_date(value)
|
493
|
+
|
494
|
+
return self if _append_date(date.year, date.month, date.day)
|
78
495
|
|
79
|
-
|
496
|
+
raise_appender_error('failed to append_date')
|
80
497
|
end
|
81
498
|
|
499
|
+
# call-seq:
|
500
|
+
# appender.append_time(val) -> self
|
82
501
|
#
|
83
|
-
#
|
502
|
+
# Appends a time value to the current row in the appender.
|
84
503
|
#
|
85
504
|
# require 'duckdb'
|
86
505
|
# db = DuckDB::Database.open
|
87
506
|
# con = db.connect
|
88
507
|
# con.query('CREATE TABLE times (time_value TIME)')
|
89
508
|
# appender = con.appender('times')
|
90
|
-
# appender.begin_row
|
91
509
|
# appender.append_time(Time.now)
|
92
510
|
# # or
|
93
511
|
# # appender.append_time('01:01:01')
|
94
512
|
# appender.end_row
|
95
513
|
# appender.flush
|
96
|
-
#
|
97
514
|
def append_time(value)
|
98
515
|
time = _parse_time(value)
|
99
516
|
|
100
|
-
_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')
|
101
520
|
end
|
102
521
|
|
522
|
+
# call-seq:
|
523
|
+
# appender.append_timestamp(val) -> self
|
103
524
|
#
|
104
|
-
#
|
525
|
+
# Appends a timestamp value to the current row in the appender.
|
105
526
|
#
|
106
527
|
# require 'duckdb'
|
107
528
|
# db = DuckDB::Database.open
|
108
529
|
# con = db.connect
|
109
530
|
# con.query('CREATE TABLE timestamps (timestamp_value TIMESTAMP)')
|
110
531
|
# appender = con.appender('timestamps')
|
111
|
-
# appender.begin_row
|
112
532
|
# appender.append_time(Time.now)
|
113
533
|
# # or
|
114
534
|
# # appender.append_time(Date.today)
|
115
535
|
# # appender.append_time('2021-08-01 01:01:01')
|
116
536
|
# appender.end_row
|
117
537
|
# appender.flush
|
118
|
-
#
|
119
538
|
def append_timestamp(value)
|
120
539
|
time = to_time(value)
|
121
540
|
|
122
|
-
_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')
|
123
544
|
end
|
124
545
|
|
546
|
+
# call-seq:
|
547
|
+
# appender.append_interval(val) -> self
|
125
548
|
#
|
126
|
-
#
|
549
|
+
# Appends an interval value to the current row in the appender.
|
127
550
|
# The argument must be ISO8601 duration format.
|
128
|
-
# WARNING: This method is expremental.
|
129
551
|
#
|
130
552
|
# require 'duckdb'
|
131
553
|
# db = DuckDB::Database.open
|
@@ -133,17 +555,17 @@ module DuckDB
|
|
133
555
|
# con.query('CREATE TABLE intervals (interval_value INTERVAL)')
|
134
556
|
# appender = con.appender('intervals')
|
135
557
|
# appender
|
136
|
-
# .begin_row
|
137
558
|
# .append_interval('P1Y2D') # => append 1 year 2 days interval.
|
138
559
|
# .end_row
|
139
560
|
# .flush
|
140
|
-
#
|
141
561
|
def append_interval(value)
|
142
562
|
value = Interval.to_interval(value)
|
143
|
-
|
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')
|
144
567
|
end
|
145
568
|
|
146
|
-
#
|
147
569
|
# appends value.
|
148
570
|
#
|
149
571
|
# require 'duckdb'
|
@@ -151,11 +573,9 @@ module DuckDB
|
|
151
573
|
# con = db.connect
|
152
574
|
# con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
|
153
575
|
# appender = con.appender('users')
|
154
|
-
# appender.begin_row
|
155
576
|
# appender.append(1)
|
156
577
|
# appender.append('Alice')
|
157
578
|
# appender.end_row
|
158
|
-
#
|
159
579
|
def append(value)
|
160
580
|
case value
|
161
581
|
when NilClass
|
@@ -188,20 +608,16 @@ module DuckDB
|
|
188
608
|
end
|
189
609
|
end
|
190
610
|
|
191
|
-
#
|
192
611
|
# append a row.
|
193
612
|
#
|
194
613
|
# appender.append_row(1, 'Alice')
|
195
614
|
#
|
196
615
|
# is same as:
|
197
616
|
#
|
198
|
-
# appender.
|
199
|
-
# appender.append(1)
|
617
|
+
# appender.append(2)
|
200
618
|
# appender.append('Alice')
|
201
619
|
# appender.end_row
|
202
|
-
#
|
203
620
|
def append_row(*args)
|
204
|
-
begin_row
|
205
621
|
args.each do |arg|
|
206
622
|
append(arg)
|
207
623
|
end
|
@@ -210,35 +626,21 @@ module DuckDB
|
|
210
626
|
|
211
627
|
private
|
212
628
|
|
213
|
-
def
|
214
|
-
|
629
|
+
def raise_appender_error(default_message) # :nodoc:
|
630
|
+
message = error_message
|
631
|
+
raise DuckDB::Error, message || default_message
|
215
632
|
end
|
216
633
|
|
217
|
-
def
|
218
|
-
|
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
|
634
|
+
def blob?(value) # :nodoc:
|
635
|
+
value.instance_of?(DuckDB::Blob) || value.encoding == Encoding::BINARY
|
228
636
|
end
|
229
637
|
|
230
|
-
def to_time(value)
|
638
|
+
def to_time(value) # :nodoc:
|
231
639
|
case value
|
232
|
-
when Time
|
233
|
-
value
|
234
640
|
when Date
|
235
641
|
value.to_time
|
236
642
|
else
|
237
|
-
|
238
|
-
Time.parse(value)
|
239
|
-
rescue StandardError
|
240
|
-
raise(ArgumentError, "Cannot parse argument `#{value}` to Time or Date.")
|
241
|
-
end
|
643
|
+
_parse_time(value)
|
242
644
|
end
|
243
645
|
end
|
244
646
|
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)
|