duckdb 0.0.12 → 0.2.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a0f6c8a46cecbe281cf970b5e8c6fd11c2903a5ddd58bf683341bcb299d7a36
4
- data.tar.gz: 6ba452c2aa37f77c68905413e3bb6cb27697f8db23bfeca1e8ca1886ce6fb1ab
3
+ metadata.gz: a07cf98bca895ec39cc43754e6f69544e22c16cab023554daa632dc0be14d527
4
+ data.tar.gz: d2e96a7556e9ab139fb4b03f8306961d011c80ff9eb259bb8f29cdbd390ea757
5
5
  SHA512:
6
- metadata.gz: beb0db8d6e590ee4014aa4fb1e09a7093d6b13cebe3ad38f90cf6f29707b5e768696732f33c5d53027032ba7eacc8bf8ddecb9b112a042f05b17bbb98e086197
7
- data.tar.gz: 228651ac8ed6c13044cbf0e3709444464ff552b0b431b051446def7dce074b38ef8a242f72e75c8c1ba788ae13dfc88a2041f7f2e9e70b64fb3c34c9c2c8ad85
6
+ metadata.gz: fc64b4021083e0837de1c22470b015be7337f2e43754771c36b4265f133542bb7161762fa51a46f2ec9f9ac992bf67bb45e7d8031206f4cd385f248bddcff14d
7
+ data.tar.gz: 131cb3b1ee245cb765b8b7081d8fb900634055cf6570e6220121991e275d53e7be44ac1c1274c64f4c8991cd3252823274fd887fa3b49a31c8dc9578dd4aade6
@@ -7,7 +7,7 @@ jobs:
7
7
  runs-on: macos-latest
8
8
  strategy:
9
9
  matrix:
10
- ruby: ['2.5.8', '2.6.6', '2.7.2', '3.0.0', 'head']
10
+ ruby: ['2.5.8', '2.6.8', '2.7.4', '3.0.2', 'head']
11
11
 
12
12
  steps:
13
13
  - uses: actions/checkout@v2
@@ -17,15 +17,9 @@ jobs:
17
17
  with:
18
18
  ruby-version: ${{ matrix.ruby }}
19
19
 
20
- - name: Install duckdb
21
- env:
22
- DUCKDB_VERSION: 0.2.4
20
+ - name: Install latest duckdb by brew
23
21
  run: |
24
22
  brew install duckdb
25
- git clone -b v${DUCKDB_VERSION} https://github.com/cwida/duckdb.git duckdb-v${DUCKDB_VERSION}
26
- cp duckdb-v${DUCKDB_VERSION}/src/include/duckdb.h /usr/local/include
27
- mkdir -p /usr/local/include/duckdb/common
28
- cp duckdb-v${DUCKDB_VERSION}/src/include/duckdb/common/winapi.hpp /usr/local/include/duckdb/common
29
23
 
30
24
  - name: Build and test with Rake with Ruby ${{ matrix.ruby }}
31
25
  run: |
@@ -8,8 +8,8 @@ jobs:
8
8
  runs-on: ubuntu-latest
9
9
  strategy:
10
10
  matrix:
11
- ruby: ['2.5.8', '2.6.6', '2.7.2', '3.0.0', 'head']
12
- duckdb: ['0.2.4', '0.2.5']
11
+ ruby: ['2.5.8', '2.6.8', '2.7.4', '3.0.2', 'head']
12
+ duckdb: ['0.2.8', '0.2.7']
13
13
 
14
14
  steps:
15
15
  - uses: actions/checkout@v2
@@ -19,43 +19,43 @@ jobs:
19
19
  with:
20
20
  ruby-version: ${{ matrix.ruby }}
21
21
 
22
- - name: duckdb 0.2.4 cache
23
- id: duckdb-cache-v0_2_4
22
+ - name: duckdb 0.2.8 cache
23
+ id: duckdb-cache-v0_2_8
24
24
  uses: actions/cache@v1.1.0
25
25
  with:
26
- path: duckdb-v0.2.4
27
- key: ${{ runner.os }}-duckdb-v0_2_4_001
26
+ path: duckdb-v0.2.8
27
+ key: ${{ runner.os }}-duckdb-v0_2_8_001
28
28
  restore-keys: |
29
- ${{ runner.os }}-duckdb-v0_2_4
29
+ ${{ runner.os }}-duckdb-v0_2_8
30
30
 
31
- - name: duckdb 0.2.5 cache
32
- id: duckdb-cache-v0_2_5
31
+ - name: duckdb 0.2.7 cache
32
+ id: duckdb-cache-v0_2_7
33
33
  uses: actions/cache@v1.1.0
34
34
  with:
35
- path: duckdb-v0.2.5
36
- key: ${{ runner.os }}-duckdb-v0_2_5_001
35
+ path: duckdb-v0.2.7
36
+ key: ${{ runner.os }}-duckdb-v0_2_7_001
37
37
  restore-keys: |
38
- ${{ runner.os }}-duckdb-v0_2_5
38
+ ${{ runner.os }}-duckdb-v0_2_7
39
39
 
40
- - name: Build duckdb 0.2.4
41
- if: steps.duckdb-cache-v0_2_4.outputs.cache-hit != 'true'
40
+ - name: Build duckdb 0.2.8
41
+ if: steps.duckdb-cache-v0_2_8.outputs.cache-hit != 'true'
42
42
  run: |
43
- git clone -b v0.2.4 https://github.com/cwida/duckdb.git duckdb-tmp-v0.2.4
44
- cd duckdb-tmp-v0.2.4 && make && cd ..
45
- rm -rf duckdb-v0.2.4
46
- mkdir -p duckdb-v0.2.4/build/release/src duckdb-v0.2.4/src
47
- cp -rip duckdb-tmp-v0.2.4/build/release/src/*.so duckdb-v0.2.4/build/release/src
48
- cp -rip duckdb-tmp-v0.2.4/src/include duckdb-v0.2.4/src/
43
+ git clone -b v0.2.8 https://github.com/cwida/duckdb.git duckdb-tmp-v0.2.8
44
+ cd duckdb-tmp-v0.2.8 && make && cd ..
45
+ rm -rf duckdb-v0.2.8
46
+ mkdir -p duckdb-v0.2.8/build/release/src duckdb-v0.2.8/src
47
+ cp -rip duckdb-tmp-v0.2.8/build/release/src/*.so duckdb-v0.2.8/build/release/src
48
+ cp -rip duckdb-tmp-v0.2.8/src/include duckdb-v0.2.8/src/
49
49
 
50
- - name: Build duckdb 0.2.5
51
- if: steps.duckdb-cache-v0_2_5.outputs.cache-hit != 'true'
50
+ - name: Build duckdb 0.2.7
51
+ if: steps.duckdb-cache-v0_2_7.outputs.cache-hit != 'true'
52
52
  run: |
53
- git clone -b v0.2.5 https://github.com/cwida/duckdb.git duckdb-tmp-v0.2.5
54
- cd duckdb-tmp-v0.2.5 && make && cd ..
55
- rm -rf duckdb-v0.2.5
56
- mkdir -p duckdb-v0.2.5/build/release/src duckdb-v0.2.5/src
57
- cp -rip duckdb-tmp-v0.2.5/build/release/src/*.so duckdb-v0.2.5/build/release/src
58
- cp -rip duckdb-tmp-v0.2.5/src/include duckdb-v0.2.5/src/
53
+ git clone -b v0.2.7 https://github.com/cwida/duckdb.git duckdb-tmp-v0.2.7
54
+ cd duckdb-tmp-v0.2.7 && make && cd ..
55
+ rm -rf duckdb-v0.2.7
56
+ mkdir -p duckdb-v0.2.7/build/release/src duckdb-v0.2.7/src
57
+ cp -rip duckdb-tmp-v0.2.7/build/release/src/*.so duckdb-v0.2.7/build/release/src
58
+ cp -rip duckdb-tmp-v0.2.7/src/include duckdb-v0.2.7/src/
59
59
 
60
60
  - name: Build and test with Rake with Ruby ${{ matrix.ruby }}
61
61
  env:
@@ -0,0 +1,37 @@
1
+ name: Windows
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: windows-latest
8
+ strategy:
9
+ matrix:
10
+ ruby: ['2.5.8', '2.6.7', '2.7.3', '3.0.1', 'head']
11
+
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+
15
+ - name: Set up Ruby
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby }}
19
+
20
+ - name: download duckdb binary for windows 64bit
21
+ run: |
22
+ curl -OL https://github.com/duckdb/duckdb/releases/download/v0.2.6/libduckdb-windows-amd64.zip
23
+
24
+ - name: extract zip file
25
+ run: |
26
+ 7z x libduckdb-windows-amd64.zip
27
+
28
+ - name: Build with Rake with Ruby ${{ matrix.ruby }}
29
+ run: |
30
+ bundle install
31
+ bundle exec rake build -- --with-duckdb-include=../../../.. --with-duckdb-lib=../../../..
32
+
33
+ # FIXME: rake test fails with LoadError
34
+ # 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)`
35
+ # - name: rake test
36
+ # run: |
37
+ # rake test
data/.travis.yml CHANGED
@@ -2,17 +2,17 @@ language: ruby
2
2
  cache:
3
3
  bundler: true
4
4
  directories:
5
- - ${HOME}/duckdb-v0.2.5
5
+ - ${HOME}/duckdb-v0.2.8
6
6
  before_install:
7
7
  - yes | gem update --system
8
- - if [[ ! -d ${HOME}/duckdb-v0.2.5/build ]]; then cd ${HOME} && git clone -b v0.2.5 https://github.com/cwida/duckdb.git duckdb-v0.2.5 && cd duckdb-v0.2.5 && make && cd ${TRAVIS_BUILD_DIR}; fi
8
+ - if [[ ! -d ${HOME}/duckdb-v0.2.8/build ]]; then cd ${HOME} && git clone -b v0.2.8 https://github.com/cwida/duckdb.git duckdb-v0.2.8 && cd duckdb-v0.2.8 && make && cd ${TRAVIS_BUILD_DIR}; fi
9
9
 
10
10
  env:
11
- - DUCKDB_VERSION=0.2.5
11
+ - DUCKDB_VERSION=0.2.8
12
12
  rvm:
13
13
  - 2.5.8
14
- - 2.6.6
15
- - 2.7.2
16
- - 3.0.0
14
+ - 2.6.8
15
+ - 2.7.4
16
+ - 3.0.2
17
17
  - ruby-head
18
18
  script: bundle exec rake -- --with-duckdb-include=${HOME}/duckdb-v${DUCKDB_VERSION}/src/include --with-duckdb-lib=${HOME}/duckdb-v${DUCKDB_VERSION}/build/release/src/
data/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # ChangeLog
2
2
 
3
+ - DuckDB::Database.open accepts 2-nd argument as DuckDB::Config object.
4
+ - add DuckDB::Config
5
+ - bump duckdb to 0.2.8 in CI
6
+ - bump Ruby to 2.6.8, 2.7.4, 3.0.2 in CI
7
+
8
+ # 0.2.7.0
9
+
10
+ - call duckdb_free after calling duckdb_value_blob, duckdb_value_varchar.
11
+ - bump DuckDB to v0.2.7 in CI
12
+ - rake build on Windows in github actions.
13
+ - There is a issue (LoadError) when running rake test on Windows (in GitHub actions).
14
+
15
+ # 0.2.6.1
16
+
17
+ - add DuckDB::PreparedStatement#bind_int8
18
+ - DuckDB::Connection#appender accepts block.
19
+ - add DuckDB::Appender#append_row.
20
+ - support HUGEINT type.
21
+ - add DuckDB::Appender#append.
22
+ - rename PreparedStatement#bind_boolean to PreparedStatement#bind_bool.
23
+ - add DuckDB::Connection#appender.
24
+
25
+ # 0.2.6.0
26
+
27
+ - change version policy
28
+ - ruby-duckdb W.X.Y.Z supports duckdb W.X.Y
29
+ - add DuckDB::Appender
30
+ - bump DuckDB to v0.2.6 in CI.
31
+ - remove unnecessary duckdb header file from MacOS CI.
32
+ - add DuckDB::Connection#prepared_statement.
33
+
3
34
  ## 0.0.12
4
35
 
5
36
  - bump DuckDB to v0.2.5
data/Gemfile.lock CHANGED
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (0.0.12)
4
+ duckdb (0.2.8.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.3)
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.3
25
+ 2.2.25
data/README.md CHANGED
@@ -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::ASCII_8BIT)
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
+ ```
@@ -0,0 +1,315 @@
1
+ #include "ruby-duckdb.h"
2
+
3
+ #ifdef HAVE_DUCKDB_APPENDER_CREATE
4
+
5
+ static VALUE cDuckDBAppender;
6
+
7
+ static void deallocate(void *);
8
+ static VALUE allocate(VALUE klass);
9
+ static VALUE appender_initialize(VALUE klass, VALUE con, VALUE schema, VALUE table);
10
+ static VALUE appender_begin_row(VALUE self);
11
+ static VALUE appender_end_row(VALUE self);
12
+ static VALUE appender_append_bool(VALUE self, VALUE val);
13
+ static VALUE appender_append_int8(VALUE self, VALUE val);
14
+ static VALUE appender_append_int16(VALUE self, VALUE val);
15
+ static VALUE appender_append_int32(VALUE self, VALUE val);
16
+ static VALUE appender_append_int64(VALUE self, VALUE val);
17
+ static VALUE appender_append_uint8(VALUE self, VALUE val);
18
+ static VALUE appender_append_uint16(VALUE self, VALUE val);
19
+ static VALUE appender_append_uint32(VALUE self, VALUE val);
20
+ static VALUE appender_append_uint64(VALUE self, VALUE val);
21
+ static VALUE appender_append_float(VALUE self, VALUE val);
22
+ static VALUE appender_append_double(VALUE self, VALUE val);
23
+ static VALUE appender_append_varchar(VALUE self, VALUE val);
24
+ static VALUE appender_append_varchar_length(VALUE self, VALUE val, VALUE len);
25
+ static VALUE appender_append_blob(VALUE self, VALUE val);
26
+ static VALUE appender_append_null(VALUE self);
27
+ static VALUE appender_flush(VALUE self);
28
+ static VALUE appender_close(VALUE self);
29
+
30
+ static void deallocate(void * ctx)
31
+ {
32
+ rubyDuckDBAppender *p = (rubyDuckDBAppender *)ctx;
33
+
34
+ duckdb_appender_destroy(&(p->appender));
35
+ xfree(p);
36
+ }
37
+
38
+ static VALUE allocate(VALUE klass)
39
+ {
40
+ rubyDuckDBAppender *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBAppender));
41
+ return Data_Wrap_Struct(klass, NULL, deallocate, ctx);
42
+ }
43
+
44
+ static VALUE appender_initialize(VALUE self, VALUE con, VALUE schema, VALUE table) {
45
+
46
+ rubyDuckDBConnection *ctxcon;
47
+ rubyDuckDBAppender *ctx;
48
+ char *pschema = 0;
49
+
50
+ if (!rb_obj_is_kind_of(con, cDuckDBConnection)) {
51
+ rb_raise(rb_eTypeError, "1st argument should be instance of DackDB::Connection");
52
+ }
53
+
54
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
55
+ Data_Get_Struct(con, rubyDuckDBConnection, ctxcon);
56
+
57
+ if (schema != Qnil) {
58
+ pschema = StringValuePtr(schema);
59
+ }
60
+
61
+ if (duckdb_appender_create(ctxcon->con, pschema, StringValuePtr(table), &(ctx->appender)) == DuckDBError) {
62
+ rb_raise(eDuckDBError, "failed to create appender");
63
+ }
64
+ return self;
65
+ }
66
+
67
+ static VALUE appender_begin_row(VALUE self) {
68
+ rubyDuckDBAppender *ctx;
69
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
70
+
71
+ if (duckdb_appender_begin_row(ctx->appender) == DuckDBError) {
72
+ rb_raise(eDuckDBError, "failed to flush");
73
+ }
74
+ return self;
75
+ }
76
+
77
+ static VALUE appender_end_row(VALUE self) {
78
+ rubyDuckDBAppender *ctx;
79
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
80
+
81
+ if (duckdb_appender_end_row(ctx->appender) == DuckDBError) {
82
+ rb_raise(eDuckDBError, "failed to flush");
83
+ }
84
+ return self;
85
+ }
86
+
87
+ static VALUE appender_append_bool(VALUE self, VALUE val) {
88
+ rubyDuckDBAppender *ctx;
89
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
90
+
91
+ if (val != Qtrue && val != Qfalse) {
92
+ rb_raise(rb_eArgError, "argument must be boolean");
93
+ }
94
+
95
+ if (duckdb_append_bool(ctx->appender, (val == Qtrue)) == DuckDBError) {
96
+ rb_raise(eDuckDBError, "failed to append boolean");
97
+ }
98
+ return self;
99
+ }
100
+
101
+ static VALUE appender_append_int8(VALUE self, VALUE val) {
102
+ rubyDuckDBAppender *ctx;
103
+ int8_t i8val = (int8_t)NUM2INT(val);
104
+
105
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
106
+
107
+ if (duckdb_append_int8(ctx->appender, i8val) == DuckDBError) {
108
+ rb_raise(eDuckDBError, "failed to append");
109
+ }
110
+ return self;
111
+ }
112
+
113
+ static VALUE appender_append_int16(VALUE self, VALUE val) {
114
+ rubyDuckDBAppender *ctx;
115
+ int16_t i16val = (int16_t)NUM2INT(val);
116
+
117
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
118
+
119
+ if (duckdb_append_int16(ctx->appender, i16val) == DuckDBError) {
120
+ rb_raise(eDuckDBError, "failed to append");
121
+ }
122
+ return self;
123
+ }
124
+
125
+ static VALUE appender_append_int32(VALUE self, VALUE val) {
126
+ rubyDuckDBAppender *ctx;
127
+ int32_t i32val = (int32_t)NUM2INT(val);
128
+
129
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
130
+
131
+ if (duckdb_append_int32(ctx->appender, i32val) == DuckDBError) {
132
+ rb_raise(eDuckDBError, "failed to append");
133
+ }
134
+ return self;
135
+ }
136
+
137
+ static VALUE appender_append_int64(VALUE self, VALUE val) {
138
+ rubyDuckDBAppender *ctx;
139
+ int64_t i64val = (int64_t)NUM2LL(val);
140
+
141
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
142
+
143
+ if (duckdb_append_int64(ctx->appender, i64val) == DuckDBError) {
144
+ rb_raise(eDuckDBError, "failed to append");
145
+ }
146
+ return self;
147
+ }
148
+
149
+ static VALUE appender_append_uint8(VALUE self, VALUE val) {
150
+ rubyDuckDBAppender *ctx;
151
+ int8_t ui8val = (uint8_t)NUM2UINT(val);
152
+
153
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
154
+
155
+ if (duckdb_append_uint8(ctx->appender, ui8val) == DuckDBError) {
156
+ rb_raise(eDuckDBError, "failed to append");
157
+ }
158
+ return self;
159
+ }
160
+
161
+ static VALUE appender_append_uint16(VALUE self, VALUE val) {
162
+ rubyDuckDBAppender *ctx;
163
+ uint16_t ui16val = (uint16_t)NUM2UINT(val);
164
+
165
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
166
+
167
+ if (duckdb_append_uint16(ctx->appender, ui16val) == DuckDBError) {
168
+ rb_raise(eDuckDBError, "failed to append");
169
+ }
170
+ return self;
171
+ }
172
+
173
+ static VALUE appender_append_uint32(VALUE self, VALUE val) {
174
+ rubyDuckDBAppender *ctx;
175
+ uint32_t ui32val = (uint32_t)NUM2UINT(val);
176
+
177
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
178
+
179
+ if (duckdb_append_uint32(ctx->appender, ui32val) == DuckDBError) {
180
+ rb_raise(eDuckDBError, "failed to append");
181
+ }
182
+ return self;
183
+ }
184
+
185
+ static VALUE appender_append_uint64(VALUE self, VALUE val) {
186
+ rubyDuckDBAppender *ctx;
187
+ uint64_t ui64val = (uint64_t)NUM2ULL(val);
188
+
189
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
190
+
191
+ if (duckdb_append_uint64(ctx->appender, ui64val) == DuckDBError) {
192
+ rb_raise(eDuckDBError, "failed to append");
193
+ }
194
+ return self;
195
+ }
196
+
197
+ static VALUE appender_append_float(VALUE self, VALUE val) {
198
+ rubyDuckDBAppender *ctx;
199
+ float fval = (float)NUM2DBL(val);
200
+
201
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
202
+
203
+ if (duckdb_append_float(ctx->appender, fval) == DuckDBError) {
204
+ rb_raise(eDuckDBError, "failed to append");
205
+ }
206
+ return self;
207
+ }
208
+
209
+ static VALUE appender_append_double(VALUE self, VALUE val) {
210
+ rubyDuckDBAppender *ctx;
211
+ double dval = NUM2DBL(val);
212
+
213
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
214
+
215
+ if (duckdb_append_double(ctx->appender, dval) == DuckDBError) {
216
+ rb_raise(eDuckDBError, "failed to append");
217
+ }
218
+ return self;
219
+ }
220
+
221
+ static VALUE appender_append_varchar(VALUE self, VALUE val) {
222
+ rubyDuckDBAppender *ctx;
223
+ char *pval = StringValuePtr(val);
224
+
225
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
226
+
227
+ if (duckdb_append_varchar(ctx->appender, pval) == DuckDBError) {
228
+ rb_raise(eDuckDBError, "failed to append");
229
+ }
230
+ return self;
231
+ }
232
+
233
+ static VALUE appender_append_varchar_length(VALUE self, VALUE val, VALUE len) {
234
+ rubyDuckDBAppender *ctx;
235
+
236
+ char *pval = StringValuePtr(val);
237
+ idx_t length = (idx_t)NUM2ULL(len);
238
+
239
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
240
+
241
+ if (duckdb_append_varchar_length(ctx->appender, pval, length) == DuckDBError) {
242
+ rb_raise(eDuckDBError, "failed to append");
243
+ }
244
+ return self;
245
+ }
246
+
247
+ static VALUE appender_append_blob(VALUE self, VALUE val) {
248
+ rubyDuckDBAppender *ctx;
249
+
250
+ char *pval = StringValuePtr(val);
251
+ idx_t length = (idx_t)RSTRING_LEN(val);
252
+
253
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
254
+
255
+ if (duckdb_append_blob(ctx->appender, (void *)pval, length) == DuckDBError) {
256
+ rb_raise(eDuckDBError, "failed to append");
257
+ }
258
+ return self;
259
+ }
260
+
261
+ static VALUE appender_append_null(VALUE self) {
262
+ rubyDuckDBAppender *ctx;
263
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
264
+
265
+ if (duckdb_append_null(ctx->appender) == DuckDBError) {
266
+ rb_raise(eDuckDBError, "failed to append");
267
+ }
268
+ return self;
269
+ }
270
+
271
+ static VALUE appender_flush(VALUE self) {
272
+ rubyDuckDBAppender *ctx;
273
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
274
+
275
+ if (duckdb_appender_flush(ctx->appender) == DuckDBError) {
276
+ rb_raise(eDuckDBError, "failed to flush");
277
+ }
278
+ return self;
279
+ }
280
+
281
+ static VALUE appender_close(VALUE self) {
282
+ rubyDuckDBAppender *ctx;
283
+ Data_Get_Struct(self, rubyDuckDBAppender, ctx);
284
+
285
+ if (duckdb_appender_close(ctx->appender) == DuckDBError) {
286
+ rb_raise(eDuckDBError, "failed to flush");
287
+ }
288
+ return self;
289
+ }
290
+
291
+ void init_duckdb_appender(void) {
292
+ cDuckDBAppender = rb_define_class_under(mDuckDB, "Appender", rb_cObject);
293
+ rb_define_alloc_func(cDuckDBAppender, allocate);
294
+ rb_define_method(cDuckDBAppender, "initialize", appender_initialize, 3);
295
+ rb_define_method(cDuckDBAppender, "begin_row", appender_begin_row, 0);
296
+ rb_define_method(cDuckDBAppender, "end_row", appender_end_row, 0);
297
+ rb_define_method(cDuckDBAppender, "append_bool", appender_append_bool, 1);
298
+ rb_define_method(cDuckDBAppender, "append_int8", appender_append_int8, 1);
299
+ rb_define_method(cDuckDBAppender, "append_int16", appender_append_int16, 1);
300
+ rb_define_method(cDuckDBAppender, "append_int32", appender_append_int32, 1);
301
+ rb_define_method(cDuckDBAppender, "append_int64", appender_append_int64, 1);
302
+ rb_define_method(cDuckDBAppender, "append_uint8", appender_append_uint8, 1);
303
+ rb_define_method(cDuckDBAppender, "append_uint16", appender_append_uint16, 1);
304
+ rb_define_method(cDuckDBAppender, "append_uint32", appender_append_uint32, 1);
305
+ rb_define_method(cDuckDBAppender, "append_uint64", appender_append_uint64, 1);
306
+ rb_define_method(cDuckDBAppender, "append_float", appender_append_float, 1);
307
+ rb_define_method(cDuckDBAppender, "append_double", appender_append_double, 1);
308
+ rb_define_method(cDuckDBAppender, "append_varchar", appender_append_varchar, 1);
309
+ rb_define_method(cDuckDBAppender, "append_varchar_length", appender_append_varchar_length, 2);
310
+ rb_define_method(cDuckDBAppender, "append_blob", appender_append_blob, 1);
311
+ rb_define_method(cDuckDBAppender, "append_null", appender_append_null, 0);
312
+ rb_define_method(cDuckDBAppender, "flush", appender_flush, 0);
313
+ rb_define_method(cDuckDBAppender, "close", appender_close, 0);
314
+ }
315
+ #endif /* HAVE_DUCKDB_APPENDER_CREATE */