duckdb 0.10.3.0 → 1.0.0.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 +2 -2
- data/.github/workflows/test_on_ubuntu.yml +2 -2
- data/.github/workflows/test_on_windows.yml +1 -1
- data/CHANGELOG.md +33 -0
- data/Dockerfile +2 -2
- data/Gemfile.lock +2 -2
- data/ext/duckdb/duckdb.c +1 -0
- data/ext/duckdb/extconf.rb +9 -2
- data/ext/duckdb/extracted_statements.c +94 -0
- data/ext/duckdb/extracted_statements.h +12 -0
- data/ext/duckdb/pending_result.c +16 -0
- data/ext/duckdb/prepared_statement.c +14 -0
- data/ext/duckdb/prepared_statement.h +1 -0
- data/ext/duckdb/result.c +140 -32
- data/ext/duckdb/ruby-duckdb.h +8 -0
- data/lib/duckdb/library_version.rb +2 -0
- data/lib/duckdb/pending_result.rb +2 -0
- data/lib/duckdb/prepared_statement.rb +2 -0
- data/lib/duckdb/result.rb +11 -3
- data/lib/duckdb/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ded07680dcaaa7309ed8578e6bd5d0a1e217b0c803f8527679e62e254aaea412
|
4
|
+
data.tar.gz: d2ff3d9a66b1487d867a95129a5c4fff3b4c01ed90198772d2a62b299c88bfca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 253d068a5c17894a482346897f499e06a79ed9741250367e76d306d3828bfdce385379bd091528ae119fa5b1d0c7a83378cb84043477f1d6d21d86d09c00cd88
|
7
|
+
data.tar.gz: 2c554bdd675fea28561ed291dc28e5b660ef85a7d737d6cd69450832aa3af6a84eb94ad6a55a922828841ee9c9f802a4f86734692afd35b3a2bde4c2d6edb7e7
|
@@ -15,8 +15,8 @@ jobs:
|
|
15
15
|
runs-on: macos-latest
|
16
16
|
strategy:
|
17
17
|
matrix:
|
18
|
-
ruby: ['3.0.7', '3.1.
|
19
|
-
duckdb: ['0.
|
18
|
+
ruby: ['3.0.7', '3.1.6', '3.2.4', '3.3.2', '3.4.0-preview1', 'head']
|
19
|
+
duckdb: ['1.0.0', '0.10.3']
|
20
20
|
|
21
21
|
steps:
|
22
22
|
- uses: actions/checkout@v4
|
@@ -15,8 +15,8 @@ jobs:
|
|
15
15
|
runs-on: ubuntu-latest
|
16
16
|
strategy:
|
17
17
|
matrix:
|
18
|
-
ruby: ['3.0.7', '3.1.
|
19
|
-
duckdb: ['0.
|
18
|
+
ruby: ['3.0.7', '3.1.6', '3.2.4', '3.3.2', '3.4.0-preview1', 'head']
|
19
|
+
duckdb: ['1.0.0', '0.10.3']
|
20
20
|
|
21
21
|
steps:
|
22
22
|
- uses: actions/checkout@v4
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,39 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
|
5
5
|
## Unreleased
|
6
6
|
|
7
|
+
# 1.0.0.0 - 2024-06-08
|
8
|
+
- bump duckdb to 1.0.0.
|
9
|
+
- add `DuckDB::ExtractedStatements` class.
|
10
|
+
- add `DuckDB::ExtractedStatements#size`.
|
11
|
+
- add `DuckDB::ExtractedStatements#prepared_statement`.
|
12
|
+
- raise error when `DuckDB::ExtractedStatements#new` is called with invalid SQL.
|
13
|
+
- The following public/private methods will be deprecated.
|
14
|
+
- `DuckDB::Result#streaming?`
|
15
|
+
- `DuckDB::Result#_null?`
|
16
|
+
- `DuckDB::Result#_to_boolean`
|
17
|
+
- `DuckDB::Result#_to_smallint`
|
18
|
+
- `DuckDB::Result#_to_utinyint`
|
19
|
+
- `DuckDB::Result#_to_integer`
|
20
|
+
- `DuckDB::Result#_to_bigint`
|
21
|
+
- `DuckDB::Result#_to_hugeint`
|
22
|
+
- `DuckDB::Result#_to_hugeint_internal`
|
23
|
+
- `DuckDB::Result#__to_hugeint_internal`
|
24
|
+
- `DuckDB::Result#_to_decimal`
|
25
|
+
- `DuckDB::Result#_to_decimal_internal`
|
26
|
+
- `DuckDB::Result#__to_decimal_internal`
|
27
|
+
- `DuckDB::Result#_to_float`
|
28
|
+
- `DuckDB::Result#_to_double`
|
29
|
+
- `DuckDB::Result#_to_string`
|
30
|
+
- `DuckDB::Result#_to_string_internal`
|
31
|
+
- `DuckDB::Result#_to_blob`
|
32
|
+
- `DuckDB::Result.use_chunk_each=`
|
33
|
+
- `DuckDB::Result#use_chunk_each?`
|
34
|
+
|
35
|
+
## Breaking changes
|
36
|
+
- DuckDB::Result.use_chunk_each is true by default.
|
37
|
+
If you want to use the old behavior, set `DuckDB::Result.use_chunk_each = false`.
|
38
|
+
But the old behavior will be removed in the future release.
|
39
|
+
|
7
40
|
# 0.10.3.0 - 2024-05-25
|
8
41
|
- bump to duckdb v0.10.3.
|
9
42
|
|
data/Dockerfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
duckdb (0.
|
4
|
+
duckdb (1.0.0.0)
|
5
5
|
bigdecimal (>= 3.1.4)
|
6
6
|
|
7
7
|
GEM
|
@@ -9,7 +9,7 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
benchmark-ips (2.13.0)
|
11
11
|
bigdecimal (3.1.8)
|
12
|
-
mini_portile2 (2.8.
|
12
|
+
mini_portile2 (2.8.7)
|
13
13
|
minitest (5.23.1)
|
14
14
|
nokogiri (1.16.5)
|
15
15
|
mini_portile2 (~> 2.8.2)
|
data/ext/duckdb/duckdb.c
CHANGED
data/ext/duckdb/extconf.rb
CHANGED
@@ -29,6 +29,10 @@ def check_duckdb_library(library, func, version)
|
|
29
29
|
have_func(func, 'duckdb.h')
|
30
30
|
return if found
|
31
31
|
|
32
|
+
raise_not_found_library(library, version)
|
33
|
+
end
|
34
|
+
|
35
|
+
def raise_not_found_library(library, version)
|
32
36
|
library_name = duckdb_library_name(library)
|
33
37
|
msg = "#{library_name} is not found. Install #{library_name} of duckdb >= #{version}."
|
34
38
|
print_message(msg)
|
@@ -36,7 +40,7 @@ def check_duckdb_library(library, func, version)
|
|
36
40
|
end
|
37
41
|
|
38
42
|
def duckdb_library_name(library)
|
39
|
-
"lib#{library}
|
43
|
+
"lib#{library}.#{RbConfig::CONFIG['DLEXT']}"
|
40
44
|
end
|
41
45
|
|
42
46
|
def print_message(msg)
|
@@ -60,7 +64,10 @@ have_func('duckdb_bind_parameter_index', 'duckdb.h')
|
|
60
64
|
# check duckdb >= 0.10.0
|
61
65
|
have_func('duckdb_appender_column_count', 'duckdb.h')
|
62
66
|
|
63
|
-
#
|
67
|
+
# check duckdb >= 1.0.0
|
68
|
+
have_func('duckdb_fetch_chunk', 'duckdb.h')
|
69
|
+
|
70
|
+
# duckdb_parameter_name in duckdb <= 0.9.1 is not found on Windows.
|
64
71
|
have_func('duckdb_parameter_name', 'duckdb.h')
|
65
72
|
|
66
73
|
create_makefile('duckdb/duckdb_native')
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#include "ruby-duckdb.h"
|
2
|
+
|
3
|
+
static VALUE cDuckDBExtractedStatements;
|
4
|
+
|
5
|
+
static void deallocate(void *ctx);
|
6
|
+
static VALUE allocate(VALUE klass);
|
7
|
+
static size_t memsize(const void *p);
|
8
|
+
|
9
|
+
static const rb_data_type_t extract_statements_data_type = {
|
10
|
+
"DuckDB/ExtractedStatements",
|
11
|
+
{NULL, deallocate, memsize,},
|
12
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
13
|
+
};
|
14
|
+
|
15
|
+
static void deallocate(void *ctx);
|
16
|
+
static VALUE allocate(VALUE klass);
|
17
|
+
static size_t memsize(const void *p);
|
18
|
+
|
19
|
+
static VALUE duckdb_extracted_statements_initialize(VALUE self, VALUE con, VALUE query);
|
20
|
+
static VALUE duckdb_extracted_statements_size(VALUE self);
|
21
|
+
static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE con, VALUE index);
|
22
|
+
|
23
|
+
static void deallocate(void *ctx) {
|
24
|
+
rubyDuckDBExtractedStatements *p = (rubyDuckDBExtractedStatements *)ctx;
|
25
|
+
|
26
|
+
duckdb_destroy_extracted(&(p->extracted_statements));
|
27
|
+
xfree(p);
|
28
|
+
}
|
29
|
+
|
30
|
+
static VALUE allocate(VALUE klass) {
|
31
|
+
rubyDuckDBExtractedStatements *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBExtractedStatements));
|
32
|
+
ctx->num_statements = 0;
|
33
|
+
|
34
|
+
return TypedData_Wrap_Struct(klass, &extract_statements_data_type, ctx);
|
35
|
+
}
|
36
|
+
|
37
|
+
static size_t memsize(const void *p) {
|
38
|
+
return sizeof(rubyDuckDBExtractedStatements);
|
39
|
+
}
|
40
|
+
|
41
|
+
static VALUE duckdb_extracted_statements_initialize(VALUE self, VALUE con, VALUE query) {
|
42
|
+
rubyDuckDBConnection *pcon;
|
43
|
+
rubyDuckDBExtractedStatements *ctx;
|
44
|
+
char *pquery;
|
45
|
+
const char *error;
|
46
|
+
|
47
|
+
if (rb_obj_is_kind_of(con, cDuckDBConnection) != Qtrue) {
|
48
|
+
rb_raise(rb_eTypeError, "1st argument must be DuckDB::Connection");
|
49
|
+
}
|
50
|
+
|
51
|
+
pquery = StringValuePtr(query);
|
52
|
+
pcon = get_struct_connection(con);
|
53
|
+
TypedData_Get_Struct(self, rubyDuckDBExtractedStatements, &extract_statements_data_type, ctx);
|
54
|
+
|
55
|
+
ctx->num_statements = duckdb_extract_statements(pcon->con, pquery, &(ctx->extracted_statements));
|
56
|
+
|
57
|
+
if (ctx->num_statements == 0) {
|
58
|
+
error = duckdb_extract_statements_error(ctx->extracted_statements);
|
59
|
+
rb_raise(eDuckDBError, "%s", error);
|
60
|
+
}
|
61
|
+
|
62
|
+
return self;
|
63
|
+
}
|
64
|
+
|
65
|
+
static VALUE duckdb_extracted_statements_size(VALUE self) {
|
66
|
+
rubyDuckDBExtractedStatements *ctx;
|
67
|
+
|
68
|
+
TypedData_Get_Struct(self, rubyDuckDBExtractedStatements, &extract_statements_data_type, ctx);
|
69
|
+
|
70
|
+
return ULL2NUM(ctx->num_statements);
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE con, VALUE index) {
|
75
|
+
rubyDuckDBConnection *pcon;
|
76
|
+
rubyDuckDBExtractedStatements *ctx;
|
77
|
+
|
78
|
+
if (rb_obj_is_kind_of(con, cDuckDBConnection) != Qtrue) {
|
79
|
+
rb_raise(rb_eTypeError, "1st argument must be DuckDB::Connection");
|
80
|
+
}
|
81
|
+
pcon = get_struct_connection(con);
|
82
|
+
TypedData_Get_Struct(self, rubyDuckDBExtractedStatements, &extract_statements_data_type, ctx);
|
83
|
+
|
84
|
+
return rbduckdb_prepared_statement_new(pcon->con, ctx->extracted_statements, NUM2ULL(index));
|
85
|
+
}
|
86
|
+
|
87
|
+
void rbduckdb_init_duckdb_extracted_statements(void) {
|
88
|
+
cDuckDBExtractedStatements = rb_define_class_under(mDuckDB, "ExtractedStatements", rb_cObject);
|
89
|
+
|
90
|
+
rb_define_alloc_func(cDuckDBExtractedStatements, allocate);
|
91
|
+
rb_define_method(cDuckDBExtractedStatements, "initialize", duckdb_extracted_statements_initialize, 2);
|
92
|
+
rb_define_method(cDuckDBExtractedStatements, "size", duckdb_extracted_statements_size, 0);
|
93
|
+
rb_define_method(cDuckDBExtractedStatements, "prepared_statement", duckdb_extracted_statements_prepared_statement, 2);
|
94
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#ifndef RUBY_DUCKDB_EXTRACTED_STATEMENTS_H
|
2
|
+
#define RUBY_DUCKDB_EXTRACTED_STATEMENTS_H
|
3
|
+
|
4
|
+
struct _rubyDuckDBExtractedStatements {
|
5
|
+
duckdb_extracted_statements extracted_statements;
|
6
|
+
idx_t num_statements;
|
7
|
+
};
|
8
|
+
|
9
|
+
typedef struct _rubyDuckDBExtractedStatements rubyDuckDBExtractedStatements;
|
10
|
+
|
11
|
+
void rbduckdb_init_duckdb_extracted_statements(void);
|
12
|
+
#endif
|
data/ext/duckdb/pending_result.c
CHANGED
@@ -39,6 +39,13 @@ static VALUE duckdb_pending_result_initialize(int argc, VALUE *argv, VALUE self)
|
|
39
39
|
VALUE streaming_p = Qfalse;
|
40
40
|
duckdb_state state;
|
41
41
|
|
42
|
+
/*
|
43
|
+
* FIXME: The 2nd argument is deprecated and will be removed in the future.
|
44
|
+
* The behavior will be same as streaming.
|
45
|
+
if (argc == 2) {
|
46
|
+
rb_warn("The 2nd argument is deprecated and will be removed in the future.");
|
47
|
+
}
|
48
|
+
*/
|
42
49
|
rb_scan_args(argc, argv, "11", &oDuckDBPreparedStatement, &streaming_p);
|
43
50
|
|
44
51
|
if (rb_obj_is_kind_of(oDuckDBPreparedStatement, cDuckDBPreparedStatement) != Qtrue) {
|
@@ -48,11 +55,20 @@ static VALUE duckdb_pending_result_initialize(int argc, VALUE *argv, VALUE self)
|
|
48
55
|
rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
|
49
56
|
rubyDuckDBPreparedStatement *stmt = get_struct_prepared_statement(oDuckDBPreparedStatement);
|
50
57
|
|
58
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
59
|
+
state = duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result));
|
60
|
+
#else
|
61
|
+
/*
|
62
|
+
* FIXME: streaming_p check will be removed in the future.
|
63
|
+
*
|
64
|
+
* state = duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result));
|
65
|
+
*/
|
51
66
|
if (!NIL_P(streaming_p) && streaming_p == Qtrue) {
|
52
67
|
state = duckdb_pending_prepared_streaming(stmt->prepared_statement, &(ctx->pending_result));
|
53
68
|
} else {
|
54
69
|
state = duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result));
|
55
70
|
}
|
71
|
+
#endif
|
56
72
|
|
57
73
|
if (state == DuckDBError) {
|
58
74
|
rb_raise(eDuckDBError, "%s", duckdb_pending_error(ctx->pending_result));
|
@@ -53,6 +53,20 @@ static size_t memsize(const void *p) {
|
|
53
53
|
return sizeof(rubyDuckDBPreparedStatement);
|
54
54
|
}
|
55
55
|
|
56
|
+
VALUE rbduckdb_prepared_statement_new(duckdb_connection con, duckdb_extracted_statements extracted_statements, idx_t index) {
|
57
|
+
VALUE obj;
|
58
|
+
rubyDuckDBPreparedStatement *ctx;
|
59
|
+
|
60
|
+
obj = allocate(cDuckDBPreparedStatement);
|
61
|
+
|
62
|
+
TypedData_Get_Struct(obj, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
|
63
|
+
|
64
|
+
if (duckdb_prepare_extracted_statement(con, extracted_statements, index, &(ctx->prepared_statement)) == DuckDBError) {
|
65
|
+
rb_raise(eDuckDBError, "Fail to get DuckDB::PreparedStatement object from ExtractedStatements object");
|
66
|
+
}
|
67
|
+
return obj;
|
68
|
+
}
|
69
|
+
|
56
70
|
static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE query) {
|
57
71
|
rubyDuckDBConnection *ctxcon;
|
58
72
|
rubyDuckDBPreparedStatement *ctx;
|
@@ -8,6 +8,7 @@ struct _rubyDuckDBPreparedStatement {
|
|
8
8
|
|
9
9
|
typedef struct _rubyDuckDBPreparedStatement rubyDuckDBPreparedStatement;
|
10
10
|
|
11
|
+
VALUE rbduckdb_prepared_statement_new(duckdb_connection con, duckdb_extracted_statements extracted_statements, idx_t index);
|
11
12
|
rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self);
|
12
13
|
void rbduckdb_init_duckdb_prepared_statement(void);
|
13
14
|
|
data/ext/duckdb/result.c
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
#include "ruby-duckdb.h"
|
2
2
|
|
3
|
+
struct chunk_arg {
|
4
|
+
duckdb_data_chunk chunk;
|
5
|
+
idx_t col_count;
|
6
|
+
};
|
7
|
+
|
3
8
|
static VALUE cDuckDBResult;
|
4
9
|
static ID id__to_date;
|
5
10
|
static ID id__to_time;
|
@@ -27,10 +32,11 @@ static VALUE duckdb_result_row_count(VALUE oDuckDBResult);
|
|
27
32
|
static VALUE duckdb_result_rows_changed(VALUE oDuckDBResult);
|
28
33
|
static VALUE duckdb_result_columns(VALUE oDuckDBResult);
|
29
34
|
static VALUE duckdb_result_streaming_p(VALUE oDuckDBResult);
|
35
|
+
static VALUE destroy_data_chunk(VALUE arg);
|
30
36
|
static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult);
|
31
37
|
|
32
38
|
static VALUE duckdb_result__chunk_stream(VALUE oDuckDBResult);
|
33
|
-
static
|
39
|
+
static VALUE yield_rows(VALUE arg);
|
34
40
|
static VALUE duckdb_result__column_type(VALUE oDuckDBResult, VALUE col_idx);
|
35
41
|
static VALUE duckdb_result__is_null(VALUE oDuckDBResult, VALUE row_idx, VALUE col_idx);
|
36
42
|
static VALUE duckdb_result__to_boolean(VALUE oDuckDBResult, VALUE row_idx, VALUE col_idx);
|
@@ -93,52 +99,102 @@ rubyDuckDBResult *get_struct_result(VALUE obj) {
|
|
93
99
|
}
|
94
100
|
|
95
101
|
static VALUE to_ruby_obj_boolean(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
102
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
103
|
+
return Qnil;
|
104
|
+
#else
|
105
|
+
rb_warn("private method `_to_boolean` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
96
106
|
bool bval = duckdb_value_boolean(result, col_idx, row_idx);
|
97
107
|
return bval ? Qtrue : Qfalse;
|
108
|
+
#endif
|
98
109
|
}
|
99
110
|
|
100
111
|
static VALUE to_ruby_obj_smallint(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
112
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
113
|
+
return Qnil;
|
114
|
+
#else
|
115
|
+
rb_warn("private method `_to_smallint` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
101
116
|
int16_t i16val = duckdb_value_int16(result, col_idx, row_idx);
|
102
117
|
return INT2FIX(i16val);
|
118
|
+
#endif
|
103
119
|
}
|
104
120
|
|
105
121
|
static VALUE to_ruby_obj_utinyint(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
122
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
123
|
+
return Qnil;
|
124
|
+
#else
|
125
|
+
rb_warn("private method `_to_utinyint` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
106
126
|
uint8_t ui8val = duckdb_value_uint8(result, col_idx, row_idx);
|
107
127
|
return UINT2NUM(ui8val);
|
128
|
+
#endif
|
108
129
|
}
|
109
130
|
|
110
131
|
static VALUE to_ruby_obj_integer(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
132
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
133
|
+
return Qnil;
|
134
|
+
#else
|
135
|
+
rb_warn("private method `_to_integer` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
111
136
|
int32_t i32val = duckdb_value_int32(result, col_idx, row_idx);
|
112
137
|
return INT2NUM(i32val);
|
138
|
+
#endif
|
113
139
|
}
|
114
140
|
|
115
141
|
static VALUE to_ruby_obj_bigint(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
142
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
143
|
+
return Qnil;
|
144
|
+
#else
|
145
|
+
rb_warn("private method `_to_bigint` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
116
146
|
int64_t i64val = duckdb_value_int64(result, col_idx, row_idx);
|
117
147
|
return LL2NUM(i64val);
|
148
|
+
#endif
|
118
149
|
}
|
119
150
|
|
120
151
|
static VALUE to_ruby_obj_hugeint(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
152
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
153
|
+
return Qnil;
|
154
|
+
#else
|
155
|
+
rb_warn("private method `__to_hugeint_internal` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
121
156
|
duckdb_hugeint hugeint = duckdb_value_hugeint(result, col_idx, row_idx);
|
122
157
|
return rb_ary_new3(2, ULL2NUM(hugeint.lower), LL2NUM(hugeint.upper));
|
158
|
+
#endif
|
123
159
|
}
|
124
160
|
|
125
161
|
static VALUE to_ruby_obj_decimal(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
162
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
163
|
+
return Qnil;
|
164
|
+
#else
|
165
|
+
rb_warn("private method `__to_decimal_internal` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
126
166
|
duckdb_decimal decimal = duckdb_value_decimal(result, col_idx, row_idx);
|
127
167
|
return rb_ary_new3(4, ULL2NUM(decimal.value.lower), LL2NUM(decimal.value.upper), UINT2NUM(decimal.width), UINT2NUM(decimal.scale));
|
168
|
+
#endif
|
128
169
|
}
|
129
170
|
|
130
171
|
static VALUE to_ruby_obj_float(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
172
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
173
|
+
return Qnil;
|
174
|
+
#else
|
175
|
+
rb_warn("private method `_to_float` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
131
176
|
float fval = duckdb_value_float(result, col_idx, row_idx);
|
132
177
|
return DBL2NUM(fval);
|
178
|
+
#endif
|
133
179
|
}
|
134
180
|
|
135
181
|
static VALUE to_ruby_obj_double(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
182
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
183
|
+
return Qnil;
|
184
|
+
#else
|
185
|
+
rb_warn("private method `_to_double` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
136
186
|
double dval = duckdb_value_double(result, col_idx, row_idx);
|
137
187
|
return DBL2NUM(dval);
|
188
|
+
#endif
|
138
189
|
}
|
139
190
|
|
140
191
|
static VALUE to_ruby_obj_blob(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
192
|
+
|
193
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
194
|
+
return Qnil;
|
195
|
+
#else
|
141
196
|
VALUE str;
|
197
|
+
rb_warn("private method `_to_blob` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
142
198
|
duckdb_blob bval = duckdb_value_blob(result, col_idx, row_idx);
|
143
199
|
str = rb_str_new(bval.data, bval.size);
|
144
200
|
|
@@ -147,6 +203,7 @@ static VALUE to_ruby_obj_blob(duckdb_result *result, idx_t col_idx, idx_t row_id
|
|
147
203
|
}
|
148
204
|
|
149
205
|
return str;
|
206
|
+
#endif
|
150
207
|
}
|
151
208
|
|
152
209
|
/*
|
@@ -220,9 +277,15 @@ static VALUE duckdb_result_column_count(VALUE oDuckDBResult) {
|
|
220
277
|
*
|
221
278
|
*/
|
222
279
|
static VALUE duckdb_result_row_count(VALUE oDuckDBResult) {
|
280
|
+
|
281
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
282
|
+
return Qnil;
|
283
|
+
#else
|
223
284
|
rubyDuckDBResult *ctx;
|
285
|
+
rb_warn("`row_count` will be deprecated in the future.");
|
224
286
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
225
287
|
return LL2NUM(duckdb_row_count(&(ctx->result)));
|
288
|
+
#endif
|
226
289
|
}
|
227
290
|
|
228
291
|
/*
|
@@ -256,51 +319,77 @@ static VALUE duckdb_result_columns(VALUE oDuckDBResult) {
|
|
256
319
|
*/
|
257
320
|
static VALUE duckdb_result_streaming_p(VALUE oDuckDBResult) {
|
258
321
|
rubyDuckDBResult *ctx;
|
322
|
+
|
323
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
324
|
+
return Qtrue;
|
325
|
+
#else
|
326
|
+
/* FIXME streaming is allways true. so this method is not useful and deprecated. */
|
259
327
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
260
328
|
return duckdb_result_is_streaming(ctx->result) ? Qtrue : Qfalse;
|
329
|
+
#endif
|
330
|
+
}
|
331
|
+
|
332
|
+
static VALUE destroy_data_chunk(VALUE arg) {
|
333
|
+
struct chunk_arg *p = (struct chunk_arg *)arg;
|
334
|
+
duckdb_destroy_data_chunk(&(p->chunk));
|
335
|
+
return Qnil;
|
261
336
|
}
|
262
337
|
|
263
338
|
static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult) {
|
339
|
+
/*
|
340
|
+
#ifdef HAVE_DUCKDB_H_GE_V1_0_0
|
341
|
+
return duckdb_result__chunk_stream(oDuckDBResult);
|
342
|
+
#else
|
343
|
+
*/
|
264
344
|
rubyDuckDBResult *ctx;
|
265
|
-
|
345
|
+
struct chunk_arg arg;
|
266
346
|
idx_t chunk_count;
|
267
347
|
idx_t chunk_idx;
|
268
|
-
duckdb_data_chunk chunk;
|
269
348
|
|
349
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
350
|
+
//TODO: use duckdb_fetch_chunk instead of duckdb_result_chunk_count and duckdb_result_get_chunk.
|
351
|
+
// duckdb_result_chunk_count will be deprecated in the future.
|
352
|
+
// duckdb_result_get_chunk will be deprecated in the future.
|
353
|
+
#else
|
270
354
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
271
355
|
|
272
|
-
col_count = duckdb_column_count(&(ctx->result));
|
356
|
+
arg.col_count = duckdb_column_count(&(ctx->result));
|
273
357
|
chunk_count = duckdb_result_chunk_count(ctx->result);
|
274
358
|
|
275
359
|
RETURN_ENUMERATOR(oDuckDBResult, 0, 0);
|
276
360
|
|
277
361
|
for (chunk_idx = 0; chunk_idx < chunk_count; chunk_idx++) {
|
278
|
-
chunk = duckdb_result_get_chunk(ctx->result, chunk_idx);
|
279
|
-
yield_rows(
|
280
|
-
duckdb_destroy_data_chunk(&chunk);
|
362
|
+
arg.chunk = duckdb_result_get_chunk(ctx->result, chunk_idx);
|
363
|
+
rb_ensure(yield_rows, (VALUE)&arg, destroy_data_chunk, (VALUE)&arg);
|
281
364
|
}
|
365
|
+
#endif
|
282
366
|
return Qnil;
|
367
|
+
/*
|
368
|
+
#endif
|
369
|
+
*/
|
283
370
|
}
|
284
371
|
|
285
372
|
static VALUE duckdb_result__chunk_stream(VALUE oDuckDBResult) {
|
286
373
|
rubyDuckDBResult *ctx;
|
287
|
-
|
288
|
-
idx_t col_count;
|
374
|
+
struct chunk_arg arg;
|
289
375
|
|
290
376
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
291
377
|
|
292
378
|
RETURN_ENUMERATOR(oDuckDBResult, 0, 0);
|
293
379
|
|
294
|
-
col_count = duckdb_column_count(&(ctx->result));
|
380
|
+
arg.col_count = duckdb_column_count(&(ctx->result));
|
295
381
|
|
296
|
-
|
297
|
-
|
298
|
-
|
382
|
+
#ifdef HAVE_DUCKDB_H_GE_V1_0_0
|
383
|
+
while((arg.chunk = duckdb_fetch_chunk(ctx->result)) != NULL) {
|
384
|
+
#else
|
385
|
+
while((arg.chunk = duckdb_stream_fetch_chunk(ctx->result)) != NULL) {
|
386
|
+
#endif
|
387
|
+
rb_ensure(yield_rows, (VALUE)&arg, destroy_data_chunk, (VALUE)&arg);
|
299
388
|
}
|
300
389
|
return Qnil;
|
301
390
|
}
|
302
391
|
|
303
|
-
static
|
392
|
+
static VALUE yield_rows(VALUE arg) {
|
304
393
|
idx_t row_count;
|
305
394
|
idx_t row_idx;
|
306
395
|
idx_t col_idx;
|
@@ -308,16 +397,19 @@ static void yield_rows(duckdb_data_chunk chunk, idx_t col_count) {
|
|
308
397
|
VALUE row;
|
309
398
|
VALUE val;
|
310
399
|
|
311
|
-
|
400
|
+
struct chunk_arg *p = (struct chunk_arg *)arg;
|
401
|
+
|
402
|
+
row_count = duckdb_data_chunk_get_size(p->chunk);
|
312
403
|
for (row_idx = 0; row_idx < row_count; row_idx++) {
|
313
|
-
row = rb_ary_new2(col_count);
|
314
|
-
for (col_idx = 0; col_idx < col_count; col_idx++) {
|
315
|
-
vector = duckdb_data_chunk_get_vector(chunk, col_idx);
|
404
|
+
row = rb_ary_new2(p->col_count);
|
405
|
+
for (col_idx = 0; col_idx < p->col_count; col_idx++) {
|
406
|
+
vector = duckdb_data_chunk_get_vector(p->chunk, col_idx);
|
316
407
|
val = vector_value(vector, row_idx);
|
317
408
|
rb_ary_store(row, col_idx, val);
|
318
409
|
}
|
319
410
|
rb_yield(row);
|
320
411
|
}
|
412
|
+
return Qnil;
|
321
413
|
}
|
322
414
|
|
323
415
|
static VALUE duckdb_result__column_type(VALUE oDuckDBResult, VALUE col_idx) {
|
@@ -329,10 +421,15 @@ static VALUE duckdb_result__column_type(VALUE oDuckDBResult, VALUE col_idx) {
|
|
329
421
|
static VALUE duckdb_result__is_null(VALUE oDuckDBResult, VALUE row_idx, VALUE col_idx) {
|
330
422
|
rubyDuckDBResult *ctx;
|
331
423
|
bool is_null;
|
424
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
425
|
+
return Qfalse;
|
426
|
+
#else
|
427
|
+
rb_warn("private method `_null?` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
332
428
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
333
429
|
|
334
430
|
is_null = duckdb_value_is_null(&(ctx->result), NUM2LL(col_idx), NUM2LL(row_idx));
|
335
431
|
return is_null ? Qtrue : Qfalse;
|
432
|
+
#endif
|
336
433
|
}
|
337
434
|
|
338
435
|
static VALUE duckdb_result__to_boolean(VALUE oDuckDBResult, VALUE row_idx, VALUE col_idx) {
|
@@ -403,6 +500,10 @@ static VALUE duckdb_result__to_string(VALUE oDuckDBResult, VALUE row_idx, VALUE
|
|
403
500
|
duckdb_string p;
|
404
501
|
VALUE obj;
|
405
502
|
|
503
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
504
|
+
return Qnil;
|
505
|
+
#else
|
506
|
+
rb_warn("private method `_to_string` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
406
507
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
407
508
|
|
408
509
|
p = duckdb_value_string(&(ctx->result), NUM2LL(col_idx), NUM2LL(row_idx));
|
@@ -411,6 +512,7 @@ static VALUE duckdb_result__to_string(VALUE oDuckDBResult, VALUE row_idx, VALUE
|
|
411
512
|
duckdb_free(p.data);
|
412
513
|
return obj;
|
413
514
|
}
|
515
|
+
#endif
|
414
516
|
return Qnil;
|
415
517
|
}
|
416
518
|
|
@@ -418,6 +520,10 @@ static VALUE duckdb_result__to_string_internal(VALUE oDuckDBResult, VALUE row_id
|
|
418
520
|
rubyDuckDBResult *ctx;
|
419
521
|
duckdb_string p;
|
420
522
|
VALUE obj;
|
523
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
524
|
+
// duckdb_value_string_internal will be deprecated in the future.
|
525
|
+
#else
|
526
|
+
rb_warn("private method `_to_string_internal` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
421
527
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
422
528
|
|
423
529
|
p = duckdb_value_string_internal(&(ctx->result), NUM2LL(col_idx), NUM2LL(row_idx));
|
@@ -425,6 +531,7 @@ static VALUE duckdb_result__to_string_internal(VALUE oDuckDBResult, VALUE row_id
|
|
425
531
|
obj = rb_utf8_str_new(p.data, p.size);
|
426
532
|
return obj;
|
427
533
|
}
|
534
|
+
#endif
|
428
535
|
return Qnil;
|
429
536
|
}
|
430
537
|
|
@@ -805,26 +912,27 @@ void rbduckdb_init_duckdb_result(void) {
|
|
805
912
|
rb_define_alloc_func(cDuckDBResult, allocate);
|
806
913
|
|
807
914
|
rb_define_method(cDuckDBResult, "column_count", duckdb_result_column_count, 0);
|
808
|
-
rb_define_method(cDuckDBResult, "row_count", duckdb_result_row_count, 0);
|
915
|
+
rb_define_method(cDuckDBResult, "row_count", duckdb_result_row_count, 0); /* deprecated */
|
809
916
|
rb_define_method(cDuckDBResult, "rows_changed", duckdb_result_rows_changed, 0);
|
810
917
|
rb_define_method(cDuckDBResult, "columns", duckdb_result_columns, 0);
|
811
918
|
rb_define_method(cDuckDBResult, "streaming?", duckdb_result_streaming_p, 0);
|
812
919
|
rb_define_method(cDuckDBResult, "chunk_each", duckdb_result_chunk_each, 0);
|
813
920
|
rb_define_private_method(cDuckDBResult, "_chunk_stream", duckdb_result__chunk_stream, 0);
|
814
921
|
rb_define_private_method(cDuckDBResult, "_column_type", duckdb_result__column_type, 1);
|
815
|
-
|
816
|
-
rb_define_private_method(cDuckDBResult, "
|
817
|
-
rb_define_private_method(cDuckDBResult, "
|
818
|
-
rb_define_private_method(cDuckDBResult, "
|
819
|
-
rb_define_private_method(cDuckDBResult, "
|
820
|
-
rb_define_private_method(cDuckDBResult, "
|
821
|
-
rb_define_private_method(cDuckDBResult, "
|
822
|
-
rb_define_private_method(cDuckDBResult, "
|
823
|
-
rb_define_private_method(cDuckDBResult, "
|
824
|
-
rb_define_private_method(cDuckDBResult, "
|
825
|
-
rb_define_private_method(cDuckDBResult, "
|
826
|
-
rb_define_private_method(cDuckDBResult, "
|
827
|
-
rb_define_private_method(cDuckDBResult, "
|
922
|
+
|
923
|
+
rb_define_private_method(cDuckDBResult, "_null?", duckdb_result__is_null, 2); /* deprecated */
|
924
|
+
rb_define_private_method(cDuckDBResult, "_to_boolean", duckdb_result__to_boolean, 2); /* deprecated */
|
925
|
+
rb_define_private_method(cDuckDBResult, "_to_smallint", duckdb_result__to_smallint, 2); /* deprecated */
|
926
|
+
rb_define_private_method(cDuckDBResult, "_to_utinyint", duckdb_result__to_utinyint, 2); /* deprecated */
|
927
|
+
rb_define_private_method(cDuckDBResult, "_to_integer", duckdb_result__to_integer, 2); /* deprecated */
|
928
|
+
rb_define_private_method(cDuckDBResult, "_to_bigint", duckdb_result__to_bigint, 2); /* deprecated */
|
929
|
+
rb_define_private_method(cDuckDBResult, "__to_hugeint_internal", duckdb_result___to_hugeint_internal, 2); /* deprecated */
|
930
|
+
rb_define_private_method(cDuckDBResult, "__to_decimal_internal", duckdb_result___to_decimal_internal, 2); /* deprecated */
|
931
|
+
rb_define_private_method(cDuckDBResult, "_to_float", duckdb_result__to_float, 2); /* deprecated */
|
932
|
+
rb_define_private_method(cDuckDBResult, "_to_double", duckdb_result__to_double, 2); /* deprecated */
|
933
|
+
rb_define_private_method(cDuckDBResult, "_to_string", duckdb_result__to_string, 2); /* deprecated */
|
934
|
+
rb_define_private_method(cDuckDBResult, "_to_string_internal", duckdb_result__to_string_internal, 2); /* deprecated */
|
935
|
+
rb_define_private_method(cDuckDBResult, "_to_blob", duckdb_result__to_blob, 2); /* deprecated */
|
828
936
|
rb_define_private_method(cDuckDBResult, "_enum_internal_type", duckdb_result__enum_internal_type, 1);
|
829
937
|
rb_define_private_method(cDuckDBResult, "_enum_dictionary_size", duckdb_result__enum_dictionary_size, 1);
|
830
938
|
rb_define_private_method(cDuckDBResult, "_enum_dictionary_value", duckdb_result__enum_dictionary_value, 2);
|
data/ext/duckdb/ruby-duckdb.h
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
#ifndef RUBY_DUCKDB_H
|
2
2
|
#define RUBY_DUCKDB_H
|
3
3
|
|
4
|
+
// #define DUCKDB_API_NO_DEPRECATED
|
5
|
+
#define DUCKDB_NO_EXTENSION_FUNCTIONS // disable extension C-functions
|
6
|
+
|
4
7
|
#include "ruby.h"
|
5
8
|
#include <duckdb.h>
|
6
9
|
|
@@ -8,12 +11,17 @@
|
|
8
11
|
#define HAVE_DUCKDB_H_GE_V0_10_0 1
|
9
12
|
#endif
|
10
13
|
|
14
|
+
#ifdef HAVE_DUCKDB_FETCH_CHUNK
|
15
|
+
#define HAVE_DUCKDB_H_GE_V1_0_0 1
|
16
|
+
#endif
|
17
|
+
|
11
18
|
#include "./error.h"
|
12
19
|
#include "./database.h"
|
13
20
|
#include "./connection.h"
|
14
21
|
#include "./result.h"
|
15
22
|
#include "./column.h"
|
16
23
|
#include "./prepared_statement.h"
|
24
|
+
#include "./extracted_statements.h"
|
17
25
|
#include "./pending_result.h"
|
18
26
|
#include "./util.h"
|
19
27
|
#include "./converter.h"
|
data/lib/duckdb/result.rb
CHANGED
@@ -53,15 +53,17 @@ module DuckDB
|
|
53
53
|
alias column_size column_count
|
54
54
|
alias row_size row_count
|
55
55
|
|
56
|
+
@use_chunk_each = true
|
57
|
+
|
56
58
|
class << self
|
57
59
|
def new
|
58
60
|
raise DuckDB::Error, 'DuckDB::Result cannot be instantiated directly.'
|
59
61
|
end
|
60
62
|
|
61
|
-
def use_chunk_each=(
|
62
|
-
|
63
|
+
def use_chunk_each=(value)
|
64
|
+
warn('`changing DuckDB::Result.use_chunk_each to false` will be deprecated.') if value == false
|
63
65
|
|
64
|
-
@use_chunk_each =
|
66
|
+
@use_chunk_each = value
|
65
67
|
end
|
66
68
|
|
67
69
|
def use_chunk_each?
|
@@ -91,6 +93,7 @@ module DuckDB
|
|
91
93
|
end
|
92
94
|
|
93
95
|
def row(row_index)
|
96
|
+
warn("#{self.class}##{__method__} will be deprecated. set `DuckDB::Result.use_chunk_each = true`.")
|
94
97
|
row = []
|
95
98
|
column_count.times do |col_index|
|
96
99
|
row << (_null?(row_index, col_index) ? nil : to_value(row_index, col_index))
|
@@ -99,6 +102,7 @@ module DuckDB
|
|
99
102
|
end
|
100
103
|
|
101
104
|
def to_value(row_index, col_index)
|
105
|
+
warn("#{self.class}##{__method__} will be deprecated. set `DuckDB::Result.use_chunk_each = true`.")
|
102
106
|
send(TO_METHODS[_column_type(col_index)], row_index, col_index)
|
103
107
|
end
|
104
108
|
|
@@ -113,19 +117,23 @@ module DuckDB
|
|
113
117
|
private
|
114
118
|
|
115
119
|
def _to_hugeint(row, col)
|
120
|
+
warn("#{self.class}##{__method__} will be deprecated.")
|
116
121
|
_to_string(row, col).to_i
|
117
122
|
end
|
118
123
|
|
119
124
|
def _to_hugeint_internal(row, col)
|
125
|
+
warn("#{self.class}##{__method__} will be deprecated.")
|
120
126
|
lower, upper = __to_hugeint_internal(row, col)
|
121
127
|
Converter._to_hugeint_from_vector(lower, upper)
|
122
128
|
end
|
123
129
|
|
124
130
|
def _to_decimal(row, col)
|
131
|
+
warn("#{self.class}##{__method__} will be deprecated.")
|
125
132
|
BigDecimal(_to_string(row, col))
|
126
133
|
end
|
127
134
|
|
128
135
|
def _to_decimal_internal(row, col)
|
136
|
+
warn("#{self.class}##{__method__} will be deprecated.")
|
129
137
|
lower, upper, width, scale = __to_decimal_internal(row, col)
|
130
138
|
Converter._to_decimal_from_hugeint(width, scale, upper, lower)
|
131
139
|
end
|
data/lib/duckdb/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: duckdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masaki Suketa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bigdecimal
|
@@ -132,6 +132,8 @@ files:
|
|
132
132
|
- ext/duckdb/error.c
|
133
133
|
- ext/duckdb/error.h
|
134
134
|
- ext/duckdb/extconf.rb
|
135
|
+
- ext/duckdb/extracted_statements.c
|
136
|
+
- ext/duckdb/extracted_statements.h
|
135
137
|
- ext/duckdb/pending_result.c
|
136
138
|
- ext/duckdb/pending_result.h
|
137
139
|
- ext/duckdb/prepared_statement.c
|