sqlite3 1.3.11-x64-mingw32 → 1.5.0.rc1-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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 +419 -0
  5. data/CONTRIBUTING.md +24 -0
  6. data/Gemfile +2 -15
  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 +210 -182
  12. data/ext/sqlite3/database.h +2 -0
  13. data/ext/sqlite3/exception.c +6 -2
  14. data/ext/sqlite3/extconf.rb +148 -39
  15. data/ext/sqlite3/sqlite3.c +67 -1
  16. data/ext/sqlite3/sqlite3_ruby.h +0 -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 +209 -58
  25. data/lib/sqlite3/errors.rb +1 -10
  26. data/lib/sqlite3/pragmas.rb +372 -57
  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/lib/sqlite3.rb +5 -0
  32. data/test/helper.rb +9 -0
  33. data/test/test_database.rb +180 -9
  34. data/test/test_database_flags.rb +95 -0
  35. data/test/test_database_readonly.rb +9 -2
  36. data/test/test_database_readwrite.rb +41 -0
  37. data/test/test_integration.rb +12 -77
  38. data/test/test_integration_aggregate.rb +336 -0
  39. data/test/test_integration_resultset.rb +0 -17
  40. data/test/test_sqlite3.rb +16 -0
  41. data/test/test_statement.rb +12 -9
  42. metadata +55 -84
  43. data/CHANGELOG.rdoc +0 -287
  44. data/Manifest.txt +0 -52
  45. data/README.rdoc +0 -101
  46. data/Rakefile +0 -10
  47. data/lib/sqlite3/2.0/sqlite3_native.so +0 -0
  48. data/lib/sqlite3/2.1/sqlite3_native.so +0 -0
  49. data/lib/sqlite3/2.2/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
  {
@@ -30,101 +35,51 @@ utf16_string_value_ptr(VALUE str)
30
35
  return RSTRING_PTR(str);
31
36
  }
32
37
 
33
- /* call-seq: SQLite3::Database.new(file, options = {})
34
- *
35
- * Create a new Database object that opens the given file. If utf16
36
- * is +true+, the filename is interpreted as a UTF-16 encoded string.
37
- *
38
- * By default, the new database will return result rows as arrays
39
- * (#results_as_hash) and has type translation disabled (#type_translation=).
40
- */
41
- static VALUE initialize(int argc, VALUE *argv, VALUE self)
38
+ static VALUE sqlite3_rb_close(VALUE self);
39
+
40
+ static VALUE rb_sqlite3_open_v2(VALUE self, VALUE file, VALUE mode, VALUE zvfs)
42
41
  {
43
42
  sqlite3RubyPtr ctx;
44
- VALUE file;
45
- VALUE opts;
46
- VALUE zvfs;
47
- #ifdef HAVE_SQLITE3_OPEN_V2
48
- int mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
49
- #endif
50
43
  int status;
51
44
 
52
45
  Data_Get_Struct(self, sqlite3Ruby, ctx);
53
46
 
54
- rb_scan_args(argc, argv, "12", &file, &opts, &zvfs);
55
- #if defined StringValueCStr
47
+ #if defined TAINTING_SUPPORT
48
+ # if defined StringValueCStr
56
49
  StringValuePtr(file);
57
50
  rb_check_safe_obj(file);
58
- #else
51
+ # else
59
52
  Check_SafeStr(file);
60
- #endif
61
- if(NIL_P(opts)) opts = rb_hash_new();
62
- else Check_Type(opts, T_HASH);
63
-
64
- #ifdef HAVE_RUBY_ENCODING_H
65
- if(UTF16_LE_P(file) || UTF16_BE_P(file)) {
66
- status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
67
- } else {
53
+ # endif
68
54
  #endif
69
55
 
70
- if(Qtrue == rb_hash_aref(opts, sym_utf16)) {
71
- status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
72
- } else {
73
-
74
- #ifdef HAVE_RUBY_ENCODING_H
75
- if(!UTF8_P(file)) {
76
- file = rb_str_export_to_enc(file, rb_utf8_encoding());
77
- }
78
- #endif
79
-
80
- if (Qtrue == rb_hash_aref(opts, ID2SYM(rb_intern("readonly")))) {
81
- #ifdef HAVE_SQLITE3_OPEN_V2
82
- mode = SQLITE_OPEN_READONLY;
83
- #else
84
- rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support readonly databases");
85
- #endif
86
- }
87
- #ifdef HAVE_SQLITE3_OPEN_V2
88
56
  status = sqlite3_open_v2(
89
57
  StringValuePtr(file),
90
58
  &ctx->db,
91
- mode,
59
+ NUM2INT(mode),
92
60
  NIL_P(zvfs) ? NULL : StringValuePtr(zvfs)
93
61
  );
94
- #else
95
- status = sqlite3_open(
96
- StringValuePtr(file),
97
- &ctx->db
98
- );
99
- #endif
100
- }
101
-
102
- #ifdef HAVE_RUBY_ENCODING_H
103
- }
104
- #endif
105
62
 
106
63
  CHECK(ctx->db, status)
107
64
 
108
- rb_iv_set(self, "@tracefunc", Qnil);
109
- rb_iv_set(self, "@authorizer", Qnil);
110
- rb_iv_set(self, "@encoding", Qnil);
111
- rb_iv_set(self, "@busy_handler", Qnil);
112
- rb_iv_set(self, "@collations", rb_hash_new());
113
- rb_iv_set(self, "@functions", rb_hash_new());
114
- rb_iv_set(self, "@results_as_hash", rb_hash_aref(opts, sym_results_as_hash));
115
- rb_iv_set(self, "@type_translation", rb_hash_aref(opts, sym_type_translation));
116
- #ifdef HAVE_SQLITE3_OPEN_V2
117
- rb_iv_set(self, "@readonly", mode == SQLITE_OPEN_READONLY ? Qtrue : Qfalse);
118
- #else
119
- rb_iv_set(self, "@readonly", Qfalse);
120
- #endif
65
+ return self;
66
+ }
121
67
 
122
- if(rb_block_given_p()) {
123
- rb_yield(self);
124
- rb_funcall(self, rb_intern("close"), 0);
125
- }
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);
126
73
 
127
- 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
128
83
  }
129
84
 
130
85
  /* call-seq: db.close
@@ -142,6 +97,8 @@ static VALUE sqlite3_rb_close(VALUE self)
142
97
 
143
98
  ctx->db = NULL;
144
99
 
100
+ rb_iv_set(self, "-aggregators", Qnil);
101
+
145
102
  return self;
146
103
  }
147
104
 
@@ -269,7 +226,7 @@ static VALUE last_insert_row_id(VALUE self)
269
226
  return LL2NUM(sqlite3_last_insert_rowid(ctx->db));
270
227
  }
271
228
 
272
- static VALUE sqlite3val2rb(sqlite3_value * val)
229
+ VALUE sqlite3val2rb(sqlite3_value * val)
273
230
  {
274
231
  switch(sqlite3_value_type(val)) {
275
232
  case SQLITE_INTEGER:
@@ -279,16 +236,16 @@ static VALUE sqlite3val2rb(sqlite3_value * val)
279
236
  return rb_float_new(sqlite3_value_double(val));
280
237
  break;
281
238
  case SQLITE_TEXT:
282
- return rb_tainted_str_new2((const char *)sqlite3_value_text(val));
239
+ return rb_str_new2((const char *)sqlite3_value_text(val));
283
240
  break;
284
241
  case SQLITE_BLOB: {
285
242
  /* Sqlite warns calling sqlite3_value_bytes may invalidate pointer from sqlite3_value_blob,
286
243
  so we explicitly get the length before getting blob pointer.
287
- 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,
288
245
  which is what we want, as blobs are binary
289
246
  */
290
247
  int len = sqlite3_value_bytes(val);
291
- return rb_tainted_str_new((const char *)sqlite3_value_blob(val), len);
248
+ return rb_str_new((const char *)sqlite3_value_blob(val), len);
292
249
  break;
293
250
  }
294
251
  case SQLITE_NULL:
@@ -299,7 +256,7 @@ static VALUE sqlite3val2rb(sqlite3_value * val)
299
256
  }
300
257
  }
301
258
 
302
- static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
259
+ void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
303
260
  {
304
261
  switch(TYPE(result)) {
305
262
  case T_NIL:
@@ -322,12 +279,23 @@ static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
322
279
  sqlite3_result_double(ctx, NUM2DBL(result));
323
280
  break;
324
281
  case T_STRING:
325
- sqlite3_result_text(
326
- ctx,
327
- (const char *)StringValuePtr(result),
328
- (int)RSTRING_LEN(result),
329
- SQLITE_TRANSIENT
330
- );
282
+ if(CLASS_OF(result) == cSqlite3Blob
283
+ || rb_enc_get_index(result) == rb_ascii8bit_encindex()
284
+ ) {
285
+ sqlite3_result_blob(
286
+ ctx,
287
+ (const void *)StringValuePtr(result),
288
+ (int)RSTRING_LEN(result),
289
+ SQLITE_TRANSIENT
290
+ );
291
+ } else {
292
+ sqlite3_result_text(
293
+ ctx,
294
+ (const char *)StringValuePtr(result),
295
+ (int)RSTRING_LEN(result),
296
+ SQLITE_TRANSIENT
297
+ );
298
+ }
331
299
  break;
332
300
  default:
333
301
  rb_raise(rb_eRuntimeError, "can't return %s",
@@ -338,22 +306,18 @@ static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
338
306
  static void rb_sqlite3_func(sqlite3_context * ctx, int argc, sqlite3_value **argv)
339
307
  {
340
308
  VALUE callable = (VALUE)sqlite3_user_data(ctx);
341
- VALUE * params = NULL;
309
+ VALUE params = rb_ary_new2(argc);
342
310
  VALUE result;
343
311
  int i;
344
312
 
345
313
  if (argc > 0) {
346
- params = xcalloc((size_t)argc, sizeof(VALUE *));
347
-
348
314
  for(i = 0; i < argc; i++) {
349
315
  VALUE param = sqlite3val2rb(argv[i]);
350
- RB_GC_GUARD(param);
351
- params[i] = param;
316
+ rb_ary_push(params, param);
352
317
  }
353
318
  }
354
319
 
355
- result = rb_funcall2(callable, rb_intern("call"), argc, params);
356
- xfree(params);
320
+ result = rb_apply(callable, rb_intern("call"), params);
357
321
 
358
322
  set_sqlite3_func_result(ctx, result);
359
323
  }
@@ -365,12 +329,12 @@ int rb_proc_arity(VALUE self)
365
329
  }
366
330
  #endif
367
331
 
368
- /* call-seq: define_function(name) { |args,...| }
332
+ /* call-seq: define_function_with_flags(name, flags) { |args,...| }
369
333
  *
370
- * 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
371
335
  * will be used as the arity for the function defined.
372
336
  */
373
- static VALUE define_function(VALUE self, VALUE name)
337
+ static VALUE define_function_with_flags(VALUE self, VALUE name, VALUE flags)
374
338
  {
375
339
  sqlite3RubyPtr ctx;
376
340
  VALUE block;
@@ -385,7 +349,7 @@ static VALUE define_function(VALUE self, VALUE name)
385
349
  ctx->db,
386
350
  StringValuePtr(name),
387
351
  rb_proc_arity(block),
388
- SQLITE_UTF8,
352
+ NUM2INT(flags),
389
353
  (void *)block,
390
354
  rb_sqlite3_func,
391
355
  NULL,
@@ -399,70 +363,14 @@ static VALUE define_function(VALUE self, VALUE name)
399
363
  return self;
400
364
  }
401
365
 
402
- static int sqlite3_obj_method_arity(VALUE obj, ID id)
403
- {
404
- VALUE method = rb_funcall(obj, rb_intern("method"), 1, ID2SYM(id));
405
- VALUE arity = rb_funcall(method, rb_intern("arity"), 0);
406
-
407
- return (int)NUM2INT(arity);
408
- }
409
-
410
- static void rb_sqlite3_step(sqlite3_context * ctx, int argc, sqlite3_value **argv)
411
- {
412
- VALUE callable = (VALUE)sqlite3_user_data(ctx);
413
- VALUE * params = NULL;
414
- int i;
415
-
416
- if (argc > 0) {
417
- params = xcalloc((size_t)argc, sizeof(VALUE *));
418
- for(i = 0; i < argc; i++) {
419
- params[i] = sqlite3val2rb(argv[i]);
420
- }
421
- }
422
- rb_funcall2(callable, rb_intern("step"), argc, params);
423
- xfree(params);
424
- }
425
-
426
- static void rb_sqlite3_final(sqlite3_context * ctx)
427
- {
428
- VALUE callable = (VALUE)sqlite3_user_data(ctx);
429
- VALUE result = rb_funcall(callable, rb_intern("finalize"), 0);
430
- set_sqlite3_func_result(ctx, result);
431
- }
432
-
433
- /* call-seq: define_aggregator(name, aggregator)
366
+ /* call-seq: define_function(name) { |args,...| }
434
367
  *
435
- * Define an aggregate function named +name+ using the object +aggregator+.
436
- * +aggregator+ must respond to +step+ and +finalize+. +step+ will be called
437
- * with row information and +finalize+ must return the return value for the
438
- * 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.
439
370
  */
440
- static VALUE define_aggregator(VALUE self, VALUE name, VALUE aggregator)
371
+ static VALUE define_function(VALUE self, VALUE name)
441
372
  {
442
- sqlite3RubyPtr ctx;
443
- int arity, status;
444
-
445
- Data_Get_Struct(self, sqlite3Ruby, ctx);
446
- REQUIRE_OPEN_DB(ctx);
447
-
448
- arity = sqlite3_obj_method_arity(aggregator, rb_intern("step"));
449
-
450
- status = sqlite3_create_function(
451
- ctx->db,
452
- StringValuePtr(name),
453
- arity,
454
- SQLITE_UTF8,
455
- (void *)aggregator,
456
- NULL,
457
- rb_sqlite3_step,
458
- rb_sqlite3_final
459
- );
460
-
461
- rb_iv_set(self, "@agregator", aggregator);
462
-
463
- CHECK(ctx->db, status);
464
-
465
- return self;
373
+ return define_function_with_flags(self, name, INT2FIX(SQLITE_UTF8));
466
374
  }
467
375
 
468
376
  /* call-seq: interrupt
@@ -610,23 +518,36 @@ static VALUE set_busy_timeout(VALUE self, VALUE timeout)
610
518
  return self;
611
519
  }
612
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
+
613
537
  int rb_comparator_func(void * ctx, int a_len, const void * a, int b_len, const void * b)
614
538
  {
615
539
  VALUE comparator;
616
540
  VALUE a_str;
617
541
  VALUE b_str;
618
542
  VALUE comparison;
619
- #ifdef HAVE_RUBY_ENCODING_H
620
543
  rb_encoding * internal_encoding;
621
544
 
622
545
  internal_encoding = rb_default_internal_encoding();
623
- #endif
624
546
 
625
547
  comparator = (VALUE)ctx;
626
548
  a_str = rb_str_new((const char *)a, a_len);
627
549
  b_str = rb_str_new((const char *)b, b_len);
628
550
 
629
- #ifdef HAVE_RUBY_ENCODING_H
630
551
  rb_enc_associate_index(a_str, rb_utf8_encindex());
631
552
  rb_enc_associate_index(b_str, rb_utf8_encindex());
632
553
 
@@ -634,7 +555,6 @@ int rb_comparator_func(void * ctx, int a_len, const void * a, int b_len, const v
634
555
  a_str = rb_str_export_to_enc(a_str, internal_encoding);
635
556
  b_str = rb_str_export_to_enc(b_str, internal_encoding);
636
557
  }
637
- #endif
638
558
 
639
559
  comparison = rb_funcall(comparator, rb_intern("compare"), 2, a_str, b_str);
640
560
 
@@ -721,7 +641,6 @@ static VALUE enable_load_extension(VALUE self, VALUE onoff)
721
641
  }
722
642
  #endif
723
643
 
724
- #ifdef HAVE_RUBY_ENCODING_H
725
644
  static int enc_cb(void * _self, int UNUSED(columns), char **data, char **UNUSED(names))
726
645
  {
727
646
  VALUE self = (VALUE)_self;
@@ -732,16 +651,6 @@ static int enc_cb(void * _self, int UNUSED(columns), char **data, char **UNUSED(
732
651
 
733
652
  return 0;
734
653
  }
735
- #else
736
- static int enc_cb(void * _self, int UNUSED(columns), char **data, char **UNUSED(names))
737
- {
738
- VALUE self = (VALUE)_self;
739
-
740
- rb_iv_set(self, "@encoding", rb_str_new2(data[0]));
741
-
742
- return 0;
743
- }
744
- #endif
745
654
 
746
655
  /* call-seq: db.encoding
747
656
  *
@@ -778,16 +687,129 @@ static VALUE transaction_active_p(VALUE self)
778
687
  return sqlite3_get_autocommit(ctx->db) ? Qfalse : Qtrue;
779
688
  }
780
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
+
762
+ /* call-seq: db.db_filename(database_name)
763
+ *
764
+ * Returns the file associated with +database_name+. Can return nil or an
765
+ * empty string if the database is temporary, or in-memory.
766
+ */
767
+ static VALUE db_filename(VALUE self, VALUE db_name)
768
+ {
769
+ sqlite3RubyPtr ctx;
770
+ const char * fname;
771
+ Data_Get_Struct(self, sqlite3Ruby, ctx);
772
+ REQUIRE_OPEN_DB(ctx);
773
+
774
+ fname = sqlite3_db_filename(ctx->db, StringValueCStr(db_name));
775
+
776
+ if(fname) return SQLITE3_UTF8_STR_NEW2(fname);
777
+ return Qnil;
778
+ }
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
+
781
803
  void init_sqlite3_database()
782
804
  {
783
- ID id_utf16, id_results_as_hash, id_type_translation;
784
805
  #if 0
785
806
  VALUE mSqlite3 = rb_define_module("SQLite3");
786
807
  #endif
787
808
  cSqlite3Database = rb_define_class_under(mSqlite3, "Database", rb_cObject);
788
809
 
789
810
  rb_define_alloc_func(cSqlite3Database, allocate);
790
- 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);
791
813
  rb_define_method(cSqlite3Database, "collation", collation, 2);
792
814
  rb_define_method(cSqlite3Database, "close", sqlite3_rb_close, 0);
793
815
  rb_define_method(cSqlite3Database, "closed?", closed_p, 0);
@@ -795,7 +817,11 @@ void init_sqlite3_database()
795
817
  rb_define_method(cSqlite3Database, "trace", trace, -1);
796
818
  rb_define_method(cSqlite3Database, "last_insert_row_id", last_insert_row_id, 0);
797
819
  rb_define_method(cSqlite3Database, "define_function", define_function, 1);
798
- 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);
799
825
  rb_define_method(cSqlite3Database, "interrupt", interrupt, 0);
800
826
  rb_define_method(cSqlite3Database, "errmsg", errmsg, 0);
801
827
  rb_define_method(cSqlite3Database, "errcode", errcode_, 0);
@@ -804,7 +830,10 @@ void init_sqlite3_database()
804
830
  rb_define_method(cSqlite3Database, "authorizer=", set_authorizer, 1);
805
831
  rb_define_method(cSqlite3Database, "busy_handler", busy_handler, -1);
806
832
  rb_define_method(cSqlite3Database, "busy_timeout=", set_busy_timeout, 1);
833
+ rb_define_method(cSqlite3Database, "extended_result_codes=", set_extended_result_codes, 1);
807
834
  rb_define_method(cSqlite3Database, "transaction_active?", transaction_active_p, 0);
835
+ rb_define_private_method(cSqlite3Database, "exec_batch", exec_batch, 2);
836
+ rb_define_private_method(cSqlite3Database, "db_filename", db_filename, 1);
808
837
 
809
838
  #ifdef HAVE_SQLITE3_LOAD_EXTENSION
810
839
  rb_define_method(cSqlite3Database, "load_extension", load_extension, 1);
@@ -816,10 +845,9 @@ void init_sqlite3_database()
816
845
 
817
846
  rb_define_method(cSqlite3Database, "encoding", db_encoding, 0);
818
847
 
819
- id_utf16 = rb_intern("utf16");
820
- sym_utf16 = ID2SYM(id_utf16);
821
- id_results_as_hash = rb_intern("results_as_hash");
822
- sym_results_as_hash = ID2SYM(id_results_as_hash);
823
- id_type_translation = rb_intern("type_translation");
824
- sym_type_translation = ID2SYM(id_type_translation);
848
+ rb_sqlite3_aggregator_init();
825
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
  }