duckdb 0.9.1 → 0.9.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test_on_macos.yml +1 -1
- data/.github/workflows/test_on_ubuntu.yml +1 -1
- data/.github/workflows/test_on_windows.yml +1 -1
- data/CHANGELOG.md +21 -6
- data/Gemfile.lock +4 -4
- data/ext/duckdb/appender.c +5 -5
- data/ext/duckdb/appender.h +1 -1
- data/ext/duckdb/blob.c +1 -1
- data/ext/duckdb/blob.h +1 -4
- data/ext/duckdb/column.c +2 -2
- data/ext/duckdb/column.h +2 -2
- data/ext/duckdb/config.c +1 -1
- data/ext/duckdb/config.h +1 -1
- data/ext/duckdb/connection.c +66 -6
- data/ext/duckdb/connection.h +2 -2
- data/ext/duckdb/converter.h +1 -1
- data/ext/duckdb/conveter.c +1 -1
- data/ext/duckdb/database.c +3 -3
- data/ext/duckdb/database.h +2 -2
- data/ext/duckdb/duckdb.c +11 -10
- data/ext/duckdb/error.c +1 -1
- data/ext/duckdb/error.h +1 -1
- data/ext/duckdb/extconf.rb +1 -6
- data/ext/duckdb/pending_result.c +123 -0
- data/ext/duckdb/pending_result.h +13 -0
- data/ext/duckdb/prepared_statement.c +12 -7
- data/ext/duckdb/prepared_statement.h +2 -1
- data/ext/duckdb/result.c +3 -9
- data/ext/duckdb/result.h +2 -2
- data/ext/duckdb/ruby-duckdb.h +1 -8
- data/ext/duckdb/util.c +4 -4
- data/ext/duckdb/util.h +4 -4
- data/lib/duckdb/appender.rb +1 -10
- data/lib/duckdb/connection.rb +28 -8
- data/lib/duckdb/converter.rb +27 -1
- data/lib/duckdb/library_version.rb +1 -1
- data/lib/duckdb/pending_result.rb +39 -0
- data/lib/duckdb/prepared_statement.rb +40 -40
- data/lib/duckdb/result.rb +16 -12
- data/lib/duckdb/version.rb +1 -1
- data/lib/duckdb.rb +1 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b492788be53be66a956ad49e4cd8a82ffa6273c12f037b2c0abd51253321802f
|
4
|
+
data.tar.gz: 50571029b1d1160a7abb6ac223bd4cda4f3791b29d26cdebac6b795f160a2a14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d80355e181599217574191f3acba24d6dbcb37e4a73b774689590f42fc9b92032d4a4285962ee65100d3a3186825b29f09066d9fd0f8f24ce46aaec85cba4701
|
7
|
+
data.tar.gz: b126f7e0057c77cae338f7c6b76d4b775c52b06f84936ebd6208a3357148ababa8c8c3aaca727dacf4b7ed05b5f5da2bedc74d8b1d46f170ddc418d4c9e125fa
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# ChangeLog
|
2
2
|
|
3
|
+
# 0.9.1.2
|
4
|
+
- add DuckDB::Connection#interrupt, DuckDB::Connection#query_progress
|
5
|
+
- add DuckDB::Connection#async_query, alias method async_execute.
|
6
|
+
|
7
|
+
# 0.9.1.1
|
8
|
+
- change default branch to main from master.
|
9
|
+
- add DuckDB::PendingResult class.
|
10
|
+
- add DuckDB::PendingResult#state.
|
11
|
+
- add DuckDB::PendingResult#execute_task.
|
12
|
+
- add DuckDB::PendingResult#execute_pending.
|
13
|
+
- add DuckDB::PreparedStatement#pending_prepared.
|
14
|
+
|
15
|
+
## Breaking Changes
|
16
|
+
- drop duckdb v0.7.x.
|
17
|
+
|
3
18
|
# 0.9.1
|
4
19
|
- add `DuckDB::PreparedStatement#parameter_name`.
|
5
20
|
- bump duckdb to 0.9.1.
|
@@ -11,7 +26,7 @@
|
|
11
26
|
# 0.9.0
|
12
27
|
- bump duckdb to 0.9.0.
|
13
28
|
|
14
|
-
## Breaking
|
29
|
+
## Breaking Changes
|
15
30
|
- deprecation warning when DuckDB::Result.each calling with `DuckDB::Result.use_chunk_each` is false.
|
16
31
|
The `each` behavior will be same as `DuckDB::Result.chunk_each` in the future.
|
17
32
|
set `DuckDB::Result.use_chunk_each = true` to suppress the warning.
|
@@ -54,7 +69,7 @@
|
|
54
69
|
- support enum type in DuckDB::Result#chunk_each.
|
55
70
|
- support uuid type in DuckDB::Result#chunk_each.
|
56
71
|
|
57
|
-
## Breaking
|
72
|
+
## Breaking Changes
|
58
73
|
|
59
74
|
- DuckDB::Config.set_config does not raise exception when invalid key specified.
|
60
75
|
Instead, DuckDB::Database.open raises DuckDB::Error with invalid key configuration.
|
@@ -64,7 +79,7 @@
|
|
64
79
|
- add DuckDB::Result#_to_decimal_internal
|
65
80
|
- add DuckDB::Result#_to_hugeint_internal
|
66
81
|
|
67
|
-
## Breaking
|
82
|
+
## Breaking Changes
|
68
83
|
- DuckDB::Result returns BigDecimal object instead of String object if the column type is DECIMAL.
|
69
84
|
|
70
85
|
# 0.7.1
|
@@ -81,7 +96,7 @@
|
|
81
96
|
- add DuckDB::Result#__to_decimal_internal
|
82
97
|
- add Ruby 3.2.1 on CI test
|
83
98
|
- add Ruby mswin on CI test
|
84
|
-
## Breaking
|
99
|
+
## Breaking Changes
|
85
100
|
- drop Ruby 2.6
|
86
101
|
|
87
102
|
# 0.6.1
|
@@ -95,7 +110,7 @@
|
|
95
110
|
- bump Ruby to 3.2.0rc1
|
96
111
|
- bump duckdb to 0.6.0
|
97
112
|
|
98
|
-
## Breaking
|
113
|
+
## Breaking Changes
|
99
114
|
- drop duckdb <= 0.4.x. ruby-duckdb supports duckdb >= 0.5.0
|
100
115
|
|
101
116
|
# 0.5.1.1
|
@@ -114,7 +129,7 @@
|
|
114
129
|
- add DuckDB::Result#row_count, DuckDB::Result#row_size(alias of row_count).
|
115
130
|
- add DuckDB::Result#column_count, DuckDB::Result#column_size(alias of column_count).
|
116
131
|
|
117
|
-
## Breaking
|
132
|
+
## Breaking Changes
|
118
133
|
- bind_varchar does not raised DuckDB::Error when the binding column is date or datetime.
|
119
134
|
|
120
135
|
# 0.3.4.0
|
data/Gemfile.lock
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
duckdb (0.9.1)
|
4
|
+
duckdb (0.9.1.2)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
benchmark-ips (2.12.0)
|
10
|
-
mini_portile2 (2.8.
|
10
|
+
mini_portile2 (2.8.5)
|
11
11
|
minitest (5.20.0)
|
12
12
|
nokogiri (1.15.4)
|
13
13
|
mini_portile2 (~> 2.8.2)
|
14
14
|
racc (~> 1.4)
|
15
15
|
nokogiri (1.15.4-x86_64-linux)
|
16
16
|
racc (~> 1.4)
|
17
|
-
racc (1.7.
|
18
|
-
rake (13.0
|
17
|
+
racc (1.7.3)
|
18
|
+
rake (13.1.0)
|
19
19
|
rake-compiler (1.2.5)
|
20
20
|
rake
|
21
21
|
ruby_memcheck (2.2.0)
|
data/ext/duckdb/appender.c
CHANGED
@@ -285,7 +285,7 @@ static VALUE appender__append_date(VALUE self, VALUE year, VALUE month, VALUE da
|
|
285
285
|
rubyDuckDBAppender *ctx;
|
286
286
|
|
287
287
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
288
|
-
dt =
|
288
|
+
dt = rbduckdb_to_duckdb_date_from_value(year, month, day);
|
289
289
|
|
290
290
|
if (duckdb_append_date(ctx->appender, dt) == DuckDBError) {
|
291
291
|
rb_raise(eDuckDBError, "failed to append date");
|
@@ -298,7 +298,7 @@ static VALUE appender__append_interval(VALUE self, VALUE months, VALUE days, VAL
|
|
298
298
|
rubyDuckDBAppender *ctx;
|
299
299
|
|
300
300
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
301
|
-
|
301
|
+
rbduckdb_to_duckdb_interval_from_value(&interval, months, days, micros);
|
302
302
|
|
303
303
|
if (duckdb_append_interval(ctx->appender, interval) == DuckDBError) {
|
304
304
|
rb_raise(eDuckDBError, "failed to append interval");
|
@@ -311,7 +311,7 @@ static VALUE appender__append_time(VALUE self, VALUE hour, VALUE min, VALUE sec,
|
|
311
311
|
rubyDuckDBAppender *ctx;
|
312
312
|
|
313
313
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
314
|
-
time =
|
314
|
+
time = rbduckdb_to_duckdb_time_from_value(hour, min, sec, micros);
|
315
315
|
|
316
316
|
if (duckdb_append_time(ctx->appender, time) == DuckDBError) {
|
317
317
|
rb_raise(eDuckDBError, "failed to append time");
|
@@ -326,7 +326,7 @@ static VALUE appender__append_timestamp(VALUE self, VALUE year, VALUE month, VAL
|
|
326
326
|
|
327
327
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
328
328
|
|
329
|
-
timestamp =
|
329
|
+
timestamp = rbduckdb_to_duckdb_timestamp_from_value(year, month, day, hour, min, sec, micros);
|
330
330
|
|
331
331
|
if (duckdb_append_timestamp(ctx->appender, timestamp) == DuckDBError) {
|
332
332
|
rb_raise(eDuckDBError, "failed to append timestamp");
|
@@ -369,7 +369,7 @@ static VALUE appender_close(VALUE self) {
|
|
369
369
|
return self;
|
370
370
|
}
|
371
371
|
|
372
|
-
void
|
372
|
+
void rbduckdb_init_duckdb_appender(void) {
|
373
373
|
cDuckDBAppender = rb_define_class_under(mDuckDB, "Appender", rb_cObject);
|
374
374
|
rb_define_alloc_func(cDuckDBAppender, allocate);
|
375
375
|
rb_define_method(cDuckDBAppender, "initialize", appender_initialize, 3);
|
data/ext/duckdb/appender.h
CHANGED
data/ext/duckdb/blob.c
CHANGED
data/ext/duckdb/blob.h
CHANGED
data/ext/duckdb/column.c
CHANGED
@@ -68,7 +68,7 @@ VALUE duckdb_column_get_name(VALUE oDuckDBColumn) {
|
|
68
68
|
return rb_utf8_str_new_cstr(duckdb_column_name(&(ctxresult->result), ctx->col));
|
69
69
|
}
|
70
70
|
|
71
|
-
VALUE
|
71
|
+
VALUE rbduckdb_create_column(VALUE oDuckDBResult, idx_t col) {
|
72
72
|
VALUE obj;
|
73
73
|
rubyDuckDBColumn *ctx;
|
74
74
|
|
@@ -81,7 +81,7 @@ VALUE create_column(VALUE oDuckDBResult, idx_t col) {
|
|
81
81
|
return obj;
|
82
82
|
}
|
83
83
|
|
84
|
-
void
|
84
|
+
void rbduckdb_init_duckdb_column(void) {
|
85
85
|
cDuckDBColumn = rb_define_class_under(mDuckDB, "Column", rb_cObject);
|
86
86
|
rb_define_alloc_func(cDuckDBColumn, allocate);
|
87
87
|
|
data/ext/duckdb/column.h
CHANGED
@@ -8,7 +8,7 @@ struct _rubyDuckDBColumn {
|
|
8
8
|
|
9
9
|
typedef struct _rubyDuckDBColumn rubyDuckDBColumn;
|
10
10
|
|
11
|
-
void
|
12
|
-
VALUE
|
11
|
+
void rbduckdb_init_duckdb_column(void);
|
12
|
+
VALUE rbduckdb_create_column(VALUE oDuckDBResult, idx_t col);
|
13
13
|
|
14
14
|
#endif
|
data/ext/duckdb/config.c
CHANGED
@@ -79,7 +79,7 @@ static VALUE config_set_config(VALUE self, VALUE key, VALUE value) {
|
|
79
79
|
return self;
|
80
80
|
}
|
81
81
|
|
82
|
-
void
|
82
|
+
void rbduckdb_init_duckdb_config(void) {
|
83
83
|
cDuckDBConfig = rb_define_class_under(mDuckDB, "Config", rb_cObject);
|
84
84
|
rb_define_alloc_func(cDuckDBConfig, allocate);
|
85
85
|
rb_define_singleton_method(cDuckDBConfig, "size", config_s_size, 0);
|
data/ext/duckdb/config.h
CHANGED
data/ext/duckdb/connection.c
CHANGED
@@ -6,6 +6,12 @@ static void deallocate(void *ctx);
|
|
6
6
|
static VALUE allocate(VALUE klass);
|
7
7
|
static size_t memsize(const void *p);
|
8
8
|
static VALUE duckdb_connection_disconnect(VALUE self);
|
9
|
+
|
10
|
+
#ifdef HAVE_DUCKDB_H_GE_V090
|
11
|
+
static VALUE duckdb_connection_interrupt(VALUE self);
|
12
|
+
static VALUE duckdb_connection_query_progress(VALUE self);
|
13
|
+
#endif
|
14
|
+
|
9
15
|
static VALUE duckdb_connection_connect(VALUE self, VALUE oDuckDBDatabase);
|
10
16
|
static VALUE duckdb_connection_query_sql(VALUE self, VALUE str);
|
11
17
|
|
@@ -37,12 +43,12 @@ rubyDuckDBConnection *get_struct_connection(VALUE obj) {
|
|
37
43
|
return ctx;
|
38
44
|
}
|
39
45
|
|
40
|
-
VALUE
|
46
|
+
VALUE rbduckdb_create_connection(VALUE oDuckDBDatabase) {
|
41
47
|
rubyDuckDB *ctxdb;
|
42
48
|
rubyDuckDBConnection *ctxcon;
|
43
49
|
VALUE obj;
|
44
50
|
|
45
|
-
ctxdb =
|
51
|
+
ctxdb = rbduckdb_get_struct_database(oDuckDBDatabase);
|
46
52
|
|
47
53
|
obj = allocate(cDuckDBConnection);
|
48
54
|
TypedData_Get_Struct(obj, rubyDuckDBConnection, &connection_data_type, ctxcon);
|
@@ -51,7 +57,6 @@ VALUE create_connection(VALUE oDuckDBDatabase) {
|
|
51
57
|
rb_raise(eDuckDBError, "connection error");
|
52
58
|
}
|
53
59
|
|
54
|
-
// rb_ivar_set(obj, rb_intern("database"), oDuckDBDatabase);
|
55
60
|
return obj;
|
56
61
|
}
|
57
62
|
|
@@ -64,6 +69,57 @@ static VALUE duckdb_connection_disconnect(VALUE self) {
|
|
64
69
|
return self;
|
65
70
|
}
|
66
71
|
|
72
|
+
#ifdef HAVE_DUCKDB_H_GE_V090
|
73
|
+
/*
|
74
|
+
* call-seq:
|
75
|
+
* connection.interrupt -> nil
|
76
|
+
*
|
77
|
+
* Interrupts the currently running query.
|
78
|
+
*
|
79
|
+
* db = DuckDB::Database.open
|
80
|
+
* conn = db.connect
|
81
|
+
* con.query('SET ENABLE_PROGRESS_BAR=true')
|
82
|
+
* con.query('SET ENABLE_PROGRESS_BAR_PRINT=false')
|
83
|
+
* pending_result = con.async_query('slow query')
|
84
|
+
*
|
85
|
+
* pending_result.execute_task
|
86
|
+
* con.interrupt # => nil
|
87
|
+
*/
|
88
|
+
static VALUE duckdb_connection_interrupt(VALUE self) {
|
89
|
+
rubyDuckDBConnection *ctx;
|
90
|
+
|
91
|
+
TypedData_Get_Struct(self, rubyDuckDBConnection, &connection_data_type, ctx);
|
92
|
+
duckdb_interrupt(ctx->con);
|
93
|
+
|
94
|
+
return Qnil;
|
95
|
+
}
|
96
|
+
|
97
|
+
/*
|
98
|
+
* Returns the progress of the currently running query.
|
99
|
+
*
|
100
|
+
* require 'duckdb'
|
101
|
+
*
|
102
|
+
* db = DuckDB::Database.open
|
103
|
+
* conn = db.connect
|
104
|
+
* con.query('SET ENABLE_PROGRESS_BAR=true')
|
105
|
+
* con.query('SET ENABLE_PROGRESS_BAR_PRINT=false')
|
106
|
+
* con.query_progress # => -1.0
|
107
|
+
* pending_result = con.async_query('slow query')
|
108
|
+
* con.query_progress # => 0.0
|
109
|
+
* pending_result.execute_task
|
110
|
+
* con.query_progress # => Float
|
111
|
+
*/
|
112
|
+
static VALUE duckdb_connection_query_progress(VALUE self) {
|
113
|
+
rubyDuckDBConnection *ctx;
|
114
|
+
double progress;
|
115
|
+
|
116
|
+
TypedData_Get_Struct(self, rubyDuckDBConnection, &connection_data_type, ctx);
|
117
|
+
progress = duckdb_query_progress(ctx->con);
|
118
|
+
|
119
|
+
return DBL2NUM(progress);
|
120
|
+
}
|
121
|
+
#endif
|
122
|
+
|
67
123
|
static VALUE duckdb_connection_connect(VALUE self, VALUE oDuckDBDatabase) {
|
68
124
|
rubyDuckDBConnection *ctx;
|
69
125
|
rubyDuckDB *ctxdb;
|
@@ -71,7 +127,7 @@ static VALUE duckdb_connection_connect(VALUE self, VALUE oDuckDBDatabase) {
|
|
71
127
|
if (!rb_obj_is_kind_of(oDuckDBDatabase, cDuckDBDatabase)) {
|
72
128
|
rb_raise(rb_eTypeError, "The first argument must be DuckDB::Database object.");
|
73
129
|
}
|
74
|
-
ctxdb =
|
130
|
+
ctxdb = rbduckdb_get_struct_database(oDuckDBDatabase);
|
75
131
|
TypedData_Get_Struct(self, rubyDuckDBConnection, &connection_data_type, ctx);
|
76
132
|
|
77
133
|
if (duckdb_connect(ctxdb->db, &(ctx->con)) == DuckDBError) {
|
@@ -85,7 +141,7 @@ static VALUE duckdb_connection_query_sql(VALUE self, VALUE str) {
|
|
85
141
|
rubyDuckDBConnection *ctx;
|
86
142
|
rubyDuckDBResult *ctxr;
|
87
143
|
|
88
|
-
VALUE result =
|
144
|
+
VALUE result = rbduckdb_create_result();
|
89
145
|
|
90
146
|
TypedData_Get_Struct(self, rubyDuckDBConnection, &connection_data_type, ctx);
|
91
147
|
ctxr = get_struct_result(result);
|
@@ -100,11 +156,15 @@ static VALUE duckdb_connection_query_sql(VALUE self, VALUE str) {
|
|
100
156
|
return result;
|
101
157
|
}
|
102
158
|
|
103
|
-
void
|
159
|
+
void rbduckdb_init_duckdb_connection(void) {
|
104
160
|
cDuckDBConnection = rb_define_class_under(mDuckDB, "Connection", rb_cObject);
|
105
161
|
rb_define_alloc_func(cDuckDBConnection, allocate);
|
106
162
|
|
107
163
|
rb_define_method(cDuckDBConnection, "disconnect", duckdb_connection_disconnect, 0);
|
164
|
+
#ifdef HAVE_DUCKDB_H_GE_V090
|
165
|
+
rb_define_method(cDuckDBConnection, "interrupt", duckdb_connection_interrupt, 0);
|
166
|
+
rb_define_method(cDuckDBConnection, "query_progress", duckdb_connection_query_progress, 0);
|
167
|
+
#endif
|
108
168
|
rb_define_private_method(cDuckDBConnection, "_connect", duckdb_connection_connect, 1);
|
109
169
|
rb_define_private_method(cDuckDBConnection, "query_sql", duckdb_connection_query_sql, 1);
|
110
170
|
}
|
data/ext/duckdb/connection.h
CHANGED
@@ -8,7 +8,7 @@ struct _rubyDuckDBConnection {
|
|
8
8
|
typedef struct _rubyDuckDBConnection rubyDuckDBConnection;
|
9
9
|
|
10
10
|
rubyDuckDBConnection *get_struct_connection(VALUE obj);
|
11
|
-
void
|
12
|
-
VALUE
|
11
|
+
void rbduckdb_init_duckdb_connection(void);
|
12
|
+
VALUE rbduckdb_create_connection(VALUE oDuckDBDatabase);
|
13
13
|
|
14
14
|
#endif
|
data/ext/duckdb/converter.h
CHANGED
data/ext/duckdb/conveter.c
CHANGED
data/ext/duckdb/database.c
CHANGED
@@ -37,7 +37,7 @@ static VALUE allocate(VALUE klass) {
|
|
37
37
|
return TypedData_Wrap_Struct(klass, &database_data_type, ctx);
|
38
38
|
}
|
39
39
|
|
40
|
-
rubyDuckDB *
|
40
|
+
rubyDuckDB *rbduckdb_get_struct_database(VALUE obj) {
|
41
41
|
rubyDuckDB *ctx;
|
42
42
|
TypedData_Get_Struct(obj, rubyDuckDB, &database_data_type, ctx);
|
43
43
|
return ctx;
|
@@ -99,7 +99,7 @@ static VALUE duckdb_database_s_open_ext(int argc, VALUE *argv, VALUE cDuckDBData
|
|
99
99
|
}
|
100
100
|
|
101
101
|
static VALUE duckdb_database_connect(VALUE self) {
|
102
|
-
return
|
102
|
+
return rbduckdb_create_connection(self);
|
103
103
|
}
|
104
104
|
|
105
105
|
/*
|
@@ -115,7 +115,7 @@ static VALUE duckdb_database_close(VALUE self) {
|
|
115
115
|
return self;
|
116
116
|
}
|
117
117
|
|
118
|
-
void
|
118
|
+
void rbduckdb_init_duckdb_database(void) {
|
119
119
|
cDuckDBDatabase = rb_define_class_under(mDuckDB, "Database", rb_cObject);
|
120
120
|
rb_define_alloc_func(cDuckDBDatabase, allocate);
|
121
121
|
rb_define_singleton_method(cDuckDBDatabase, "_open", duckdb_database_s_open, -1);
|
data/ext/duckdb/database.h
CHANGED
data/ext/duckdb/duckdb.c
CHANGED
@@ -22,14 +22,15 @@ Init_duckdb_native(void) {
|
|
22
22
|
|
23
23
|
rb_define_singleton_method(mDuckDB, "library_version", duckdb_s_library_version, 0);
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
rbduckdb_init_duckdb_error();
|
26
|
+
rbduckdb_init_duckdb_database();
|
27
|
+
rbduckdb_init_duckdb_connection();
|
28
|
+
rbduckdb_init_duckdb_result();
|
29
|
+
rbduckdb_init_duckdb_column();
|
30
|
+
rbduckdb_init_duckdb_prepared_statement();
|
31
|
+
rbduckdb_init_duckdb_pending_result();
|
32
|
+
rbduckdb_init_duckdb_blob();
|
33
|
+
rbduckdb_init_duckdb_appender();
|
34
|
+
rbduckdb_init_duckdb_config();
|
35
|
+
rbduckdb_init_duckdb_converter();
|
35
36
|
}
|
data/ext/duckdb/error.c
CHANGED
data/ext/duckdb/error.h
CHANGED
data/ext/duckdb/extconf.rb
CHANGED
@@ -20,13 +20,8 @@ end
|
|
20
20
|
|
21
21
|
dir_config('duckdb')
|
22
22
|
|
23
|
-
check_duckdb_library('duckdb_extract_statements', '0.7.0')
|
24
|
-
|
25
|
-
# check duckdb >= 0.7.0
|
26
|
-
have_func('duckdb_extract_statements', 'duckdb.h')
|
27
|
-
|
28
23
|
# check duckdb >= 0.8.0
|
29
|
-
|
24
|
+
check_duckdb_library('duckdb_string_is_inlined', '0.8.0')
|
30
25
|
|
31
26
|
# check duckdb >= 0.9.0
|
32
27
|
have_func('duckdb_bind_parameter_index', 'duckdb.h')
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#include "ruby-duckdb.h"
|
2
|
+
|
3
|
+
static VALUE cDuckDBPendingResult;
|
4
|
+
|
5
|
+
static void deallocate(void *ctx);
|
6
|
+
static VALUE allocate(VALUE klass);
|
7
|
+
static size_t memsize(const void *p);
|
8
|
+
static VALUE duckdb_pending_result_initialize(VALUE self, VALUE oDuckDBPreparedStatement);
|
9
|
+
static VALUE duckdb_pending_result_execute_task(VALUE self);
|
10
|
+
static VALUE duckdb_pending_result_execute_pending(VALUE self);
|
11
|
+
|
12
|
+
#ifdef HAVE_DUCKDB_H_GE_V090
|
13
|
+
static VALUE duckdb_pending_result_execution_finished_p(VALUE self);
|
14
|
+
#endif
|
15
|
+
|
16
|
+
static VALUE duckdb_pending_result__state(VALUE self);
|
17
|
+
|
18
|
+
static const rb_data_type_t pending_result_data_type = {
|
19
|
+
"DuckDB/PendingResult",
|
20
|
+
{NULL, deallocate, memsize,},
|
21
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
22
|
+
};
|
23
|
+
|
24
|
+
static void deallocate(void *ctx) {
|
25
|
+
rubyDuckDBPendingResult *p = (rubyDuckDBPendingResult *)ctx;
|
26
|
+
|
27
|
+
duckdb_destroy_pending(&(p->pending_result));
|
28
|
+
xfree(p);
|
29
|
+
}
|
30
|
+
|
31
|
+
static VALUE allocate(VALUE klass) {
|
32
|
+
rubyDuckDBPendingResult *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBPendingResult));
|
33
|
+
ctx->state = DUCKDB_PENDING_RESULT_NOT_READY;
|
34
|
+
return TypedData_Wrap_Struct(klass, &pending_result_data_type, ctx);
|
35
|
+
}
|
36
|
+
|
37
|
+
static size_t memsize(const void *p) {
|
38
|
+
return sizeof(rubyDuckDBPendingResult);
|
39
|
+
}
|
40
|
+
|
41
|
+
static VALUE duckdb_pending_result_initialize(VALUE self, VALUE oDuckDBPreparedStatement) {
|
42
|
+
rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
|
43
|
+
rubyDuckDBPreparedStatement *stmt = get_struct_prepared_statement(oDuckDBPreparedStatement);
|
44
|
+
|
45
|
+
if (duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result)) == DuckDBError) {
|
46
|
+
rb_raise(eDuckDBError, "%s", duckdb_pending_error(ctx->pending_result));
|
47
|
+
}
|
48
|
+
return self;
|
49
|
+
}
|
50
|
+
|
51
|
+
/*
|
52
|
+
* call-seq:
|
53
|
+
* pending_result.execute_task -> nil
|
54
|
+
*
|
55
|
+
* Executes the task in the pending result.
|
56
|
+
*
|
57
|
+
* db = DuckDB::Database.open
|
58
|
+
* conn = db.connect
|
59
|
+
* pending_result = conn.async_query("slow query")
|
60
|
+
* pending_result.execute_task
|
61
|
+
*/
|
62
|
+
static VALUE duckdb_pending_result_execute_task(VALUE self) {
|
63
|
+
rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
|
64
|
+
ctx->state = duckdb_pending_execute_task(ctx->pending_result);
|
65
|
+
return Qnil;
|
66
|
+
}
|
67
|
+
|
68
|
+
#ifdef HAVE_DUCKDB_H_GE_V090
|
69
|
+
static VALUE duckdb_pending_result_execution_finished_p(VALUE self) {
|
70
|
+
rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
|
71
|
+
return duckdb_pending_execution_is_finished(ctx->state) ? Qtrue : Qfalse;
|
72
|
+
}
|
73
|
+
#endif
|
74
|
+
|
75
|
+
/*
|
76
|
+
* call-seq:
|
77
|
+
* pending_result.execute_pending -> DuckDB::Result
|
78
|
+
*
|
79
|
+
* Get DuckDB::Result object after query execution finished.
|
80
|
+
*
|
81
|
+
* db = DuckDB::Database.open
|
82
|
+
* conn = db.connect
|
83
|
+
* pending_result = conn.async_query("slow query")
|
84
|
+
* pending_result.execute_task while pending_result.state != :ready
|
85
|
+
* result = pending_result.execute_pending # => DuckDB::Result
|
86
|
+
*/
|
87
|
+
static VALUE duckdb_pending_result_execute_pending(VALUE self) {
|
88
|
+
rubyDuckDBPendingResult *ctx;
|
89
|
+
rubyDuckDBResult *ctxr;
|
90
|
+
VALUE result = rbduckdb_create_result();
|
91
|
+
|
92
|
+
TypedData_Get_Struct(self, rubyDuckDBPendingResult, &pending_result_data_type, ctx);
|
93
|
+
ctxr = get_struct_result(result);
|
94
|
+
if (duckdb_execute_pending(ctx->pending_result, &(ctxr->result)) == DuckDBError) {
|
95
|
+
rb_raise(eDuckDBError, "%s", duckdb_pending_error(ctx->pending_result));
|
96
|
+
}
|
97
|
+
return result;
|
98
|
+
}
|
99
|
+
|
100
|
+
static VALUE duckdb_pending_result__state(VALUE self) {
|
101
|
+
rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
|
102
|
+
return INT2FIX(ctx->state);
|
103
|
+
}
|
104
|
+
|
105
|
+
rubyDuckDBPendingResult *get_struct_pending_result(VALUE obj) {
|
106
|
+
rubyDuckDBPendingResult *ctx;
|
107
|
+
TypedData_Get_Struct(obj, rubyDuckDBPendingResult, &pending_result_data_type, ctx);
|
108
|
+
return ctx;
|
109
|
+
}
|
110
|
+
|
111
|
+
void rbduckdb_init_duckdb_pending_result(void) {
|
112
|
+
cDuckDBPendingResult = rb_define_class_under(mDuckDB, "PendingResult", rb_cObject);
|
113
|
+
rb_define_alloc_func(cDuckDBPendingResult, allocate);
|
114
|
+
|
115
|
+
rb_define_method(cDuckDBPendingResult, "initialize", duckdb_pending_result_initialize, 1);
|
116
|
+
rb_define_method(cDuckDBPendingResult, "execute_task", duckdb_pending_result_execute_task, 0);
|
117
|
+
rb_define_method(cDuckDBPendingResult, "execute_pending", duckdb_pending_result_execute_pending, 0);
|
118
|
+
|
119
|
+
#ifdef HAVE_DUCKDB_H_GE_V090
|
120
|
+
rb_define_method(cDuckDBPendingResult, "execution_finished?", duckdb_pending_result_execution_finished_p, 0);
|
121
|
+
#endif
|
122
|
+
rb_define_private_method(cDuckDBPendingResult, "_state", duckdb_pending_result__state, 0);
|
123
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#ifndef RUBY_DUCKDB_PENDING_RESULT_H
|
2
|
+
#define RUBY_DUCKDB_PENDING_RESULT_H
|
3
|
+
|
4
|
+
struct _rubyDuckDBPendingResult {
|
5
|
+
duckdb_pending_result pending_result;
|
6
|
+
duckdb_pending_state state;
|
7
|
+
};
|
8
|
+
|
9
|
+
typedef struct _rubyDuckDBPendingResult rubyDuckDBPendingResult;
|
10
|
+
|
11
|
+
rubyDuckDBPendingResult *get_struct_pending_result(VALUE obj);
|
12
|
+
void rbduckdb_init_duckdb_pending_result(void);
|
13
|
+
#endif
|