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 +4 -4
- data/.github/workflows/test_on_macos.yml +1 -1
- data/.github/workflows/test_on_ubuntu.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +11 -0
- data/ext/duckdb/prepared_statement.c +24 -0
- data/lib/duckdb/connection.rb +12 -5
- data/lib/duckdb/prepared_statement.rb +32 -12
- data/lib/duckdb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aac4fbdeca8ed41cef872ace9dd3c8784ce43ee224a733f469fcd0907e852cd5
|
4
|
+
data.tar.gz: 56c8a5831830264fd4dfac41ba7a60bb9e6493a40536a5502c10dc0fc41b16d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b94ffce97a54769bae379a3b13765b2132df1efe80fdb8f4855f77248855e95e9370651dbbe165a64c6ee45aff5bef20b3800a680f3da5287528974a243af338
|
7
|
+
data.tar.gz: 96accf18b7f4df7721efaec8e215e92dcbe97d22a99d89ffb64658f4696eb462b8ceaa27a3e558cba8ef5a7ce257fc4e3b35f83178fadf8047e19280563e7ae6
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
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);
|
data/lib/duckdb/connection.rb
CHANGED
@@ -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
|
-
|
25
|
-
|
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.
|
29
|
-
stmt.bind(i
|
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 '
|
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(
|
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(
|
188
|
+
bind_null(index)
|
174
189
|
when Float
|
175
|
-
bind_double(
|
190
|
+
bind_double(index, value)
|
176
191
|
when Integer
|
177
192
|
case value
|
178
193
|
when RANGE_INT64
|
179
|
-
bind_int64(
|
194
|
+
bind_int64(index, value)
|
180
195
|
else
|
181
|
-
bind_varchar(
|
196
|
+
bind_varchar(index, value.to_s)
|
182
197
|
end
|
183
198
|
when String
|
184
|
-
blob?(value) ? bind_blob(
|
199
|
+
blob?(value) ? bind_blob(index, value) : bind_varchar(index, value)
|
185
200
|
when TrueClass, FalseClass
|
186
|
-
bind_bool(
|
201
|
+
bind_bool(index, value)
|
187
202
|
when Time
|
188
|
-
bind_varchar(
|
203
|
+
bind_varchar(index, value.strftime('%Y-%m-%d %H:%M:%S.%N'))
|
189
204
|
when Date
|
190
|
-
bind_varchar(
|
205
|
+
bind_varchar(index, value.strftime('%Y-%m-%d'))
|
191
206
|
when BigDecimal
|
192
|
-
bind_varchar(
|
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
|
-
|
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
|
data/lib/duckdb/version.rb
CHANGED
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-
|
11
|
+
date: 2023-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|