sqlite3 1.3.13 → 1.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gemtest +0 -0
- data/.travis.yml +33 -0
- data/CHANGELOG.rdoc +27 -1
- data/Gemfile +6 -4
- data/Manifest.txt +12 -4
- data/README.rdoc +1 -1
- data/Rakefile +0 -2
- data/appveyor.yml +36 -0
- data/ext/sqlite3/aggregator.c +273 -0
- data/ext/sqlite3/aggregator.h +12 -0
- data/ext/sqlite3/database.c +140 -201
- data/ext/sqlite3/database.h +2 -0
- data/ext/sqlite3/exception.c +6 -2
- data/ext/sqlite3/extconf.rb +39 -10
- data/ext/sqlite3/sqlite3.c +10 -1
- data/ext/sqlite3/sqlite3_ruby.h +0 -7
- data/ext/sqlite3/statement.c +13 -18
- data/lib/sqlite3/constants.rb +1 -0
- data/lib/sqlite3/database.rb +196 -51
- data/lib/sqlite3/errors.rb +1 -10
- data/lib/sqlite3/pragmas.rb +7 -7
- data/lib/sqlite3/resultset.rb +2 -10
- data/lib/sqlite3/version.rb +3 -3
- data/{tasks → rakelib}/faq.rake +0 -0
- data/{tasks → rakelib}/gem.rake +6 -4
- data/{tasks → rakelib}/native.rake +4 -0
- data/{tasks → rakelib}/vendor_sqlite3.rake +0 -0
- data/test/test_database.rb +79 -6
- data/test/test_database_flags.rb +95 -0
- data/test/test_database_readwrite.rb +41 -0
- data/test/test_integration.rb +12 -81
- data/test/test_integration_aggregate.rb +336 -0
- data/test/test_integration_resultset.rb +0 -17
- data/test/test_statement.rb +11 -8
- metadata +56 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ff35addc187325a243e752d17c9f38ac54ea4a5b8a48c4809c4dd91692f1f94d
|
4
|
+
data.tar.gz: c9c22fc4b4a091197b12ae09c13d199c2fcd5f8c836944bf04f50be919d32f8a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68c1c1233ff73049b7c1ff1e0bbeec883bc90228182bd090564ff4df2b9f37fe92e4e9333a374306ba7fcdd10b0b2f914c4116dff0c34ef5c2e964f9342de986
|
7
|
+
data.tar.gz: 698263b49e7efa9a3c06220d71e617657fdf31b8e8097a9e2278b5ca3a5fbbb3468b2492fa51670345a3756b4760169d2b79681fac523144166f99253f1e40f3
|
data/.gemtest
ADDED
File without changes
|
data/.travis.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
before_install:
|
4
|
+
- gem update --system 2.7.7
|
5
|
+
- gem install bundler -v 1.16.2
|
6
|
+
addons:
|
7
|
+
apt:
|
8
|
+
packages:
|
9
|
+
- libgmp-dev
|
10
|
+
|
11
|
+
after_failure:
|
12
|
+
- "find . -name mkmf.log -exec cat {} \\;"
|
13
|
+
|
14
|
+
after_success:
|
15
|
+
- "find . -name mkmf.log -exec cat {} \\;"
|
16
|
+
|
17
|
+
env:
|
18
|
+
- USE_MINI_PORTILE=true
|
19
|
+
- USE_MINI_PORTILE=false
|
20
|
+
rvm:
|
21
|
+
- 1.9.3
|
22
|
+
- 2.0.0
|
23
|
+
- 2.1
|
24
|
+
- 2.2
|
25
|
+
- 2.3
|
26
|
+
- 2.4
|
27
|
+
- 2.5
|
28
|
+
- 2.6
|
29
|
+
- 2.7
|
30
|
+
- ruby-head
|
31
|
+
matrix:
|
32
|
+
allow_failures:
|
33
|
+
- env: USE_MINI_PORTILE=false
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
=== 1.4.2
|
2
|
+
|
3
|
+
* Travis: Drop unused setting "sudo: false"
|
4
|
+
* The taint mechanism will be deprecated in Ruby 2.7
|
5
|
+
* Fix Ruby 2.7 rb_check_safe_obj warnings
|
6
|
+
* Update travis config
|
7
|
+
|
8
|
+
=== 1.4.1
|
9
|
+
|
10
|
+
* Don't mandate dl functions for the extention build
|
11
|
+
* bumping version
|
12
|
+
|
13
|
+
=== 1.4.0
|
14
|
+
|
15
|
+
* Enhancements
|
16
|
+
* Better aggregator support
|
17
|
+
|
18
|
+
* Bugfixes
|
19
|
+
* Various
|
20
|
+
|
21
|
+
=== 1.3.13
|
22
|
+
|
23
|
+
* Enancements
|
24
|
+
* Support SQLite flags when defining functions
|
25
|
+
* Add definition for SQLITE_DETERMINISTIC flag
|
26
|
+
|
1
27
|
=== 1.3.12
|
2
28
|
|
3
29
|
* Bugfixes:
|
@@ -15,7 +41,7 @@
|
|
15
41
|
=== 1.3.10 / 2014-10-30
|
16
42
|
|
17
43
|
* Enhancements:
|
18
|
-
* Windows: build against SQLite 3.8.
|
44
|
+
* Windows: build against SQLite 3.8.6. Closes #135 [Hubro]
|
19
45
|
|
20
46
|
=== 1.3.9 / 2014-02-25
|
21
47
|
|
data/Gemfile
CHANGED
@@ -5,11 +5,13 @@
|
|
5
5
|
source "https://rubygems.org/"
|
6
6
|
|
7
7
|
|
8
|
-
gem "minitest", "~>5.
|
9
|
-
gem "rake-compiler", "~>0
|
10
|
-
gem "rake-compiler-dock", "~>0.
|
8
|
+
gem "minitest", "~>5.11", :group => [:development, :test]
|
9
|
+
gem "rake-compiler", "~>1.0", :group => [:development, :test]
|
10
|
+
gem "rake-compiler-dock", "~>0.6.0", :group => [:development, :test]
|
11
11
|
gem "mini_portile", "~>0.6.2", :group => [:development, :test]
|
12
12
|
gem "hoe-bundler", "~>1.0", :group => [:development, :test]
|
13
|
-
gem "hoe", "~>
|
13
|
+
gem "hoe-gemspec", "~>1.0", :group => [:development, :test]
|
14
|
+
gem "rdoc", ">=4.0", "<6", :group => [:development, :test]
|
15
|
+
gem "hoe", "~>3.17", :group => [:development, :test]
|
14
16
|
|
15
17
|
# vim: syntax=ruby
|
data/Manifest.txt
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
.gemtest
|
2
|
+
.travis.yml
|
1
3
|
API_CHANGES.rdoc
|
2
4
|
CHANGELOG.rdoc
|
3
5
|
ChangeLog.cvs
|
@@ -6,6 +8,9 @@ LICENSE
|
|
6
8
|
Manifest.txt
|
7
9
|
README.rdoc
|
8
10
|
Rakefile
|
11
|
+
appveyor.yml
|
12
|
+
ext/sqlite3/aggregator.c
|
13
|
+
ext/sqlite3/aggregator.h
|
9
14
|
ext/sqlite3/backup.c
|
10
15
|
ext/sqlite3/backup.h
|
11
16
|
ext/sqlite3/database.c
|
@@ -29,19 +34,22 @@ lib/sqlite3/statement.rb
|
|
29
34
|
lib/sqlite3/translator.rb
|
30
35
|
lib/sqlite3/value.rb
|
31
36
|
lib/sqlite3/version.rb
|
37
|
+
rakelib/faq.rake
|
38
|
+
rakelib/gem.rake
|
39
|
+
rakelib/native.rake
|
40
|
+
rakelib/vendor_sqlite3.rake
|
32
41
|
setup.rb
|
33
|
-
tasks/faq.rake
|
34
|
-
tasks/gem.rake
|
35
|
-
tasks/native.rake
|
36
|
-
tasks/vendor_sqlite3.rake
|
37
42
|
test/helper.rb
|
38
43
|
test/test_backup.rb
|
39
44
|
test/test_collation.rb
|
40
45
|
test/test_database.rb
|
46
|
+
test/test_database_flags.rb
|
41
47
|
test/test_database_readonly.rb
|
48
|
+
test/test_database_readwrite.rb
|
42
49
|
test/test_deprecated.rb
|
43
50
|
test/test_encoding.rb
|
44
51
|
test/test_integration.rb
|
52
|
+
test/test_integration_aggregate.rb
|
45
53
|
test/test_integration_open_close.rb
|
46
54
|
test/test_integration_pending.rb
|
47
55
|
test/test_integration_resultset.rb
|
data/README.rdoc
CHANGED
@@ -107,7 +107,7 @@ which can be found here:
|
|
107
107
|
|
108
108
|
For help figuring out the SQLite3/Ruby interface, check out the
|
109
109
|
SYNOPSIS as well as the RDoc. It includes examples of
|
110
|
-
usage. If you have any questions that you feel should be
|
110
|
+
usage. If you have any questions that you feel should be addressed in the
|
111
111
|
FAQ, please send them to {the mailing list}[http://groups.google.com/group/sqlite3-ruby]
|
112
112
|
|
113
113
|
== Source Code
|
data/Rakefile
CHANGED
data/appveyor.yml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
version: "{build}"
|
3
|
+
branches:
|
4
|
+
only:
|
5
|
+
- master
|
6
|
+
- 1-3-stable
|
7
|
+
clone_depth: 10
|
8
|
+
install:
|
9
|
+
- SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
|
10
|
+
- ruby --version
|
11
|
+
- gem --version
|
12
|
+
- gem install bundler --quiet --no-ri --no-rdoc
|
13
|
+
- bundler --version
|
14
|
+
- bundle install
|
15
|
+
build_script:
|
16
|
+
- rake native gem
|
17
|
+
test_script:
|
18
|
+
- rake test
|
19
|
+
artifacts:
|
20
|
+
- path: pkg\*.gem
|
21
|
+
|
22
|
+
environment:
|
23
|
+
matrix:
|
24
|
+
- ruby_version: "193"
|
25
|
+
- ruby_version: "200"
|
26
|
+
- ruby_version: "200-x64"
|
27
|
+
- ruby_version: "21"
|
28
|
+
- ruby_version: "21-x64"
|
29
|
+
- ruby_version: "22"
|
30
|
+
- ruby_version: "22-x64"
|
31
|
+
- ruby_version: "23"
|
32
|
+
- ruby_version: "23-x64"
|
33
|
+
- ruby_version: "24"
|
34
|
+
- ruby_version: "24-x64"
|
35
|
+
- ruby_version: "25"
|
36
|
+
- ruby_version: "25-x64"
|
@@ -0,0 +1,273 @@
|
|
1
|
+
#include <aggregator.h>
|
2
|
+
#include <database.h>
|
3
|
+
|
4
|
+
/* wraps a factory "handler" class. The "-aggregators" instance variable of
|
5
|
+
* the SQLite3::Database holds an array of all AggrogatorWrappers.
|
6
|
+
*
|
7
|
+
* An AggregatorWrapper holds the following instance variables:
|
8
|
+
* -handler_klass: the handler that creates the instances.
|
9
|
+
* -instances: array of all the cAggregatorInstance objects currently
|
10
|
+
* in-flight for this aggregator. */
|
11
|
+
static VALUE cAggregatorWrapper;
|
12
|
+
|
13
|
+
/* wraps a intance of the "handler" class. Loses its reference at the end of
|
14
|
+
* the xFinal callback.
|
15
|
+
*
|
16
|
+
* An AggregatorInstance holds the following instnace variables:
|
17
|
+
* -handler_instance: the instance to call `step` and `finalize` on.
|
18
|
+
* -exc_status: status returned by rb_protect.
|
19
|
+
* != 0 if an exception occurred. If an exception occured
|
20
|
+
* `step` and `finalize` won't be called any more. */
|
21
|
+
static VALUE cAggregatorInstance;
|
22
|
+
|
23
|
+
typedef struct rb_sqlite3_protected_funcall_args {
|
24
|
+
VALUE self;
|
25
|
+
ID method;
|
26
|
+
int argc;
|
27
|
+
VALUE *params;
|
28
|
+
} protected_funcall_args_t;
|
29
|
+
|
30
|
+
/* why isn't there something like this in the ruby API? */
|
31
|
+
static VALUE
|
32
|
+
rb_sqlite3_protected_funcall_body(VALUE protected_funcall_args_ptr)
|
33
|
+
{
|
34
|
+
protected_funcall_args_t *args =
|
35
|
+
(protected_funcall_args_t*)protected_funcall_args_ptr;
|
36
|
+
|
37
|
+
return rb_funcall2(args->self, args->method, args->argc, args->params);
|
38
|
+
}
|
39
|
+
|
40
|
+
static VALUE
|
41
|
+
rb_sqlite3_protected_funcall(VALUE self, ID method, int argc, VALUE *params,
|
42
|
+
int* exc_status)
|
43
|
+
{
|
44
|
+
protected_funcall_args_t args = {
|
45
|
+
.self = self, .method = method, .argc = argc, .params = params
|
46
|
+
};
|
47
|
+
return rb_protect(rb_sqlite3_protected_funcall_body, (VALUE)(&args), exc_status);
|
48
|
+
}
|
49
|
+
|
50
|
+
/* called in rb_sqlite3_aggregator_step and rb_sqlite3_aggregator_final. It
|
51
|
+
* checks if the exection context already has an associated instance. If it
|
52
|
+
* has one, it returns it. If there is no instance yet, it creates one and
|
53
|
+
* associates it with the context. */
|
54
|
+
static VALUE
|
55
|
+
rb_sqlite3_aggregate_instance(sqlite3_context *ctx)
|
56
|
+
{
|
57
|
+
VALUE aw = (VALUE) sqlite3_user_data(ctx);
|
58
|
+
VALUE handler_klass = rb_iv_get(aw, "-handler_klass");
|
59
|
+
VALUE inst;
|
60
|
+
VALUE *inst_ptr = sqlite3_aggregate_context(ctx, (int)sizeof(VALUE));
|
61
|
+
|
62
|
+
if (!inst_ptr) {
|
63
|
+
rb_fatal("SQLite is out-of-merory");
|
64
|
+
}
|
65
|
+
|
66
|
+
inst = *inst_ptr;
|
67
|
+
|
68
|
+
if (inst == Qfalse) { /* Qfalse == 0 */
|
69
|
+
VALUE instances = rb_iv_get(aw, "-instances");
|
70
|
+
int exc_status;
|
71
|
+
|
72
|
+
inst = rb_class_new_instance(0, NULL, cAggregatorInstance);
|
73
|
+
rb_iv_set(inst, "-handler_instance", rb_sqlite3_protected_funcall(
|
74
|
+
handler_klass, rb_intern("new"), 0, NULL, &exc_status));
|
75
|
+
rb_iv_set(inst, "-exc_status", INT2NUM(exc_status));
|
76
|
+
|
77
|
+
rb_ary_push(instances, inst);
|
78
|
+
|
79
|
+
*inst_ptr = inst;
|
80
|
+
}
|
81
|
+
|
82
|
+
if (inst == Qnil) {
|
83
|
+
rb_fatal("SQLite called us back on an already destroyed aggregate instance");
|
84
|
+
}
|
85
|
+
|
86
|
+
return inst;
|
87
|
+
}
|
88
|
+
|
89
|
+
/* called by rb_sqlite3_aggregator_final. Unlinks and frees the
|
90
|
+
* aggregator_instance_t, so the handler_instance won't be marked any more
|
91
|
+
* and Ruby's GC may free it. */
|
92
|
+
static void
|
93
|
+
rb_sqlite3_aggregate_instance_destroy(sqlite3_context *ctx)
|
94
|
+
{
|
95
|
+
VALUE aw = (VALUE) sqlite3_user_data(ctx);
|
96
|
+
VALUE instances = rb_iv_get(aw, "-instances");
|
97
|
+
VALUE *inst_ptr = sqlite3_aggregate_context(ctx, 0);
|
98
|
+
VALUE inst;
|
99
|
+
|
100
|
+
if (!inst_ptr || (inst = *inst_ptr)) {
|
101
|
+
return;
|
102
|
+
}
|
103
|
+
|
104
|
+
if (inst == Qnil) {
|
105
|
+
rb_fatal("attempt to destroy aggregate instance twice");
|
106
|
+
}
|
107
|
+
|
108
|
+
rb_iv_set(inst, "-handler_instance", Qnil); // may catch use-after-free
|
109
|
+
if (rb_ary_delete(instances, inst) == Qnil) {
|
110
|
+
rb_fatal("must be in instances at that point");
|
111
|
+
}
|
112
|
+
|
113
|
+
*inst_ptr = Qnil;
|
114
|
+
}
|
115
|
+
|
116
|
+
static void
|
117
|
+
rb_sqlite3_aggregator_step(sqlite3_context * ctx, int argc, sqlite3_value **argv)
|
118
|
+
{
|
119
|
+
VALUE inst = rb_sqlite3_aggregate_instance(ctx);
|
120
|
+
VALUE handler_instance = rb_iv_get(inst, "-handler_instance");
|
121
|
+
VALUE * params = NULL;
|
122
|
+
VALUE one_param;
|
123
|
+
int exc_status = NUM2INT(rb_iv_get(inst, "-exc_status"));
|
124
|
+
int i;
|
125
|
+
|
126
|
+
if (exc_status) {
|
127
|
+
return;
|
128
|
+
}
|
129
|
+
|
130
|
+
if (argc == 1) {
|
131
|
+
one_param = sqlite3val2rb(argv[0]);
|
132
|
+
params = &one_param;
|
133
|
+
}
|
134
|
+
if (argc > 1) {
|
135
|
+
params = xcalloc((size_t)argc, sizeof(VALUE));
|
136
|
+
for(i = 0; i < argc; i++) {
|
137
|
+
params[i] = sqlite3val2rb(argv[i]);
|
138
|
+
}
|
139
|
+
}
|
140
|
+
rb_sqlite3_protected_funcall(
|
141
|
+
handler_instance, rb_intern("step"), argc, params, &exc_status);
|
142
|
+
if (argc > 1) {
|
143
|
+
xfree(params);
|
144
|
+
}
|
145
|
+
|
146
|
+
rb_iv_set(inst, "-exc_status", INT2NUM(exc_status));
|
147
|
+
}
|
148
|
+
|
149
|
+
/* we assume that this function is only called once per execution context */
|
150
|
+
static void
|
151
|
+
rb_sqlite3_aggregator_final(sqlite3_context * ctx)
|
152
|
+
{
|
153
|
+
VALUE inst = rb_sqlite3_aggregate_instance(ctx);
|
154
|
+
VALUE handler_instance = rb_iv_get(inst, "-handler_instance");
|
155
|
+
int exc_status = NUM2INT(rb_iv_get(inst, "-exc_status"));
|
156
|
+
|
157
|
+
if (!exc_status) {
|
158
|
+
VALUE result = rb_sqlite3_protected_funcall(
|
159
|
+
handler_instance, rb_intern("finalize"), 0, NULL, &exc_status);
|
160
|
+
if (!exc_status) {
|
161
|
+
set_sqlite3_func_result(ctx, result);
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
if (exc_status) {
|
166
|
+
/* the user should never see this, as Statement.step() will pick up the
|
167
|
+
* outstanding exception and raise it instead of generating a new one
|
168
|
+
* for SQLITE_ERROR with message "Ruby Exception occured" */
|
169
|
+
sqlite3_result_error(ctx, "Ruby Exception occured", -1);
|
170
|
+
}
|
171
|
+
|
172
|
+
rb_sqlite3_aggregate_instance_destroy(ctx);
|
173
|
+
}
|
174
|
+
|
175
|
+
/* call-seq: define_aggregator2(aggregator)
|
176
|
+
*
|
177
|
+
* Define an aggregrate function according to a factory object (the "handler")
|
178
|
+
* that knows how to obtain to all the information. The handler must provide
|
179
|
+
* the following class methods:
|
180
|
+
*
|
181
|
+
* +arity+:: corresponds to the +arity+ parameter of #create_aggregate. This
|
182
|
+
* message is optional, and if the handler does not respond to it,
|
183
|
+
* the function will have an arity of -1.
|
184
|
+
* +name+:: this is the name of the function. The handler _must_ implement
|
185
|
+
* this message.
|
186
|
+
* +new+:: this must be implemented by the handler. It should return a new
|
187
|
+
* instance of the object that will handle a specific invocation of
|
188
|
+
* the function.
|
189
|
+
*
|
190
|
+
* The handler instance (the object returned by the +new+ message, described
|
191
|
+
* above), must respond to the following messages:
|
192
|
+
*
|
193
|
+
* +step+:: this is the method that will be called for each step of the
|
194
|
+
* aggregate function's evaluation. It should take parameters according
|
195
|
+
* to the *arity* definition.
|
196
|
+
* +finalize+:: this is the method that will be called to finalize the
|
197
|
+
* aggregate function's evaluation. It should not take arguments.
|
198
|
+
*
|
199
|
+
* Note the difference between this function and #create_aggregate_handler
|
200
|
+
* is that no FunctionProxy ("ctx") object is involved. This manifests in two
|
201
|
+
* ways: The return value of the aggregate function is the return value of
|
202
|
+
* +finalize+ and neither +step+ nor +finalize+ take an additional "ctx"
|
203
|
+
* parameter.
|
204
|
+
*/
|
205
|
+
VALUE
|
206
|
+
rb_sqlite3_define_aggregator2(VALUE self, VALUE aggregator, VALUE ruby_name)
|
207
|
+
{
|
208
|
+
/* define_aggregator is added as a method to SQLite3::Database in database.c */
|
209
|
+
sqlite3RubyPtr ctx;
|
210
|
+
int arity, status;
|
211
|
+
VALUE aw;
|
212
|
+
VALUE aggregators;
|
213
|
+
|
214
|
+
Data_Get_Struct(self, sqlite3Ruby, ctx);
|
215
|
+
if (!ctx->db) {
|
216
|
+
rb_raise(rb_path2class("SQLite3::Exception"), "cannot use a closed database");
|
217
|
+
}
|
218
|
+
|
219
|
+
if (rb_respond_to(aggregator, rb_intern("arity"))) {
|
220
|
+
VALUE ruby_arity = rb_funcall(aggregator, rb_intern("arity"), 0);
|
221
|
+
arity = NUM2INT(ruby_arity);
|
222
|
+
} else {
|
223
|
+
arity = -1;
|
224
|
+
}
|
225
|
+
|
226
|
+
if (arity < -1 || arity > 127) {
|
227
|
+
#ifdef PRIsVALUE
|
228
|
+
rb_raise(rb_eArgError, "%"PRIsVALUE" arity=%d out of range -1..127",
|
229
|
+
self, arity);
|
230
|
+
#else
|
231
|
+
rb_raise(rb_eArgError, "Aggregator arity=%d out of range -1..127", arity);
|
232
|
+
#endif
|
233
|
+
}
|
234
|
+
|
235
|
+
if (!rb_ivar_defined(self, rb_intern("-aggregators"))) {
|
236
|
+
rb_iv_set(self, "-aggregators", rb_ary_new());
|
237
|
+
}
|
238
|
+
aggregators = rb_iv_get(self, "-aggregators");
|
239
|
+
|
240
|
+
aw = rb_class_new_instance(0, NULL, cAggregatorWrapper);
|
241
|
+
rb_iv_set(aw, "-handler_klass", aggregator);
|
242
|
+
rb_iv_set(aw, "-instances", rb_ary_new());
|
243
|
+
|
244
|
+
status = sqlite3_create_function(
|
245
|
+
ctx->db,
|
246
|
+
StringValueCStr(ruby_name),
|
247
|
+
arity,
|
248
|
+
SQLITE_UTF8,
|
249
|
+
(void*)aw,
|
250
|
+
NULL,
|
251
|
+
rb_sqlite3_aggregator_step,
|
252
|
+
rb_sqlite3_aggregator_final
|
253
|
+
);
|
254
|
+
|
255
|
+
if (status != SQLITE_OK) {
|
256
|
+
rb_sqlite3_raise(ctx->db, status);
|
257
|
+
return self; // just in case rb_sqlite3_raise returns.
|
258
|
+
}
|
259
|
+
|
260
|
+
rb_ary_push(aggregators, aw);
|
261
|
+
|
262
|
+
return self;
|
263
|
+
}
|
264
|
+
|
265
|
+
void
|
266
|
+
rb_sqlite3_aggregator_init(void)
|
267
|
+
{
|
268
|
+
rb_gc_register_address(&cAggregatorWrapper);
|
269
|
+
rb_gc_register_address(&cAggregatorInstance);
|
270
|
+
/* rb_class_new generatos class with undefined allocator in ruby 1.9 */
|
271
|
+
cAggregatorWrapper = rb_funcall(rb_cClass, rb_intern("new"), 0);
|
272
|
+
cAggregatorInstance = rb_funcall(rb_cClass, rb_intern("new"), 0);
|
273
|
+
}
|