sqlite3 1.3.13-x64-mingw32 → 1.5.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sqlite3 might be problematic. Click here for more details.

Files changed (54) hide show
  1. checksums.yaml +5 -5
  2. data/.gemtest +0 -0
  3. data/{API_CHANGES.rdoc → API_CHANGES.md} +3 -4
  4. data/CHANGELOG.md +425 -0
  5. data/CONTRIBUTING.md +24 -0
  6. data/Gemfile +2 -14
  7. data/LICENSE-DEPENDENCIES +20 -0
  8. data/README.md +233 -0
  9. data/ext/sqlite3/aggregator.c +274 -0
  10. data/ext/sqlite3/aggregator.h +12 -0
  11. data/ext/sqlite3/database.c +171 -206
  12. data/ext/sqlite3/database.h +2 -0
  13. data/ext/sqlite3/exception.c +6 -2
  14. data/ext/sqlite3/extconf.rb +236 -55
  15. data/ext/sqlite3/sqlite3.c +12 -1
  16. data/ext/sqlite3/sqlite3_ruby.h +3 -7
  17. data/ext/sqlite3/statement.c +15 -20
  18. data/faq/faq.md +431 -0
  19. data/faq/faq.yml +1 -1
  20. data/lib/sqlite3/2.6/sqlite3_native.so +0 -0
  21. data/lib/sqlite3/2.7/sqlite3_native.so +0 -0
  22. data/lib/sqlite3/3.0/sqlite3_native.so +0 -0
  23. data/lib/sqlite3/constants.rb +2 -1
  24. data/lib/sqlite3/database.rb +202 -52
  25. data/lib/sqlite3/errors.rb +1 -10
  26. data/lib/sqlite3/pragmas.rb +17 -10
  27. data/lib/sqlite3/resultset.rb +2 -10
  28. data/lib/sqlite3/statement.rb +2 -1
  29. data/lib/sqlite3/translator.rb +1 -1
  30. data/lib/sqlite3/version.rb +3 -5
  31. data/test/helper.rb +9 -0
  32. data/test/test_database.rb +126 -11
  33. data/test/test_database_flags.rb +95 -0
  34. data/test/test_database_readwrite.rb +41 -0
  35. data/test/test_integration.rb +12 -81
  36. data/test/test_integration_aggregate.rb +336 -0
  37. data/test/test_integration_resultset.rb +0 -17
  38. data/test/test_sqlite3.rb +9 -0
  39. data/test/test_statement.rb +11 -8
  40. metadata +54 -85
  41. data/CHANGELOG.rdoc +0 -292
  42. data/Manifest.txt +0 -52
  43. data/README.rdoc +0 -118
  44. data/Rakefile +0 -10
  45. data/lib/sqlite3/2.0/sqlite3_native.so +0 -0
  46. data/lib/sqlite3/2.1/sqlite3_native.so +0 -0
  47. data/lib/sqlite3/2.2/sqlite3_native.so +0 -0
  48. data/lib/sqlite3/2.3/sqlite3_native.so +0 -0
  49. data/lib/sqlite3/2.4/sqlite3_native.so +0 -0
  50. data/setup.rb +0 -1333
  51. data/tasks/faq.rake +0 -9
  52. data/tasks/gem.rake +0 -38
  53. data/tasks/native.rake +0 -52
  54. data/tasks/vendor_sqlite3.rake +0 -97
@@ -1,11 +1,16 @@
1
1
  #include <sqlite3_ruby.h>
2
+ #include <aggregator.h>
3
+
4
+ #ifdef _MSC_VER
5
+ #pragma warning( push )
6
+ #pragma warning( disable : 4028 )
7
+ #endif
2
8
 
3
9
  #define REQUIRE_OPEN_DB(_ctxt) \
4
10
  if(!_ctxt->db) \
5
11
  rb_raise(rb_path2class("SQLite3::Exception"), "cannot use a closed database");
6
12
 
7
13
  VALUE cSqlite3Database;
8
- static VALUE sym_utf16, sym_results_as_hash, sym_type_translation;
9
14
 
10
15
  static void deallocate(void * ctx)
11
16
  {
@@ -26,133 +31,55 @@ static char *
26
31
  utf16_string_value_ptr(VALUE str)
27
32
  {
28
33
  StringValue(str);
29
- rb_str_buf_cat(str, "\x00", 1L);
34
+ rb_str_buf_cat(str, "\x00\x00", 2L);
30
35
  return RSTRING_PTR(str);
31
36
  }
32
37
 
33
38
  static VALUE sqlite3_rb_close(VALUE self);
34
39
 
35
- /* call-seq: SQLite3::Database.new(file, options = {})
36
- *
37
- * Create a new Database object that opens the given file. If utf16
38
- * is +true+, the filename is interpreted as a UTF-16 encoded string.
39
- *
40
- * By default, the new database will return result rows as arrays
41
- * (#results_as_hash) and has type translation disabled (#type_translation=).
42
- */
43
- static VALUE initialize(int argc, VALUE *argv, VALUE self)
40
+ static VALUE rb_sqlite3_open_v2(VALUE self, VALUE file, VALUE mode, VALUE zvfs)
44
41
  {
45
42
  sqlite3RubyPtr ctx;
46
- VALUE file;
47
- VALUE opts;
48
- VALUE zvfs;
49
- VALUE flags;
50
- #ifdef HAVE_SQLITE3_OPEN_V2
51
- int mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
52
- #endif
53
43
  int status;
54
44
 
55
45
  Data_Get_Struct(self, sqlite3Ruby, ctx);
56
46
 
57
- rb_scan_args(argc, argv, "12", &file, &opts, &zvfs);
58
- #if defined StringValueCStr
47
+ #if defined TAINTING_SUPPORT
48
+ # if defined StringValueCStr
59
49
  StringValuePtr(file);
60
50
  rb_check_safe_obj(file);
61
- #else
51
+ # else
62
52
  Check_SafeStr(file);
63
- #endif
64
- if(NIL_P(opts)) opts = rb_hash_new();
65
- else Check_Type(opts, T_HASH);
66
-
67
- #ifdef HAVE_RUBY_ENCODING_H
68
- if(UTF16_LE_P(file) || UTF16_BE_P(file)) {
69
- status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
70
- } else {
53
+ # endif
71
54
  #endif
72
55
 
73
- if(Qtrue == rb_hash_aref(opts, sym_utf16)) {
74
- status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
75
- } else {
76
-
77
- #ifdef HAVE_RUBY_ENCODING_H
78
- if(!UTF8_P(file)) {
79
- file = rb_str_export_to_enc(file, rb_utf8_encoding());
80
- }
81
- #endif
82
-
83
- /* The three primary flag values for sqlite3_open_v2 are:
84
- * SQLITE_OPEN_READONLY
85
- * SQLITE_OPEN_READWRITE
86
- * SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE -- always used for sqlite3_open and sqlite3_open16
87
- */
88
- if (Qtrue == rb_hash_aref(opts, ID2SYM(rb_intern("readonly")))) {
89
- #ifdef HAVE_SQLITE3_OPEN_V2
90
- mode = SQLITE_OPEN_READONLY;
91
- #else
92
- rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support readonly databases");
93
- #endif
94
- }
95
- if (Qtrue == rb_hash_aref(opts, ID2SYM(rb_intern("readwrite")))) {
96
- #ifdef HAVE_SQLITE3_OPEN_V2
97
- if (mode == SQLITE_OPEN_READONLY) {
98
- rb_raise(rb_eRuntimeError, "conflicting options: readonly and readwrite");
99
- }
100
- mode = SQLITE_OPEN_READWRITE;
101
- #else
102
- rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support readwrite without create");
103
- #endif
104
- }
105
- flags = rb_hash_aref(opts, ID2SYM(rb_intern("flags")));
106
- if (flags != Qnil) {
107
- #ifdef HAVE_SQLITE3_OPEN_V2
108
- if ((mode & SQLITE_OPEN_CREATE) == 0) {
109
- rb_raise(rb_eRuntimeError, "conflicting options: flags with readonly and/or readwrite");
110
- }
111
- mode = (int)NUM2INT(flags);
112
- #else
113
- rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support flags on open");
114
- #endif
115
- }
116
- #ifdef HAVE_SQLITE3_OPEN_V2
117
56
  status = sqlite3_open_v2(
118
57
  StringValuePtr(file),
119
58
  &ctx->db,
120
- mode,
59
+ NUM2INT(mode),
121
60
  NIL_P(zvfs) ? NULL : StringValuePtr(zvfs)
122
61
  );
123
- #else
124
- status = sqlite3_open(
125
- StringValuePtr(file),
126
- &ctx->db
127
- );
128
- #endif
129
- }
130
-
131
- #ifdef HAVE_RUBY_ENCODING_H
132
- }
133
- #endif
134
62
 
135
63
  CHECK(ctx->db, status)
136
64
 
137
- rb_iv_set(self, "@tracefunc", Qnil);
138
- rb_iv_set(self, "@authorizer", Qnil);
139
- rb_iv_set(self, "@encoding", Qnil);
140
- rb_iv_set(self, "@busy_handler", Qnil);
141
- rb_iv_set(self, "@collations", rb_hash_new());
142
- rb_iv_set(self, "@functions", rb_hash_new());
143
- rb_iv_set(self, "@results_as_hash", rb_hash_aref(opts, sym_results_as_hash));
144
- rb_iv_set(self, "@type_translation", rb_hash_aref(opts, sym_type_translation));
145
- #ifdef HAVE_SQLITE3_OPEN_V2
146
- rb_iv_set(self, "@readonly", (mode & SQLITE_OPEN_READONLY) ? Qtrue : Qfalse);
147
- #else
148
- rb_iv_set(self, "@readonly", Qfalse);
149
- #endif
65
+ return self;
66
+ }
150
67
 
151
- if(rb_block_given_p()) {
152
- rb_ensure(rb_yield, self, sqlite3_rb_close, self);
153
- }
68
+ static VALUE rb_sqlite3_disable_quirk_mode(VALUE self)
69
+ {
70
+ #if defined SQLITE_DBCONFIG_DQS_DDL
71
+ sqlite3RubyPtr ctx;
72
+ Data_Get_Struct(self, sqlite3Ruby, ctx);
154
73
 
155
- return self;
74
+ if(!ctx->db) return Qfalse;
75
+
76
+ sqlite3_db_config(ctx->db, SQLITE_DBCONFIG_DQS_DDL, 0, (void*)0);
77
+ sqlite3_db_config(ctx->db, SQLITE_DBCONFIG_DQS_DML, 0, (void*)0);
78
+
79
+ return Qtrue;
80
+ #else
81
+ return Qfalse;
82
+ #endif
156
83
  }
157
84
 
158
85
  /* call-seq: db.close
@@ -170,6 +97,8 @@ static VALUE sqlite3_rb_close(VALUE self)
170
97
 
171
98
  ctx->db = NULL;
172
99
 
100
+ rb_iv_set(self, "-aggregators", Qnil);
101
+
173
102
  return self;
174
103
  }
175
104
 
@@ -297,7 +226,7 @@ static VALUE last_insert_row_id(VALUE self)
297
226
  return LL2NUM(sqlite3_last_insert_rowid(ctx->db));
298
227
  }
299
228
 
300
- static VALUE sqlite3val2rb(sqlite3_value * val)
229
+ VALUE sqlite3val2rb(sqlite3_value * val)
301
230
  {
302
231
  switch(sqlite3_value_type(val)) {
303
232
  case SQLITE_INTEGER:
@@ -307,23 +236,16 @@ static VALUE sqlite3val2rb(sqlite3_value * val)
307
236
  return rb_float_new(sqlite3_value_double(val));
308
237
  break;
309
238
  case SQLITE_TEXT:
310
- return rb_tainted_str_new2((const char *)sqlite3_value_text(val));
239
+ return rb_str_new2((const char *)sqlite3_value_text(val));
311
240
  break;
312
241
  case SQLITE_BLOB: {
313
242
  /* Sqlite warns calling sqlite3_value_bytes may invalidate pointer from sqlite3_value_blob,
314
243
  so we explicitly get the length before getting blob pointer.
315
- Note that rb_str_new and rb_tainted_str_new apparently create string with ASCII-8BIT (BINARY) encoding,
244
+ Note that rb_str_new apparently create string with ASCII-8BIT (BINARY) encoding,
316
245
  which is what we want, as blobs are binary
317
246
  */
318
247
  int len = sqlite3_value_bytes(val);
319
- #ifdef HAVE_RUBY_ENCODING_H
320
- return rb_tainted_str_new((const char *)sqlite3_value_blob(val), len);
321
- #else
322
- /* When encoding is not available, make it class SQLite3::Blob. */
323
- VALUE strargv[1];
324
- strargv[0] = rb_tainted_str_new((const char *)sqlite3_value_blob(val), len);
325
- return rb_class_new_instance(1, strargv, cSqlite3Blob);
326
- #endif
248
+ return rb_str_new((const char *)sqlite3_value_blob(val), len);
327
249
  break;
328
250
  }
329
251
  case SQLITE_NULL:
@@ -334,7 +256,7 @@ static VALUE sqlite3val2rb(sqlite3_value * val)
334
256
  }
335
257
  }
336
258
 
337
- static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
259
+ void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
338
260
  {
339
261
  switch(TYPE(result)) {
340
262
  case T_NIL:
@@ -358,9 +280,7 @@ static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
358
280
  break;
359
281
  case T_STRING:
360
282
  if(CLASS_OF(result) == cSqlite3Blob
361
- #ifdef HAVE_RUBY_ENCODING_H
362
283
  || rb_enc_get_index(result) == rb_ascii8bit_encindex()
363
- #endif
364
284
  ) {
365
285
  sqlite3_result_blob(
366
286
  ctx,
@@ -409,12 +329,12 @@ int rb_proc_arity(VALUE self)
409
329
  }
410
330
  #endif
411
331
 
412
- /* call-seq: define_function(name) { |args,...| }
332
+ /* call-seq: define_function_with_flags(name, flags) { |args,...| }
413
333
  *
414
- * Define a function named +name+ with +args+. The arity of the block
334
+ * Define a function named +name+ with +args+ using TextRep bitflags +flags+. The arity of the block
415
335
  * will be used as the arity for the function defined.
416
336
  */
417
- static VALUE define_function(VALUE self, VALUE name)
337
+ static VALUE define_function_with_flags(VALUE self, VALUE name, VALUE flags)
418
338
  {
419
339
  sqlite3RubyPtr ctx;
420
340
  VALUE block;
@@ -429,7 +349,7 @@ static VALUE define_function(VALUE self, VALUE name)
429
349
  ctx->db,
430
350
  StringValuePtr(name),
431
351
  rb_proc_arity(block),
432
- SQLITE_UTF8,
352
+ NUM2INT(flags),
433
353
  (void *)block,
434
354
  rb_sqlite3_func,
435
355
  NULL,
@@ -443,70 +363,14 @@ static VALUE define_function(VALUE self, VALUE name)
443
363
  return self;
444
364
  }
445
365
 
446
- static int sqlite3_obj_method_arity(VALUE obj, ID id)
447
- {
448
- VALUE method = rb_funcall(obj, rb_intern("method"), 1, ID2SYM(id));
449
- VALUE arity = rb_funcall(method, rb_intern("arity"), 0);
450
-
451
- return (int)NUM2INT(arity);
452
- }
453
-
454
- static void rb_sqlite3_step(sqlite3_context * ctx, int argc, sqlite3_value **argv)
455
- {
456
- VALUE callable = (VALUE)sqlite3_user_data(ctx);
457
- VALUE * params = NULL;
458
- int i;
459
-
460
- if (argc > 0) {
461
- params = xcalloc((size_t)argc, sizeof(VALUE *));
462
- for(i = 0; i < argc; i++) {
463
- params[i] = sqlite3val2rb(argv[i]);
464
- }
465
- }
466
- rb_funcall2(callable, rb_intern("step"), argc, params);
467
- xfree(params);
468
- }
469
-
470
- static void rb_sqlite3_final(sqlite3_context * ctx)
471
- {
472
- VALUE callable = (VALUE)sqlite3_user_data(ctx);
473
- VALUE result = rb_funcall(callable, rb_intern("finalize"), 0);
474
- set_sqlite3_func_result(ctx, result);
475
- }
476
-
477
- /* call-seq: define_aggregator(name, aggregator)
366
+ /* call-seq: define_function(name) { |args,...| }
478
367
  *
479
- * Define an aggregate function named +name+ using the object +aggregator+.
480
- * +aggregator+ must respond to +step+ and +finalize+. +step+ will be called
481
- * with row information and +finalize+ must return the return value for the
482
- * aggregator function.
368
+ * Define a function named +name+ with +args+. The arity of the block
369
+ * will be used as the arity for the function defined.
483
370
  */
484
- static VALUE define_aggregator(VALUE self, VALUE name, VALUE aggregator)
371
+ static VALUE define_function(VALUE self, VALUE name)
485
372
  {
486
- sqlite3RubyPtr ctx;
487
- int arity, status;
488
-
489
- Data_Get_Struct(self, sqlite3Ruby, ctx);
490
- REQUIRE_OPEN_DB(ctx);
491
-
492
- arity = sqlite3_obj_method_arity(aggregator, rb_intern("step"));
493
-
494
- status = sqlite3_create_function(
495
- ctx->db,
496
- StringValuePtr(name),
497
- arity,
498
- SQLITE_UTF8,
499
- (void *)aggregator,
500
- NULL,
501
- rb_sqlite3_step,
502
- rb_sqlite3_final
503
- );
504
-
505
- rb_iv_set(self, "@agregator", aggregator);
506
-
507
- CHECK(ctx->db, status);
508
-
509
- return self;
373
+ return define_function_with_flags(self, name, INT2FIX(SQLITE_UTF8));
510
374
  }
511
375
 
512
376
  /* call-seq: interrupt
@@ -654,23 +518,36 @@ static VALUE set_busy_timeout(VALUE self, VALUE timeout)
654
518
  return self;
655
519
  }
656
520
 
521
+ /* call-seq: db.extended_result_codes = true
522
+ *
523
+ * Enable extended result codes in SQLite. These result codes allow for more
524
+ * detailed exception reporting, such a which type of constraint is violated.
525
+ */
526
+ static VALUE set_extended_result_codes(VALUE self, VALUE enable)
527
+ {
528
+ sqlite3RubyPtr ctx;
529
+ Data_Get_Struct(self, sqlite3Ruby, ctx);
530
+ REQUIRE_OPEN_DB(ctx);
531
+
532
+ CHECK(ctx->db, sqlite3_extended_result_codes(ctx->db, RTEST(enable) ? 1 : 0));
533
+
534
+ return self;
535
+ }
536
+
657
537
  int rb_comparator_func(void * ctx, int a_len, const void * a, int b_len, const void * b)
658
538
  {
659
539
  VALUE comparator;
660
540
  VALUE a_str;
661
541
  VALUE b_str;
662
542
  VALUE comparison;
663
- #ifdef HAVE_RUBY_ENCODING_H
664
543
  rb_encoding * internal_encoding;
665
544
 
666
545
  internal_encoding = rb_default_internal_encoding();
667
- #endif
668
546
 
669
547
  comparator = (VALUE)ctx;
670
548
  a_str = rb_str_new((const char *)a, a_len);
671
549
  b_str = rb_str_new((const char *)b, b_len);
672
550
 
673
- #ifdef HAVE_RUBY_ENCODING_H
674
551
  rb_enc_associate_index(a_str, rb_utf8_encindex());
675
552
  rb_enc_associate_index(b_str, rb_utf8_encindex());
676
553
 
@@ -678,7 +555,6 @@ int rb_comparator_func(void * ctx, int a_len, const void * a, int b_len, const v
678
555
  a_str = rb_str_export_to_enc(a_str, internal_encoding);
679
556
  b_str = rb_str_export_to_enc(b_str, internal_encoding);
680
557
  }
681
- #endif
682
558
 
683
559
  comparison = rb_funcall(comparator, rb_intern("compare"), 2, a_str, b_str);
684
560
 
@@ -727,7 +603,7 @@ static VALUE load_extension(VALUE self, VALUE file)
727
603
  Data_Get_Struct(self, sqlite3Ruby, ctx);
728
604
  REQUIRE_OPEN_DB(ctx);
729
605
 
730
- status = sqlite3_load_extension(ctx->db, RSTRING_PTR(file), 0, &errMsg);
606
+ status = sqlite3_load_extension(ctx->db, StringValuePtr(file), 0, &errMsg);
731
607
  if (status != SQLITE_OK)
732
608
  {
733
609
  errexp = rb_exc_new2(rb_eRuntimeError, errMsg);
@@ -765,7 +641,6 @@ static VALUE enable_load_extension(VALUE self, VALUE onoff)
765
641
  }
766
642
  #endif
767
643
 
768
- #ifdef HAVE_RUBY_ENCODING_H
769
644
  static int enc_cb(void * _self, int UNUSED(columns), char **data, char **UNUSED(names))
770
645
  {
771
646
  VALUE self = (VALUE)_self;
@@ -776,16 +651,6 @@ static int enc_cb(void * _self, int UNUSED(columns), char **data, char **UNUSED(
776
651
 
777
652
  return 0;
778
653
  }
779
- #else
780
- static int enc_cb(void * _self, int UNUSED(columns), char **data, char **UNUSED(names))
781
- {
782
- VALUE self = (VALUE)_self;
783
-
784
- rb_iv_set(self, "@encoding", rb_str_new2(data[0]));
785
-
786
- return 0;
787
- }
788
- #endif
789
654
 
790
655
  /* call-seq: db.encoding
791
656
  *
@@ -822,6 +687,78 @@ static VALUE transaction_active_p(VALUE self)
822
687
  return sqlite3_get_autocommit(ctx->db) ? Qfalse : Qtrue;
823
688
  }
824
689
 
690
+ static int hash_callback_function(VALUE callback_ary, int count, char **data, char **columns)
691
+ {
692
+ VALUE new_hash = rb_hash_new();
693
+ int i;
694
+
695
+ for (i = 0; i < count; i++) {
696
+ if (data[i] == NULL) {
697
+ rb_hash_aset(new_hash, rb_str_new_cstr(columns[i]), Qnil);
698
+ } else {
699
+ rb_hash_aset(new_hash, rb_str_new_cstr(columns[i]), rb_str_new_cstr(data[i]));
700
+ }
701
+ }
702
+
703
+ rb_ary_push(callback_ary, new_hash);
704
+
705
+ return 0;
706
+ }
707
+
708
+ static int regular_callback_function(VALUE callback_ary, int count, char **data, char **columns)
709
+ {
710
+ VALUE new_ary = rb_ary_new();
711
+ int i;
712
+
713
+ for (i = 0; i < count; i++) {
714
+ if (data[i] == NULL) {
715
+ rb_ary_push(new_ary, Qnil);
716
+ } else {
717
+ rb_ary_push(new_ary, rb_str_new_cstr(data[i]));
718
+ }
719
+ }
720
+
721
+ rb_ary_push(callback_ary, new_ary);
722
+
723
+ return 0;
724
+ }
725
+
726
+
727
+ /* Is invoked by calling db.execute_batch2(sql, &block)
728
+ *
729
+ * Executes all statements in a given string separated by semicolons.
730
+ * If a query is made, all values returned are strings
731
+ * (except for 'NULL' values which return nil),
732
+ * so the user may parse values with a block.
733
+ * If no query is made, an empty array will be returned.
734
+ */
735
+ static VALUE exec_batch(VALUE self, VALUE sql, VALUE results_as_hash)
736
+ {
737
+ sqlite3RubyPtr ctx;
738
+ int status;
739
+ VALUE callback_ary = rb_ary_new();
740
+ char *errMsg;
741
+ VALUE errexp;
742
+
743
+ Data_Get_Struct(self, sqlite3Ruby, ctx);
744
+ REQUIRE_OPEN_DB(ctx);
745
+
746
+ if(results_as_hash == Qtrue) {
747
+ status = sqlite3_exec(ctx->db, StringValuePtr(sql), (sqlite3_callback)hash_callback_function, (void*)callback_ary, &errMsg);
748
+ } else {
749
+ status = sqlite3_exec(ctx->db, StringValuePtr(sql), (sqlite3_callback)regular_callback_function, (void*)callback_ary, &errMsg);
750
+ }
751
+
752
+ if (status != SQLITE_OK)
753
+ {
754
+ errexp = rb_exc_new2(rb_eRuntimeError, errMsg);
755
+ sqlite3_free(errMsg);
756
+ rb_exc_raise(errexp);
757
+ }
758
+
759
+ return callback_ary;
760
+ }
761
+
825
762
  /* call-seq: db.db_filename(database_name)
826
763
  *
827
764
  * Returns the file associated with +database_name+. Can return nil or an
@@ -840,16 +777,39 @@ static VALUE db_filename(VALUE self, VALUE db_name)
840
777
  return Qnil;
841
778
  }
842
779
 
780
+ static VALUE rb_sqlite3_open16(VALUE self, VALUE file)
781
+ {
782
+ int status;
783
+ sqlite3RubyPtr ctx;
784
+
785
+ Data_Get_Struct(self, sqlite3Ruby, ctx);
786
+
787
+ #if defined TAINTING_SUPPORT
788
+ #if defined StringValueCStr
789
+ StringValuePtr(file);
790
+ rb_check_safe_obj(file);
791
+ #else
792
+ Check_SafeStr(file);
793
+ #endif
794
+ #endif
795
+
796
+ status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
797
+
798
+ CHECK(ctx->db, status)
799
+
800
+ return INT2NUM(status);
801
+ }
802
+
843
803
  void init_sqlite3_database()
844
804
  {
845
- ID id_utf16, id_results_as_hash, id_type_translation;
846
805
  #if 0
847
806
  VALUE mSqlite3 = rb_define_module("SQLite3");
848
807
  #endif
849
808
  cSqlite3Database = rb_define_class_under(mSqlite3, "Database", rb_cObject);
850
809
 
851
810
  rb_define_alloc_func(cSqlite3Database, allocate);
852
- rb_define_method(cSqlite3Database, "initialize", initialize, -1);
811
+ rb_define_private_method(cSqlite3Database, "open_v2", rb_sqlite3_open_v2, 3);
812
+ rb_define_private_method(cSqlite3Database, "open16", rb_sqlite3_open16, 1);
853
813
  rb_define_method(cSqlite3Database, "collation", collation, 2);
854
814
  rb_define_method(cSqlite3Database, "close", sqlite3_rb_close, 0);
855
815
  rb_define_method(cSqlite3Database, "closed?", closed_p, 0);
@@ -857,7 +817,11 @@ void init_sqlite3_database()
857
817
  rb_define_method(cSqlite3Database, "trace", trace, -1);
858
818
  rb_define_method(cSqlite3Database, "last_insert_row_id", last_insert_row_id, 0);
859
819
  rb_define_method(cSqlite3Database, "define_function", define_function, 1);
860
- rb_define_method(cSqlite3Database, "define_aggregator", define_aggregator, 2);
820
+ rb_define_method(cSqlite3Database, "define_function_with_flags", define_function_with_flags, 2);
821
+ /* public "define_aggregator" is now a shim around define_aggregator2
822
+ * implemented in Ruby */
823
+ rb_define_private_method(cSqlite3Database, "define_aggregator2", rb_sqlite3_define_aggregator2, 2);
824
+ rb_define_private_method(cSqlite3Database, "disable_quirk_mode", rb_sqlite3_disable_quirk_mode, 0);
861
825
  rb_define_method(cSqlite3Database, "interrupt", interrupt, 0);
862
826
  rb_define_method(cSqlite3Database, "errmsg", errmsg, 0);
863
827
  rb_define_method(cSqlite3Database, "errcode", errcode_, 0);
@@ -866,7 +830,9 @@ void init_sqlite3_database()
866
830
  rb_define_method(cSqlite3Database, "authorizer=", set_authorizer, 1);
867
831
  rb_define_method(cSqlite3Database, "busy_handler", busy_handler, -1);
868
832
  rb_define_method(cSqlite3Database, "busy_timeout=", set_busy_timeout, 1);
833
+ rb_define_method(cSqlite3Database, "extended_result_codes=", set_extended_result_codes, 1);
869
834
  rb_define_method(cSqlite3Database, "transaction_active?", transaction_active_p, 0);
835
+ rb_define_private_method(cSqlite3Database, "exec_batch", exec_batch, 2);
870
836
  rb_define_private_method(cSqlite3Database, "db_filename", db_filename, 1);
871
837
 
872
838
  #ifdef HAVE_SQLITE3_LOAD_EXTENSION
@@ -879,10 +845,9 @@ void init_sqlite3_database()
879
845
 
880
846
  rb_define_method(cSqlite3Database, "encoding", db_encoding, 0);
881
847
 
882
- id_utf16 = rb_intern("utf16");
883
- sym_utf16 = ID2SYM(id_utf16);
884
- id_results_as_hash = rb_intern("results_as_hash");
885
- sym_results_as_hash = ID2SYM(id_results_as_hash);
886
- id_type_translation = rb_intern("type_translation");
887
- sym_type_translation = ID2SYM(id_type_translation);
848
+ rb_sqlite3_aggregator_init();
888
849
  }
850
+
851
+ #ifdef _MSC_VER
852
+ #pragma warning( pop )
853
+ #endif
@@ -11,5 +11,7 @@ typedef struct _sqlite3Ruby sqlite3Ruby;
11
11
  typedef sqlite3Ruby * sqlite3RubyPtr;
12
12
 
13
13
  void init_sqlite3_database();
14
+ void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result);
15
+ VALUE sqlite3val2rb(sqlite3_value * val);
14
16
 
15
17
  #endif
@@ -4,7 +4,9 @@ void rb_sqlite3_raise(sqlite3 * db, int status)
4
4
  {
5
5
  VALUE klass = Qnil;
6
6
 
7
- switch(status) {
7
+ /* Consider only lower 8 bits, to work correctly when
8
+ extended result codes are enabled. */
9
+ switch(status & 0xff) {
8
10
  case SQLITE_OK:
9
11
  return;
10
12
  break;
@@ -90,5 +92,7 @@ void rb_sqlite3_raise(sqlite3 * db, int status)
90
92
  klass = rb_eRuntimeError;
91
93
  }
92
94
 
93
- rb_raise(klass, "%s", sqlite3_errmsg(db));
95
+ klass = rb_exc_new2(klass, sqlite3_errmsg(db));
96
+ rb_iv_set(klass, "@code", INT2FIX(status));
97
+ rb_exc_raise(klass);
94
98
  }