duckdb 1.1.1.0 → 1.1.2.1

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: 84935b6317fa4bef4b62197645f061b179e3358e93cba3b976672eb1988715fc
4
- data.tar.gz: 7ff6b2f4b46ea16bcfa2e7de486e9a5bb30aa7d4dccb14e32af7b9886d6fcac4
3
+ metadata.gz: f326104e9d96a1fce6a508d481101c37eca2b12a421eb2ddb07acb838f14c118
4
+ data.tar.gz: 999db21104bb772564ecb41bbc2fee06d728f65618bb8538d14bc20c22173424
5
5
  SHA512:
6
- metadata.gz: d90dbdbf57d5cc282049f6297d00674ff57d9fafbfd7bfab8db8c87fb1153d3c9ea93ceda3b440d066c24ceef5dd1e349dedea6f4b17557bda590bb92f93fc5a
7
- data.tar.gz: cbcbd5c50c6ddc92c01001b36cbe5aad8a87729ea5518a881dcf8c21621679d1c3740c0ed97672d597aca351ea09548d6f7b5e722fde32077cb811a57c3dfd40
6
+ metadata.gz: 6cb7f30f39a2b768d1d6441e324f2c86f910f7af2cff9ca403b91eeb13cacbc0bee56dc54d3786f58e27af9276ae91d4a2ce22c705727b0c8ef5cd3251ab83fe
7
+ data.tar.gz: f17ea13a5aca9640e17e8983a37f9ba88e6ace381d5ad7e979232b0158028b92aa07ddea758ffdd9868511fb2b868354f7f15c20d6c14fb4f2e537613f8ee670
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: macos-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['3.1.6', '3.2.5', '3.3.5', '3.4.0-preview1', 'head']
19
- duckdb: ['1.1.1', '1.1.0', '1.0.0']
18
+ ruby: ['3.1.6', '3.2.5', '3.3.5', '3.4.0-preview2', 'head']
19
+ duckdb: ['1.1.2', '1.1.1', '1.0.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v4
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: ubuntu-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['3.1.6', '3.2.5', '3.3.5', '3.4.0-preview1', 'head']
19
- duckdb: ['1.1.1', '1.1.0', '1.0.0']
18
+ ruby: ['3.1.6', '3.2.5', '3.3.5', '3.4.0-preview2', 'head']
19
+ duckdb: ['1.1.2', '1.1.1', '1.0.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v4
@@ -16,7 +16,7 @@ jobs:
16
16
  strategy:
17
17
  matrix:
18
18
  ruby: ['3.1.6', '3.2.5', '3.3.5', 'ucrt', 'mingw', 'mswin', 'head']
19
- duckdb: ['1.1.1', '1.1.0', '1.0.0']
19
+ duckdb: ['1.1.2', '1.1.1', '1.0.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v4
data/.gitignore CHANGED
@@ -15,3 +15,4 @@
15
15
  *.obj
16
16
  *.so
17
17
  Makefile
18
+ ng_test
data/CHANGELOG.md CHANGED
@@ -3,8 +3,29 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  # Unreleased
5
5
 
6
+ # 1.1.2.1 - 2024-11-04
7
+ - `DuckDB::Connection#query` accepts multiple SQL statement.
8
+ - When multiple SQL statements are given, `DuckDB::Connection#query` returns the last statement result.
9
+ - `DuckDB::Connection#query` does not support multiple SQL statements with bind parameters. If you pass 2 or more argument,
10
+ `DuckDB::Connection#query` will regard first argument as only one SQL statement and the rest as bind parameters.
11
+ - add `DuckDB::ExtracteStatements#each` method.
12
+ - add `DuckDB::ExtracteStatementsImpl#destroy` method.
13
+ - add `DuckDB::PreparedStatement#prepare`.
14
+ - `DuckDB::Connection#prepared_statement` accepts block and calls `PreparedStatement#destroy` after block executed.
15
+ ```ruby
16
+ con.prepared_statement('SELECT * FROM table WHERE id = ?') do |stmt|
17
+ stmt.bind(1)
18
+ stmt.execute
19
+ end
20
+ ```
21
+ # 1.1.2.0 - 2024-10-20
22
+ - bump duckdb to 1.1.2.
23
+ - add `DuckDB::PreparedStatement#destroy`.
24
+ - `DuckDB::Connection#query`, `DuckDB::Connection#async_query`, `DuckDB::Connection#async_query_stream` call
25
+ `DuckDB::PreparedStatement#destroy` to free the prepared statement immediately (#775, #781).
26
+
6
27
  # 1.1.1.0 - 2024-10-06
7
- - bump duckdb 1.1.1.
28
+ - bump duckdb to 1.1.1.
8
29
  ## Breaking changes
9
30
  - drop duckdb v0.10.x.
10
31
 
data/CONTRIBUTION.md CHANGED
@@ -14,7 +14,7 @@ docker compose run --rm ubuntu bash
14
14
 
15
15
  In case you want custom ruby or duckdb versions, use `--build-arg` options
16
16
  ```
17
- docker-compose build ubuntu --build-arg RUBY_VERSION=3.1.3 --build-arg DUCKDB_VERSION=0.6.0
17
+ docker compose build ubuntu --build-arg RUBY_VERSION=3.1.3 --build-arg DUCKDB_VERSION=1.0.0
18
18
  ```
19
19
 
20
20
  ### Without docker
data/Dockerfile CHANGED
@@ -1,7 +1,7 @@
1
1
  ARG RUBY_VERSION=3.3.5
2
2
  FROM ruby:${RUBY_VERSION}
3
3
 
4
- ARG DUCKDB_VERSION=1.1.1
4
+ ARG DUCKDB_VERSION=1.1.2
5
5
 
6
6
  RUN apt update -qq && \
7
7
  apt install -y build-essential curl git wget
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in duckdb.gemspec
4
4
  gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (1.1.1.0)
4
+ duckdb (1.1.2.1)
5
5
  bigdecimal (>= 3.1.4)
6
6
 
7
7
  GEM
@@ -17,6 +17,7 @@ static VALUE allocate(VALUE klass);
17
17
  static size_t memsize(const void *p);
18
18
 
19
19
  static VALUE duckdb_extracted_statements_initialize(VALUE self, VALUE con, VALUE query);
20
+ static VALUE duckdb_extracted_statements_destroy(VALUE self);
20
21
  static VALUE duckdb_extracted_statements_size(VALUE self);
21
22
  static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE con, VALUE index);
22
23
 
@@ -56,12 +57,22 @@ static VALUE duckdb_extracted_statements_initialize(VALUE self, VALUE con, VALUE
56
57
 
57
58
  if (ctx->num_statements == 0) {
58
59
  error = duckdb_extract_statements_error(ctx->extracted_statements);
59
- rb_raise(eDuckDBError, "%s", error);
60
+ rb_raise(eDuckDBError, "%s", error ? error : "Failed to extract statements(Database connection closed?).");
60
61
  }
61
62
 
62
63
  return self;
63
64
  }
64
65
 
66
+ static VALUE duckdb_extracted_statements_destroy(VALUE self) {
67
+ rubyDuckDBExtractedStatements *ctx;
68
+
69
+ TypedData_Get_Struct(self, rubyDuckDBExtractedStatements, &extract_statements_data_type, ctx);
70
+
71
+ duckdb_destroy_extracted(&(ctx->extracted_statements));
72
+
73
+ return Qnil;
74
+ }
75
+
65
76
  static VALUE duckdb_extracted_statements_size(VALUE self) {
66
77
  rubyDuckDBExtractedStatements *ctx;
67
78
 
@@ -85,10 +96,11 @@ static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE co
85
96
  }
86
97
 
87
98
  void rbduckdb_init_duckdb_extracted_statements(void) {
88
- cDuckDBExtractedStatements = rb_define_class_under(mDuckDB, "ExtractedStatements", rb_cObject);
99
+ cDuckDBExtractedStatements = rb_define_class_under(mDuckDB, "ExtractedStatementsImpl", rb_cObject);
89
100
 
90
101
  rb_define_alloc_func(cDuckDBExtractedStatements, allocate);
91
102
  rb_define_method(cDuckDBExtractedStatements, "initialize", duckdb_extracted_statements_initialize, 2);
103
+ rb_define_method(cDuckDBExtractedStatements, "destroy", duckdb_extracted_statements_destroy, 0);
92
104
  rb_define_method(cDuckDBExtractedStatements, "size", duckdb_extracted_statements_size, 0);
93
105
  rb_define_method(cDuckDBExtractedStatements, "prepared_statement", duckdb_extracted_statements_prepared_statement, 2);
94
106
  }
@@ -2,12 +2,14 @@
2
2
 
3
3
  VALUE cDuckDBPreparedStatement;
4
4
 
5
+ static void destroy_prepared_statement(rubyDuckDBPreparedStatement *p);
5
6
  static void deallocate(void *ctx);
6
7
  static VALUE allocate(VALUE klass);
7
8
  static size_t memsize(const void *p);
8
9
  static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE query);
9
10
  static VALUE duckdb_prepared_statement_nparams(VALUE self);
10
11
  static VALUE duckdb_prepared_statement_execute(VALUE self);
12
+ static VALUE duckdb_prepared_statement_destroy(VALUE self);
11
13
  static idx_t check_index(VALUE vidx);
12
14
 
13
15
  static VALUE duckdb_prepared_statement_bind_parameter_index(VALUE self, VALUE name);
@@ -30,6 +32,7 @@ static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE
30
32
  static VALUE duckdb_prepared_statement__bind_timestamp(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros);
31
33
  static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VALUE months, VALUE days, VALUE micros);
32
34
  static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper);
35
+ static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale);
33
36
 
34
37
  static const rb_data_type_t prepared_statement_data_type = {
35
38
  "DuckDB/PreparedStatement",
@@ -37,10 +40,17 @@ static const rb_data_type_t prepared_statement_data_type = {
37
40
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY
38
41
  };
39
42
 
43
+ static void destroy_prepared_statement(rubyDuckDBPreparedStatement *p) {
44
+ if (p->prepared_statement) {
45
+ duckdb_destroy_prepare(&(p->prepared_statement));
46
+ }
47
+ }
48
+
40
49
  static void deallocate(void *ctx) {
41
50
  rubyDuckDBPreparedStatement *p = (rubyDuckDBPreparedStatement *)ctx;
42
51
 
43
- duckdb_destroy_prepare(&(p->prepared_statement));
52
+ destroy_prepared_statement(p);
53
+ // duckdb_destroy_prepare(&(p->prepared_statement));
44
54
  xfree(p);
45
55
  }
46
56
 
@@ -62,7 +72,7 @@ VALUE rbduckdb_prepared_statement_new(duckdb_connection con, duckdb_extracted_st
62
72
  TypedData_Get_Struct(obj, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
63
73
 
64
74
  if (duckdb_prepare_extracted_statement(con, extracted_statements, index, &(ctx->prepared_statement)) == DuckDBError) {
65
- rb_raise(eDuckDBError, "Fail to get DuckDB::PreparedStatement object from ExtractedStatements object");
75
+ rb_raise(eDuckDBError, "Failed to create DuckDB::PreparedStatement object.");
66
76
  }
67
77
  return obj;
68
78
  }
@@ -91,20 +101,37 @@ static VALUE duckdb_prepared_statement_nparams(VALUE self) {
91
101
  return ULL2NUM(duckdb_nparams(ctx->prepared_statement));
92
102
  }
93
103
 
94
-
95
104
  static VALUE duckdb_prepared_statement_execute(VALUE self) {
96
105
  rubyDuckDBPreparedStatement *ctx;
97
106
  rubyDuckDBResult *ctxr;
98
107
  VALUE result = rbduckdb_create_result();
108
+ const char *p = NULL;
99
109
 
100
110
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
101
111
  ctxr = get_struct_result(result);
102
112
  if (duckdb_execute_prepared(ctx->prepared_statement, &(ctxr->result)) == DuckDBError) {
103
- rb_raise(eDuckDBError, "%s", duckdb_result_error(&(ctxr->result)));
113
+ p = duckdb_result_error(&(ctxr->result));
114
+ if (p == NULL) {
115
+ p = duckdb_prepare_error(ctx->prepared_statement);
116
+ }
117
+ rb_raise(eDuckDBError, "%s", p ? p : "Failed to execute prepared statement.");
104
118
  }
105
119
  return result;
106
120
  }
107
121
 
122
+ /*
123
+ * :nodoc:
124
+ */
125
+ static VALUE duckdb_prepared_statement_destroy(VALUE self) {
126
+ rubyDuckDBPreparedStatement *ctx;
127
+ TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
128
+ destroy_prepared_statement(ctx);
129
+ /*
130
+ ctx->prepared_statement = NULL;
131
+ */
132
+ return Qnil;
133
+ }
134
+
108
135
  static idx_t check_index(VALUE vidx) {
109
136
  idx_t idx = NUM2ULL(vidx);
110
137
  if (idx <= 0) {
@@ -378,6 +405,26 @@ static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VAL
378
405
  return self;
379
406
  }
380
407
 
408
+ static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale) {
409
+ duckdb_hugeint hugeint;
410
+ duckdb_decimal decimal;
411
+ rubyDuckDBPreparedStatement *ctx;
412
+ idx_t idx = check_index(vidx);
413
+
414
+ TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
415
+ hugeint.lower = NUM2ULL(lower);
416
+ hugeint.upper = NUM2LL(upper);
417
+ decimal.value = hugeint;
418
+ decimal.width = (uint8_t)NUM2UINT(width);
419
+ decimal.scale = (uint8_t)NUM2UINT(scale);
420
+
421
+ if (duckdb_bind_decimal(ctx->prepared_statement, idx, decimal) == DuckDBError) {
422
+ rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx);
423
+ }
424
+
425
+ return self;
426
+ }
427
+
381
428
  rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self) {
382
429
  rubyDuckDBPreparedStatement *ctx;
383
430
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
@@ -391,6 +438,7 @@ void rbduckdb_init_duckdb_prepared_statement(void) {
391
438
 
392
439
  rb_define_method(cDuckDBPreparedStatement, "initialize", duckdb_prepared_statement_initialize, 2);
393
440
  rb_define_method(cDuckDBPreparedStatement, "execute", duckdb_prepared_statement_execute, 0);
441
+ rb_define_method(cDuckDBPreparedStatement, "destroy", duckdb_prepared_statement_destroy, 0);
394
442
  rb_define_method(cDuckDBPreparedStatement, "nparams", duckdb_prepared_statement_nparams, 0);
395
443
  rb_define_method(cDuckDBPreparedStatement, "bind_parameter_index", duckdb_prepared_statement_bind_parameter_index, 1);
396
444
  rb_define_method(cDuckDBPreparedStatement, "parameter_name", duckdb_prepared_statement_parameter_name, 1);
@@ -412,4 +460,5 @@ void rbduckdb_init_duckdb_prepared_statement(void) {
412
460
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_timestamp", duckdb_prepared_statement__bind_timestamp, 8);
413
461
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_interval", duckdb_prepared_statement__bind_interval, 4);
414
462
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_hugeint", duckdb_prepared_statement__bind_hugeint, 3);
463
+ rb_define_private_method(cDuckDBPreparedStatement, "_bind_decimal", duckdb_prepared_statement__bind_decimal, 5);
415
464
  }
@@ -74,16 +74,7 @@ module DuckDB
74
74
  # appender.flush
75
75
  #
76
76
  def append_date(value)
77
- date = case value
78
- when Date, Time
79
- value
80
- else
81
- begin
82
- Date.parse(value)
83
- rescue
84
- raise(ArgumentError, "Cannot parse argument `#{value}` to Date.")
85
- end
86
- end
77
+ date = to_date(value)
87
78
 
88
79
  _append_date(date.year, date.month, date.day)
89
80
  end
@@ -126,18 +117,7 @@ module DuckDB
126
117
  # appender.flush
127
118
  #
128
119
  def append_timestamp(value)
129
- time = case value
130
- when Time
131
- value
132
- when Date
133
- value.to_time
134
- else
135
- begin
136
- Time.parse(value)
137
- rescue
138
- raise(ArgumentError, "Cannot parse argument `#{value}` to Time or Date.")
139
- end
140
- end
120
+ time = to_time(value)
141
121
 
142
122
  _append_timestamp(time.year, time.month, time.day, time.hour, time.min, time.sec, time.nsec / 1000)
143
123
  end
@@ -233,5 +213,33 @@ module DuckDB
233
213
  def blob?(value)
234
214
  value.instance_of?(DuckDB::Blob) || value.encoding == Encoding::BINARY
235
215
  end
216
+
217
+ def to_date(value)
218
+ case value
219
+ when Date, Time
220
+ value
221
+ else
222
+ begin
223
+ Date.parse(value)
224
+ rescue StandardError
225
+ raise(ArgumentError, "Cannot parse argument `#{value}` to Date.")
226
+ end
227
+ end
228
+ end
229
+
230
+ def to_time(value)
231
+ case value
232
+ when Time
233
+ value
234
+ when Date
235
+ value.to_time
236
+ else
237
+ begin
238
+ Time.parse(value)
239
+ rescue StandardError
240
+ raise(ArgumentError, "Cannot parse argument `#{value}` to Time or Date.")
241
+ end
242
+ end
243
+ end
236
244
  end
237
245
  end
@@ -26,11 +26,23 @@ module DuckDB
26
26
  # dave = con.query(sql, name: 'Dave', email: 'dave@example.com')
27
27
  #
28
28
  def query(sql, *args, **kwargs)
29
- return query_sql(sql) if args.empty? && kwargs.empty?
29
+ return query_multi_sql(sql) if args.empty? && kwargs.empty?
30
30
 
31
- stmt = PreparedStatement.new(self, sql)
32
- stmt.bind_args(*args, **kwargs)
33
- stmt.execute
31
+ prepare(sql) do |stmt|
32
+ stmt.bind_args(*args, **kwargs)
33
+ stmt.execute
34
+ end
35
+ end
36
+
37
+ def query_multi_sql(sql)
38
+ stmts = ExtractedStatements.new(self, sql)
39
+ result = nil
40
+ stmts.each do |stmt|
41
+ result = stmt.execute
42
+ end
43
+ result
44
+ ensure
45
+ stmts&.destroy
34
46
  end
35
47
 
36
48
  #
@@ -50,9 +62,10 @@ module DuckDB
50
62
  # result.each.first
51
63
  #
52
64
  def async_query(sql, *args, **kwargs)
53
- stmt = PreparedStatement.new(self, sql)
54
- stmt.bind_args(*args, **kwargs)
55
- stmt.pending_prepared
65
+ prepare(sql) do |stmt|
66
+ stmt.bind_args(*args, **kwargs)
67
+ stmt.pending_prepared
68
+ end
56
69
  end
57
70
 
58
71
  #
@@ -73,9 +86,10 @@ module DuckDB
73
86
  # result.each.first
74
87
  #
75
88
  def async_query_stream(sql, *args, **kwargs)
76
- stmt = PreparedStatement.new(self, sql)
77
- stmt.bind_args(*args, **kwargs)
78
- stmt.pending_prepared_stream
89
+ prepare(sql) do |stmt|
90
+ stmt.bind_args(*args, **kwargs)
91
+ stmt.pending_prepared_stream
92
+ end
79
93
  end
80
94
 
81
95
  #
@@ -96,6 +110,8 @@ module DuckDB
96
110
  #
97
111
  # returns PreparedStatement object.
98
112
  # The first argument is SQL string.
113
+ # If block is given, the block is executed with PreparedStatement object
114
+ # and the object is cleaned up immediately.
99
115
  #
100
116
  # require 'duckdb'
101
117
  # db = DuckDB::Database.open('duckdb_file')
@@ -105,8 +121,17 @@ module DuckDB
105
121
  # stmt = con.prepared_statement(sql)
106
122
  # stmt.bind_args(name: 'Dave', email: 'dave@example.com')
107
123
  # result = stmt.execute
108
- def prepared_statement(str)
109
- PreparedStatement.new(self, str)
124
+ #
125
+ # # or
126
+ # result = con.prepared_statement(sql) do |stmt|
127
+ # stmt.bind_args(name: 'Dave', email: 'dave@example.com')
128
+ # stmt.execute
129
+ # end
130
+ #
131
+ def prepared_statement(str, &)
132
+ return PreparedStatement.new(self, str) unless block_given?
133
+
134
+ PreparedStatement.prepare(self, str, &)
110
135
  end
111
136
 
112
137
  #
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DuckDB
4
+ class ExtractedStatements < ExtractedStatementsImpl
5
+ include Enumerable
6
+
7
+ def initialize(con, sql)
8
+ @con = con
9
+ super(con, sql)
10
+ end
11
+
12
+ def each
13
+ return to_enum(__method__) { size } unless block_given?
14
+
15
+ size.times do |i|
16
+ yield prepared_statement(@con, i)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -22,6 +22,31 @@ module DuckDB
22
22
  RANGE_INT32 = -2_147_483_648..2_147_483_647
23
23
  RANGE_INT64 = -9_223_372_036_854_775_808..9_223_372_036_854_775_807
24
24
 
25
+ class << self
26
+ # return DuckDB::PreparedStatement object.
27
+ # The first argument is DuckDB::Connection object.
28
+ # The second argument is SQL string.
29
+ # If block is given, the block is executed and the statement is destroyed.
30
+ #
31
+ # require 'duckdb'
32
+ # db = DuckDB::Database.open('duckdb_database')
33
+ # con = db.connection
34
+ # DuckDB::PreparedStatement.prepare(con, 'SELECT * FROM users WHERE id = ?') do |stmt|
35
+ # stmt.bind(1, 1)
36
+ # stmt.execute
37
+ # end
38
+ def prepare(con, sql)
39
+ stmt = new(con, sql)
40
+ return stmt unless block_given?
41
+
42
+ begin
43
+ yield stmt
44
+ ensure
45
+ stmt.destroy
46
+ end
47
+ end
48
+ end
49
+
25
50
  def pending_prepared
26
51
  PendingResult.new(self)
27
52
  end
@@ -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 = '1.1.1.0'
6
+ VERSION = '1.1.2.1'
7
7
  end
data/lib/duckdb.rb CHANGED
@@ -6,6 +6,7 @@ require 'duckdb/version'
6
6
  require 'duckdb/converter'
7
7
  require 'duckdb/database'
8
8
  require 'duckdb/connection'
9
+ require 'duckdb/extracted_statements'
9
10
  require 'duckdb/result'
10
11
  require 'duckdb/prepared_statement'
11
12
  require 'duckdb/pending_result'
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: 1.1.1.0
4
+ version: 1.1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaki Suketa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-06 00:00:00.000000000 Z
11
+ date: 2024-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal
@@ -149,6 +149,7 @@ files:
149
149
  - lib/duckdb/converter.rb
150
150
  - lib/duckdb/converter/int_to_sym.rb
151
151
  - lib/duckdb/database.rb
152
+ - lib/duckdb/extracted_statements.rb
152
153
  - lib/duckdb/infinity.rb
153
154
  - lib/duckdb/interval.rb
154
155
  - lib/duckdb/library_version.rb