duckdb 0.9.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f3ac463fffc2fc6362c34abbfa5b862a7b8c993052ede087ca4403542c98dc8
4
- data.tar.gz: c5ea1236f240a62165b7e371ae48033447868d119261def6c5310d3911e9df91
3
+ metadata.gz: b492788be53be66a956ad49e4cd8a82ffa6273c12f037b2c0abd51253321802f
4
+ data.tar.gz: 50571029b1d1160a7abb6ac223bd4cda4f3791b29d26cdebac6b795f160a2a14
5
5
  SHA512:
6
- metadata.gz: 210fe783740da4b6eb7991de416a7b5581403d8ad3661625110e275c030fe9dc1192d6fe2d73dcb778e53408b0e349eb28f37f2a1308d31ff30b0b783be5e498
7
- data.tar.gz: b6fcc8d47c20ff9ce053122d9d9c03f4b19f1a72d9cd56addc1704d862ab7cfda4b3bec88bb3d8580befa006dcfeeee76138e00a2a34f065cca630bde523fb7d
6
+ metadata.gz: d80355e181599217574191f3acba24d6dbcb37e4a73b774689590f42fc9b92032d4a4285962ee65100d3a3186825b29f09066d9fd0f8f24ce46aaec85cba4701
7
+ data.tar.gz: b126f7e0057c77cae338f7c6b76d4b775c52b06f84936ebd6208a3357148ababa8c8c3aaca727dacf4b7ed05b5f5da2bedc74d8b1d46f170ddc418d4c9e125fa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
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
+
3
7
  # 0.9.1.1
4
8
  - change default branch to main from master.
5
9
  - add DuckDB::PendingResult class.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (0.9.1.1)
4
+ duckdb (0.9.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -14,7 +14,7 @@ GEM
14
14
  racc (~> 1.4)
15
15
  nokogiri (1.15.4-x86_64-linux)
16
16
  racc (~> 1.4)
17
- racc (1.7.1)
17
+ racc (1.7.3)
18
18
  rake (13.1.0)
19
19
  rake-compiler (1.2.5)
20
20
  rake
@@ -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 = to_duckdb_date_from_value(year, month, day);
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
- to_duckdb_interval_from_value(&interval, months, days, micros);
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 = to_duckdb_time_from_value(hour, min, sec, micros);
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 = to_duckdb_timestamp_from_value(year, month, day, hour, min, sec, micros);
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 init_duckdb_appender(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);
@@ -7,6 +7,6 @@ struct _rubyDuckDBAppender {
7
7
 
8
8
  typedef struct _rubyDuckDBAppender rubyDuckDBAppender;
9
9
 
10
- void init_duckdb_appender(void);
10
+ void rbduckdb_init_duckdb_appender(void);
11
11
 
12
12
  #endif
data/ext/duckdb/blob.c CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  VALUE cDuckDBBlob;
4
4
 
5
- void init_duckdb_blob(void) {
5
+ void rbduckdb_init_duckdb_blob(void) {
6
6
  cDuckDBBlob = rb_define_class_under(mDuckDB, "Blob", rb_cString);
7
7
  }
data/ext/duckdb/blob.h CHANGED
@@ -1,10 +1,7 @@
1
1
  #ifndef RUBY_DUCKDB_BLOB_H
2
2
  #define RUBY_DUCKDB_BLOB_H
3
3
 
4
- /*
5
- * blob is supported by duckdb v0.2.5 or later
6
- */
7
- void init_duckdb_blob(void);
4
+ void rbduckdb_init_duckdb_blob(void);
8
5
 
9
6
  #endif
10
7
 
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 create_column(VALUE oDuckDBResult, idx_t col) {
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 init_duckdb_column(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 init_duckdb_column(void);
12
- VALUE create_column(VALUE oDuckDBResult, idx_t col);
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 init_duckdb_config(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
@@ -9,6 +9,6 @@ typedef struct _rubyDuckDBConfig rubyDuckDBConfig;
9
9
 
10
10
  rubyDuckDBConfig *get_struct_config(VALUE obj);
11
11
 
12
- void init_duckdb_config(void);
12
+ void rbduckdb_init_duckdb_config(void);
13
13
 
14
14
  #endif
@@ -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 create_connection(VALUE oDuckDBDatabase) {
46
+ VALUE rbduckdb_create_connection(VALUE oDuckDBDatabase) {
41
47
  rubyDuckDB *ctxdb;
42
48
  rubyDuckDBConnection *ctxcon;
43
49
  VALUE obj;
44
50
 
45
- ctxdb = get_struct_database(oDuckDBDatabase);
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 = get_struct_database(oDuckDBDatabase);
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 = create_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 init_duckdb_connection(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
  }
@@ -8,7 +8,7 @@ struct _rubyDuckDBConnection {
8
8
  typedef struct _rubyDuckDBConnection rubyDuckDBConnection;
9
9
 
10
10
  rubyDuckDBConnection *get_struct_connection(VALUE obj);
11
- void init_duckdb_connection(void);
12
- VALUE create_connection(VALUE oDuckDBDatabase);
11
+ void rbduckdb_init_duckdb_connection(void);
12
+ VALUE rbduckdb_create_connection(VALUE oDuckDBDatabase);
13
13
 
14
14
  #endif
@@ -1,6 +1,6 @@
1
1
  #ifndef RUBY_DUCKDB_CONVERTER_H
2
2
  #define RUBY_DUCKDB_CONVERTER_H
3
3
 
4
- void init_duckdb_converter(void);
4
+ void rbduckdb_init_duckdb_converter(void);
5
5
 
6
6
  #endif
@@ -2,6 +2,6 @@
2
2
 
3
3
  VALUE mDuckDBConverter;
4
4
 
5
- void init_duckdb_converter(void) {
5
+ void rbduckdb_init_duckdb_converter(void) {
6
6
  mDuckDBConverter = rb_define_module_under(mDuckDB, "Converter");
7
7
  }
@@ -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 *get_struct_database(VALUE obj) {
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 create_connection(self);
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 init_duckdb_database(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);
@@ -7,7 +7,7 @@ struct _rubyDuckDB {
7
7
 
8
8
  typedef struct _rubyDuckDB rubyDuckDB;
9
9
 
10
- rubyDuckDB *get_struct_database(VALUE obj);
11
- void init_duckdb_database(void);
10
+ rubyDuckDB *rbduckdb_get_struct_database(VALUE obj);
11
+ void rbduckdb_init_duckdb_database(void);
12
12
 
13
13
  #endif
data/ext/duckdb/duckdb.c CHANGED
@@ -22,15 +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
- init_duckdb_error();
26
- init_duckdb_database();
27
- init_duckdb_connection();
28
- init_duckdb_result();
29
- init_duckdb_column();
30
- init_duckdb_prepared_statement();
31
- init_duckdb_pending_result();
32
- init_duckdb_blob();
33
- init_duckdb_appender();
34
- init_duckdb_config();
35
- init_duckdb_converter();
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();
36
36
  }
data/ext/duckdb/error.c CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  VALUE eDuckDBError;
4
4
 
5
- void init_duckdb_error(void) {
5
+ void rbduckdb_init_duckdb_error(void) {
6
6
  eDuckDBError = rb_define_class_under(mDuckDB, "Error", rb_eStandardError);
7
7
  }
data/ext/duckdb/error.h CHANGED
@@ -1,7 +1,7 @@
1
1
  #ifndef RUBY_DUCKDB_ERROR_H
2
2
  #define RUBY_DUCKDB_ERROR_H
3
3
 
4
- void init_duckdb_error(void);
4
+ void rbduckdb_init_duckdb_error(void);
5
5
 
6
6
  #endif
7
7
 
@@ -48,6 +48,17 @@ static VALUE duckdb_pending_result_initialize(VALUE self, VALUE oDuckDBPreparedS
48
48
  return self;
49
49
  }
50
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
+ */
51
62
  static VALUE duckdb_pending_result_execute_task(VALUE self) {
52
63
  rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
53
64
  ctx->state = duckdb_pending_execute_task(ctx->pending_result);
@@ -61,10 +72,22 @@ static VALUE duckdb_pending_result_execution_finished_p(VALUE self) {
61
72
  }
62
73
  #endif
63
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
+ */
64
87
  static VALUE duckdb_pending_result_execute_pending(VALUE self) {
65
88
  rubyDuckDBPendingResult *ctx;
66
89
  rubyDuckDBResult *ctxr;
67
- VALUE result = create_result();
90
+ VALUE result = rbduckdb_create_result();
68
91
 
69
92
  TypedData_Get_Struct(self, rubyDuckDBPendingResult, &pending_result_data_type, ctx);
70
93
  ctxr = get_struct_result(result);
@@ -85,7 +108,7 @@ rubyDuckDBPendingResult *get_struct_pending_result(VALUE obj) {
85
108
  return ctx;
86
109
  }
87
110
 
88
- void init_duckdb_pending_result(void) {
111
+ void rbduckdb_init_duckdb_pending_result(void) {
89
112
  cDuckDBPendingResult = rb_define_class_under(mDuckDB, "PendingResult", rb_cObject);
90
113
  rb_define_alloc_func(cDuckDBPendingResult, allocate);
91
114
 
@@ -9,5 +9,5 @@ struct _rubyDuckDBPendingResult {
9
9
  typedef struct _rubyDuckDBPendingResult rubyDuckDBPendingResult;
10
10
 
11
11
  rubyDuckDBPendingResult *get_struct_pending_result(VALUE obj);
12
- void init_duckdb_pending_result(void);
12
+ void rbduckdb_init_duckdb_pending_result(void);
13
13
  #endif
@@ -83,7 +83,7 @@ static VALUE duckdb_prepared_statement_nparams(VALUE self) {
83
83
  static VALUE duckdb_prepared_statement_execute(VALUE self) {
84
84
  rubyDuckDBPreparedStatement *ctx;
85
85
  rubyDuckDBResult *ctxr;
86
- VALUE result = create_result();
86
+ VALUE result = rbduckdb_create_result();
87
87
 
88
88
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
89
89
  ctxr = get_struct_result(result);
@@ -268,7 +268,7 @@ static VALUE duckdb_prepared_statement__bind_date(VALUE self, VALUE vidx, VALUE
268
268
  duckdb_date dt;
269
269
  idx_t idx = check_index(vidx);
270
270
 
271
- dt = to_duckdb_date_from_value(year, month, day);
271
+ dt = rbduckdb_to_duckdb_date_from_value(year, month, day);
272
272
 
273
273
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
274
274
 
@@ -285,7 +285,7 @@ static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE
285
285
 
286
286
  idx_t idx = check_index(vidx);
287
287
 
288
- time = to_duckdb_time_from_value(hour, min, sec, micros);
288
+ time = rbduckdb_to_duckdb_time_from_value(hour, min, sec, micros);
289
289
 
290
290
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
291
291
 
@@ -301,7 +301,7 @@ static VALUE duckdb_prepared_statement__bind_timestamp(VALUE self, VALUE vidx, V
301
301
  rubyDuckDBPreparedStatement *ctx;
302
302
  idx_t idx = check_index(vidx);
303
303
 
304
- timestamp = to_duckdb_timestamp_from_value(year, month, day, hour, min, sec, micros);
304
+ timestamp = rbduckdb_to_duckdb_timestamp_from_value(year, month, day, hour, min, sec, micros);
305
305
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
306
306
 
307
307
  if (duckdb_bind_timestamp(ctx->prepared_statement, idx, timestamp) == DuckDBError) {
@@ -317,7 +317,7 @@ static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VA
317
317
 
318
318
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
319
319
 
320
- to_duckdb_interval_from_value(&interval, months, days, micros);
320
+ rbduckdb_to_duckdb_interval_from_value(&interval, months, days, micros);
321
321
 
322
322
  if (duckdb_bind_interval(ctx->prepared_statement, idx, interval) == DuckDBError) {
323
323
  rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx);
@@ -347,7 +347,7 @@ rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self) {
347
347
  return ctx;
348
348
  }
349
349
 
350
- void init_duckdb_prepared_statement(void) {
350
+ void rbduckdb_init_duckdb_prepared_statement(void) {
351
351
  cDuckDBPreparedStatement = rb_define_class_under(mDuckDB, "PreparedStatement", rb_cObject);
352
352
 
353
353
  rb_define_alloc_func(cDuckDBPreparedStatement, allocate);
@@ -9,6 +9,6 @@ struct _rubyDuckDBPreparedStatement {
9
9
  typedef struct _rubyDuckDBPreparedStatement rubyDuckDBPreparedStatement;
10
10
 
11
11
  rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self);
12
- void init_duckdb_prepared_statement(void);
12
+ void rbduckdb_init_duckdb_prepared_statement(void);
13
13
 
14
14
  #endif
data/ext/duckdb/result.c CHANGED
@@ -229,7 +229,7 @@ static VALUE duckdb_result_columns(VALUE oDuckDBResult) {
229
229
 
230
230
  VALUE ary = rb_ary_new2(column_count);
231
231
  for(col_idx = 0; col_idx < column_count; col_idx++) {
232
- VALUE column = create_column(oDuckDBResult, col_idx);
232
+ VALUE column = rbduckdb_create_column(oDuckDBResult, col_idx);
233
233
  rb_ary_store(ary, col_idx, column);
234
234
  }
235
235
  return ary;
@@ -397,7 +397,7 @@ static VALUE duckdb_result__enum_dictionary_value(VALUE oDuckDBResult, VALUE col
397
397
  return value;
398
398
  }
399
399
 
400
- VALUE create_result(void) {
400
+ VALUE rbduckdb_create_result(void) {
401
401
  return allocate(cDuckDBResult);
402
402
  }
403
403
 
@@ -717,7 +717,7 @@ static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult) {
717
717
  return Qnil;
718
718
  }
719
719
 
720
- void init_duckdb_result(void) {
720
+ void rbduckdb_init_duckdb_result(void) {
721
721
  cDuckDBResult = rb_define_class_under(mDuckDB, "Result", rb_cObject);
722
722
  rb_define_alloc_func(cDuckDBResult, allocate);
723
723
 
data/ext/duckdb/result.h CHANGED
@@ -8,8 +8,8 @@ struct _rubyDuckDBResult {
8
8
  typedef struct _rubyDuckDBResult rubyDuckDBResult;
9
9
 
10
10
  rubyDuckDBResult *get_struct_result(VALUE obj);
11
- void init_duckdb_result(void);
12
- VALUE create_result(void);
11
+ void rbduckdb_init_duckdb_result(void);
12
+ VALUE rbduckdb_create_result(void);
13
13
 
14
14
  #endif
15
15
 
data/ext/duckdb/util.c CHANGED
@@ -1,6 +1,6 @@
1
1
  #include "ruby-duckdb.h"
2
2
 
3
- duckdb_date to_duckdb_date_from_value(VALUE year, VALUE month, VALUE day) {
3
+ duckdb_date rbduckdb_to_duckdb_date_from_value(VALUE year, VALUE month, VALUE day) {
4
4
  duckdb_date_struct dt_struct;
5
5
 
6
6
  dt_struct.year = NUM2INT(year);
@@ -10,7 +10,7 @@ duckdb_date to_duckdb_date_from_value(VALUE year, VALUE month, VALUE day) {
10
10
  return duckdb_to_date(dt_struct);
11
11
  }
12
12
 
13
- duckdb_time to_duckdb_time_from_value(VALUE hour, VALUE min, VALUE sec, VALUE micros) {
13
+ duckdb_time rbduckdb_to_duckdb_time_from_value(VALUE hour, VALUE min, VALUE sec, VALUE micros) {
14
14
  duckdb_time_struct time_st;
15
15
 
16
16
  time_st.hour = NUM2INT(hour);
@@ -21,7 +21,7 @@ duckdb_time to_duckdb_time_from_value(VALUE hour, VALUE min, VALUE sec, VALUE mi
21
21
  return duckdb_to_time(time_st);
22
22
  }
23
23
 
24
- duckdb_timestamp to_duckdb_timestamp_from_value(VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros) {
24
+ duckdb_timestamp rbduckdb_to_duckdb_timestamp_from_value(VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros) {
25
25
  duckdb_timestamp_struct timestamp_st;
26
26
 
27
27
  timestamp_st.date.year = NUM2INT(year);
@@ -35,7 +35,7 @@ duckdb_timestamp to_duckdb_timestamp_from_value(VALUE year, VALUE month, VALUE d
35
35
  return duckdb_to_timestamp(timestamp_st);
36
36
  }
37
37
 
38
- void to_duckdb_interval_from_value(duckdb_interval* interval, VALUE months, VALUE days, VALUE micros) {
38
+ void rbduckdb_to_duckdb_interval_from_value(duckdb_interval* interval, VALUE months, VALUE days, VALUE micros) {
39
39
  interval->months = NUM2INT(months);
40
40
  interval->days = NUM2INT(days);
41
41
  interval->micros = NUM2LL(micros);
data/ext/duckdb/util.h CHANGED
@@ -1,9 +1,9 @@
1
1
  #ifndef RUBY_DUCKDB_UTIL_H
2
2
  #define RUBY_DUCKDB_UTIL_H
3
3
 
4
- duckdb_date to_duckdb_date_from_value(VALUE year, VALUE month, VALUE day);
5
- duckdb_time to_duckdb_time_from_value(VALUE hour, VALUE min, VALUE sec, VALUE micros);
6
- duckdb_timestamp to_duckdb_timestamp_from_value(VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros);
7
- void to_duckdb_interval_from_value(duckdb_interval* interval, VALUE months, VALUE days, VALUE micros);
4
+ duckdb_date rbduckdb_to_duckdb_date_from_value(VALUE year, VALUE month, VALUE day);
5
+ duckdb_time rbduckdb_to_duckdb_time_from_value(VALUE hour, VALUE min, VALUE sec, VALUE micros);
6
+ duckdb_timestamp rbduckdb_to_duckdb_timestamp_from_value(VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros);
7
+ void rbduckdb_to_duckdb_interval_from_value(duckdb_interval* interval, VALUE months, VALUE days, VALUE micros);
8
8
 
9
9
  #endif
@@ -86,16 +86,7 @@ module DuckDB
86
86
  # appender.flush
87
87
  #
88
88
  def append_time(value)
89
- time = case value
90
- when Time
91
- value
92
- else
93
- begin
94
- Time.parse(value)
95
- rescue
96
- raise(ArgumentError, "Cannot parse argument `#{value}` to Time.")
97
- end
98
- end
89
+ time = _parse_time(value)
99
90
 
100
91
  _append_time(time.hour, time.min, time.sec, time.usec)
101
92
  end
@@ -25,19 +25,38 @@ module DuckDB
25
25
  # sql = 'SELECT * FROM users WHERE name = $name AND email = $email'
26
26
  # dave = con.query(sql, name: 'Dave', email: 'dave@example.com')
27
27
  #
28
- def query(sql, *args, **hash)
29
- return query_sql(sql) if args.empty? && hash.empty?
28
+ def query(sql, *args, **kwargs)
29
+ return query_sql(sql) if args.empty? && kwargs.empty?
30
30
 
31
31
  stmt = PreparedStatement.new(self, sql)
32
- args.each.with_index(1) do |arg, i|
33
- stmt.bind(i, arg)
34
- end
35
- hash.each do |key, value|
36
- stmt.bind(key, value)
37
- end
32
+ stmt.bind_args(*args, **kwargs)
38
33
  stmt.execute
39
34
  end
40
35
 
36
+ #
37
+ # executes sql with args asynchronously.
38
+ # The first argument sql must be SQL string.
39
+ # The rest arguments are parameters of SQL string.
40
+ # This method returns DuckDB::PendingResult object.
41
+ #
42
+ # require 'duckdb'
43
+ # db = DuckDB::Database.open('duckdb_file')
44
+ # con = db.connect
45
+ # pending_result = con.async_query('SELECT * FROM users')
46
+ # sql = 'SELECT * FROM users WHERE name = ? AND email = ?'
47
+ # pending_result = con.async_query(sql, 'Dave', 'dave@example.com')
48
+ #
49
+ # # or You can use named parameter.
50
+ #
51
+ # sql = 'SELECT * FROM users WHERE name = $name AND email = $email'
52
+ # pending_result = con.async_query(sql, name: 'Dave', email: 'dave@example.com')
53
+ #
54
+ def async_query(sql, *args, **kwargs)
55
+ stmt = PreparedStatement.new(self, sql)
56
+ stmt.bind_args(*args, **kwargs)
57
+ stmt.pending_prepared
58
+ end
59
+
41
60
  #
42
61
  # connects DuckDB database
43
62
  # The first argument is DuckDB::Database object
@@ -83,6 +102,7 @@ module DuckDB
83
102
  end
84
103
 
85
104
  alias execute query
105
+ alias async_execute async_query
86
106
  alias open connect
87
107
  alias close disconnect
88
108
  end
@@ -42,6 +42,32 @@ module DuckDB
42
42
  "#{str[0, 8]}-#{str[8, 4]}-#{str[12, 4]}-#{str[16, 4]}-#{str[20, 12]}"
43
43
  end
44
44
 
45
+ def _parse_date(value)
46
+ case value
47
+ when Date, Time
48
+ value
49
+ else
50
+ begin
51
+ Date.parse(value)
52
+ rescue StandardError => e
53
+ raise(ArgumentError, "Cannot parse `#{value.inspect}` to Date object. #{e.message}")
54
+ end
55
+ end
56
+ end
57
+
58
+ def _parse_time(value)
59
+ case value
60
+ when Time
61
+ value
62
+ else
63
+ begin
64
+ Time.parse(value)
65
+ rescue StandardError => e
66
+ raise(ArgumentError, "Cannot parse `#{value.inspect}` to Time object. #{e.message}")
67
+ end
68
+ end
69
+ end
70
+
45
71
  private
46
72
 
47
73
  def integer_to_hugeint(value)
@@ -51,7 +77,7 @@ module DuckDB
51
77
  lower = value - (upper << HALF_HUGEINT_BIT)
52
78
  [lower, upper]
53
79
  else
54
- raise(ArgumentError, "The argument `#{value}` must be Integer.")
80
+ raise(ArgumentError, "The argument `#{value.inspect}` must be Integer.")
55
81
  end
56
82
  end
57
83
  end
@@ -24,21 +24,43 @@ module DuckDB
24
24
  PendingResult.new(self)
25
25
  end
26
26
 
27
+ # binds all parameters with SQL prepared statement.
28
+ #
29
+ # require 'duckdb'
30
+ # db = DuckDB::Database.open('duckdb_database')
31
+ # con = db.connect
32
+ # sql ='SELECT name FROM users WHERE id = ?'
33
+ # # or
34
+ # # sql ='SELECT name FROM users WHERE id = $id'
35
+ # stmt = PreparedStatement.new(con, sql)
36
+ # stmt.bind_args([1])
37
+ # # or
38
+ # # stmt.bind_args(id: 1)
39
+ def bind_args(*args, **kwargs)
40
+ args.each.with_index(1) do |arg, i|
41
+ bind(i, arg)
42
+ end
43
+ kwargs.each do |key, value|
44
+ bind(key, value)
45
+ end
46
+ end
47
+
27
48
  # binds i-th parameter with SQL prepared statement.
28
49
  # The first argument is index of parameter.
29
50
  # The index of first parameter is 1 not 0.
30
51
  # The second argument value is to expected Integer value.
31
52
  # This method uses bind_varchar internally.
53
+ #
32
54
  # require 'duckdb'
33
55
  # db = DuckDB::Database.open('duckdb_database')
34
56
  # con = db.connect
35
57
  # sql ='SELECT name FROM users WHERE bigint_col = ?'
36
58
  # stmt = PreparedStatement.new(con, sql)
37
59
  # stmt.bind_hugeint(1, 1_234_567_890_123_456_789_012_345)
38
- def bind_hugeint(i, value)
60
+ def bind_hugeint(index, value)
39
61
  case value
40
62
  when Integer
41
- bind_varchar(i, value.to_s)
63
+ bind_varchar(index, value.to_s)
42
64
  else
43
65
  raise(ArgumentError, "2nd argument `#{value}` must be Integer.")
44
66
  end
@@ -49,6 +71,7 @@ module DuckDB
49
71
  # The index of first parameter is 1 not 0.
50
72
  # The second argument value must be Integer value.
51
73
  # This method uses duckdb_bind_hugeint internally.
74
+ #
52
75
  # require 'duckdb'
53
76
  # db = DuckDB::Database.open('duckdb_database')
54
77
  # con = db.connect
@@ -73,19 +96,10 @@ module DuckDB
73
96
  # stmt.bind(1, Date.today)
74
97
  # # or you can specify date string.
75
98
  # # stmt.bind(1, '2021-02-23')
76
- def bind_date(i, value)
77
- case value
78
- when Date, Time
79
- date = value
80
- else
81
- begin
82
- date = Date.parse(value)
83
- rescue => e
84
- raise(ArgumentError, "Cannot parse argument value to date. #{e.message}")
85
- end
86
- end
99
+ def bind_date(index, value)
100
+ date = _parse_date(value)
87
101
 
88
- _bind_date(i, date.year, date.month, date.day)
102
+ _bind_date(index, date.year, date.month, date.day)
89
103
  end
90
104
 
91
105
  # binds i-th parameter with SQL prepared statement.
@@ -101,19 +115,10 @@ module DuckDB
101
115
  # stmt.bind(1, Time.now)
102
116
  # # or you can specify time string.
103
117
  # # stmt.bind(1, '07:39:45')
104
- def bind_time(i, value)
105
- case value
106
- when Time
107
- time = value
108
- else
109
- begin
110
- time = Time.parse(value)
111
- rescue => e
112
- raise(ArgumentError, "Cannot parse argument value to time. #{e.message}")
113
- end
114
- end
118
+ def bind_time(index, value)
119
+ time = _parse_time(value)
115
120
 
116
- _bind_time(i, time.hour, time.min, time.sec, time.usec)
121
+ _bind_time(index, time.hour, time.min, time.sec, time.usec)
117
122
  end
118
123
 
119
124
  # binds i-th parameter with SQL prepared statement.
@@ -129,19 +134,10 @@ module DuckDB
129
134
  # stmt.bind(1, Time.now)
130
135
  # # or you can specify timestamp string.
131
136
  # # stmt.bind(1, '2022-02-23 07:39:45')
132
- def bind_timestamp(i, value)
133
- case value
134
- when Time
135
- time = value
136
- else
137
- begin
138
- time = Time.parse(value)
139
- rescue => e
140
- raise(ArgumentError, "Cannot parse argument value to time. #{e.message}")
141
- end
142
- end
137
+ def bind_timestamp(index, value)
138
+ time = _parse_time(value)
143
139
 
144
- _bind_timestamp(i, time.year, time.month, time.day, time.hour, time.min, time.sec, time.usec)
140
+ _bind_timestamp(index, time.year, time.month, time.day, time.hour, time.min, time.sec, time.usec)
145
141
  end
146
142
 
147
143
  # binds i-th parameter with SQL prepared statement.
@@ -155,9 +151,9 @@ module DuckDB
155
151
  # sql ='SELECT value FROM intervals WHERE interval = ?'
156
152
  # stmt = PreparedStatement.new(con, sql)
157
153
  # stmt.bind(1, 'P1Y2D')
158
- def bind_interval(i, value)
154
+ def bind_interval(index, value)
159
155
  value = Interval.to_interval(value)
160
- _bind_interval(i, value.interval_months, value.interval_days, value.interval_micros)
156
+ _bind_interval(index, value.interval_months, value.interval_days, value.interval_micros)
161
157
  end
162
158
 
163
159
  # binds i-th parameter with SQL prepared statement.
@@ -3,5 +3,5 @@
3
3
  module DuckDB
4
4
  # The version string of ruby-duckdb.
5
5
  # Currently, ruby-duckdb is NOT semantic versioning.
6
- VERSION = '0.9.1.1'
6
+ VERSION = '0.9.1.2'
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duckdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1.1
4
+ version: 0.9.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaki Suketa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-28 00:00:00.000000000 Z
11
+ date: 2023-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler