duckdb 0.9.0 → 0.9.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f7738df010c1fb1aab32b61077ff9409566cfaddecfef3b27aa6e7ee7a8651f2
4
- data.tar.gz: 6357f43da56b7c4fbea72ec7b3c549f598f3a91b88c1c91ab5320a01606f3589
3
+ metadata.gz: aac4fbdeca8ed41cef872ace9dd3c8784ce43ee224a733f469fcd0907e852cd5
4
+ data.tar.gz: 56c8a5831830264fd4dfac41ba7a60bb9e6493a40536a5502c10dc0fc41b16d7
5
5
  SHA512:
6
- metadata.gz: e417badc1b301fdea9f3f4b27648e7e1c7d8e125a0a1323bb69e93a992467eca0a57a320b0bb14f7fda45bf8d9d3706b59eb586a71e3c9f77bd2ec18c88b8b3a
7
- data.tar.gz: b1486d0d525fa93a8485504eac95015a07ac064a4dfb15bb0689aa7be4cb41edcf03436324e822bda26a8c3c6e8a9e2a690efcd49f7180f675777f75284df5e8
6
+ metadata.gz: b94ffce97a54769bae379a3b13765b2132df1efe80fdb8f4855f77248855e95e9370651dbbe165a64c6ee45aff5bef20b3800a680f3da5287528974a243af338
7
+ data.tar.gz: 96accf18b7f4df7721efaec8e215e92dcbe97d22a99d89ffb64658f4696eb462b8ceaa27a3e558cba8ef5a7ce257fc4e3b35f83178fadf8047e19280563e7ae6
@@ -15,7 +15,7 @@ jobs:
15
15
  runs-on: macos-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['2.7.8', '3.0.6', '3.1.4', '3.2.2', '3.3.0-preview1', 'head']
18
+ ruby: ['2.7.8', '3.0.6', '3.1.4', '3.2.2', '3.3.0-preview2', 'head']
19
19
  duckdb: ['0.9.0', '0.8.1']
20
20
 
21
21
  steps:
@@ -15,7 +15,7 @@ jobs:
15
15
  runs-on: ubuntu-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['2.7.8', '3.0.6', '3.1.4', '3.2.2', '3.3.0-preview1', 'head']
18
+ ruby: ['2.7.8', '3.0.6', '3.1.4', '3.2.2', '3.3.0-preview2', 'head']
19
19
  duckdb: ['0.9.0', '0.8.1']
20
20
 
21
21
  steps:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # ChangeLog
2
2
 
3
+ # 0.9.0.1
4
+
5
+ - add `DuckDB::PreparedStatement#bind_parameter_index`.
6
+ - DuckDB::Connection#query accepts SQL with named bind parameters.
7
+
3
8
  # 0.9.0
4
9
  - bump duckdb to 0.9.0.
5
10
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (0.9.0)
4
+ duckdb (0.9.0.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -94,6 +94,17 @@ DuckDB::Database.open do |db|
94
94
  end
95
95
  ```
96
96
 
97
+ ### using bind variables
98
+
99
+ You can use bind variables.
100
+
101
+ ```ruby
102
+ con.query('SELECT * FROM users WHERE name = ? AND email = ?', 'Alice', 'alice@example.com')
103
+ # or
104
+ con.query('SELECT * FROM users WHERE name = $name AND email = $email', name: 'Alice', email: 'alice@example.com')
105
+ ```
106
+
107
+
97
108
  ### using BLOB column
98
109
 
99
110
  BLOB is available with DuckDB v0.2.5 or later.
@@ -9,6 +9,11 @@ static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE q
9
9
  static VALUE duckdb_prepared_statement_nparams(VALUE self);
10
10
  static VALUE duckdb_prepared_statement_execute(VALUE self);
11
11
  static idx_t check_index(VALUE vidx);
12
+
13
+ #ifdef HAVE_DUCKDB_H_GE_V090
14
+ static VALUE duckdb_prepared_statement_bind_parameter_index(VALUE self, VALUE name);
15
+ #endif
16
+
12
17
  static VALUE duckdb_prepared_statement_bind_bool(VALUE self, VALUE vidx, VALUE val);
13
18
  static VALUE duckdb_prepared_statement_bind_int8(VALUE self, VALUE vidx, VALUE val);
14
19
  static VALUE duckdb_prepared_statement_bind_int16(VALUE self, VALUE vidx, VALUE val);
@@ -93,6 +98,20 @@ static idx_t check_index(VALUE vidx) {
93
98
  return idx;
94
99
  }
95
100
 
101
+ #ifdef HAVE_DUCKDB_H_GE_V090
102
+ static VALUE duckdb_prepared_statement_bind_parameter_index(VALUE self, VALUE name) {
103
+ rubyDuckDBPreparedStatement *ctx;
104
+ idx_t idx;
105
+
106
+ TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
107
+
108
+ if (duckdb_bind_parameter_index(ctx->prepared_statement, &idx, StringValuePtr(name)) == DuckDBError) {;
109
+ rb_raise(rb_eArgError, "parameter '%s' not found", StringValuePtr(name));
110
+ }
111
+ return ULL2NUM(idx);
112
+ }
113
+ #endif
114
+
96
115
  static VALUE duckdb_prepared_statement_bind_bool(VALUE self, VALUE vidx, VALUE val) {
97
116
  rubyDuckDBPreparedStatement *ctx;
98
117
  idx_t idx = check_index(vidx);
@@ -308,6 +327,11 @@ void init_duckdb_prepared_statement(void) {
308
327
  rb_define_method(cDuckDBPreparedStatement, "initialize", duckdb_prepared_statement_initialize, 2);
309
328
  rb_define_method(cDuckDBPreparedStatement, "execute", duckdb_prepared_statement_execute, 0);
310
329
  rb_define_method(cDuckDBPreparedStatement, "nparams", duckdb_prepared_statement_nparams, 0);
330
+
331
+ #ifdef HAVE_DUCKDB_H_GE_V090
332
+ rb_define_method(cDuckDBPreparedStatement, "bind_parameter_index", duckdb_prepared_statement_bind_parameter_index, 1);
333
+ #endif
334
+
311
335
  rb_define_method(cDuckDBPreparedStatement, "bind_bool", duckdb_prepared_statement_bind_bool, 2);
312
336
  rb_define_method(cDuckDBPreparedStatement, "bind_int8", duckdb_prepared_statement_bind_int8, 2);
313
337
  rb_define_method(cDuckDBPreparedStatement, "bind_int16", duckdb_prepared_statement_bind_int16, 2);
@@ -12,7 +12,6 @@ module DuckDB
12
12
  # executes sql with args.
13
13
  # The first argument sql must be SQL string.
14
14
  # The rest arguments are parameters of SQL string.
15
- # The parameters must be '?' in SQL statement.
16
15
  #
17
16
  # require 'duckdb'
18
17
  # db = DuckDB::Database.open('duckdb_file')
@@ -21,12 +20,20 @@ module DuckDB
21
20
  # sql = 'SELECT * FROM users WHERE name = ? AND email = ?'
22
21
  # dave = con.query(sql, 'Dave', 'dave@example.com')
23
22
  #
24
- def query(sql, *args)
25
- return query_sql(sql) if args.empty?
23
+ # # or You can use named parameter.
24
+ #
25
+ # sql = 'SELECT * FROM users WHERE name = $name AND email = $email'
26
+ # dave = con.query(sql, name: 'Dave', email: 'dave@example.com')
27
+ #
28
+ def query(sql, *args, **hash)
29
+ return query_sql(sql) if args.empty? && hash.empty?
26
30
 
27
31
  stmt = PreparedStatement.new(self, sql)
28
- args.each_with_index do |arg, i|
29
- stmt.bind(i + 1, arg)
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)
30
37
  end
31
38
  stmt.execute
32
39
  end
@@ -1,6 +1,6 @@
1
1
  require 'date'
2
2
  require 'bigdecimal'
3
- require_relative './converter'
3
+ require_relative 'converter'
4
4
 
5
5
  module DuckDB
6
6
  # The DuckDB::PreparedStatement encapsulates connection with DuckDB prepared
@@ -167,35 +167,55 @@ module DuckDB
167
167
  # sql ='SELECT name, email FROM users WHERE email = ?'
168
168
  # stmt = PreparedStatement.new(con, sql)
169
169
  # stmt.bind(1, 'email@example.com')
170
- def bind(i, value)
170
+ def bind(index, value)
171
+ case index
172
+ when Integer
173
+ bind_with_index(index, value)
174
+ when String
175
+ bind_with_name(index, value)
176
+ when Symbol
177
+ bind_with_name(index.to_s, value)
178
+ else
179
+ raise(ArgumentError, "1st argument `#{index}` must be Integer or String or Symbol.")
180
+ end
181
+ end
182
+
183
+ private
184
+
185
+ def bind_with_index(index, value)
171
186
  case value
172
187
  when NilClass
173
- bind_null(i)
188
+ bind_null(index)
174
189
  when Float
175
- bind_double(i, value)
190
+ bind_double(index, value)
176
191
  when Integer
177
192
  case value
178
193
  when RANGE_INT64
179
- bind_int64(i, value)
194
+ bind_int64(index, value)
180
195
  else
181
- bind_varchar(i, value.to_s)
196
+ bind_varchar(index, value.to_s)
182
197
  end
183
198
  when String
184
- blob?(value) ? bind_blob(i, value) : bind_varchar(i, value)
199
+ blob?(value) ? bind_blob(index, value) : bind_varchar(index, value)
185
200
  when TrueClass, FalseClass
186
- bind_bool(i, value)
201
+ bind_bool(index, value)
187
202
  when Time
188
- bind_varchar(i, value.strftime('%Y-%m-%d %H:%M:%S.%N'))
203
+ bind_varchar(index, value.strftime('%Y-%m-%d %H:%M:%S.%N'))
189
204
  when Date
190
- bind_varchar(i, value.strftime('%Y-%m-%d'))
205
+ bind_varchar(index, value.strftime('%Y-%m-%d'))
191
206
  when BigDecimal
192
- bind_varchar(i, value.to_s('F'))
207
+ bind_varchar(index, value.to_s('F'))
193
208
  else
194
209
  raise(DuckDB::Error, "not supported type `#{value}` (#{value.class})")
195
210
  end
196
211
  end
197
212
 
198
- private
213
+ def bind_with_name(name, value)
214
+ raise DuckDB::Error, 'not supported binding with name' unless respond_to?(:bind_parameter_index)
215
+
216
+ i = bind_parameter_index(name)
217
+ bind_with_index(i, value)
218
+ end
199
219
 
200
220
  def blob?(value)
201
221
  value.instance_of?(DuckDB::Blob) || value.encoding == Encoding::BINARY
@@ -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.0'
6
+ VERSION = '0.9.0.1'
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.0
4
+ version: 0.9.0.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: 2023-09-29 00:00:00.000000000 Z
11
+ date: 2023-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler