sqlite3 1.6.8-x86_64-darwin → 1.7.0-x86_64-darwin
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/Gemfile +3 -3
- data/dependencies.yml +8 -8
- data/ext/sqlite3/aggregator.c +1 -2
- data/ext/sqlite3/backup.c +25 -12
- data/ext/sqlite3/database.c +51 -26
- data/ext/sqlite3/database.h +2 -0
- data/ext/sqlite3/statement.c +32 -23
- data/lib/sqlite3/3.0/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/3.1/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/3.2/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/3.3/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/database.rb +22 -7
- data/lib/sqlite3/version.rb +3 -3
- data/test/test_database.rb +40 -0
- metadata +5 -5
- data/lib/sqlite3/2.7/sqlite3_native.bundle +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78cc7bc12ce14e990165e4ba0ba63de21a673dad21f817ae706aa61599eea87d
|
4
|
+
data.tar.gz: 372ff0709ddecdfeacdfe519d2be08159acd26b0a21ae3750247eeabf77e3a56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83d13669e3daf2308af8e3d088fa2a5064360a1930a282b4b4384e74112ed587b0d5172364149ec19a6a965fa944643f8156714cb5bc0f1367b581f98fe98d70
|
7
|
+
data.tar.gz: 29c8abfe3b661ce4775fb6a7d1274e2511554247350ca60f2369d88f07098b0a11e33cafaf8ff4b9c557dec5ef055a75db9499623dc214466c05621295ccb26a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
# sqlite3-ruby Changelog
|
2
2
|
|
3
|
+
## 1.7.0 / 2023-12-27
|
4
|
+
|
5
|
+
### Ruby
|
6
|
+
|
7
|
+
This release introduces native gem support for Ruby 3.3.
|
8
|
+
|
9
|
+
This release ends native gem support for Ruby 2.7, for which [upstream support ended 2023-03-31](https://www.ruby-lang.org/en/downloads/branches/). Ruby 2.7 is still generally supported, but will not be shipped in the native gems.
|
10
|
+
|
11
|
+
This release ends support for Ruby 1.9.3, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, and 2.6.
|
12
|
+
|
13
|
+
### Improved
|
14
|
+
|
15
|
+
- SQLite3::Statement, Database, and Backup objects have been converted to use the TypedData API. See https://bugs.ruby-lang.org/issues/19998 for more context. [#432] @casperisfine
|
16
|
+
|
17
|
+
|
18
|
+
## 1.6.9 / 2023-11-26
|
19
|
+
|
20
|
+
### Dependencies
|
21
|
+
|
22
|
+
- Vendored sqlite is update to [v3.44.2](https://sqlite.org/releaselog/3_44_2.html). @flavorjones
|
23
|
+
|
24
|
+
### Added
|
25
|
+
|
26
|
+
- `Database.new` now accepts a `:default_transaction_mode` option (defaulting to `:deferred`), and `Database#transaction` no longer requires a transaction mode to be specified. This should allow higher-level adapters to more easily choose a transaction mode for a database connection. [#426] @masamitsu-murase
|
27
|
+
|
28
|
+
|
3
29
|
## 1.6.8 / 2023-11-01
|
4
30
|
|
5
31
|
### Dependencies
|
data/Gemfile
CHANGED
@@ -4,7 +4,7 @@ gemspec
|
|
4
4
|
|
5
5
|
gem("minitest", "5.20.0")
|
6
6
|
gem("rake-compiler", "1.2.5")
|
7
|
-
gem("rake-compiler-dock", "1.
|
8
|
-
gem("rdoc", "6.
|
7
|
+
gem("rake-compiler-dock", "1.4.0")
|
8
|
+
gem("rdoc", "6.6.2")
|
9
9
|
|
10
|
-
gem("ruby_memcheck", "2.
|
10
|
+
gem("ruby_memcheck", "2.3.0") if Gem::Platform.local.os == "linux"
|
data/dependencies.yml
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# TODO: stop using symbols here once we no longer support Ruby 2.7 and can rely on symbolize_names
|
2
2
|
:sqlite3:
|
3
3
|
# checksum verified by first checking the published sha3(256) checksum against https://sqlite.org/download.html:
|
4
|
-
#
|
4
|
+
# 6c427f0547e2f7babe636b748dd5d5a1f2f31601adadef7e2805e7d1f7171861
|
5
5
|
#
|
6
|
-
# $ sha3sum -a 256 ports/archives/sqlite-autoconf-
|
7
|
-
#
|
6
|
+
# $ sha3sum -a 256 ports/archives/sqlite-autoconf-3440200.tar.gz
|
7
|
+
# 6c427f0547e2f7babe636b748dd5d5a1f2f31601adadef7e2805e7d1f7171861 ports/archives/sqlite-autoconf-3440200.tar.gz
|
8
8
|
#
|
9
|
-
# $ sha256sum ports/archives/sqlite-autoconf-
|
10
|
-
#
|
11
|
-
:version: "3.44.
|
9
|
+
# $ sha256sum ports/archives/sqlite-autoconf-3440200.tar.gz
|
10
|
+
# 1c6719a148bc41cf0f2bbbe3926d7ce3f5ca09d878f1246fcc20767b175bb407 ports/archives/sqlite-autoconf-3440200.tar.gz
|
11
|
+
:version: "3.44.2"
|
12
12
|
:files:
|
13
|
-
- :url: "https://sqlite.org/2023/sqlite-autoconf-
|
14
|
-
:sha256: "
|
13
|
+
- :url: "https://sqlite.org/2023/sqlite-autoconf-3440200.tar.gz"
|
14
|
+
:sha256: "1c6719a148bc41cf0f2bbbe3926d7ce3f5ca09d878f1246fcc20767b175bb407"
|
data/ext/sqlite3/aggregator.c
CHANGED
@@ -206,12 +206,11 @@ VALUE
|
|
206
206
|
rb_sqlite3_define_aggregator2(VALUE self, VALUE aggregator, VALUE ruby_name)
|
207
207
|
{
|
208
208
|
/* define_aggregator is added as a method to SQLite3::Database in database.c */
|
209
|
-
sqlite3RubyPtr ctx;
|
209
|
+
sqlite3RubyPtr ctx = sqlite3_database_unwrap(self);
|
210
210
|
int arity, status;
|
211
211
|
VALUE aw;
|
212
212
|
VALUE aggregators;
|
213
213
|
|
214
|
-
Data_Get_Struct(self, sqlite3Ruby, ctx);
|
215
214
|
if (!ctx->db) {
|
216
215
|
rb_raise(rb_path2class("SQLite3::Exception"), "cannot use a closed database");
|
217
216
|
}
|
data/ext/sqlite3/backup.c
CHANGED
@@ -8,16 +8,29 @@
|
|
8
8
|
|
9
9
|
VALUE cSqlite3Backup;
|
10
10
|
|
11
|
-
static
|
11
|
+
static size_t backup_memsize(const void *data)
|
12
12
|
{
|
13
|
-
sqlite3BackupRubyPtr
|
14
|
-
|
13
|
+
sqlite3BackupRubyPtr ctx = (sqlite3BackupRubyPtr)data;
|
14
|
+
// NB: can't account for ctx->p because the type is incomplete.
|
15
|
+
return sizeof(*ctx);
|
15
16
|
}
|
16
17
|
|
18
|
+
static const rb_data_type_t backup_type = {
|
19
|
+
"SQLite3::Backup",
|
20
|
+
{
|
21
|
+
NULL,
|
22
|
+
RUBY_TYPED_DEFAULT_FREE,
|
23
|
+
backup_memsize,
|
24
|
+
},
|
25
|
+
0,
|
26
|
+
0,
|
27
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
28
|
+
};
|
29
|
+
|
17
30
|
static VALUE allocate(VALUE klass)
|
18
31
|
{
|
19
|
-
sqlite3BackupRubyPtr ctx
|
20
|
-
return
|
32
|
+
sqlite3BackupRubyPtr ctx;
|
33
|
+
return TypedData_Make_Struct(klass, sqlite3BackupRuby, &backup_type, ctx);
|
21
34
|
}
|
22
35
|
|
23
36
|
/* call-seq: SQLite3::Backup.new(dstdb, dstname, srcdb, srcname)
|
@@ -62,9 +75,9 @@ static VALUE initialize(VALUE self, VALUE dstdb, VALUE dstname, VALUE srcdb, VAL
|
|
62
75
|
sqlite3RubyPtr ddb_ctx, sdb_ctx;
|
63
76
|
sqlite3_backup *pBackup;
|
64
77
|
|
65
|
-
|
66
|
-
|
67
|
-
|
78
|
+
TypedData_Get_Struct(self, sqlite3BackupRuby, &backup_type, ctx);
|
79
|
+
ddb_ctx = sqlite3_database_unwrap(dstdb);
|
80
|
+
sdb_ctx = sqlite3_database_unwrap(srcdb);
|
68
81
|
|
69
82
|
if(!sdb_ctx->db)
|
70
83
|
rb_raise(rb_eArgError, "cannot backup from a closed database");
|
@@ -97,7 +110,7 @@ static VALUE step(VALUE self, VALUE nPage)
|
|
97
110
|
sqlite3BackupRubyPtr ctx;
|
98
111
|
int status;
|
99
112
|
|
100
|
-
|
113
|
+
TypedData_Get_Struct(self, sqlite3BackupRuby, &backup_type, ctx);
|
101
114
|
REQUIRE_OPEN_BACKUP(ctx);
|
102
115
|
status = sqlite3_backup_step(ctx->p, NUM2INT(nPage));
|
103
116
|
return INT2NUM(status);
|
@@ -111,7 +124,7 @@ static VALUE finish(VALUE self)
|
|
111
124
|
{
|
112
125
|
sqlite3BackupRubyPtr ctx;
|
113
126
|
|
114
|
-
|
127
|
+
TypedData_Get_Struct(self, sqlite3BackupRuby, &backup_type, ctx);
|
115
128
|
REQUIRE_OPEN_BACKUP(ctx);
|
116
129
|
(void)sqlite3_backup_finish(ctx->p);
|
117
130
|
ctx->p = NULL;
|
@@ -129,7 +142,7 @@ static VALUE remaining(VALUE self)
|
|
129
142
|
{
|
130
143
|
sqlite3BackupRubyPtr ctx;
|
131
144
|
|
132
|
-
|
145
|
+
TypedData_Get_Struct(self, sqlite3BackupRuby, &backup_type, ctx);
|
133
146
|
REQUIRE_OPEN_BACKUP(ctx);
|
134
147
|
return INT2NUM(sqlite3_backup_remaining(ctx->p));
|
135
148
|
}
|
@@ -145,7 +158,7 @@ static VALUE pagecount(VALUE self)
|
|
145
158
|
{
|
146
159
|
sqlite3BackupRubyPtr ctx;
|
147
160
|
|
148
|
-
|
161
|
+
TypedData_Get_Struct(self, sqlite3BackupRuby, &backup_type, ctx);
|
149
162
|
REQUIRE_OPEN_BACKUP(ctx);
|
150
163
|
return INT2NUM(sqlite3_backup_pagecount(ctx->p));
|
151
164
|
}
|
data/ext/sqlite3/database.c
CHANGED
@@ -21,10 +21,29 @@ static void deallocate(void * ctx)
|
|
21
21
|
xfree(c);
|
22
22
|
}
|
23
23
|
|
24
|
+
static size_t database_memsize(const void *ctx)
|
25
|
+
{
|
26
|
+
const sqlite3RubyPtr c = (const sqlite3RubyPtr)ctx;
|
27
|
+
// NB: can't account for ctx->db because the type is incomplete.
|
28
|
+
return sizeof(*c);
|
29
|
+
}
|
30
|
+
|
31
|
+
static const rb_data_type_t database_type = {
|
32
|
+
"SQLite3::Backup",
|
33
|
+
{
|
34
|
+
NULL,
|
35
|
+
deallocate,
|
36
|
+
database_memsize,
|
37
|
+
},
|
38
|
+
0,
|
39
|
+
0,
|
40
|
+
RUBY_TYPED_WB_PROTECTED, // Not freed immediately because the dfree function do IOs.
|
41
|
+
};
|
42
|
+
|
24
43
|
static VALUE allocate(VALUE klass)
|
25
44
|
{
|
26
|
-
sqlite3RubyPtr ctx
|
27
|
-
return
|
45
|
+
sqlite3RubyPtr ctx;
|
46
|
+
return TypedData_Make_Struct(klass, sqlite3Ruby, &database_type, ctx);
|
28
47
|
}
|
29
48
|
|
30
49
|
static char *
|
@@ -37,12 +56,18 @@ utf16_string_value_ptr(VALUE str)
|
|
37
56
|
|
38
57
|
static VALUE sqlite3_rb_close(VALUE self);
|
39
58
|
|
59
|
+
sqlite3RubyPtr sqlite3_database_unwrap(VALUE database){
|
60
|
+
sqlite3RubyPtr ctx;
|
61
|
+
TypedData_Get_Struct(database, sqlite3Ruby, &database_type, ctx);
|
62
|
+
return ctx;
|
63
|
+
}
|
64
|
+
|
40
65
|
static VALUE rb_sqlite3_open_v2(VALUE self, VALUE file, VALUE mode, VALUE zvfs)
|
41
66
|
{
|
42
67
|
sqlite3RubyPtr ctx;
|
43
68
|
int status;
|
44
69
|
|
45
|
-
|
70
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
46
71
|
|
47
72
|
#if defined TAINTING_SUPPORT
|
48
73
|
# if defined StringValueCStr
|
@@ -69,7 +94,7 @@ static VALUE rb_sqlite3_disable_quirk_mode(VALUE self)
|
|
69
94
|
{
|
70
95
|
#if defined SQLITE_DBCONFIG_DQS_DDL
|
71
96
|
sqlite3RubyPtr ctx;
|
72
|
-
|
97
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
73
98
|
|
74
99
|
if(!ctx->db) return Qfalse;
|
75
100
|
|
@@ -90,7 +115,7 @@ static VALUE sqlite3_rb_close(VALUE self)
|
|
90
115
|
{
|
91
116
|
sqlite3RubyPtr ctx;
|
92
117
|
sqlite3 * db;
|
93
|
-
|
118
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
94
119
|
|
95
120
|
db = ctx->db;
|
96
121
|
CHECK(db, sqlite3_close(ctx->db));
|
@@ -109,7 +134,7 @@ static VALUE sqlite3_rb_close(VALUE self)
|
|
109
134
|
static VALUE closed_p(VALUE self)
|
110
135
|
{
|
111
136
|
sqlite3RubyPtr ctx;
|
112
|
-
|
137
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
113
138
|
|
114
139
|
if(!ctx->db) return Qtrue;
|
115
140
|
|
@@ -124,7 +149,7 @@ static VALUE closed_p(VALUE self)
|
|
124
149
|
static VALUE total_changes(VALUE self)
|
125
150
|
{
|
126
151
|
sqlite3RubyPtr ctx;
|
127
|
-
|
152
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
128
153
|
REQUIRE_OPEN_DB(ctx);
|
129
154
|
|
130
155
|
return INT2NUM(sqlite3_total_changes(ctx->db));
|
@@ -150,7 +175,7 @@ static VALUE trace(int argc, VALUE *argv, VALUE self)
|
|
150
175
|
sqlite3RubyPtr ctx;
|
151
176
|
VALUE block;
|
152
177
|
|
153
|
-
|
178
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
154
179
|
REQUIRE_OPEN_DB(ctx);
|
155
180
|
|
156
181
|
rb_scan_args(argc, argv, "01", &block);
|
@@ -195,7 +220,7 @@ static VALUE busy_handler(int argc, VALUE *argv, VALUE self)
|
|
195
220
|
VALUE block;
|
196
221
|
int status;
|
197
222
|
|
198
|
-
|
223
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
199
224
|
REQUIRE_OPEN_DB(ctx);
|
200
225
|
|
201
226
|
rb_scan_args(argc, argv, "01", &block);
|
@@ -220,7 +245,7 @@ static VALUE busy_handler(int argc, VALUE *argv, VALUE self)
|
|
220
245
|
static VALUE last_insert_row_id(VALUE self)
|
221
246
|
{
|
222
247
|
sqlite3RubyPtr ctx;
|
223
|
-
|
248
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
224
249
|
REQUIRE_OPEN_DB(ctx);
|
225
250
|
|
226
251
|
return LL2NUM(sqlite3_last_insert_rowid(ctx->db));
|
@@ -340,7 +365,7 @@ static VALUE define_function_with_flags(VALUE self, VALUE name, VALUE flags)
|
|
340
365
|
VALUE block;
|
341
366
|
int status;
|
342
367
|
|
343
|
-
|
368
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
344
369
|
REQUIRE_OPEN_DB(ctx);
|
345
370
|
|
346
371
|
block = rb_block_proc();
|
@@ -380,7 +405,7 @@ static VALUE define_function(VALUE self, VALUE name)
|
|
380
405
|
static VALUE interrupt(VALUE self)
|
381
406
|
{
|
382
407
|
sqlite3RubyPtr ctx;
|
383
|
-
|
408
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
384
409
|
REQUIRE_OPEN_DB(ctx);
|
385
410
|
|
386
411
|
sqlite3_interrupt(ctx->db);
|
@@ -396,7 +421,7 @@ static VALUE interrupt(VALUE self)
|
|
396
421
|
static VALUE errmsg(VALUE self)
|
397
422
|
{
|
398
423
|
sqlite3RubyPtr ctx;
|
399
|
-
|
424
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
400
425
|
REQUIRE_OPEN_DB(ctx);
|
401
426
|
|
402
427
|
return rb_str_new2(sqlite3_errmsg(ctx->db));
|
@@ -410,7 +435,7 @@ static VALUE errmsg(VALUE self)
|
|
410
435
|
static VALUE errcode_(VALUE self)
|
411
436
|
{
|
412
437
|
sqlite3RubyPtr ctx;
|
413
|
-
|
438
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
414
439
|
REQUIRE_OPEN_DB(ctx);
|
415
440
|
|
416
441
|
return INT2NUM(sqlite3_errcode(ctx->db));
|
@@ -438,7 +463,7 @@ static VALUE complete_p(VALUE UNUSED(self), VALUE sql)
|
|
438
463
|
static VALUE changes(VALUE self)
|
439
464
|
{
|
440
465
|
sqlite3RubyPtr ctx;
|
441
|
-
|
466
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
442
467
|
REQUIRE_OPEN_DB(ctx);
|
443
468
|
|
444
469
|
return INT2NUM(sqlite3_changes(ctx->db));
|
@@ -483,7 +508,7 @@ static VALUE set_authorizer(VALUE self, VALUE authorizer)
|
|
483
508
|
sqlite3RubyPtr ctx;
|
484
509
|
int status;
|
485
510
|
|
486
|
-
|
511
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
487
512
|
REQUIRE_OPEN_DB(ctx);
|
488
513
|
|
489
514
|
status = sqlite3_set_authorizer(
|
@@ -510,7 +535,7 @@ static VALUE set_authorizer(VALUE self, VALUE authorizer)
|
|
510
535
|
static VALUE set_busy_timeout(VALUE self, VALUE timeout)
|
511
536
|
{
|
512
537
|
sqlite3RubyPtr ctx;
|
513
|
-
|
538
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
514
539
|
REQUIRE_OPEN_DB(ctx);
|
515
540
|
|
516
541
|
CHECK(ctx->db, sqlite3_busy_timeout(ctx->db, (int)NUM2INT(timeout)));
|
@@ -526,7 +551,7 @@ static VALUE set_busy_timeout(VALUE self, VALUE timeout)
|
|
526
551
|
static VALUE set_extended_result_codes(VALUE self, VALUE enable)
|
527
552
|
{
|
528
553
|
sqlite3RubyPtr ctx;
|
529
|
-
|
554
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
530
555
|
REQUIRE_OPEN_DB(ctx);
|
531
556
|
|
532
557
|
CHECK(ctx->db, sqlite3_extended_result_codes(ctx->db, RTEST(enable) ? 1 : 0));
|
@@ -571,7 +596,7 @@ int rb_comparator_func(void * ctx, int a_len, const void * a, int b_len, const v
|
|
571
596
|
static VALUE collation(VALUE self, VALUE name, VALUE comparator)
|
572
597
|
{
|
573
598
|
sqlite3RubyPtr ctx;
|
574
|
-
|
599
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
575
600
|
REQUIRE_OPEN_DB(ctx);
|
576
601
|
|
577
602
|
CHECK(ctx->db, sqlite3_create_collation(
|
@@ -600,7 +625,7 @@ static VALUE load_extension(VALUE self, VALUE file)
|
|
600
625
|
int status;
|
601
626
|
char *errMsg;
|
602
627
|
VALUE errexp;
|
603
|
-
|
628
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
604
629
|
REQUIRE_OPEN_DB(ctx);
|
605
630
|
|
606
631
|
status = sqlite3_load_extension(ctx->db, StringValuePtr(file), 0, &errMsg);
|
@@ -624,7 +649,7 @@ static VALUE enable_load_extension(VALUE self, VALUE onoff)
|
|
624
649
|
{
|
625
650
|
sqlite3RubyPtr ctx;
|
626
651
|
int onoffparam;
|
627
|
-
|
652
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
628
653
|
REQUIRE_OPEN_DB(ctx);
|
629
654
|
|
630
655
|
if (Qtrue == onoff) {
|
@@ -661,7 +686,7 @@ static VALUE db_encoding(VALUE self)
|
|
661
686
|
sqlite3RubyPtr ctx;
|
662
687
|
VALUE enc;
|
663
688
|
|
664
|
-
|
689
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
665
690
|
REQUIRE_OPEN_DB(ctx);
|
666
691
|
|
667
692
|
enc = rb_iv_get(self, "@encoding");
|
@@ -681,7 +706,7 @@ static VALUE db_encoding(VALUE self)
|
|
681
706
|
static VALUE transaction_active_p(VALUE self)
|
682
707
|
{
|
683
708
|
sqlite3RubyPtr ctx;
|
684
|
-
|
709
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
685
710
|
REQUIRE_OPEN_DB(ctx);
|
686
711
|
|
687
712
|
return sqlite3_get_autocommit(ctx->db) ? Qfalse : Qtrue;
|
@@ -740,7 +765,7 @@ static VALUE exec_batch(VALUE self, VALUE sql, VALUE results_as_hash)
|
|
740
765
|
char *errMsg;
|
741
766
|
VALUE errexp;
|
742
767
|
|
743
|
-
|
768
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
744
769
|
REQUIRE_OPEN_DB(ctx);
|
745
770
|
|
746
771
|
if(results_as_hash == Qtrue) {
|
@@ -768,7 +793,7 @@ static VALUE db_filename(VALUE self, VALUE db_name)
|
|
768
793
|
{
|
769
794
|
sqlite3RubyPtr ctx;
|
770
795
|
const char * fname;
|
771
|
-
|
796
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
772
797
|
REQUIRE_OPEN_DB(ctx);
|
773
798
|
|
774
799
|
fname = sqlite3_db_filename(ctx->db, StringValueCStr(db_name));
|
@@ -782,7 +807,7 @@ static VALUE rb_sqlite3_open16(VALUE self, VALUE file)
|
|
782
807
|
int status;
|
783
808
|
sqlite3RubyPtr ctx;
|
784
809
|
|
785
|
-
|
810
|
+
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
|
786
811
|
|
787
812
|
#if defined TAINTING_SUPPORT
|
788
813
|
#if defined StringValueCStr
|
data/ext/sqlite3/database.h
CHANGED
@@ -12,6 +12,8 @@ typedef sqlite3Ruby * sqlite3RubyPtr;
|
|
12
12
|
|
13
13
|
void init_sqlite3_database();
|
14
14
|
void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result);
|
15
|
+
|
16
|
+
sqlite3RubyPtr sqlite3_database_unwrap(VALUE database);
|
15
17
|
VALUE sqlite3val2rb(sqlite3_value * val);
|
16
18
|
|
17
19
|
#endif
|
data/ext/sqlite3/statement.c
CHANGED
@@ -6,19 +6,29 @@
|
|
6
6
|
|
7
7
|
VALUE cSqlite3Statement;
|
8
8
|
|
9
|
-
static
|
9
|
+
static size_t statement_memsize(const void *data)
|
10
10
|
{
|
11
|
-
sqlite3StmtRubyPtr
|
12
|
-
|
11
|
+
const sqlite3StmtRubyPtr s = (const sqlite3StmtRubyPtr)data;
|
12
|
+
// NB: can't account for s->st because the type is incomplete.
|
13
|
+
return sizeof(*s);
|
13
14
|
}
|
14
15
|
|
16
|
+
static const rb_data_type_t statement_type = {
|
17
|
+
"SQLite3::Backup",
|
18
|
+
{
|
19
|
+
NULL,
|
20
|
+
RUBY_TYPED_DEFAULT_FREE,
|
21
|
+
statement_memsize,
|
22
|
+
},
|
23
|
+
0,
|
24
|
+
0,
|
25
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
26
|
+
};
|
27
|
+
|
15
28
|
static VALUE allocate(VALUE klass)
|
16
29
|
{
|
17
|
-
sqlite3StmtRubyPtr ctx
|
18
|
-
ctx
|
19
|
-
ctx->done_p = 0;
|
20
|
-
|
21
|
-
return Data_Wrap_Struct(klass, NULL, deallocate, ctx);
|
30
|
+
sqlite3StmtRubyPtr ctx;
|
31
|
+
return TypedData_Make_Struct(klass, sqlite3StmtRuby, &statement_type, ctx);
|
22
32
|
}
|
23
33
|
|
24
34
|
/* call-seq: SQLite3::Statement.new(db, sql)
|
@@ -30,15 +40,14 @@ static VALUE allocate(VALUE klass)
|
|
30
40
|
*/
|
31
41
|
static VALUE initialize(VALUE self, VALUE db, VALUE sql)
|
32
42
|
{
|
33
|
-
sqlite3RubyPtr db_ctx;
|
43
|
+
sqlite3RubyPtr db_ctx = sqlite3_database_unwrap(db);
|
34
44
|
sqlite3StmtRubyPtr ctx;
|
35
45
|
const char *tail = NULL;
|
36
46
|
int status;
|
37
47
|
|
38
48
|
StringValue(sql);
|
39
49
|
|
40
|
-
|
41
|
-
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
50
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
42
51
|
|
43
52
|
if(!db_ctx->db)
|
44
53
|
rb_raise(rb_eArgError, "prepare called on a closed database");
|
@@ -78,7 +87,7 @@ static VALUE sqlite3_rb_close(VALUE self)
|
|
78
87
|
{
|
79
88
|
sqlite3StmtRubyPtr ctx;
|
80
89
|
|
81
|
-
|
90
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
82
91
|
|
83
92
|
REQUIRE_OPEN_STMT(ctx);
|
84
93
|
|
@@ -95,7 +104,7 @@ static VALUE sqlite3_rb_close(VALUE self)
|
|
95
104
|
static VALUE closed_p(VALUE self)
|
96
105
|
{
|
97
106
|
sqlite3StmtRubyPtr ctx;
|
98
|
-
|
107
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
99
108
|
|
100
109
|
if(!ctx->st) return Qtrue;
|
101
110
|
|
@@ -110,7 +119,7 @@ static VALUE step(VALUE self)
|
|
110
119
|
VALUE list;
|
111
120
|
rb_encoding * internal_encoding;
|
112
121
|
|
113
|
-
|
122
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
114
123
|
|
115
124
|
REQUIRE_OPEN_STMT(ctx);
|
116
125
|
|
@@ -206,7 +215,7 @@ static VALUE bind_param(VALUE self, VALUE key, VALUE value)
|
|
206
215
|
int status;
|
207
216
|
int index;
|
208
217
|
|
209
|
-
|
218
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
210
219
|
REQUIRE_OPEN_STMT(ctx);
|
211
220
|
|
212
221
|
switch(TYPE(key)) {
|
@@ -296,7 +305,7 @@ static VALUE reset_bang(VALUE self)
|
|
296
305
|
{
|
297
306
|
sqlite3StmtRubyPtr ctx;
|
298
307
|
|
299
|
-
|
308
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
300
309
|
REQUIRE_OPEN_STMT(ctx);
|
301
310
|
|
302
311
|
sqlite3_reset(ctx->st);
|
@@ -315,7 +324,7 @@ static VALUE clear_bindings_bang(VALUE self)
|
|
315
324
|
{
|
316
325
|
sqlite3StmtRubyPtr ctx;
|
317
326
|
|
318
|
-
|
327
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
319
328
|
REQUIRE_OPEN_STMT(ctx);
|
320
329
|
|
321
330
|
sqlite3_clear_bindings(ctx->st);
|
@@ -332,7 +341,7 @@ static VALUE clear_bindings_bang(VALUE self)
|
|
332
341
|
static VALUE done_p(VALUE self)
|
333
342
|
{
|
334
343
|
sqlite3StmtRubyPtr ctx;
|
335
|
-
|
344
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
336
345
|
|
337
346
|
if(ctx->done_p) return Qtrue;
|
338
347
|
return Qfalse;
|
@@ -345,7 +354,7 @@ static VALUE done_p(VALUE self)
|
|
345
354
|
static VALUE column_count(VALUE self)
|
346
355
|
{
|
347
356
|
sqlite3StmtRubyPtr ctx;
|
348
|
-
|
357
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
349
358
|
REQUIRE_OPEN_STMT(ctx);
|
350
359
|
|
351
360
|
return INT2NUM(sqlite3_column_count(ctx->st));
|
@@ -360,7 +369,7 @@ static VALUE column_name(VALUE self, VALUE index)
|
|
360
369
|
sqlite3StmtRubyPtr ctx;
|
361
370
|
const char * name;
|
362
371
|
|
363
|
-
|
372
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
364
373
|
REQUIRE_OPEN_STMT(ctx);
|
365
374
|
|
366
375
|
name = sqlite3_column_name(ctx->st, (int)NUM2INT(index));
|
@@ -378,7 +387,7 @@ static VALUE column_decltype(VALUE self, VALUE index)
|
|
378
387
|
sqlite3StmtRubyPtr ctx;
|
379
388
|
const char * name;
|
380
389
|
|
381
|
-
|
390
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
382
391
|
REQUIRE_OPEN_STMT(ctx);
|
383
392
|
|
384
393
|
name = sqlite3_column_decltype(ctx->st, (int)NUM2INT(index));
|
@@ -394,7 +403,7 @@ static VALUE column_decltype(VALUE self, VALUE index)
|
|
394
403
|
static VALUE bind_parameter_count(VALUE self)
|
395
404
|
{
|
396
405
|
sqlite3StmtRubyPtr ctx;
|
397
|
-
|
406
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
398
407
|
REQUIRE_OPEN_STMT(ctx);
|
399
408
|
|
400
409
|
return INT2NUM(sqlite3_bind_parameter_count(ctx->st));
|
@@ -409,7 +418,7 @@ static VALUE bind_parameter_count(VALUE self)
|
|
409
418
|
static VALUE database_name(VALUE self, VALUE index)
|
410
419
|
{
|
411
420
|
sqlite3StmtRubyPtr ctx;
|
412
|
-
|
421
|
+
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);
|
413
422
|
REQUIRE_OPEN_STMT(ctx);
|
414
423
|
|
415
424
|
return SQLITE3_UTF8_STR_NEW2(
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/sqlite3/database.rb
CHANGED
@@ -71,12 +71,23 @@ module SQLite3
|
|
71
71
|
|
72
72
|
# call-seq: SQLite3::Database.new(file, options = {})
|
73
73
|
#
|
74
|
-
# Create a new Database object that opens the given file.
|
75
|
-
#
|
74
|
+
# Create a new Database object that opens the given file.
|
75
|
+
#
|
76
|
+
# Supported permissions +options+:
|
77
|
+
# - the default mode is <tt>READWRITE | CREATE</tt>
|
78
|
+
# - +:readonly+: boolean (default false), true to set the mode to +READONLY+
|
79
|
+
# - +:readwrite+: boolean (default false), true to set the mode to +READWRITE+
|
80
|
+
# - +:flags+: set the mode to a combination of SQLite3::Constants::Open flags.
|
81
|
+
#
|
82
|
+
# Supported encoding +options+:
|
83
|
+
# - +:utf16+: boolean (default false), is the filename's encoding UTF-16 (only needed if the filename encoding is not UTF_16LE or BE)
|
84
|
+
#
|
85
|
+
# Other supported +options+:
|
86
|
+
# - +:strict+: boolean (default false), disallow the use of double-quoted string literals (see https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted)
|
87
|
+
# - +:results_as_hash+: boolean (default false), return rows as hashes instead of arrays
|
88
|
+
# - +:type_translation+: boolean (default false), enable type translation
|
89
|
+
# - +:default_transaction_mode+: one of +:deferred+ (default), +:immediate+, or +:exclusive+. If a mode is not specified in a call to #transaction, this will be the default transaction mode.
|
76
90
|
#
|
77
|
-
# By default, the new database will return result rows as arrays
|
78
|
-
# (#results_as_hash) and has type translation disabled (#type_translation=).
|
79
|
-
|
80
91
|
def initialize file, options = {}, zvfs = nil
|
81
92
|
mode = Constants::Open::READWRITE | Constants::Open::CREATE
|
82
93
|
|
@@ -119,6 +130,7 @@ module SQLite3
|
|
119
130
|
@type_translation = options[:type_translation]
|
120
131
|
@type_translator = make_type_translator @type_translation
|
121
132
|
@readonly = mode & Constants::Open::READONLY != 0
|
133
|
+
@default_transaction_mode = options[:default_transaction_mode] || :deferred
|
122
134
|
|
123
135
|
if block_given?
|
124
136
|
begin
|
@@ -622,8 +634,10 @@ module SQLite3
|
|
622
634
|
# by SQLite, so attempting to nest a transaction will result in a runtime
|
623
635
|
# exception.
|
624
636
|
#
|
625
|
-
# The +mode+ parameter may be either <tt>:deferred</tt
|
637
|
+
# The +mode+ parameter may be either <tt>:deferred</tt>,
|
626
638
|
# <tt>:immediate</tt>, or <tt>:exclusive</tt>.
|
639
|
+
# If `nil` is specified, the default transaction mode, which was
|
640
|
+
# passed to #initialize, is used.
|
627
641
|
#
|
628
642
|
# If a block is given, the database instance is yielded to it, and the
|
629
643
|
# transaction is committed when the block terminates. If the block
|
@@ -634,7 +648,8 @@ module SQLite3
|
|
634
648
|
# If a block is not given, it is the caller's responsibility to end the
|
635
649
|
# transaction explicitly, either by calling #commit, or by calling
|
636
650
|
# #rollback.
|
637
|
-
def transaction( mode =
|
651
|
+
def transaction( mode = nil )
|
652
|
+
mode = @default_transaction_mode if mode.nil?
|
638
653
|
execute "begin #{mode.to_s} transaction"
|
639
654
|
|
640
655
|
if block_given?
|
data/lib/sqlite3/version.rb
CHANGED
data/test/test_database.rb
CHANGED
@@ -624,5 +624,45 @@ module SQLite3
|
|
624
624
|
db.execute("insert into foo values (?)", Float::INFINITY)
|
625
625
|
assert_equal Float::INFINITY, db.execute("select avg(temperature) from foo").first.first
|
626
626
|
end
|
627
|
+
|
628
|
+
def test_default_transaction_mode
|
629
|
+
tf = Tempfile.new 'database_default_transaction_mode'
|
630
|
+
SQLite3::Database.new(tf.path) do |db|
|
631
|
+
db.execute("create table foo (score int)")
|
632
|
+
db.execute("insert into foo values (?)", 1)
|
633
|
+
end
|
634
|
+
|
635
|
+
test_cases = [
|
636
|
+
{mode: nil, read: true, write: true},
|
637
|
+
{mode: :deferred, read: true, write: true},
|
638
|
+
{mode: :immediate, read: true, write: false},
|
639
|
+
{mode: :exclusive, read: false, write: false},
|
640
|
+
]
|
641
|
+
|
642
|
+
test_cases.each do |item|
|
643
|
+
db = SQLite3::Database.new tf.path, default_transaction_mode: item[:mode]
|
644
|
+
db2 = SQLite3::Database.new tf.path
|
645
|
+
db.transaction do
|
646
|
+
sql_for_read_test = "select * from foo"
|
647
|
+
if item[:read]
|
648
|
+
assert_nothing_raised{ db2.execute(sql_for_read_test) }
|
649
|
+
else
|
650
|
+
assert_raises(SQLite3::BusyException){ db2.execute(sql_for_read_test) }
|
651
|
+
end
|
652
|
+
|
653
|
+
sql_for_write_test = "insert into foo values (2)"
|
654
|
+
if item[:write]
|
655
|
+
assert_nothing_raised{ db2.execute(sql_for_write_test) }
|
656
|
+
else
|
657
|
+
assert_raises(SQLite3::BusyException){ db2.execute(sql_for_write_test) }
|
658
|
+
end
|
659
|
+
end
|
660
|
+
ensure
|
661
|
+
db.close if db && !db.closed?
|
662
|
+
db2.close if db2 && !db2.closed?
|
663
|
+
end
|
664
|
+
ensure
|
665
|
+
tf.unlink if tf
|
666
|
+
end
|
627
667
|
end
|
628
668
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqlite3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: x86_64-darwin
|
6
6
|
authors:
|
7
7
|
- Jamis Buck
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2023-
|
14
|
+
date: 2023-12-27 00:00:00.000000000 Z
|
15
15
|
dependencies: []
|
16
16
|
description: |
|
17
17
|
Ruby library to interface with the SQLite3 database engine (http://www.sqlite.org). Precompiled
|
@@ -56,10 +56,10 @@ files:
|
|
56
56
|
- ext/sqlite3/statement.c
|
57
57
|
- ext/sqlite3/statement.h
|
58
58
|
- lib/sqlite3.rb
|
59
|
-
- lib/sqlite3/2.7/sqlite3_native.bundle
|
60
59
|
- lib/sqlite3/3.0/sqlite3_native.bundle
|
61
60
|
- lib/sqlite3/3.1/sqlite3_native.bundle
|
62
61
|
- lib/sqlite3/3.2/sqlite3_native.bundle
|
62
|
+
- lib/sqlite3/3.3/sqlite3_native.bundle
|
63
63
|
- lib/sqlite3/constants.rb
|
64
64
|
- lib/sqlite3/database.rb
|
65
65
|
- lib/sqlite3/errors.rb
|
@@ -109,10 +109,10 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
109
109
|
requirements:
|
110
110
|
- - ">="
|
111
111
|
- !ruby/object:Gem::Version
|
112
|
-
version: '
|
112
|
+
version: '3.0'
|
113
113
|
- - "<"
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version: 3.
|
115
|
+
version: 3.4.dev
|
116
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
117
|
requirements:
|
118
118
|
- - ">="
|
Binary file
|