duckdb 0.2.6.0 → 0.2.9.0
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 +4 -4
- data/.github/workflows/test_on_macos.yml +27 -3
- data/.github/workflows/test_on_ubuntu.yml +17 -36
- data/.github/workflows/test_on_windows.yml +43 -0
- data/CHANGELOG.md +42 -0
- data/CONTRIBUTION.md +24 -0
- data/Gemfile.lock +3 -3
- data/README.md +84 -4
- data/duckdb.gemspec +2 -2
- data/ext/duckdb/appender.c +139 -3
- data/ext/duckdb/config.c +80 -0
- data/ext/duckdb/config.h +18 -0
- data/ext/duckdb/database.c +48 -2
- data/ext/duckdb/duckdb.c +6 -0
- data/ext/duckdb/extconf.rb +15 -0
- data/ext/duckdb/prepared_statement.c +26 -3
- data/ext/duckdb/result.c +67 -33
- data/ext/duckdb/ruby-duckdb.h +12 -0
- data/lib/duckdb/appender.rb +303 -0
- data/lib/duckdb/config.rb +65 -0
- data/lib/duckdb/connection.rb +21 -0
- data/lib/duckdb/database.rb +15 -2
- data/lib/duckdb/prepared_statement.rb +22 -4
- data/lib/duckdb/version.rb +1 -1
- data/lib/duckdb.rb +2 -0
- metadata +13 -8
- 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: af998f52f46c0ef8f51501333cbaf39d720daaa389eb618d7d7ad79627d70ad9
|
4
|
+
data.tar.gz: 8e1c5323fa2f917c9ab6050a0350e5e25b646559492501f636af026b79cb20f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14809adeffb7bc79f2102e29f89a6fe6ea276ab38eaeabed9f3c18a023566c3bbad06c1ab31e55499e77d3f0f9ced186d618c24639b8c16ceff1ee61304f9f67
|
7
|
+
data.tar.gz: 15d164af6af9d985765d7b9fa87dcf7f9cf89fb2d691c9d44ea2d2bb72341a77213647cb08bcacc66094eb1622d250fe203f41a9529866af9f358518800f7183
|
@@ -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.2.8', '0.2.9']
|
11
12
|
|
12
13
|
steps:
|
13
14
|
- uses: actions/checkout@v2
|
@@ -17,9 +18,32 @@ jobs:
|
|
17
18
|
with:
|
18
19
|
ruby-version: ${{ matrix.ruby }}
|
19
20
|
|
20
|
-
- name:
|
21
|
+
- name: duckdb cache
|
22
|
+
id: duckdb-cache
|
23
|
+
uses: actions/cache@v2
|
24
|
+
with:
|
25
|
+
path: /usr/local/Cellar/duckdb@${{ matrix.duckdb }}
|
26
|
+
key: ${{ runner.os }}-duckdb-v${{ matrix.duckdb }}
|
27
|
+
|
28
|
+
- name: Install duckdb v${{ matrix.duckdb }} by brew
|
29
|
+
env:
|
30
|
+
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
31
|
+
if: steps.duckdb-cache.outputs.cache-hit != 'true'
|
32
|
+
run: |
|
33
|
+
brew tap-new duckdb/taps
|
34
|
+
brew extract duckdb duckdb/taps --version $DUCKDB_VERSION
|
35
|
+
brew install duckdb/taps/duckdb@$DUCKDB_VERSION
|
36
|
+
|
37
|
+
- name: setup duckdb v${{ matrix.duckdb }} headers and libraries
|
38
|
+
env:
|
39
|
+
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
21
40
|
run: |
|
22
|
-
|
41
|
+
if [ ! -L /usr/local/include/duckdb.h ]; then
|
42
|
+
header=`find /usr/local/Cellar/duckdb@$DUCKDB_VERSION -name "duckdb.h"`
|
43
|
+
lib=`find /usr/local/Cellar/duckdb@$DUCKDB_VERSION -name "libduckdb.dylib"`
|
44
|
+
ln -s $header /usr/local/include/duckdb.h
|
45
|
+
ln -s $lib /usr/local/lib/libduckdb.dylib
|
46
|
+
fi
|
23
47
|
|
24
48
|
- name: Build and test with Rake with Ruby ${{ matrix.ruby }}
|
25
49
|
run: |
|
@@ -8,8 +8,8 @@ jobs:
|
|
8
8
|
runs-on: ubuntu-latest
|
9
9
|
strategy:
|
10
10
|
matrix:
|
11
|
-
ruby: ['2.
|
12
|
-
duckdb: ['0.2.
|
11
|
+
ruby: ['2.6.8', '2.7.4', '3.0.2', 'head']
|
12
|
+
duckdb: ['0.2.8', '0.2.9']
|
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,43 @@
|
|
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.2.8', '0.2.9']
|
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
|
+
# FIXME: rake test fails with LoadError
|
40
|
+
# C:/hostedtoolcache/windows/Ruby/2.7.3/x64/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:83:in `require': 126: The specified module could not be found. - D:/a/ruby-duckdb/ruby-duckdb/lib/duckdb/duckdb_native.so (LoadError)`
|
41
|
+
- name: rake test
|
42
|
+
run: |
|
43
|
+
rake test
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,47 @@
|
|
1
1
|
# ChangeLog
|
2
2
|
|
3
|
+
# 0.2.9.0
|
4
|
+
|
5
|
+
- add DuckDB::Appender#append
|
6
|
+
- breaking change.
|
7
|
+
- append_timestamp is called when the argument is Time object.
|
8
|
+
- append_date is called when the argument is Date object.
|
9
|
+
- add DuckDB::Appender#append_timestamp.
|
10
|
+
- add DuckDB::Appender#append_interval. append_interval is expremental.
|
11
|
+
- add DuckDB::Result#rows_changed
|
12
|
+
- refactoring DuckDB::Append#append_hugeint with duckdb v0.2.9
|
13
|
+
- test 2 versions of duckdb on github actions macos CI.
|
14
|
+
- fix windows CI failes
|
15
|
+
- update github actions CI on ubuntu
|
16
|
+
- fix to build with duckdb v0.2.9
|
17
|
+
- use duckdb_prepare_error when get error message of prepared statement.
|
18
|
+
- add DuckDB::Appender#append_date
|
19
|
+
- add DuckDB::Appender#append_time
|
20
|
+
|
21
|
+
# 0.2.8.0
|
22
|
+
|
23
|
+
- DuckDB::Database.open accepts 2-nd argument as DuckDB::Config object.
|
24
|
+
- add DuckDB::Config
|
25
|
+
- bump duckdb to 0.2.8 in CI
|
26
|
+
- bump Ruby to 2.6.8, 2.7.4, 3.0.2 in CI
|
27
|
+
|
28
|
+
# 0.2.7.0
|
29
|
+
|
30
|
+
- call duckdb_free after calling duckdb_value_blob, duckdb_value_varchar.
|
31
|
+
- bump DuckDB to v0.2.7 in CI
|
32
|
+
- rake build on Windows in github actions.
|
33
|
+
- There is a issue (LoadError) when running rake test on Windows (in GitHub actions).
|
34
|
+
|
35
|
+
# 0.2.6.1
|
36
|
+
|
37
|
+
- add DuckDB::PreparedStatement#bind_int8
|
38
|
+
- DuckDB::Connection#appender accepts block.
|
39
|
+
- add DuckDB::Appender#append_row.
|
40
|
+
- support HUGEINT type.
|
41
|
+
- add DuckDB::Appender#append.
|
42
|
+
- rename PreparedStatement#bind_boolean to PreparedStatement#bind_bool.
|
43
|
+
- add DuckDB::Connection#appender.
|
44
|
+
|
3
45
|
# 0.2.6.0
|
4
46
|
|
5
47
|
- change version policy
|
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.2.
|
4
|
+
duckdb (0.2.9.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
|
-
[](https://travis-ci.com/suketa/ruby-duckdb)
|
4
3
|
[](https://github.com/suketa/ruby-duckdb/actions?query=workflow%3AUbuntu)
|
5
4
|
[](https://github.com/suketa/ruby-duckdb/actions?query=workflow%3AMacOS)
|
5
|
+
[](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
|
@@ -68,7 +68,7 @@ end
|
|
68
68
|
### using BLOB column
|
69
69
|
|
70
70
|
BLOB is available with DuckDB v0.2.5 or later.
|
71
|
-
Use `DuckDB::Blob.new` or use sting#force_encoding(Encoding::
|
71
|
+
Use `DuckDB::Blob.new` or use sting#force_encoding(Encoding::BINARY)
|
72
72
|
|
73
73
|
```
|
74
74
|
require 'duckdb'
|
@@ -87,3 +87,83 @@ DuckDB::Database.open do |db|
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
```
|
90
|
+
|
91
|
+
### Appender
|
92
|
+
|
93
|
+
Appender class provides Ruby interface of [DuckDB Appender](https://duckdb.org/docs/data/appender)
|
94
|
+
|
95
|
+
```
|
96
|
+
require 'duckdb'
|
97
|
+
require 'benchmark'
|
98
|
+
|
99
|
+
def insert
|
100
|
+
DuckDB::Database.open do |db|
|
101
|
+
db.connect do |con|
|
102
|
+
con.query('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
|
103
|
+
10000.times do
|
104
|
+
con.query("INSERT into users VALUES(1, 'Alice')")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def prepare
|
111
|
+
DuckDB::Database.open do |db|
|
112
|
+
db.connect do |con|
|
113
|
+
con.query('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
|
114
|
+
stmt = con.prepared_statement('INSERT INTO users VALUES($1, $2)')
|
115
|
+
10000.times do
|
116
|
+
stmt.bind(1, 1)
|
117
|
+
stmt.bind(2, 'Alice')
|
118
|
+
stmt.execute
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def append
|
125
|
+
DuckDB::Database.open do |db|
|
126
|
+
db.connect do |con|
|
127
|
+
con.query('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
|
128
|
+
appender = con.appender('users')
|
129
|
+
10000.times do
|
130
|
+
appender.begin_row
|
131
|
+
appender.append(1)
|
132
|
+
appender.append('Alice')
|
133
|
+
appender.end_row
|
134
|
+
end
|
135
|
+
appender.flush
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
Benchmark.bm(8) do |x|
|
141
|
+
x.report('insert') { insert }
|
142
|
+
x.report('prepare') { prepare }
|
143
|
+
x.report('append') { append }
|
144
|
+
end
|
145
|
+
|
146
|
+
# =>
|
147
|
+
# user system total real
|
148
|
+
# insert 0.637439 0.000000 0.637439 ( 0.637486 )
|
149
|
+
# prepare 0.230457 0.000000 0.230457 ( 0.230460 )
|
150
|
+
# append 0.012666 0.000000 0.012666 ( 0.012670 )
|
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
|
|
@@ -112,7 +133,7 @@ static VALUE appender_append_int8(VALUE self, VALUE val) {
|
|
112
133
|
|
113
134
|
static VALUE appender_append_int16(VALUE self, VALUE val) {
|
114
135
|
rubyDuckDBAppender *ctx;
|
115
|
-
int16_t i16val = NUM2INT(val);
|
136
|
+
int16_t i16val = (int16_t)NUM2INT(val);
|
116
137
|
|
117
138
|
Data_Get_Struct(self, rubyDuckDBAppender, ctx);
|
118
139
|
|
@@ -136,7 +157,7 @@ static VALUE appender_append_int32(VALUE self, VALUE val) {
|
|
136
157
|
|
137
158
|
static VALUE appender_append_int64(VALUE self, VALUE val) {
|
138
159
|
rubyDuckDBAppender *ctx;
|
139
|
-
int64_t i64val = NUM2LL(val);
|
160
|
+
int64_t i64val = (int64_t)NUM2LL(val);
|
140
161
|
|
141
162
|
Data_Get_Struct(self, rubyDuckDBAppender, ctx);
|
142
163
|
|
@@ -184,7 +205,7 @@ static VALUE appender_append_uint32(VALUE self, VALUE val) {
|
|
184
205
|
|
185
206
|
static VALUE appender_append_uint64(VALUE self, VALUE val) {
|
186
207
|
rubyDuckDBAppender *ctx;
|
187
|
-
uint64_t ui64val = (
|
208
|
+
uint64_t ui64val = (uint64_t)NUM2ULL(val);
|
188
209
|
|
189
210
|
Data_Get_Struct(self, rubyDuckDBAppender, ctx);
|
190
211
|
|
@@ -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
|
+
|