duckdb 0.9.1 → 0.9.1.2
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/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
|