sqlite3 1.3.13 → 1.4.0

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
- SHA1:
3
- metadata.gz: b430789a68a6d6079e0395db6fc53421e4b317ab
4
- data.tar.gz: db014f4a1f4e980913a3dcb48d9aab14a5a9eca1
2
+ SHA256:
3
+ metadata.gz: 12a87a5d693b4d68db868158d5df73469c5ad1498dd5bfc9cd0cd6b482996b00
4
+ data.tar.gz: cfd6ea51679375b03a9a4a22ab107bd12965e9559be4bba9ef0f40e6dfd40cd5
5
5
  SHA512:
6
- metadata.gz: 7e2764239b107677240476bb608bcb46cc0966c06d06e90881113b91dbdb8342c6c7558760cf0645a56449ac8e267f13a0e25dbef0d3e820a38f5857a96c4e05
7
- data.tar.gz: 1e08a478ed043d22bbe95df2151bf009a7f03a1457c37df4199c8601fa1ccb9de27986e64341c4fb9a009e5ab4023638704078222f88441b55ac1ee2773838d8
6
+ metadata.gz: 4aff04e4371d3c78405719e0dc26b297f19514c1541190a23deadd96de3d71e94241cb5222c0623aa7cfd7e28ce731e37535cbc9b19a9cba63f7004c60d1afda
7
+ data.tar.gz: 31d1404b0a34ea5513d8b0ad8d3fe7d129c4ac94ba26e96e7e03f94bb7f119ffaad42254f6c2ecf4b95be0aa1f871fe14e79ad60360c2117e7d4fb980e958fba
File without changes
@@ -0,0 +1,32 @@
1
+ sudo: false
2
+ language: ruby
3
+ cache: bundler
4
+ before_install:
5
+ - gem update --system
6
+ - gem install bundler
7
+ addons:
8
+ apt:
9
+ packages:
10
+ - libgmp-dev
11
+
12
+ after_failure:
13
+ - "find . -name mkmf.log -exec cat {} \\;"
14
+
15
+ after_success:
16
+ - "find . -name mkmf.log -exec cat {} \\;"
17
+
18
+ env:
19
+ - USE_MINI_PORTILE=true
20
+ - USE_MINI_PORTILE=false
21
+ rvm:
22
+ - 1.9.3
23
+ - 2.0.0
24
+ - 2.1
25
+ - 2.2
26
+ - 2.3
27
+ - 2.4
28
+ - 2.5
29
+ - ruby-head
30
+ matrix:
31
+ allow_failures:
32
+ - env: USE_MINI_PORTILE=false
@@ -1,3 +1,17 @@
1
+ === 1.4.0
2
+
3
+ * Enhancements
4
+ * Better aggregator support
5
+
6
+ * Bugfixes
7
+ * Various
8
+
9
+ === 1.3.13
10
+
11
+ * Enancements
12
+ * Support SQLite flags when defining functions
13
+ * Add definition for SQLITE_DETERMINISTIC flag
14
+
1
15
  === 1.3.12
2
16
 
3
17
  * Bugfixes:
@@ -15,7 +29,7 @@
15
29
  === 1.3.10 / 2014-10-30
16
30
 
17
31
  * Enhancements:
18
- * Windows: build against SQLite 3.8.7.1. Closes #134, #135 [Hubro]
32
+ * Windows: build against SQLite 3.8.6. Closes #135 [Hubro]
19
33
 
20
34
  === 1.3.9 / 2014-02-25
21
35
 
data/Gemfile CHANGED
@@ -5,11 +5,13 @@
5
5
  source "https://rubygems.org/"
6
6
 
7
7
 
8
- gem "minitest", "~>5.9", :group => [:development, :test]
9
- gem "rake-compiler", "~>0.9.3", :group => [:development, :test]
10
- gem "rake-compiler-dock", "~>0.5.2", :group => [:development, :test]
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", "~>3.15", :group => [:development, :test]
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
@@ -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
@@ -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 address in the
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
@@ -4,7 +4,5 @@
4
4
  # Thank You.
5
5
  #
6
6
 
7
- # load rakefile extensions (tasks)
8
- Dir['tasks/*.rake'].sort.each { |f| load f }
9
7
 
10
8
  # vim: syntax=ruby
@@ -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
+ }