duckdb 0.2.6.1 → 0.3.1.0
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 +12 -3
- data/.github/workflows/test_on_ubuntu.yml +17 -36
- data/.github/workflows/test_on_windows.yml +41 -0
- data/CHANGELOG.md +39 -0
- data/CONTRIBUTION.md +24 -0
- data/Gemfile.lock +3 -3
- data/README.md +21 -7
- data/duckdb.gemspec +2 -2
- data/ext/duckdb/appender.c +136 -0
- data/ext/duckdb/config.c +80 -0
- data/ext/duckdb/config.h +18 -0
- data/ext/duckdb/connection.c +12 -12
- data/ext/duckdb/database.c +56 -16
- data/ext/duckdb/duckdb.c +6 -0
- data/ext/duckdb/extconf.rb +15 -0
- data/ext/duckdb/prepared_statement.c +9 -1
- data/ext/duckdb/result.c +66 -35
- data/ext/duckdb/ruby-duckdb.h +12 -0
- data/lib/duckdb/appender.rb +204 -8
- data/lib/duckdb/config.rb +65 -0
- data/lib/duckdb/database.rb +15 -2
- data/lib/duckdb/prepared_statement.rb +3 -3
- data/lib/duckdb/version.rb +1 -1
- data/lib/duckdb.rb +1 -0
- metadata +9 -5
- data/.travis.yml +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba5fa57fc1eaf1a2b0bb6ffa7379b8982d3858d17075c83b949af79331322a1e
|
4
|
+
data.tar.gz: cbe87ed1de6de024e9941e063102e7bf31a5407945d99180121a38fde703a8d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52d8cff8db75e7e2d7f86632573fda6d1fe021e7ff38524edf9307e2d3c4720541daab609caee24307c3a8b6a0fa40d6b1cca4151d1edbb8b17f3c7f770bb7d3
|
7
|
+
data.tar.gz: 371925fa099235c382cdd370f0d43d346f40b9dc45332931956f953ab742b0a55ec7afa52f73aa942695fe30b1df78722e7afadb1de66a6250381fdf0ed990f8
|
@@ -7,7 +7,8 @@ jobs:
|
|
7
7
|
runs-on: macos-latest
|
8
8
|
strategy:
|
9
9
|
matrix:
|
10
|
-
ruby: ['2.
|
10
|
+
ruby: ['2.6.8', '2.7.4', '3.0.2', 'head']
|
11
|
+
duckdb: ['0.3.0', '0.3.1']
|
11
12
|
|
12
13
|
steps:
|
13
14
|
- uses: actions/checkout@v2
|
@@ -17,9 +18,17 @@ jobs:
|
|
17
18
|
with:
|
18
19
|
ruby-version: ${{ matrix.ruby }}
|
19
20
|
|
20
|
-
- name:
|
21
|
+
- name: download duckdb binary for MacOS 64bit
|
22
|
+
env:
|
23
|
+
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
21
24
|
run: |
|
22
|
-
|
25
|
+
curl -OL https://github.com/duckdb/duckdb/releases/download/v${DUCKDB_VERSION}/libduckdb-osx-amd64.zip
|
26
|
+
|
27
|
+
- name: extract zip file
|
28
|
+
run: |
|
29
|
+
unzip libduckdb-osx-amd64.zip
|
30
|
+
cp duckdb.h /usr/local/include
|
31
|
+
cp libduckdb.dylib /usr/local/lib
|
23
32
|
|
24
33
|
- name: Build and test with Rake with Ruby ${{ matrix.ruby }}
|
25
34
|
run: |
|
@@ -8,8 +8,8 @@ jobs:
|
|
8
8
|
runs-on: ubuntu-latest
|
9
9
|
strategy:
|
10
10
|
matrix:
|
11
|
-
ruby: ['2.
|
12
|
-
duckdb: ['0.
|
11
|
+
ruby: ['2.6.8', '2.7.4', '3.0.2', 'head']
|
12
|
+
duckdb: ['0.3.0', '0.3.1']
|
13
13
|
|
14
14
|
steps:
|
15
15
|
- uses: actions/checkout@v2
|
@@ -19,43 +19,24 @@ jobs:
|
|
19
19
|
with:
|
20
20
|
ruby-version: ${{ matrix.ruby }}
|
21
21
|
|
22
|
-
- name: duckdb
|
23
|
-
id: duckdb-cache
|
24
|
-
uses: actions/cache@
|
22
|
+
- name: duckdb cache
|
23
|
+
id: duckdb-cache
|
24
|
+
uses: actions/cache@v2
|
25
25
|
with:
|
26
|
-
path: duckdb-
|
27
|
-
key: ${{ runner.os }}-duckdb-
|
28
|
-
restore-keys: |
|
29
|
-
${{ runner.os }}-duckdb-v0_2_6
|
26
|
+
path: duckdb-v${{ matrix.duckdb }}
|
27
|
+
key: ${{ runner.os }}-duckdb-v${{ matrix.duckdb }}
|
30
28
|
|
31
|
-
- name: duckdb
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
path: duckdb-v0.2.5
|
36
|
-
key: ${{ runner.os }}-duckdb-v0_2_5_001
|
37
|
-
restore-keys: |
|
38
|
-
${{ runner.os }}-duckdb-v0_2_5
|
39
|
-
|
40
|
-
- name: Build duckdb 0.2.6
|
41
|
-
if: steps.duckdb-cache-v0_2_6.outputs.cache-hit != 'true'
|
42
|
-
run: |
|
43
|
-
git clone -b v0.2.6 https://github.com/cwida/duckdb.git duckdb-tmp-v0.2.6
|
44
|
-
cd duckdb-tmp-v0.2.6 && make && cd ..
|
45
|
-
rm -rf duckdb-v0.2.6
|
46
|
-
mkdir -p duckdb-v0.2.6/build/release/src duckdb-v0.2.6/src
|
47
|
-
cp -rip duckdb-tmp-v0.2.6/build/release/src/*.so duckdb-v0.2.6/build/release/src
|
48
|
-
cp -rip duckdb-tmp-v0.2.6/src/include duckdb-v0.2.6/src/
|
49
|
-
|
50
|
-
- name: Build duckdb 0.2.5
|
51
|
-
if: steps.duckdb-cache-v0_2_5.outputs.cache-hit != 'true'
|
29
|
+
- name: Build duckdb ${{ matrix.duckdb }}
|
30
|
+
env:
|
31
|
+
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
32
|
+
if: steps.duckdb-cache.outputs.cache-hit != 'true'
|
52
33
|
run: |
|
53
|
-
git clone -b
|
54
|
-
cd duckdb-tmp-
|
55
|
-
rm -rf duckdb-
|
56
|
-
mkdir -p duckdb-
|
57
|
-
cp -rip duckdb-tmp-
|
58
|
-
cp -rip duckdb-tmp-
|
34
|
+
git clone -b v$DUCKDB_VERSION https://github.com/cwida/duckdb.git duckdb-tmp-v$DUCKDB_VERSION
|
35
|
+
cd duckdb-tmp-v$DUCKDB_VERSION && make && cd ..
|
36
|
+
rm -rf duckdb-v$DUCKDB_VERSION
|
37
|
+
mkdir -p duckdb-v$DUCKDB_VERSION/build/release/src duckdb-v$DUCKDB_VERSION/src
|
38
|
+
cp -rip duckdb-tmp-v$DUCKDB_VERSION/build/release/src/*.so duckdb-v$DUCKDB_VERSION/build/release/src
|
39
|
+
cp -rip duckdb-tmp-v$DUCKDB_VERSION/src/include duckdb-v$DUCKDB_VERSION/src/
|
59
40
|
|
60
41
|
- name: Build and test with Rake with Ruby ${{ matrix.ruby }}
|
61
42
|
env:
|
@@ -0,0 +1,41 @@
|
|
1
|
+
name: Windows
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: windows-latest
|
8
|
+
strategy:
|
9
|
+
matrix:
|
10
|
+
ruby: ['2.6.8', '2.7.4', '3.0.2', 'head']
|
11
|
+
duckdb: ['0.3.0', '0.3.1']
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@v2
|
15
|
+
|
16
|
+
- name: Set up Ruby
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: ${{ matrix.ruby }}
|
20
|
+
|
21
|
+
- name: download duckdb binary for windows 64bit
|
22
|
+
env:
|
23
|
+
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
24
|
+
run: |
|
25
|
+
curl -OL https://github.com/duckdb/duckdb/releases/download/v${env:DUCKDB_VERSION}/libduckdb-windows-amd64.zip
|
26
|
+
|
27
|
+
- name: extract zip file
|
28
|
+
run: |
|
29
|
+
7z x libduckdb-windows-amd64.zip
|
30
|
+
|
31
|
+
- name: Build with Rake with Ruby ${{ matrix.ruby }}
|
32
|
+
run: |
|
33
|
+
bundle install
|
34
|
+
bundle exec rake build -- --with-duckdb-include=../../../.. --with-duckdb-lib=../../../..
|
35
|
+
- name: setup duckdb.dll
|
36
|
+
run: |
|
37
|
+
cp duckdb.dll C:/Windows/System32/
|
38
|
+
|
39
|
+
- name: rake test
|
40
|
+
run: |
|
41
|
+
rake test
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,44 @@
|
|
1
1
|
# ChangeLog
|
2
2
|
|
3
|
+
# 0.3.1.0
|
4
|
+
|
5
|
+
- bump duckdb to 0.3.1 in CI.
|
6
|
+
- bump duckdb to 0.3.0 in CI.
|
7
|
+
- append_time, append_date, append_timestamp of DuckDB::Appender accept argument
|
8
|
+
having to_str to convert time string.
|
9
|
+
|
10
|
+
# 0.2.9.0
|
11
|
+
|
12
|
+
- add DuckDB::Appender#append
|
13
|
+
- breaking change.
|
14
|
+
- append_timestamp is called when the argument is Time object.
|
15
|
+
- append_date is called when the argument is Date object.
|
16
|
+
- add DuckDB::Appender#append_timestamp.
|
17
|
+
- add DuckDB::Appender#append_interval. append_interval is expremental.
|
18
|
+
- add DuckDB::Result#rows_changed
|
19
|
+
- refactoring DuckDB::Append#append_hugeint with duckdb v0.2.9
|
20
|
+
- test 2 versions of duckdb on github actions macos CI.
|
21
|
+
- fix windows CI failes
|
22
|
+
- update github actions CI on ubuntu
|
23
|
+
- fix to build with duckdb v0.2.9
|
24
|
+
- use duckdb_prepare_error when get error message of prepared statement.
|
25
|
+
- add DuckDB::Appender#append_date
|
26
|
+
- add DuckDB::Appender#append_time
|
27
|
+
|
28
|
+
# 0.2.8.0
|
29
|
+
|
30
|
+
- DuckDB::Database.open accepts 2-nd argument as DuckDB::Config object.
|
31
|
+
- add DuckDB::Config
|
32
|
+
- bump duckdb to 0.2.8 in CI
|
33
|
+
- bump Ruby to 2.6.8, 2.7.4, 3.0.2 in CI
|
34
|
+
|
35
|
+
# 0.2.7.0
|
36
|
+
|
37
|
+
- call duckdb_free after calling duckdb_value_blob, duckdb_value_varchar.
|
38
|
+
- bump DuckDB to v0.2.7 in CI
|
39
|
+
- rake build on Windows in github actions.
|
40
|
+
- There is a issue (LoadError) when running rake test on Windows (in GitHub actions).
|
41
|
+
|
3
42
|
# 0.2.6.1
|
4
43
|
|
5
44
|
- add DuckDB::PreparedStatement#bind_int8
|
data/CONTRIBUTION.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Contribution Guide
|
2
|
+
|
3
|
+
## Issue
|
4
|
+
|
5
|
+
If you spot a problem, [search if an issue already exists](https://github.com/suketa/ruby-duckdb/issues).
|
6
|
+
If a related issue doesn't exist, you can open a [new issue](https://github.com/suketa/ruby-duckdb/issues/new).
|
7
|
+
|
8
|
+
|
9
|
+
## Fix Issues or Add New Features.
|
10
|
+
|
11
|
+
1. install [Ruby](https://www.ruby-lang.org/) into your local machine.
|
12
|
+
2. install [duckdb](https://duckdb.org/) into your local machine.
|
13
|
+
3. fork the repository and `git clone` to your local machine.
|
14
|
+
4. run `bundle install`
|
15
|
+
5. run `rake build`
|
16
|
+
or you might run with C duckdb header and library directories:
|
17
|
+
`rake build -- --with-duckdb-include=/duckdb_header_directory --with-duckdb-lib=/duckdb_library_directory`
|
18
|
+
6. run `rake test`
|
19
|
+
7. create new branch to change the code.
|
20
|
+
8. change the code.
|
21
|
+
9. write test.
|
22
|
+
10. run `rake test` and confirm all tests pass.
|
23
|
+
11. git push.
|
24
|
+
12. create PR.
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
duckdb (0.
|
4
|
+
duckdb (0.3.1.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
minitest (5.14.4)
|
10
|
-
rake (13.0.
|
10
|
+
rake (13.0.6)
|
11
11
|
rake-compiler (1.1.1)
|
12
12
|
rake
|
13
13
|
|
@@ -22,4 +22,4 @@ DEPENDENCIES
|
|
22
22
|
rake-compiler
|
23
23
|
|
24
24
|
BUNDLED WITH
|
25
|
-
2.2.
|
25
|
+
2.2.25
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# ruby-duckdb
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.com/suketa/ruby-duckdb.svg?branch=master)](https://travis-ci.com/suketa/ruby-duckdb)
|
4
3
|
[![](https://github.com/suketa/ruby-duckdb/workflows/Ubuntu/badge.svg)](https://github.com/suketa/ruby-duckdb/actions?query=workflow%3AUbuntu)
|
5
4
|
[![](https://github.com/suketa/ruby-duckdb/workflows/MacOS/badge.svg)](https://github.com/suketa/ruby-duckdb/actions?query=workflow%3AMacOS)
|
5
|
+
[![](https://github.com/suketa/ruby-duckdb/workflows/Windows/badge.svg)](https://github.com/suketa/ruby-duckdb/actions?query=workflow%3AWindows)
|
6
6
|
|
7
7
|
## Description
|
8
8
|
|
@@ -18,10 +18,10 @@ You must have [DuckDB](http://www.duckdb.org) engine installed in order to build
|
|
18
18
|
gem install duckdb
|
19
19
|
```
|
20
20
|
|
21
|
-
or you must specify the location of the
|
21
|
+
or you must specify the location of the C header and library files:
|
22
22
|
|
23
23
|
```
|
24
|
-
gem install duckdb -- --with-duckdb-include=/
|
24
|
+
gem install duckdb -- --with-duckdb-include=/duckdb_header_directory --with-duckdb-lib=/duckdb_library_directory
|
25
25
|
```
|
26
26
|
|
27
27
|
## Usage
|
@@ -103,8 +103,6 @@ def insert
|
|
103
103
|
10000.times do
|
104
104
|
con.query("INSERT into users VALUES(1, 'Alice')")
|
105
105
|
end
|
106
|
-
# r = con.query('SELECT count(*) from users')
|
107
|
-
# p r.each.first
|
108
106
|
end
|
109
107
|
end
|
110
108
|
end
|
@@ -135,8 +133,6 @@ def append
|
|
135
133
|
appender.end_row
|
136
134
|
end
|
137
135
|
appender.flush
|
138
|
-
# r = con.query('SELECT count(*) from users')
|
139
|
-
# p r.each.first
|
140
136
|
end
|
141
137
|
end
|
142
138
|
end
|
@@ -153,3 +149,21 @@ end
|
|
153
149
|
# prepare 0.230457 0.000000 0.230457 ( 0.230460 )
|
154
150
|
# append 0.012666 0.000000 0.012666 ( 0.012670 )
|
155
151
|
```
|
152
|
+
|
153
|
+
### Configuration
|
154
|
+
|
155
|
+
Config class provides Ruby interface of [DuckDB configuration](https://duckdb.org/docs/api/c/config).
|
156
|
+
|
157
|
+
```
|
158
|
+
require 'duckdb'
|
159
|
+
config = DuckDB::Config.new
|
160
|
+
config['default_order'] = 'DESC'
|
161
|
+
db = DuckDB::Database.open(nil, config)
|
162
|
+
con = db.connect
|
163
|
+
con.query('CREATE TABLE numbers (number INTEGER)')
|
164
|
+
con.query('INSERT INTO numbers VALUES (2), (1), (4), (3)')
|
165
|
+
|
166
|
+
# number is ordered by descending.
|
167
|
+
r = con.query('SELECT number FROM numbers ORDER BY number')
|
168
|
+
r.first.first # => 4
|
169
|
+
```
|
data/duckdb.gemspec
CHANGED
@@ -21,12 +21,12 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
# Specify which files should be added to the gem when it is released.
|
23
23
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
-
spec.files = Dir.chdir(File.expand_path(
|
24
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
25
25
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
26
|
end
|
27
27
|
spec.require_paths = ['lib']
|
28
28
|
spec.extensions = ['ext/duckdb/extconf.rb']
|
29
|
-
spec.required_ruby_version = '>= 2.
|
29
|
+
spec.required_ruby_version = '>= 2.6.0'
|
30
30
|
|
31
31
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
32
32
|
spec.add_development_dependency 'minitest', '~> 5.0'
|
data/ext/duckdb/appender.c
CHANGED
@@ -24,6 +24,27 @@ static VALUE appender_append_varchar(VALUE self, VALUE val);
|
|
24
24
|
static VALUE appender_append_varchar_length(VALUE self, VALUE val, VALUE len);
|
25
25
|
static VALUE appender_append_blob(VALUE self, VALUE val);
|
26
26
|
static VALUE appender_append_null(VALUE self);
|
27
|
+
|
28
|
+
#ifdef HAVE_DUCKDB_APPEND_DATE
|
29
|
+
static VALUE appender__append_date(VALUE self, VALUE yearval, VALUE monthval, VALUE dayval);
|
30
|
+
#endif
|
31
|
+
|
32
|
+
#ifdef HAVE_DUCKDB_APPEND_INTERVAL
|
33
|
+
static VALUE appender__append_interval(VALUE self, VALUE months, VALUE days, VALUE micros);
|
34
|
+
#endif
|
35
|
+
|
36
|
+
#ifdef HAVE_DUCKDB_APPEND_TIME
|
37
|
+
static VALUE appender__append_time(VALUE self, VALUE hour, VALUE min, VALUE sec, VALUE micros);
|
38
|
+
#endif
|
39
|
+
|
40
|
+
#ifdef HAVE_DUCKDB_APPEND_TIMESTAMP
|
41
|
+
static VALUE appender__append_timestamp(VALUE self, VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros);
|
42
|
+
#endif
|
43
|
+
|
44
|
+
#ifdef HAVE_DUCKDB_APPEND_HUGEINT
|
45
|
+
static VALUE appender__append_hugeint(VALUE self, VALUE lower, VALUE upper);
|
46
|
+
#endif
|
47
|
+
|
27
48
|
static VALUE appender_flush(VALUE self);
|
28
49
|
static VALUE appender_close(VALUE self);
|
29
50
|
|
@@ -268,6 +289,106 @@ static VALUE appender_append_null(VALUE self) {
|
|
268
289
|
return self;
|
269
290
|
}
|
270
291
|
|
292
|
+
#ifdef HAVE_DUCKDB_APPEND_DATE
|
293
|
+
static VALUE appender__append_date(VALUE self, VALUE yearval, VALUE monthval, VALUE dayval) {
|
294
|
+
duckdb_date_struct dt_struct;
|
295
|
+
duckdb_date dt;
|
296
|
+
rubyDuckDBAppender *ctx;
|
297
|
+
|
298
|
+
Data_Get_Struct(self, rubyDuckDBAppender, ctx);
|
299
|
+
dt_struct.year = NUM2INT(yearval);
|
300
|
+
dt_struct.month = NUM2INT(monthval);
|
301
|
+
dt_struct.day = NUM2INT(dayval);
|
302
|
+
dt = duckdb_to_date(dt_struct);
|
303
|
+
|
304
|
+
if (duckdb_append_date(ctx->appender, dt) == DuckDBError) {
|
305
|
+
rb_raise(eDuckDBError, "failed to append date");
|
306
|
+
}
|
307
|
+
return self;
|
308
|
+
}
|
309
|
+
#endif
|
310
|
+
|
311
|
+
#ifdef HAVE_DUCKDB_APPEND_INTERVAL
|
312
|
+
static VALUE appender__append_interval(VALUE self, VALUE months, VALUE days, VALUE micros) {
|
313
|
+
duckdb_interval interval;
|
314
|
+
rubyDuckDBAppender *ctx;
|
315
|
+
|
316
|
+
Data_Get_Struct(self, rubyDuckDBAppender, ctx);
|
317
|
+
interval.months = NUM2INT(months);
|
318
|
+
interval.days = NUM2INT(days);
|
319
|
+
interval.micros = NUM2LL(micros);
|
320
|
+
|
321
|
+
if (duckdb_append_interval(ctx->appender, interval) == DuckDBError) {
|
322
|
+
rb_raise(eDuckDBError, "failed to append interval");
|
323
|
+
}
|
324
|
+
return self;
|
325
|
+
}
|
326
|
+
#endif
|
327
|
+
|
328
|
+
#ifdef HAVE_DUCKDB_APPEND_TIME
|
329
|
+
static VALUE appender__append_time(VALUE self, VALUE hour, VALUE min, VALUE sec, VALUE micros) {
|
330
|
+
duckdb_time_struct time_st;
|
331
|
+
duckdb_time time;
|
332
|
+
rubyDuckDBAppender *ctx;
|
333
|
+
|
334
|
+
Data_Get_Struct(self, rubyDuckDBAppender, ctx);
|
335
|
+
time_st.hour = NUM2INT(hour);
|
336
|
+
time_st.min = NUM2INT(min);
|
337
|
+
time_st.sec = NUM2INT(sec);
|
338
|
+
time_st.micros = NUM2INT(micros);
|
339
|
+
|
340
|
+
time = duckdb_to_time(time_st);
|
341
|
+
|
342
|
+
if (duckdb_append_time(ctx->appender, time) == DuckDBError) {
|
343
|
+
rb_raise(eDuckDBError, "failed to append time");
|
344
|
+
}
|
345
|
+
return self;
|
346
|
+
}
|
347
|
+
#endif
|
348
|
+
|
349
|
+
#ifdef HAVE_DUCKDB_APPEND_TIMESTAMP
|
350
|
+
static VALUE appender__append_timestamp(VALUE self, VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros) {
|
351
|
+
duckdb_timestamp_struct timestamp_st;
|
352
|
+
duckdb_timestamp timestamp;
|
353
|
+
|
354
|
+
rubyDuckDBAppender *ctx;
|
355
|
+
|
356
|
+
Data_Get_Struct(self, rubyDuckDBAppender, ctx);
|
357
|
+
|
358
|
+
timestamp_st.date.year = NUM2INT(year);
|
359
|
+
timestamp_st.date.month = NUM2INT(month);
|
360
|
+
timestamp_st.date.day = NUM2INT(day);
|
361
|
+
timestamp_st.time.hour = NUM2INT(hour);
|
362
|
+
timestamp_st.time.min = NUM2INT(min);
|
363
|
+
timestamp_st.time.sec = NUM2INT(sec);
|
364
|
+
timestamp_st.time.micros = NUM2INT(micros);
|
365
|
+
|
366
|
+
timestamp = duckdb_to_timestamp(timestamp_st);
|
367
|
+
|
368
|
+
if (duckdb_append_timestamp(ctx->appender, timestamp) == DuckDBError) {
|
369
|
+
rb_raise(eDuckDBError, "failed to append timestamp");
|
370
|
+
}
|
371
|
+
return self;
|
372
|
+
}
|
373
|
+
#endif
|
374
|
+
|
375
|
+
#ifdef HAVE_DUCKDB_APPEND_HUGEINT
|
376
|
+
static VALUE appender__append_hugeint(VALUE self, VALUE lower, VALUE upper) {
|
377
|
+
duckdb_hugeint hugeint;
|
378
|
+
|
379
|
+
hugeint.lower = NUM2ULL(lower);
|
380
|
+
hugeint.upper = NUM2LL(upper);
|
381
|
+
|
382
|
+
rubyDuckDBAppender *ctx;
|
383
|
+
|
384
|
+
Data_Get_Struct(self, rubyDuckDBAppender, ctx);
|
385
|
+
if (duckdb_append_hugeint(ctx->appender, hugeint) == DuckDBError) {
|
386
|
+
rb_raise(eDuckDBError, "failed to append hugeint");
|
387
|
+
}
|
388
|
+
return self;
|
389
|
+
}
|
390
|
+
#endif
|
391
|
+
|
271
392
|
static VALUE appender_flush(VALUE self) {
|
272
393
|
rubyDuckDBAppender *ctx;
|
273
394
|
Data_Get_Struct(self, rubyDuckDBAppender, ctx);
|
@@ -309,6 +430,21 @@ void init_duckdb_appender(void) {
|
|
309
430
|
rb_define_method(cDuckDBAppender, "append_varchar_length", appender_append_varchar_length, 2);
|
310
431
|
rb_define_method(cDuckDBAppender, "append_blob", appender_append_blob, 1);
|
311
432
|
rb_define_method(cDuckDBAppender, "append_null", appender_append_null, 0);
|
433
|
+
#ifdef HAVE_DUCKDB_APPEND_DATE
|
434
|
+
rb_define_private_method(cDuckDBAppender, "_append_date", appender__append_date, 3);
|
435
|
+
#endif
|
436
|
+
#ifdef HAVE_DUCKDB_APPEND_INTERVAL
|
437
|
+
rb_define_private_method(cDuckDBAppender, "_append_interval", appender__append_interval, 3);
|
438
|
+
#endif
|
439
|
+
#ifdef HAVE_DUCKDB_APPEND_TIME
|
440
|
+
rb_define_private_method(cDuckDBAppender, "_append_time", appender__append_time, 4);
|
441
|
+
#endif
|
442
|
+
#ifdef HAVE_DUCKDB_APPEND_TIMESTAMP
|
443
|
+
rb_define_private_method(cDuckDBAppender, "_append_timestamp", appender__append_timestamp, 7);
|
444
|
+
#endif
|
445
|
+
#ifdef HAVE_DUCKDB_APPEND_HUGEINT
|
446
|
+
rb_define_private_method(cDuckDBAppender, "_append_hugeint", appender__append_hugeint, 2);
|
447
|
+
#endif
|
312
448
|
rb_define_method(cDuckDBAppender, "flush", appender_flush, 0);
|
313
449
|
rb_define_method(cDuckDBAppender, "close", appender_close, 0);
|
314
450
|
}
|
data/ext/duckdb/config.c
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#include "ruby-duckdb.h"
|
2
|
+
|
3
|
+
#ifdef HAVE_DUCKDB_CREATE_CONFIG
|
4
|
+
|
5
|
+
VALUE cDuckDBConfig;
|
6
|
+
|
7
|
+
static void deallocate(void *);
|
8
|
+
static VALUE allocate(VALUE klass);
|
9
|
+
static VALUE config_s_size(VALUE klass);
|
10
|
+
static VALUE config_s_get_config_flag(VALUE self, VALUE value);
|
11
|
+
static VALUE config_initialize(VALUE self);
|
12
|
+
static VALUE config_set_config(VALUE self, VALUE key, VALUE value);
|
13
|
+
|
14
|
+
static void deallocate(void * ctx)
|
15
|
+
{
|
16
|
+
rubyDuckDBConfig *p = (rubyDuckDBConfig *)ctx;
|
17
|
+
|
18
|
+
duckdb_destroy_config(&(p->config));
|
19
|
+
xfree(p);
|
20
|
+
}
|
21
|
+
|
22
|
+
static VALUE allocate(VALUE klass)
|
23
|
+
{
|
24
|
+
rubyDuckDBConfig *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBConfig));
|
25
|
+
return Data_Wrap_Struct(klass, NULL, deallocate, ctx);
|
26
|
+
}
|
27
|
+
|
28
|
+
static VALUE config_initialize(VALUE self) {
|
29
|
+
rubyDuckDBConfig *ctx;
|
30
|
+
|
31
|
+
Data_Get_Struct(self, rubyDuckDBConfig, ctx);
|
32
|
+
|
33
|
+
if (duckdb_create_config(&(ctx->config)) == DuckDBError) {
|
34
|
+
rb_raise(eDuckDBError, "failed to create config");
|
35
|
+
}
|
36
|
+
return self;
|
37
|
+
}
|
38
|
+
|
39
|
+
static VALUE config_s_size(VALUE self) {
|
40
|
+
return ULONG2NUM(duckdb_config_count());
|
41
|
+
}
|
42
|
+
|
43
|
+
static VALUE config_s_get_config_flag(VALUE klass, VALUE value) {
|
44
|
+
const char *pkey;
|
45
|
+
const char *pdesc;
|
46
|
+
|
47
|
+
size_t i = NUM2INT(value);
|
48
|
+
|
49
|
+
if (duckdb_get_config_flag(i, &pkey, &pdesc) == DuckDBError) {
|
50
|
+
rb_raise(eDuckDBError, "failed to get config information of index %ld", i);
|
51
|
+
}
|
52
|
+
|
53
|
+
return rb_ary_new3(2, rb_str_new2(pkey), rb_str_new2(pdesc));
|
54
|
+
}
|
55
|
+
|
56
|
+
static VALUE config_set_config(VALUE self, VALUE key, VALUE value) {
|
57
|
+
const char *pkey = StringValuePtr(key);
|
58
|
+
const char *pval = StringValuePtr(value);
|
59
|
+
|
60
|
+
rubyDuckDBConfig *ctx;
|
61
|
+
Data_Get_Struct(self, rubyDuckDBConfig, ctx);
|
62
|
+
|
63
|
+
if (duckdb_set_config(ctx->config, pkey, pval) == DuckDBError) {
|
64
|
+
rb_raise(eDuckDBError, "failed to set config %s => %s", pkey, pval);
|
65
|
+
}
|
66
|
+
return self;
|
67
|
+
}
|
68
|
+
|
69
|
+
void init_duckdb_config(void) {
|
70
|
+
cDuckDBConfig = rb_define_class_under(mDuckDB, "Config", rb_cObject);
|
71
|
+
rb_define_alloc_func(cDuckDBConfig, allocate);
|
72
|
+
rb_define_singleton_method(cDuckDBConfig, "size", config_s_size, 0);
|
73
|
+
rb_define_singleton_method(cDuckDBConfig, "get_config_flag", config_s_get_config_flag, 1);
|
74
|
+
|
75
|
+
rb_define_method(cDuckDBConfig, "initialize", config_initialize, 0);
|
76
|
+
rb_define_method(cDuckDBConfig, "set_config", config_set_config, 2);
|
77
|
+
}
|
78
|
+
|
79
|
+
#endif
|
80
|
+
|
data/ext/duckdb/config.h
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#ifndef RUBY_DUCKDB_CONFIG_H
|
2
|
+
#define RUBY_DUCKDB_CONFIG_H
|
3
|
+
|
4
|
+
#ifdef HAVE_DUCKDB_CREATE_CONFIG
|
5
|
+
|
6
|
+
struct _rubyDuckDBConfig {
|
7
|
+
duckdb_config config;
|
8
|
+
};
|
9
|
+
|
10
|
+
typedef struct _rubyDuckDBConfig rubyDuckDBConfig;
|
11
|
+
|
12
|
+
void init_duckdb_config(void);
|
13
|
+
|
14
|
+
#endif
|
15
|
+
|
16
|
+
#endif
|
17
|
+
|
18
|
+
|
data/ext/duckdb/connection.c
CHANGED
@@ -2,22 +2,25 @@
|
|
2
2
|
|
3
3
|
VALUE cDuckDBConnection;
|
4
4
|
|
5
|
-
static void deallocate(void *ctx)
|
6
|
-
|
5
|
+
static void deallocate(void *ctx);
|
6
|
+
static VALUE allocate(VALUE klass);
|
7
|
+
static VALUE duckdb_connection_disconnect(VALUE self);
|
8
|
+
static VALUE duckdb_connection_connect(VALUE self, VALUE oDuckDBDatabase);
|
9
|
+
static VALUE duckdb_connection_query_sql(VALUE self, VALUE str);
|
10
|
+
|
11
|
+
static void deallocate(void *ctx) {
|
7
12
|
rubyDuckDBConnection *p = (rubyDuckDBConnection *)ctx;
|
8
13
|
|
9
14
|
duckdb_disconnect(&(p->con));
|
10
15
|
xfree(p);
|
11
16
|
}
|
12
17
|
|
13
|
-
static VALUE allocate(VALUE klass)
|
14
|
-
{
|
18
|
+
static VALUE allocate(VALUE klass) {
|
15
19
|
rubyDuckDBConnection *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBConnection));
|
16
20
|
return Data_Wrap_Struct(klass, NULL, deallocate, ctx);
|
17
21
|
}
|
18
22
|
|
19
|
-
VALUE create_connection(VALUE oDuckDBDatabase)
|
20
|
-
{
|
23
|
+
VALUE create_connection(VALUE oDuckDBDatabase) {
|
21
24
|
rubyDuckDB *ctxdb;
|
22
25
|
rubyDuckDBConnection *ctxcon;
|
23
26
|
VALUE obj;
|
@@ -35,8 +38,7 @@ VALUE create_connection(VALUE oDuckDBDatabase)
|
|
35
38
|
return obj;
|
36
39
|
}
|
37
40
|
|
38
|
-
static VALUE duckdb_connection_disconnect(VALUE self)
|
39
|
-
{
|
41
|
+
static VALUE duckdb_connection_disconnect(VALUE self) {
|
40
42
|
rubyDuckDBConnection *ctx;
|
41
43
|
|
42
44
|
Data_Get_Struct(self, rubyDuckDBConnection, ctx);
|
@@ -45,8 +47,7 @@ static VALUE duckdb_connection_disconnect(VALUE self)
|
|
45
47
|
return self;
|
46
48
|
}
|
47
49
|
|
48
|
-
static VALUE duckdb_connection_connect(VALUE self, VALUE oDuckDBDatabase)
|
49
|
-
{
|
50
|
+
static VALUE duckdb_connection_connect(VALUE self, VALUE oDuckDBDatabase) {
|
50
51
|
rubyDuckDBConnection *ctx;
|
51
52
|
rubyDuckDB *ctxdb;
|
52
53
|
|
@@ -63,8 +64,7 @@ static VALUE duckdb_connection_connect(VALUE self, VALUE oDuckDBDatabase)
|
|
63
64
|
return self;
|
64
65
|
}
|
65
66
|
|
66
|
-
static VALUE duckdb_connection_query_sql(VALUE self, VALUE str)
|
67
|
-
{
|
67
|
+
static VALUE duckdb_connection_query_sql(VALUE self, VALUE str) {
|
68
68
|
rubyDuckDBConnection *ctx;
|
69
69
|
rubyDuckDBResult *ctxr;
|
70
70
|
|