duckdb 0.0.5 → 0.0.9

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: 599ebecd3f693be06ff46fec535485d6ac6019cd889405a502d21a2f801c9ba8
4
- data.tar.gz: '0811911b5f0c3404f8c7ff9c2351d97668013dd576d4f5a98775e9af45df5e52'
3
+ metadata.gz: bf81ef5bf9902f3bf915c375d87d4e56b5b753a290aad2020c20757b1aaaa86b
4
+ data.tar.gz: 8ef86fc4daba6aac83b83d48ee98613e4ca62fee7d9520610cf05b9afa4baaa8
5
5
  SHA512:
6
- metadata.gz: b4ca8e956de0edbb9aa9ceed9273a48f3cf847e5ff79732b849465c59fa2030af5cd81c62344e953e96990e11c48ff1b2dd8bd3cd87f3bc8271079aeb69a31bd
7
- data.tar.gz: 3501865c8c0aa7c70761705e06026aadd95e112d34fd9eed1152ae269407fddc7cdbe6a84f6f3f8cda917022bda45fb0d349b51400b939f43b74ae64bb8e43bf
6
+ metadata.gz: c5006b08f821979184ee6edd3f7ef2a47339aab1487b6208cf4ea7af2d55e846fb5f197810e265f27ca327bd4004a2778569ed7bf7adf64e371df7eb7b11c253
7
+ data.tar.gz: 174232c0eef492cf9d98dc979dbe7f6960c57cb72d76d9adf2cee59cf5a09cc0643919044fa4e111c65a65b53e2bbe15b3e6891482630e72813ab73f9e6f464b
@@ -0,0 +1,66 @@
1
+ name: Ubuntu
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+
8
+ runs-on: ubuntu-latest
9
+ strategy:
10
+ matrix:
11
+ ruby: ['2.5.8', '2.6.6', '2.7.2', 'head']
12
+ duckdb: ['0.2.0', '0.2.1']
13
+
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+
17
+ - name: Set up Ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: ${{ matrix.ruby }}
21
+
22
+ - name: duckdb 0.2.0 cache
23
+ id: duckdb-cache-v0_2_0
24
+ uses: actions/cache@v1.1.0
25
+ with:
26
+ path: duckdb-v0.2.0
27
+ key: ${{ runner.os }}-duckdb-v0_2_0_001
28
+ restore-keys: |
29
+ ${{ runner.os }}-duckdb-v0_2_0
30
+
31
+ - name: duckdb 0.2.1 cache
32
+ id: duckdb-cache-v0_2_1
33
+ uses: actions/cache@v1.1.0
34
+ with:
35
+ path: duckdb-v0.2.1
36
+ key: ${{ runner.os }}-duckdb-v0_2_1_001
37
+ restore-keys: |
38
+ ${{ runner.os }}-duckdb-v0_2_1
39
+
40
+ - name: Build duckdb 0.2.0
41
+ if: steps.duckdb-cache-v0_2_0.outputs.cache-hit != 'true'
42
+ run: |
43
+ git clone -b v0.2.0 https://github.com/cwida/duckdb.git duckdb-tmp-v0.2.0
44
+ cd duckdb-tmp-v0.2.0 && make && cd ..
45
+ rm -rf duckdb-v0.2.0
46
+ mkdir -p duckdb-v0.2.0/build/release/src duckdb-v0.2.0/src
47
+ cp -rip duckdb-tmp-v0.2.0/build/release/src/*.so duckdb-v0.2.0/build/release/src
48
+ cp -rip duckdb-tmp-v0.2.0/src/include duckdb-v0.2.0/src/
49
+
50
+ - name: Build duckdb 0.2.1
51
+ if: steps.duckdb-cache-v0_2_1.outputs.cache-hit != 'true'
52
+ run: |
53
+ git clone -b v0.2.1 https://github.com/cwida/duckdb.git duckdb-tmp-v0.2.1
54
+ cd duckdb-tmp-v0.2.1 && make && cd ..
55
+ rm -rf duckdb-v0.2.1
56
+ mkdir -p duckdb-v0.2.1/build/release/src duckdb-v0.2.1/src
57
+ cp -rip duckdb-tmp-v0.2.1/build/release/src/*.so duckdb-v0.2.1/build/release/src
58
+ cp -rip duckdb-tmp-v0.2.1/src/include duckdb-v0.2.1/src/
59
+
60
+ - name: Build and test with Rake with Ruby ${{ matrix.ruby }}
61
+ env:
62
+ DUCKDB_VERSION: ${{ matrix.duckdb }}
63
+ run: |
64
+ gem install bundler
65
+ bundle install --jobs 4 --retry 3
66
+ bundle exec rake -- --with-duckdb-include=${GITHUB_WORKSPACE}/duckdb-v${DUCKDB_VERSION}/src/include --with-duckdb-lib=${GITHUB_WORKSPACE}/duckdb-v${DUCKDB_VERSION}/build/release/src/
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ cache:
3
+ bundler: true
4
+ directories:
5
+ - ${HOME}/duckdb-v0.2.1
6
+ before_install:
7
+ - yes | gem update --system
8
+ - if [[ ! -d ${HOME}/duckdb-v0.2.1/build ]]; then cd ${HOME} && git clone -b v0.2.1 https://github.com/cwida/duckdb.git duckdb-v0.2.1 && cd duckdb-v0.2.1 && make && cd ${TRAVIS_BUILD_DIR}; fi
9
+
10
+ env:
11
+ - DUCKDB_VERSION=0.2.1
12
+ rvm:
13
+ - 2.5.8
14
+ - 2.6.6
15
+ - 2.7.2
16
+ - ruby-head
17
+ 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/
@@ -1,5 +1,48 @@
1
1
  # ChangeLog
2
2
 
3
+ ## 0.0.9
4
+
5
+ - bump DuckDB to v0.2.1
6
+ - bump Ruby to v2.7.2
7
+ - bunmp DuckDB to v0.2.0
8
+
9
+ ## 0.0.8.1
10
+
11
+ - update Gemfile.lock
12
+ - unsupport Ruby 2.4
13
+
14
+ ## 0.0.8
15
+
16
+ - remove test with Ruby 2.4.10
17
+ - bump DuckDB to v0.1.8
18
+ - bump DuckDB to v0.1.8
19
+ - bump DuckDB to v0.1.7
20
+ - current ruby-duckdb supports DuckDB version 0.1.5 and 0.1.6
21
+ - support Ruby 2.7.1
22
+ - bump DuckDB to v0.1.6
23
+ - current ruby-duckdb supports DuckDB version 0.1.5 and 0.1.6
24
+ - DuckDB::Connection#connect accepts block
25
+ - add DuckDB::Connection#connect
26
+ - DuckDB::Database#connect accepts block
27
+ - DuckDB::Database.open accepts block
28
+ - update duckdb.gemspec, required ruby version >= 2.4.0
29
+
30
+ ## 0.0.7
31
+
32
+ - bump DuckDB to v0.1.5
33
+ - DuckDB version must be 0.1.5 or later.
34
+ - add DuckDB::Connection#connect, alias method open
35
+ - add DuckDB::Connection#disconnect, alias method close
36
+ - add DuckDB::Database#close
37
+
38
+ ## 0.0.6
39
+
40
+ - add alias `execute` of `DuckDB::Connection#query`
41
+ - support `duckdb version 0.1.3`
42
+ - add `DuckDB:PreparedStatement`
43
+ - create CI (GitHub Actions / Travis-CI)
44
+ - create database only once in result_test.rb
45
+
3
46
  ## 0.0.5
4
47
 
5
48
  - add `DuckDB::Error`
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (0.0.5)
4
+ duckdb (0.0.9)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- minitest (5.13.0)
10
- rake (10.5.0)
11
- rake-compiler (1.0.8)
9
+ minitest (5.14.2)
10
+ rake (13.0.1)
11
+ rake-compiler (1.1.1)
12
12
  rake
13
13
 
14
14
  PLATFORMS
@@ -18,8 +18,8 @@ DEPENDENCIES
18
18
  bundler (~> 2.0)
19
19
  duckdb!
20
20
  minitest (~> 5.0)
21
- rake (~> 10.0)
21
+ rake (~> 13.0)
22
22
  rake-compiler
23
23
 
24
24
  BUNDLED WITH
25
- 2.0.2
25
+ 2.1.4
data/README.md CHANGED
@@ -1,5 +1,7 @@
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
+ [![](https://github.com/suketa/ruby-duckdb/workflows/Ubuntu/badge.svg)](https://github.com/suketa/ruby-duckdb/actions?query=workflow%3AUbuntu)
3
5
 
4
6
  ## Description
5
7
 
@@ -40,3 +42,24 @@ result.each do |row|
40
42
  p row
41
43
  end
42
44
  ```
45
+
46
+ Or, you can use block.
47
+
48
+ ```
49
+ require 'duckdb'
50
+
51
+ DuckDB::Database.open do |db|
52
+ db.connect do |con|
53
+ con.query('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
54
+
55
+ con.query("INSERT into users VALUES(1, 'Alice')")
56
+ con.query("INSERT into users VALUES(2, 'Bob')")
57
+ con.query("INSERT into users VALUES(3, 'Cathy')")
58
+
59
+ result = con.query('SELECT * from users')
60
+ result.each do |row|
61
+ p row
62
+ end
63
+ end
64
+ end
65
+ ```
@@ -1,32 +1,35 @@
1
- lib = File.expand_path("lib", __dir__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "duckdb/version"
5
+ require 'duckdb/version'
4
6
 
5
7
  Gem::Specification.new do |spec|
6
- spec.name = "duckdb"
8
+ spec.name = 'duckdb'
7
9
  spec.version = DuckDB::VERSION
8
- spec.authors = ["Masaki Suketa"]
9
- spec.email = ["masaki.suketa@nifty.ne.jp"]
10
+ spec.authors = ['Masaki Suketa']
11
+ spec.email = ['masaki.suketa@nifty.ne.jp']
10
12
 
11
- spec.summary = %q{This module is Ruby binding for DuckDB database engine.}
12
- spec.description = "This module is Ruby binding for DuckDB database engine. You must have the DuckDB engine installed to build/use this module."
13
- spec.homepage = "https://github.com/suketa/ruby-duckdb"
14
- spec.license = "MIT"
13
+ spec.summary = 'This module is Ruby binding for DuckDB database engine.'
14
+ spec.description = 'This module is Ruby binding for DuckDB database engine. You must have the DuckDB engine installed to build/use this module.'
15
+ spec.homepage = 'https://github.com/suketa/ruby-duckdb'
16
+ spec.license = 'MIT'
15
17
 
16
- spec.metadata["homepage_uri"] = spec.homepage
17
- spec.metadata["source_code_uri"] = "https://github.com/suketa/ruby-duckdb"
18
- spec.metadata["changelog_uri"] = "https://github.com/suketa/ruby-duckdb/blob/master/CHANGELOG.md"
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = 'https://github.com/suketa/ruby-duckdb'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/suketa/ruby-duckdb/blob/master/CHANGELOG.md'
19
21
 
20
22
  # Specify which files should be added to the gem when it is released.
21
23
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
25
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
26
  end
25
- spec.require_paths = ["lib"]
26
- spec.extensions = ["ext/duckdb/extconf.rb"]
27
+ spec.require_paths = ['lib']
28
+ spec.extensions = ['ext/duckdb/extconf.rb']
29
+ spec.required_ruby_version = '>= 2.5.0'
27
30
 
28
- spec.add_development_dependency "bundler", "~> 2.0"
29
- spec.add_development_dependency "rake", "~> 10.0"
30
- spec.add_development_dependency "rake-compiler"
31
- spec.add_development_dependency "minitest", "~> 5.0"
31
+ spec.add_development_dependency 'bundler', '~> 2.0'
32
+ spec.add_development_dependency 'minitest', '~> 5.0'
33
+ spec.add_development_dependency 'rake', '~> 13.0'
34
+ spec.add_development_dependency 'rake-compiler'
32
35
  end
@@ -1,7 +1,5 @@
1
1
  #include "ruby-duckdb.h"
2
2
 
3
- static VALUE cDuckDBConnection;
4
-
5
3
  static void deallocate(void *ctx)
6
4
  {
7
5
  rubyDuckDBConnection *p = (rubyDuckDBConnection *)ctx;
@@ -16,7 +14,8 @@ static VALUE allocate(VALUE klass)
16
14
  return Data_Wrap_Struct(klass, NULL, deallocate, ctx);
17
15
  }
18
16
 
19
- VALUE create_connection(VALUE oDuckDBDatabase) {
17
+ VALUE create_connection(VALUE oDuckDBDatabase)
18
+ {
20
19
  rubyDuckDB *ctxdb;
21
20
  rubyDuckDBConnection *ctxcon;
22
21
  VALUE obj;
@@ -34,8 +33,36 @@ VALUE create_connection(VALUE oDuckDBDatabase) {
34
33
  return obj;
35
34
  }
36
35
 
37
- static VALUE duckdb_connection_query(VALUE self, VALUE str) {
36
+ static VALUE duckdb_connection_disconnect(VALUE self)
37
+ {
38
+ rubyDuckDBConnection *ctx;
39
+
40
+ Data_Get_Struct(self, rubyDuckDBConnection, ctx);
41
+ duckdb_disconnect(&(ctx->con));
42
+
43
+ return self;
44
+ }
45
+
46
+ static VALUE duckdb_connection_connect(VALUE self, VALUE oDuckDBDatabase)
47
+ {
48
+ rubyDuckDBConnection *ctx;
49
+ rubyDuckDB *ctxdb;
50
+
51
+ if (!rb_obj_is_kind_of(oDuckDBDatabase, cDuckDBDatabase)) {
52
+ rb_raise(rb_eTypeError, "The first argument must be DuckDB::Database object.");
53
+ }
54
+ Data_Get_Struct(oDuckDBDatabase, rubyDuckDB, ctxdb);
55
+ Data_Get_Struct(self, rubyDuckDBConnection, ctx);
56
+
57
+ if (duckdb_connect(ctxdb->db, &(ctx->con)) == DuckDBError) {
58
+ rb_raise(eDuckDBError, "connection error");
59
+ }
60
+
61
+ return self;
62
+ }
38
63
 
64
+ static VALUE duckdb_connection_query_sql(VALUE self, VALUE str)
65
+ {
39
66
  rubyDuckDBConnection *ctx;
40
67
  rubyDuckDBResult *ctxr;
41
68
 
@@ -44,6 +71,10 @@ static VALUE duckdb_connection_query(VALUE self, VALUE str) {
44
71
  Data_Get_Struct(self, rubyDuckDBConnection, ctx);
45
72
  Data_Get_Struct(result, rubyDuckDBResult, ctxr);
46
73
 
74
+ if (!(ctx->con)) {
75
+ rb_raise(eDuckDBError, "Database connection closed");
76
+ }
77
+
47
78
  if (duckdb_query(ctx->con, StringValueCStr(str), &(ctxr->result)) == DuckDBError) {
48
79
  rb_raise(eDuckDBError, "%s", ctxr->result.error_message);
49
80
  }
@@ -55,5 +86,7 @@ void init_duckdb_connection(void)
55
86
  cDuckDBConnection = rb_define_class_under(mDuckDB, "Connection", rb_cObject);
56
87
  rb_define_alloc_func(cDuckDBConnection, allocate);
57
88
 
58
- rb_define_method(cDuckDBConnection, "query", duckdb_connection_query, 1);
89
+ rb_define_method(cDuckDBConnection, "disconnect", duckdb_connection_disconnect, 0);
90
+ rb_define_private_method(cDuckDBConnection, "_connect", duckdb_connection_connect, 1);
91
+ rb_define_private_method(cDuckDBConnection, "query_sql", duckdb_connection_query_sql, 1);
59
92
  }
@@ -7,6 +7,8 @@ struct _rubyDuckDBConnection {
7
7
 
8
8
  typedef struct _rubyDuckDBConnection rubyDuckDBConnection;
9
9
 
10
+ VALUE cDuckDBConnection;
11
+
10
12
  void init_duckdb_connection(void);
11
13
  VALUE create_connection(VALUE oDuckDBDatabase);
12
14
 
@@ -1,10 +1,15 @@
1
1
  #include "ruby-duckdb.h"
2
2
 
3
+ static void close_database(rubyDuckDB *p)
4
+ {
5
+ duckdb_close(&(p->db));
6
+ }
7
+
3
8
  static void deallocate(void * ctx)
4
9
  {
5
10
  rubyDuckDB *p = (rubyDuckDB *)ctx;
6
11
 
7
- duckdb_close(&(p->db));
12
+ close_database(p);
8
13
  xfree(p);
9
14
  }
10
15
 
@@ -36,13 +41,30 @@ static VALUE duckdb_database_s_open(int argc, VALUE *argv, VALUE cDuckDBDatabase
36
41
  return obj;
37
42
  }
38
43
 
39
- static VALUE duckdb_database_connect(VALUE self) {
44
+ static VALUE duckdb_database_connect(VALUE self)
45
+ {
40
46
  return create_connection(self);
41
47
  }
42
48
 
43
- void init_duckdb_database(void) {
44
- VALUE cDuckDBDatabase = rb_define_class_under(mDuckDB, "Database", rb_cObject);
49
+ /*
50
+ * call-seq:
51
+ * duckdb.close -> DuckDB::Database
52
+ *
53
+ * closes DuckDB database.
54
+ */
55
+ static VALUE duckdb_database_close(VALUE self)
56
+ {
57
+ rubyDuckDB *ctx;
58
+ Data_Get_Struct(self, rubyDuckDB, ctx);
59
+ close_database(ctx);
60
+ return self;
61
+ }
62
+
63
+ void init_duckdb_database(void)
64
+ {
65
+ cDuckDBDatabase = rb_define_class_under(mDuckDB, "Database", rb_cObject);
45
66
  rb_define_alloc_func(cDuckDBDatabase, allocate);
46
- rb_define_singleton_method(cDuckDBDatabase, "open", duckdb_database_s_open, -1);
47
- rb_define_method(cDuckDBDatabase, "connect", duckdb_database_connect, 0);
67
+ rb_define_singleton_method(cDuckDBDatabase, "_open", duckdb_database_s_open, -1);
68
+ rb_define_private_method(cDuckDBDatabase, "_connect", duckdb_database_connect, 0);
69
+ rb_define_method(cDuckDBDatabase, "close", duckdb_database_close, 0);
48
70
  }
@@ -7,6 +7,8 @@ struct _rubyDuckDB {
7
7
 
8
8
  typedef struct _rubyDuckDB rubyDuckDB;
9
9
 
10
+ VALUE cDuckDBDatabase;
11
+
10
12
  void init_duckdb_database(void);
11
13
 
12
14
  #endif
@@ -3,11 +3,13 @@
3
3
  VALUE mDuckDB;
4
4
 
5
5
  void
6
- Init_duckdb_native(void) {
6
+ Init_duckdb_native(void)
7
+ {
7
8
  mDuckDB = rb_define_module("DuckDB");
8
9
 
9
10
  init_duckdb_error();
10
11
  init_duckdb_database();
11
12
  init_duckdb_connection();
12
13
  init_duckdb_result();
14
+ init_duckdb_prepared_statement();
13
15
  }
@@ -1,5 +1,6 @@
1
1
  #include "ruby-duckdb.h"
2
2
 
3
- void init_duckdb_error(void) {
3
+ void init_duckdb_error(void)
4
+ {
4
5
  eDuckDBError = rb_define_class_under(mDuckDB, "Error", rb_eStandardError);
5
6
  }
@@ -1,5 +1,6 @@
1
1
  require 'mkmf'
2
2
 
3
3
  dir_config('duckdb')
4
- have_library('duckdb')
5
- create_makefile('duckdb/duckdb_native')
4
+ if have_library('duckdb')
5
+ create_makefile('duckdb/duckdb_native')
6
+ end
@@ -0,0 +1,200 @@
1
+ #include "ruby-duckdb.h"
2
+
3
+ static VALUE cDuckDBPreparedStatement;
4
+
5
+ static void deallocate(void *ctx)
6
+ {
7
+ rubyDuckDBPreparedStatement *p = (rubyDuckDBPreparedStatement *)ctx;
8
+
9
+ duckdb_destroy_prepare(&(p->prepared_statement));
10
+ xfree(p);
11
+ }
12
+
13
+ static VALUE allocate(VALUE klass)
14
+ {
15
+ rubyDuckDBPreparedStatement *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBPreparedStatement));
16
+ return Data_Wrap_Struct(klass, NULL, deallocate, ctx);
17
+ }
18
+
19
+ static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE query)
20
+ {
21
+ rubyDuckDBConnection *ctxcon;
22
+ rubyDuckDBPreparedStatement *ctx;
23
+
24
+ if (!rb_obj_is_kind_of(con, cDuckDBConnection)) {
25
+ rb_raise(rb_eTypeError, "1st argument should be instance of DackDB::Connection");
26
+ }
27
+
28
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
29
+ Data_Get_Struct(con, rubyDuckDBConnection, ctxcon);
30
+
31
+ if (duckdb_prepare(ctxcon->con, StringValuePtr(query), &(ctx->prepared_statement)) == DuckDBError) {
32
+ /* TODO: include query parameter information in error message. */
33
+ rb_raise(eDuckDBError, "failed to prepare statement");
34
+ }
35
+ return self;
36
+ }
37
+
38
+ static VALUE duckdb_prepared_statement_nparams(VALUE self)
39
+ {
40
+ rubyDuckDBPreparedStatement *ctx;
41
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
42
+
43
+ if (duckdb_nparams(ctx->prepared_statement, &(ctx->nparams)) == DuckDBError) {
44
+ rb_raise(eDuckDBError, "failed to get number of parameters");
45
+ }
46
+ return rb_int2big(ctx->nparams);
47
+ }
48
+
49
+
50
+ static VALUE duckdb_prepared_statement_execute(VALUE self)
51
+ {
52
+ rubyDuckDBPreparedStatement *ctx;
53
+ rubyDuckDBResult *ctxr;
54
+ VALUE result = create_result();
55
+
56
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
57
+ Data_Get_Struct(result, rubyDuckDBResult, ctxr);
58
+ if (duckdb_execute_prepared(ctx->prepared_statement, &(ctxr->result)) == DuckDBError) {
59
+ rb_raise(eDuckDBError, "%s", ctxr->result.error_message);
60
+ }
61
+ return result;
62
+ }
63
+
64
+ static idx_t check_index(VALUE vidx)
65
+ {
66
+ idx_t idx = FIX2INT(vidx);
67
+ if (idx <= 0) {
68
+ rb_raise(rb_eArgError, "index of parameter must be greater than 0");
69
+ }
70
+ return idx;
71
+ }
72
+
73
+ static VALUE duckdb_prepared_statement_bind_boolean(VALUE self, VALUE vidx, VALUE val)
74
+ {
75
+ rubyDuckDBPreparedStatement *ctx;
76
+ idx_t idx = check_index(vidx);
77
+
78
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
79
+ if (val != Qtrue && val != Qfalse) {
80
+ rb_raise(rb_eArgError, "binding value must be boolean");
81
+ }
82
+
83
+ if (duckdb_bind_boolean(ctx->prepared_statement, idx, (val == Qtrue)) == DuckDBError) {
84
+ rb_raise(eDuckDBError, "fail to bind %ld parameter", idx);
85
+ }
86
+ return self;
87
+ }
88
+
89
+ static VALUE duckdb_prepared_statement_bind_int16(VALUE self, VALUE vidx, VALUE val)
90
+ {
91
+ rubyDuckDBPreparedStatement *ctx;
92
+ idx_t idx = check_index(vidx);
93
+ int16_t i16val = NUM2INT(val);
94
+
95
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
96
+
97
+ if (duckdb_bind_int16(ctx->prepared_statement, idx, i16val) == DuckDBError) {
98
+ rb_raise(eDuckDBError, "fail to bind %ld parameter", idx);
99
+ }
100
+ return self;
101
+ }
102
+
103
+ static VALUE duckdb_prepared_statement_bind_int32(VALUE self, VALUE vidx, VALUE val)
104
+ {
105
+ rubyDuckDBPreparedStatement *ctx;
106
+ idx_t idx = check_index(vidx);
107
+ int32_t i32val = NUM2LONG(val);
108
+
109
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
110
+
111
+ if (duckdb_bind_int32(ctx->prepared_statement, idx, i32val) == DuckDBError) {
112
+ rb_raise(eDuckDBError, "fail to bind %ld parameter", idx);
113
+ }
114
+ return self;
115
+ }
116
+
117
+ static VALUE duckdb_prepared_statement_bind_int64(VALUE self, VALUE vidx, VALUE val)
118
+ {
119
+ rubyDuckDBPreparedStatement *ctx;
120
+ idx_t idx = check_index(vidx);
121
+ int64_t i64val = NUM2LL(val);
122
+
123
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
124
+
125
+ if (duckdb_bind_int64(ctx->prepared_statement, idx, i64val) == DuckDBError) {
126
+ rb_raise(eDuckDBError, "fail to bind %ld parameter", idx);
127
+ }
128
+ return self;
129
+ }
130
+
131
+ static VALUE duckdb_prepared_statement_bind_float(VALUE self, VALUE vidx, VALUE val)
132
+ {
133
+ rubyDuckDBPreparedStatement *ctx;
134
+ idx_t idx = check_index(vidx);
135
+ double dbl = NUM2DBL(val);
136
+
137
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
138
+
139
+ if (duckdb_bind_float(ctx->prepared_statement, idx, (float)dbl) == DuckDBError) {
140
+ rb_raise(eDuckDBError, "fail to bind %ld parameter", idx);
141
+ }
142
+ return self;
143
+ }
144
+
145
+ static VALUE duckdb_prepared_statement_bind_double(VALUE self, VALUE vidx, VALUE val)
146
+ {
147
+ rubyDuckDBPreparedStatement *ctx;
148
+ idx_t idx = check_index(vidx);
149
+ double dbl = NUM2DBL(val);
150
+
151
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
152
+
153
+ if (duckdb_bind_double(ctx->prepared_statement, idx, dbl) == DuckDBError) {
154
+ rb_raise(eDuckDBError, "fail to bind %ld parameter", idx);
155
+ }
156
+ return self;
157
+ }
158
+
159
+ static VALUE duckdb_prepared_statement_bind_varchar(VALUE self, VALUE vidx, VALUE str)
160
+ {
161
+ rubyDuckDBPreparedStatement *ctx;
162
+ idx_t idx = check_index(vidx);
163
+
164
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
165
+ if (duckdb_bind_varchar(ctx->prepared_statement, idx, StringValuePtr(str)) == DuckDBError) {
166
+ rb_raise(eDuckDBError, "fail to bind %ld parameter", idx);
167
+ }
168
+ return self;
169
+ }
170
+
171
+ static VALUE duckdb_prepared_statement_bind_null(VALUE self, VALUE vidx)
172
+ {
173
+ rubyDuckDBPreparedStatement *ctx;
174
+ idx_t idx = check_index(vidx);
175
+
176
+ Data_Get_Struct(self, rubyDuckDBPreparedStatement, ctx);
177
+ if (duckdb_bind_null(ctx->prepared_statement, idx) == DuckDBError) {
178
+ rb_raise(eDuckDBError, "fail to bind %ld parameter", idx);
179
+ }
180
+ return self;
181
+ }
182
+
183
+ void init_duckdb_prepared_statement(void)
184
+ {
185
+ cDuckDBPreparedStatement = rb_define_class_under(mDuckDB, "PreparedStatement", rb_cObject);
186
+
187
+ rb_define_alloc_func(cDuckDBPreparedStatement, allocate);
188
+
189
+ rb_define_method(cDuckDBPreparedStatement, "initialize", duckdb_prepared_statement_initialize, 2);
190
+ rb_define_method(cDuckDBPreparedStatement, "execute", duckdb_prepared_statement_execute, 0);
191
+ rb_define_method(cDuckDBPreparedStatement, "nparams", duckdb_prepared_statement_nparams, 0);
192
+ rb_define_method(cDuckDBPreparedStatement, "bind_boolean", duckdb_prepared_statement_bind_boolean, 2);
193
+ rb_define_method(cDuckDBPreparedStatement, "bind_int16", duckdb_prepared_statement_bind_int16, 2);
194
+ rb_define_method(cDuckDBPreparedStatement, "bind_int32", duckdb_prepared_statement_bind_int32, 2);
195
+ rb_define_method(cDuckDBPreparedStatement, "bind_int64", duckdb_prepared_statement_bind_int64, 2);
196
+ rb_define_method(cDuckDBPreparedStatement, "bind_float", duckdb_prepared_statement_bind_float, 2);
197
+ rb_define_method(cDuckDBPreparedStatement, "bind_double", duckdb_prepared_statement_bind_double, 2);
198
+ rb_define_method(cDuckDBPreparedStatement, "bind_varchar", duckdb_prepared_statement_bind_varchar, 2);
199
+ rb_define_method(cDuckDBPreparedStatement, "bind_null", duckdb_prepared_statement_bind_null, 1);
200
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef RUBY_DUCKDB_PREPARED_STATEMENT_H
2
+ #define RUBY_DUCKDB_PREPARED_STATEMENT_H
3
+
4
+ struct _rubyDuckDBPreparedStatement {
5
+ duckdb_prepared_statement prepared_statement;
6
+ idx_t nparams;
7
+ };
8
+
9
+ typedef struct _rubyDuckDBPreparedStatement rubyDuckDBPreparedStatement;
10
+
11
+ void init_duckdb_prepared_statement(void);
12
+
13
+ #endif
@@ -16,37 +16,44 @@ static VALUE allocate(VALUE klass)
16
16
  return Data_Wrap_Struct(klass, NULL, deallocate, ctx);
17
17
  }
18
18
 
19
- static VALUE to_ruby_obj_boolean(duckdb_result *result, size_t col_idx, size_t row_idx) {
19
+ static VALUE to_ruby_obj_boolean(duckdb_result *result, idx_t col_idx, idx_t row_idx)
20
+ {
20
21
  bool bval = duckdb_value_boolean(result, col_idx, row_idx);
21
22
  return bval ? Qtrue : Qnil;
22
23
  }
23
24
 
24
- static VALUE to_ruby_obj_smallint(duckdb_result *result, size_t col_idx, size_t row_idx) {
25
+ static VALUE to_ruby_obj_smallint(duckdb_result *result, idx_t col_idx, idx_t row_idx)
26
+ {
25
27
  int16_t i16val = duckdb_value_int16(result, col_idx, row_idx);
26
28
  return INT2FIX(i16val);
27
29
  }
28
30
 
29
- static VALUE to_ruby_obj_integer(duckdb_result *result, size_t col_idx, size_t row_idx) {
31
+ static VALUE to_ruby_obj_integer(duckdb_result *result, idx_t col_idx, idx_t row_idx)
32
+ {
30
33
  int32_t i32val = duckdb_value_int32(result, col_idx, row_idx);
31
34
  return INT2NUM(i32val);
32
35
  }
33
36
 
34
- static VALUE to_ruby_obj_bigint(duckdb_result *result, size_t col_idx, size_t row_idx) {
37
+ static VALUE to_ruby_obj_bigint(duckdb_result *result, idx_t col_idx, idx_t row_idx)
38
+ {
35
39
  int64_t i64val = duckdb_value_int64(result, col_idx, row_idx);
36
40
  return rb_int2big(i64val);
37
41
  }
38
42
 
39
- static VALUE to_ruby_obj_float(duckdb_result *result, size_t col_idx, size_t row_idx) {
43
+ static VALUE to_ruby_obj_float(duckdb_result *result, idx_t col_idx, idx_t row_idx)
44
+ {
40
45
  float fval = duckdb_value_float(result, col_idx, row_idx);
41
46
  return DBL2NUM(fval);
42
47
  }
43
48
 
44
- static VALUE to_ruby_obj_double(duckdb_result *result, size_t col_idx, size_t row_idx) {
49
+ static VALUE to_ruby_obj_double(duckdb_result *result, idx_t col_idx, idx_t row_idx)
50
+ {
45
51
  double dval = duckdb_value_double(result, col_idx, row_idx);
46
52
  return DBL2NUM(dval);
47
53
  }
48
54
 
49
- static VALUE to_ruby_obj(duckdb_result *result, size_t col_idx, size_t row_idx) {
55
+ static VALUE to_ruby_obj(duckdb_result *result, idx_t col_idx, idx_t row_idx)
56
+ {
50
57
  char *p;
51
58
  VALUE obj = Qnil;
52
59
  if (result->columns[col_idx].nullmask[row_idx]) {
@@ -73,8 +80,9 @@ static VALUE to_ruby_obj(duckdb_result *result, size_t col_idx, size_t row_idx)
73
80
  return obj;
74
81
  }
75
82
 
76
- static VALUE row_array(rubyDuckDBResult *ctx, size_t row_idx) {
77
- size_t col_idx;
83
+ static VALUE row_array(rubyDuckDBResult *ctx, idx_t row_idx)
84
+ {
85
+ idx_t col_idx;
78
86
  VALUE ary = rb_ary_new2(ctx->result.column_count);
79
87
  for(col_idx = 0; col_idx < ctx->result.column_count; col_idx++) {
80
88
  rb_ary_store(ary, col_idx, to_ruby_obj(&(ctx->result), col_idx, row_idx));
@@ -82,16 +90,18 @@ static VALUE row_array(rubyDuckDBResult *ctx, size_t row_idx) {
82
90
  return ary;
83
91
  }
84
92
 
85
- static VALUE duckdb_result_row_size(VALUE oDuckDBResult, VALUE args, VALUE obj) {
93
+ static VALUE duckdb_result_row_size(VALUE oDuckDBResult, VALUE args, VALUE obj)
94
+ {
86
95
  rubyDuckDBResult *ctx;
87
96
  Data_Get_Struct(oDuckDBResult, rubyDuckDBResult, ctx);
88
97
 
89
98
  return LONG2FIX(ctx->result.row_count);
90
99
  }
91
100
 
92
- static VALUE duckdb_result_each(VALUE oDuckDBResult) {
101
+ static VALUE duckdb_result_each(VALUE oDuckDBResult)
102
+ {
93
103
  rubyDuckDBResult *ctx;
94
- size_t row_idx = 0;
104
+ idx_t row_idx = 0;
95
105
 
96
106
  RETURN_SIZED_ENUMERATOR(oDuckDBResult, 0, 0, duckdb_result_row_size);
97
107
 
@@ -102,7 +112,8 @@ static VALUE duckdb_result_each(VALUE oDuckDBResult) {
102
112
  return oDuckDBResult;
103
113
  }
104
114
 
105
- VALUE create_result(void) {
115
+ VALUE create_result(void)
116
+ {
106
117
  return allocate(cDuckDBResult);
107
118
  }
108
119
 
@@ -7,6 +7,7 @@
7
7
  #include "./database.h"
8
8
  #include "./connection.h"
9
9
  #include "./result.h"
10
+ #include "./prepared_statement.h"
10
11
 
11
12
  extern VALUE mDuckDB;
12
13
 
@@ -1,6 +1,10 @@
1
- require 'duckdb/version'
2
1
  require 'duckdb/duckdb_native'
2
+ require 'duckdb/version'
3
+ require 'duckdb/database'
4
+ require 'duckdb/connection'
3
5
  require 'duckdb/result'
6
+ require 'duckdb/prepared_statement'
4
7
 
8
+ # DuckDB provides Ruby interface of DuckDB.
5
9
  module DuckDB
6
10
  end
@@ -0,0 +1,51 @@
1
+ module DuckDB
2
+ # The DuckDB::Connection encapsulates connection with DuckDB database.
3
+ #
4
+ # require 'duckdb'
5
+ # db = DuckDB::Database.open
6
+ # con = db.connect
7
+ # con.query(sql)
8
+ class Connection
9
+ #
10
+ # executes sql with args.
11
+ # The first argument sql must be SQL string.
12
+ # The rest arguments are parameters of SQL string.
13
+ # The parameters must be '?' in SQL statement.
14
+ #
15
+ # require 'duckdb'
16
+ # db = DuckDB::Database.open('duckdb_file')
17
+ # con = db.connect
18
+ # users = con.query('SELECT * FROM users')
19
+ # sql = 'SELECT * FROM users WHERE name = ? AND email = ?'
20
+ # dave = con.query(sql, 'Dave', 'dave@example.com')
21
+ #
22
+ def query(sql, *args)
23
+ return query_sql(sql) if args.empty?
24
+
25
+ stmt = PreparedStatement.new(self, sql)
26
+ args.each_with_index do |arg, i|
27
+ stmt.bind(i + 1, arg)
28
+ end
29
+ stmt.execute
30
+ end
31
+
32
+ #
33
+ # connects DuckDB database
34
+ # The first argument is DuckDB::Database object
35
+ #
36
+ def connect(db)
37
+ conn = _connect(db)
38
+ return conn unless block_given?
39
+
40
+ begin
41
+ yield conn
42
+ ensure
43
+ conn.disconnect
44
+ end
45
+ end
46
+
47
+ alias execute query
48
+ alias open connect
49
+ alias close disconnect
50
+ end
51
+ end
@@ -0,0 +1,77 @@
1
+ module DuckDB
2
+ # The Database class encapsulates a DuckDB database.
3
+ #
4
+ # The usage is as follows:
5
+ #
6
+ # require 'duckdb'
7
+ #
8
+ # db = DuckDB::Database.open # database in memory
9
+ # con = db.connect
10
+ #
11
+ # con.query('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
12
+ #
13
+ # con.query("INSERT into users VALUES(1, 'Alice')")
14
+ # con.query("INSERT into users VALUES(2, 'Bob')")
15
+ # con.query("INSERT into users VALUES(3, 'Cathy')")
16
+ #
17
+ # result = con.query('SELECT * from users')
18
+ # result.each do |row|
19
+ # p row
20
+ # end
21
+ #
22
+ class Database
23
+ private_class_method :_open
24
+
25
+ class << self
26
+ ##
27
+ # Opens database.
28
+ # The first argument is DuckDB database file path to open.
29
+ # If there is no argument, the method opens DuckDB database in memory.
30
+ # The method yields block if block is given.
31
+ #
32
+ # DuckDB::Database.open('duckdb_database.db') #=> DuckDB::Database
33
+ #
34
+ # DuckDB::Database.open #=> opens DuckDB::Database in memory.
35
+ #
36
+ # DuckDB::Database.open do |db|
37
+ # con = db.connect
38
+ # con.query('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
39
+ # end
40
+ #
41
+ def open(*args)
42
+ db = _open(*args)
43
+ return db unless block_given?
44
+
45
+ begin
46
+ yield db
47
+ ensure
48
+ db.close
49
+ end
50
+ end
51
+ end
52
+
53
+ ##
54
+ # connects database.
55
+ #
56
+ # The method yields block and disconnects the database if block given
57
+ #
58
+ # db = DuckDB::Database.open
59
+ #
60
+ # con = db.connect # => DuckDB::Connection
61
+ #
62
+ # db.connect do |con|
63
+ # con.query('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
64
+ # end
65
+ #
66
+ def connect
67
+ conn = _connect
68
+ return conn unless block_given?
69
+
70
+ begin
71
+ yield conn
72
+ ensure
73
+ conn.disconnect
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,48 @@
1
+ require 'date'
2
+
3
+ module DuckDB
4
+ # The DuckDB::PreparedStatement encapsulates connection with DuckDB prepared
5
+ # statement.
6
+ #
7
+ # require 'duckdb'
8
+ # db = DuckDB::Database.open('duckdb_database')
9
+ # con = db.connect
10
+ # sql ='SELECT name, email FROM users WHERE email = ?'
11
+ # stmt = PreparedStatement.new(con, sql)
12
+ # stmt.bind(1, 'email@example.com')
13
+ # stmt.execute
14
+ class PreparedStatement
15
+
16
+ # binds i-th parameter with SQL prepared statement.
17
+ # The first argument is index of parameter. The index of first parameter is
18
+ # 1 not 0.
19
+ # The second argument value is the value of prepared statement parameter.
20
+ #
21
+ # require 'duckdb'
22
+ # db = DuckDB::Database.open('duckdb_database')
23
+ # con = db.connect
24
+ # sql ='SELECT name, email FROM users WHERE email = ?'
25
+ # stmt = PreparedStatement.new(con, sql)
26
+ # stmt.bind(1, 'email@example.com')
27
+ def bind(i, value)
28
+ case value
29
+ when NilClass
30
+ respond_to?(:bind_null) ? bind_null(i) : rb_raise(DuckDB::Error, 'This bind method does not support nil value. Re-compile ruby-duckdb with DuckDB version >= 0.1.1')
31
+ when Float
32
+ bind_double(i, value)
33
+ when Integer
34
+ bind_int64(i, value)
35
+ when String
36
+ bind_varchar(i, value)
37
+ when TrueClass, FalseClass
38
+ bind_boolean(i, value)
39
+ when Time
40
+ bind_varchar(i, value.strftime('%Y-%m-%d %H:%M:%S.%N'))
41
+ when Date
42
+ bind_varchar(i, value.strftime('%Y-%m-%d'))
43
+ else
44
+ rb_raise(DuckDB::Error, "not supported type #{value} (value.class)")
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,4 +1,23 @@
1
1
  module DuckDB
2
+ # The Result class encapsulates a execute result of DuckDB database.
3
+ #
4
+ # The usage is as follows:
5
+ #
6
+ # require 'duckdb'
7
+ #
8
+ # db = DuckDB::Database.open # database in memory
9
+ # con = db.connect
10
+ #
11
+ # con.execute('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
12
+ #
13
+ # con.execute("INSERT into users VALUES(1, 'Alice')")
14
+ # con.execute("INSERT into users VALUES(2, 'Bob')")
15
+ # con.execute("INSERT into users VALUES(3, 'Cathy')")
16
+ #
17
+ # result = con.execute('SELECT * from users')
18
+ # result.each do |row|
19
+ # p row
20
+ # end
2
21
  class Result
3
22
  include Enumerable
4
23
  end
@@ -1,3 +1,5 @@
1
1
  module DuckDB
2
- VERSION = '0.0.5'.freeze
2
+ # The version string of ruby-duckdb.
3
+ # Currently, ruby-duckdb is NOT semantic versioning.
4
+ VERSION = '0.0.9'.freeze
3
5
  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.0.5
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaki Suketa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-04 00:00:00.000000000 Z
11
+ date: 2020-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,47 +25,47 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '5.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '5.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rake-compiler
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '13.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: minitest
56
+ name: rake-compiler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '5.0'
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '5.0'
68
+ version: '0'
69
69
  description: This module is Ruby binding for DuckDB database engine. You must have
70
70
  the DuckDB engine installed to build/use this module.
71
71
  email:
@@ -75,14 +75,15 @@ extensions:
75
75
  - ext/duckdb/extconf.rb
76
76
  extra_rdoc_files: []
77
77
  files:
78
+ - ".github/workflows/test_by_github.yml"
78
79
  - ".gitignore"
80
+ - ".travis.yml"
79
81
  - CHANGELOG.md
80
82
  - Gemfile
81
83
  - Gemfile.lock
82
84
  - LICENSE
83
85
  - README.md
84
86
  - Rakefile
85
- - TODO
86
87
  - bin/console
87
88
  - bin/setup
88
89
  - duckdb.gemspec
@@ -94,10 +95,15 @@ files:
94
95
  - ext/duckdb/error.c
95
96
  - ext/duckdb/error.h
96
97
  - ext/duckdb/extconf.rb
98
+ - ext/duckdb/prepared_statement.c
99
+ - ext/duckdb/prepared_statement.h
97
100
  - ext/duckdb/result.c
98
101
  - ext/duckdb/result.h
99
102
  - ext/duckdb/ruby-duckdb.h
100
103
  - lib/duckdb.rb
104
+ - lib/duckdb/connection.rb
105
+ - lib/duckdb/database.rb
106
+ - lib/duckdb/prepared_statement.rb
101
107
  - lib/duckdb/result.rb
102
108
  - lib/duckdb/version.rb
103
109
  homepage: https://github.com/suketa/ruby-duckdb
@@ -115,14 +121,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
121
  requirements:
116
122
  - - ">="
117
123
  - !ruby/object:Gem::Version
118
- version: '0'
124
+ version: 2.5.0
119
125
  required_rubygems_version: !ruby/object:Gem::Requirement
120
126
  requirements:
121
127
  - - ">="
122
128
  - !ruby/object:Gem::Version
123
129
  version: '0'
124
130
  requirements: []
125
- rubygems_version: 3.0.3
131
+ rubygems_version: 3.1.2
126
132
  signing_key:
127
133
  specification_version: 4
128
134
  summary: This module is Ruby binding for DuckDB database engine.
data/TODO DELETED
@@ -1,2 +0,0 @@
1
- - add test
2
- - support prepared statement