sqlite3 1.3.12-x64-mingw32 → 1.5.0.rc2-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) 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 +273 -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 -19
  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 +4 -4
  31. data/test/helper.rb +9 -0
  32. data/test/test_database.rb +127 -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 +12 -9
  40. metadata +55 -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/setup.rb +0 -1333
  50. data/tasks/faq.rake +0 -9
  51. data/tasks/gem.rake +0 -38
  52. data/tasks/native.rake +0 -52
  53. 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
- #ifdef HAVE_SQLITE3_OPEN_V2
50
- VALUE flags;
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
  }