extralite-bundle 3.1.1 → 3.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile +0 -4
- data/LICENSE +1 -1
- data/README.md +26 -1
- data/TODO.md +6 -0
- data/ext/extralite/common.c +9 -7
- data/ext/extralite/database.c +12 -17
- data/ext/extralite/query.c +5 -5
- data/gemspec.rb +3 -3
- data/lib/extralite/version.rb +1 -1
- data/lib/extralite.rb +25 -1
- data/test/test_database.rb +112 -1
- data/test/test_query.rb +1 -1
- metadata +11 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 476ad3a137ab5292ac1e7a5b6053db39b8136141154e42c06502e0d723875680
|
|
4
|
+
data.tar.gz: d33bae3131575f702577d7e1960a54f64d4d2ac6d3903eb41b3f8fb9f896288f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cbeb90a19c16e0355825de837ef6488614c1576df06ab2ba4dba1e6868568b839ee124d1713f4884156aa58ae3d7c8314e5675d90022fe3a08c6a54ec3448498
|
|
7
|
+
data.tar.gz: 885f3d695eec965ef271c3500eb07a56f9f06890b514f52d27d8f3a6e25c71c43b8034d730048b1a7f9db7e8f25ddebb5f69f1ddd2a9f53fe8adb926d323ad4a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# 3.1.3 2026-10-03
|
|
2
|
+
|
|
3
|
+
- Fix database finalization of stmts (on free/close)
|
|
4
|
+
- Use stmt_cache for storing Query stmts
|
|
5
|
+
|
|
6
|
+
# 3.1.2 2026-10-03
|
|
7
|
+
|
|
8
|
+
- Fix handling of failed BEGIN in #transaction (#89)
|
|
9
|
+
- Reset of cached statements post-query (#88)
|
|
10
|
+
- Add missing wal checkpoint, integrity_check docs to README
|
|
11
|
+
- Implement `Database#integrity_check`, `Database#quick_check`
|
|
12
|
+
|
|
1
13
|
# 3.1.1 2026-09-26
|
|
2
14
|
|
|
3
15
|
- Fix clearing of stmt cache after `DB#close` or after GC (#87)
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -56,7 +56,7 @@ latest features and enhancements.
|
|
|
56
56
|
[backups](#creating-backups), retrieve [status
|
|
57
57
|
information](#retrieving-status-information), work with
|
|
58
58
|
[changesets](#working-with-changesets), interrogate [database
|
|
59
|
-
limits](#working-with-database-limits), [trace](#tracing-sql-statements)
|
|
59
|
+
limits](#working-with-database-limits), [trace](#tracing-sql-statements), [WAL checkpoints](#wal-checkpoints), and run [integrity checks](#integrity-checks).
|
|
60
60
|
queries.
|
|
61
61
|
- [Sequel](#usage-with-sequel) adapter.
|
|
62
62
|
|
|
@@ -1313,6 +1313,31 @@ db.query('select ?, ?', 1, 2)
|
|
|
1313
1313
|
# { sql: "select ?, ?", args: [1, 2] }
|
|
1314
1314
|
```
|
|
1315
1315
|
|
|
1316
|
+
### WAL Checkpoints
|
|
1317
|
+
|
|
1318
|
+
Exrtralite lets you manually perform a WAL checkpoint in order to truncate the
|
|
1319
|
+
WAL file at any given moment using the `Database#wal_checkpoint` method:
|
|
1320
|
+
|
|
1321
|
+
```ruby
|
|
1322
|
+
db.wal_checkpoint(:full)
|
|
1323
|
+
```
|
|
1324
|
+
|
|
1325
|
+
The `#wal_checkpoint` method takes a mode argument, which should be one
|
|
1326
|
+
`:passive`, `:full`, `:restart`, `:truncate`. For a discussion of the different
|
|
1327
|
+
modes, you can refer to the [SQLite
|
|
1328
|
+
documentation](https://sqlite.org/c3ref/wal_checkpoint_v2.html).
|
|
1329
|
+
|
|
1330
|
+
### Integrity Checks
|
|
1331
|
+
|
|
1332
|
+
Extralite provides two methods for performing integrity checks,
|
|
1333
|
+
`Database#integrity_check` and `Database#quick_check`, which map to the
|
|
1334
|
+
corresponding pragmas. The two methods return an array of error messages. In the
|
|
1335
|
+
case of a normal, uncorrupted database, the methods will return `['ok']`:
|
|
1336
|
+
|
|
1337
|
+
```ruby
|
|
1338
|
+
db.integrity_check #=> ['ok'] (hopefully)
|
|
1339
|
+
```
|
|
1340
|
+
|
|
1316
1341
|
## Usage with Sequel
|
|
1317
1342
|
|
|
1318
1343
|
Extralite includes an adapter for
|
data/TODO.md
CHANGED
data/ext/extralite/common.c
CHANGED
|
@@ -226,6 +226,8 @@ static inline void finalize_stmt_ctx(stmt_ctx *ctx) {
|
|
|
226
226
|
return;
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
sqlite3_reset(*(ctx->stmtptr));
|
|
230
|
+
sqlite3_clear_bindings(*(ctx->stmtptr));
|
|
229
231
|
if (!(ctx->flags & STMT_CTX_F_CACHE_HIT))
|
|
230
232
|
rb_hash_aset(ctx->stmt_cache, ctx->sql, ULONG2NUM((uint64_t)*(ctx->stmtptr)));
|
|
231
233
|
}
|
|
@@ -241,11 +243,7 @@ void make_stmt_ctx(
|
|
|
241
243
|
|
|
242
244
|
int use_cache = (argc > 0) && (db->flags & DB_F_STMT_CACHE);
|
|
243
245
|
ctx->flags = use_cache ? STMT_CTX_F_USE_CACHE : 0;
|
|
244
|
-
if (use_cache)
|
|
245
|
-
lookup_cache_entry(ctx);
|
|
246
|
-
if (ctx->flags & STMT_CTX_F_CACHE_HIT)
|
|
247
|
-
sqlite3_clear_bindings(*(ctx->stmtptr));
|
|
248
|
-
}
|
|
246
|
+
if (use_cache) lookup_cache_entry(ctx);
|
|
249
247
|
|
|
250
248
|
if (!use_cache || !(*(ctx->stmtptr))) {
|
|
251
249
|
ctx->str = RSTRING_PTR(sql);
|
|
@@ -458,8 +456,12 @@ VALUE cleanup_stmt(query_ctx *ctx) {
|
|
|
458
456
|
|
|
459
457
|
if (!(ctx->flags & STMT_CTX_F_USE_CACHE))
|
|
460
458
|
sqlite3_finalize(ctx->stmt);
|
|
461
|
-
else
|
|
462
|
-
|
|
459
|
+
else {
|
|
460
|
+
sqlite3_reset(ctx->stmt);
|
|
461
|
+
sqlite3_clear_bindings(ctx->stmt);
|
|
462
|
+
if (!(ctx->flags & STMT_CTX_F_CACHE_HIT))
|
|
463
|
+
rb_hash_aset(ctx->db->stmt_cache, ctx->sql, ULONG2NUM((uint64_t)(ctx->stmt)));
|
|
464
|
+
}
|
|
463
465
|
done:
|
|
464
466
|
return Qnil;
|
|
465
467
|
}
|
data/ext/extralite/database.c
CHANGED
|
@@ -72,25 +72,19 @@ static void Database_compact(void *ptr) {
|
|
|
72
72
|
db->progress_handler.proc = rb_gc_location(db->progress_handler.proc);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
static
|
|
76
|
-
sqlite3_stmt *stmt = (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (stmt_cache == Qnil) return;
|
|
83
|
-
if (rb_hash_size_num(stmt_cache) == 0) return;
|
|
84
|
-
|
|
85
|
-
rb_hash_foreach(stmt_cache, stmt_cache_iter, Qnil);
|
|
86
|
-
rb_hash_clear(stmt_cache);
|
|
87
|
-
RB_GC_GUARD(stmt_cache);
|
|
75
|
+
static inline void finalize_all_stmts(sqlite3 *db) {
|
|
76
|
+
sqlite3_stmt *stmt = sqlite3_next_stmt(db, NULL);
|
|
77
|
+
while (stmt) {
|
|
78
|
+
sqlite3_stmt *next = sqlite3_next_stmt(db, stmt);
|
|
79
|
+
sqlite3_finalize(stmt);
|
|
80
|
+
stmt = next;
|
|
81
|
+
}
|
|
88
82
|
}
|
|
89
83
|
|
|
90
84
|
static void Database_free(void *ptr) {
|
|
91
85
|
Database_t *db = ptr;
|
|
92
86
|
if (db->sqlite3_db) {
|
|
93
|
-
|
|
87
|
+
finalize_all_stmts(db->sqlite3_db);
|
|
94
88
|
sqlite3_close_v2(db->sqlite3_db);
|
|
95
89
|
}
|
|
96
90
|
free(ptr);
|
|
@@ -279,7 +273,8 @@ VALUE Database_close(VALUE self) {
|
|
|
279
273
|
int rc;
|
|
280
274
|
Database_t *db = self_to_database(self);
|
|
281
275
|
|
|
282
|
-
|
|
276
|
+
finalize_all_stmts(db->sqlite3_db);
|
|
277
|
+
rb_hash_clear(db->stmt_cache);
|
|
283
278
|
rc = sqlite3_close_v2(db->sqlite3_db);
|
|
284
279
|
if (rc) {
|
|
285
280
|
rb_raise(cError, "%s", sqlite3_errmsg(db->sqlite3_db));
|
|
@@ -1565,11 +1560,11 @@ int checkpoint_mode_symbol_to_int(VALUE mode) {
|
|
|
1565
1560
|
*
|
|
1566
1561
|
* @overload wal_checkpoint(mode)
|
|
1567
1562
|
* @param mode [Symbol] checkpoint mode (`:passive`, `:full`, `:restart`, `:truncate`)
|
|
1568
|
-
* @return [Array<
|
|
1563
|
+
* @return [Array<Integer>] total and checkpointed frame count
|
|
1569
1564
|
* @overload wal_checkpoint(mode, db_name)
|
|
1570
1565
|
* @param mode [Symbol] checkpoint mode (`:passive`, `:full`, `:restart`, `:truncate`)
|
|
1571
1566
|
* @param db_name [String] attached database name
|
|
1572
|
-
* @return [Array<
|
|
1567
|
+
* @return [Array<Integer>] total and checkpointed frame count
|
|
1573
1568
|
*/
|
|
1574
1569
|
VALUE Database_wal_checkpoint(int argc, VALUE *argv, VALUE self) {
|
|
1575
1570
|
Database_t *db = self_to_open_database(self);
|
data/ext/extralite/query.c
CHANGED
|
@@ -40,8 +40,7 @@ static void Query_compact(void *ptr) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
static void Query_free(void *ptr) {
|
|
43
|
-
Query_t *query = ptr;
|
|
44
|
-
if (query->stmt) sqlite3_finalize(query->stmt);
|
|
43
|
+
// Query_t *query = ptr;
|
|
45
44
|
free(ptr);
|
|
46
45
|
}
|
|
47
46
|
|
|
@@ -70,7 +69,7 @@ static inline Query_t *self_to_query(VALUE obj) {
|
|
|
70
69
|
// verifies that the query is not closed
|
|
71
70
|
static inline Query_t *self_to_query_verify(VALUE obj) {
|
|
72
71
|
Query_t *query = self_to_query(obj);
|
|
73
|
-
if (query->closed) rb_raise(cError, "Query is closed");
|
|
72
|
+
if (query->closed || !(query->db_struct->sqlite3_db)) rb_raise(cError, "Query is closed");
|
|
74
73
|
return query;
|
|
75
74
|
}
|
|
76
75
|
|
|
@@ -133,8 +132,10 @@ VALUE Query_initialize(VALUE self, VALUE db, VALUE sql, VALUE mode) {
|
|
|
133
132
|
|
|
134
133
|
static inline void prep_query(Query_t *query) {
|
|
135
134
|
stmt_ctx stmt_ctx;
|
|
136
|
-
make_stmt_ctx(&stmt_ctx, query->db_struct, &(query->stmt), query->sql,
|
|
135
|
+
make_stmt_ctx(&stmt_ctx, query->db_struct, &(query->stmt), query->sql, 1, NULL);
|
|
137
136
|
prep_single_stmt(&stmt_ctx);
|
|
137
|
+
if (!(stmt_ctx.flags & STMT_CTX_F_CACHE_HIT))
|
|
138
|
+
rb_hash_aset(query->db_struct->stmt_cache, query->sql, ULONG2NUM((uint64_t)(query->stmt)));
|
|
138
139
|
}
|
|
139
140
|
|
|
140
141
|
static inline void query_reset(Query_t *query) {
|
|
@@ -531,7 +532,6 @@ VALUE Query_clone(VALUE self) {
|
|
|
531
532
|
VALUE Query_close(VALUE self) {
|
|
532
533
|
Query_t *query = self_to_query(self);
|
|
533
534
|
if (query->stmt) {
|
|
534
|
-
sqlite3_finalize(query->stmt);
|
|
535
535
|
query->stmt = NULL;
|
|
536
536
|
}
|
|
537
537
|
query->closed = 1;
|
data/gemspec.rb
CHANGED
|
@@ -19,7 +19,7 @@ def common_spec(s)
|
|
|
19
19
|
|
|
20
20
|
s.add_development_dependency 'rake-compiler', '1.3.1'
|
|
21
21
|
s.add_development_dependency 'minitest'
|
|
22
|
-
s.add_development_dependency 'simplecov'
|
|
23
|
-
s.add_development_dependency 'yard'
|
|
24
|
-
s.add_development_dependency 'sequel', '5.
|
|
22
|
+
s.add_development_dependency 'simplecov'
|
|
23
|
+
s.add_development_dependency 'yard'
|
|
24
|
+
s.add_development_dependency 'sequel', '5.108.0'
|
|
25
25
|
end
|
data/lib/extralite/version.rb
CHANGED
data/lib/extralite.rb
CHANGED
|
@@ -215,6 +215,29 @@ module Extralite
|
|
|
215
215
|
value.is_a?(Hash) ? pragma_set(value) : pragma_get(value)
|
|
216
216
|
end
|
|
217
217
|
|
|
218
|
+
# Performs a low-level formatting and consistency check of the database
|
|
219
|
+
# using PRAGMA integrity_check. See:
|
|
220
|
+
# https://www.sqlite.org/pragma.html#pragma_integrity_check
|
|
221
|
+
#
|
|
222
|
+
# @param v [Integer, String, nil] max errors or table name
|
|
223
|
+
# @return [Array<String>] array of error strings or 'ok'
|
|
224
|
+
def integrity_check(v = nil)
|
|
225
|
+
query_splat(
|
|
226
|
+
v ? "pragma integrity_check(#{v})" : 'pragma integrity_check'
|
|
227
|
+
)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Performs a quicker integrity check of the database using PRAGMA
|
|
231
|
+
# quick_check. See: https://www.sqlite.org/pragma.html#pragma_quick_check
|
|
232
|
+
#
|
|
233
|
+
# @param v [Integer, String, nil] max errors or table name
|
|
234
|
+
# @return [Array<String>] array of error strings or 'ok'
|
|
235
|
+
def quick_check(v = nil)
|
|
236
|
+
query_splat(
|
|
237
|
+
v ? "pragma quick_check(#{v})" : 'pragma quick_check'
|
|
238
|
+
)
|
|
239
|
+
end
|
|
240
|
+
|
|
218
241
|
# Error class used to roll back a transaction without propagating an
|
|
219
242
|
# exception.
|
|
220
243
|
class Rollback < Error
|
|
@@ -237,12 +260,13 @@ module Extralite
|
|
|
237
260
|
def transaction(mode = :immediate)
|
|
238
261
|
abort = false
|
|
239
262
|
execute "begin #{mode} transaction"
|
|
263
|
+
started = true
|
|
240
264
|
yield self
|
|
241
265
|
rescue => e
|
|
242
266
|
abort = true
|
|
243
267
|
e.is_a?(Rollback) ? nil : raise
|
|
244
268
|
ensure
|
|
245
|
-
execute(abort ? 'rollback' : 'commit')
|
|
269
|
+
execute(abort ? 'rollback' : 'commit') if started
|
|
246
270
|
end
|
|
247
271
|
|
|
248
272
|
# Creates a savepoint with the given name. For more information on
|
data/test/test_database.rb
CHANGED
|
@@ -372,6 +372,86 @@ class DatabaseTest < Minitest::Test
|
|
|
372
372
|
# assert_equal 1, @db.pragma('foreign_keys')
|
|
373
373
|
end
|
|
374
374
|
|
|
375
|
+
def test_integrity_check_ok
|
|
376
|
+
r = @db.integrity_check
|
|
377
|
+
assert_equal ['ok'], r
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def test_integrity_check_bad_var
|
|
381
|
+
assert_raises(Extralite::Error) { @db.integrity_check('foobar') }
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def test_integrity_check_damaged
|
|
385
|
+
fn = Tempfile.new('extralite_test_integrity_check_damaged').path
|
|
386
|
+
db = Extralite::Database.new(fn)
|
|
387
|
+
|
|
388
|
+
db.execute <<~SQL
|
|
389
|
+
create table foo (x);
|
|
390
|
+
SQL
|
|
391
|
+
|
|
392
|
+
db.batch_execute("insert into foo values (?)", 1..100)
|
|
393
|
+
|
|
394
|
+
assert_equal (1..100).to_a, db.query_splat('select * from foo')
|
|
395
|
+
db.close
|
|
396
|
+
|
|
397
|
+
File.open(fn, 'r+b') do |f|
|
|
398
|
+
1.times do
|
|
399
|
+
f.seek(8015)
|
|
400
|
+
f.write('\x00' * 16)
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
db = Extralite::Database.new(fn, legacy: true)
|
|
405
|
+
assert_raises(Extralite::Error) { db.query_splat('select * from foo') }
|
|
406
|
+
r = db.integrity_check
|
|
407
|
+
assert_equal 2, r.size
|
|
408
|
+
assert_equal 'database disk image is malformed', r[1]
|
|
409
|
+
|
|
410
|
+
r = db.integrity_check(1)
|
|
411
|
+
assert_equal 1, r.size
|
|
412
|
+
assert_match /^\*\*\* in database main \*\*\*/, r[0]
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
def test_quick_check_ok
|
|
416
|
+
r = @db.quick_check
|
|
417
|
+
assert_equal ['ok'], r
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
def test_quick_check_bad_var
|
|
421
|
+
assert_raises(Extralite::Error) { @db.quick_check('foobar') }
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
def test_quick_check_damaged
|
|
425
|
+
fn = Tempfile.new('extralite_test_quick_check_damaged').path
|
|
426
|
+
db = Extralite::Database.new(fn)
|
|
427
|
+
|
|
428
|
+
db.execute <<~SQL
|
|
429
|
+
create table foo (x);
|
|
430
|
+
SQL
|
|
431
|
+
|
|
432
|
+
db.batch_execute("insert into foo values (?)", 1..100)
|
|
433
|
+
|
|
434
|
+
assert_equal (1..100).to_a, db.query_splat('select * from foo')
|
|
435
|
+
db.close
|
|
436
|
+
|
|
437
|
+
File.open(fn, 'r+b') do |f|
|
|
438
|
+
1.times do
|
|
439
|
+
f.seek(8015)
|
|
440
|
+
f.write('\x00' * 16)
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
db = Extralite::Database.new(fn, legacy: true)
|
|
445
|
+
assert_raises(Extralite::Error) { db.query_splat('select * from foo') }
|
|
446
|
+
r = db.quick_check
|
|
447
|
+
assert_equal 2, r.size
|
|
448
|
+
assert_equal 'database disk image is malformed', r[1]
|
|
449
|
+
|
|
450
|
+
r = db.integrity_check(1)
|
|
451
|
+
assert_equal 1, r.size
|
|
452
|
+
assert_match /^\*\*\* in database main \*\*\*/, r[0]
|
|
453
|
+
end
|
|
454
|
+
|
|
375
455
|
def test_execute
|
|
376
456
|
changes = @db.execute('update t set x = 42')
|
|
377
457
|
assert_equal 2, changes
|
|
@@ -2244,7 +2324,7 @@ class StmtCacheText < Minitest::Test
|
|
|
2244
2324
|
end
|
|
2245
2325
|
|
|
2246
2326
|
def test_stmt_cache_gc
|
|
2247
|
-
fn = Tempfile.new('
|
|
2327
|
+
fn = Tempfile.new('extralite_test_stmt_cache_gc').path
|
|
2248
2328
|
|
|
2249
2329
|
db = Extralite::Database.new(fn)
|
|
2250
2330
|
db.query('create table t (x)')
|
|
@@ -2260,4 +2340,35 @@ class StmtCacheText < Minitest::Test
|
|
|
2260
2340
|
GC.start
|
|
2261
2341
|
refute File.file?("#{fn}-wal"), "WAL file should not exist after GC"
|
|
2262
2342
|
end
|
|
2343
|
+
|
|
2344
|
+
def test_stmt_cache_concurrent_access
|
|
2345
|
+
# https://github.com/digital-fabric/extralite/issues/88
|
|
2346
|
+
fn = Tempfile.new('extralite_test_stmt_cache_concurrent_access').path
|
|
2347
|
+
|
|
2348
|
+
a = Extralite::Database.new(fn)
|
|
2349
|
+
a.execute("pragma journal_mode=wal")
|
|
2350
|
+
a.execute("create table t (id integer primary key, x)")
|
|
2351
|
+
a.execute("insert into t (x) values (1)")
|
|
2352
|
+
a.query_single("select * from t where id = ?", 1)
|
|
2353
|
+
|
|
2354
|
+
b = Extralite::Database.new(fn)
|
|
2355
|
+
b.execute("insert into t (x) values (2)")
|
|
2356
|
+
|
|
2357
|
+
assert_equal 2, b.query_single_splat("select count(*) from t")
|
|
2358
|
+
assert_equal 2, a.query_single_splat("select count(*) from t")
|
|
2359
|
+
end
|
|
2360
|
+
|
|
2361
|
+
def test_stmt_cache_concurrent_transactions
|
|
2362
|
+
# https://github.com/digital-fabric/extralite/issues/89
|
|
2363
|
+
fn = Tempfile.new('extralite_test_stmt_cache_concurrent_access').path
|
|
2364
|
+
|
|
2365
|
+
a = Extralite::Database.new(fn)
|
|
2366
|
+
a.execute('create table t (x)')
|
|
2367
|
+
b = Extralite::Database.new(fn)
|
|
2368
|
+
b.execute('begin immediate transaction')
|
|
2369
|
+
|
|
2370
|
+
assert_raises(Extralite::BusyError) {
|
|
2371
|
+
a.transaction { a.execute("insert into t values (1)") }
|
|
2372
|
+
}
|
|
2373
|
+
end
|
|
2263
2374
|
end
|
data/test/test_query.rb
CHANGED
|
@@ -933,7 +933,7 @@ class QueryTest < Minitest::Test
|
|
|
933
933
|
def test_query_after_db_close
|
|
934
934
|
assert_equal [{ x: 4, y: 5, z: 6}], @query.bind(4).to_a
|
|
935
935
|
@db.close
|
|
936
|
-
|
|
936
|
+
assert_raises(Extralite::Error) { @query.bind(4).to_a }
|
|
937
937
|
end
|
|
938
938
|
|
|
939
939
|
def test_query_eof
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: extralite-bundle
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.
|
|
4
|
+
version: 3.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sharon Rosner
|
|
@@ -41,44 +41,44 @@ dependencies:
|
|
|
41
41
|
name: simplecov
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
43
43
|
requirements:
|
|
44
|
-
- -
|
|
44
|
+
- - ">="
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 0
|
|
46
|
+
version: '0'
|
|
47
47
|
type: :development
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
|
-
- -
|
|
51
|
+
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 0
|
|
53
|
+
version: '0'
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: yard
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
|
-
- -
|
|
58
|
+
- - ">="
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: 0
|
|
60
|
+
version: '0'
|
|
61
61
|
type: :development
|
|
62
62
|
prerelease: false
|
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
|
-
- -
|
|
65
|
+
- - ">="
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: 0
|
|
67
|
+
version: '0'
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
69
|
name: sequel
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - '='
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: 5.
|
|
74
|
+
version: 5.108.0
|
|
75
75
|
type: :development
|
|
76
76
|
prerelease: false
|
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
|
79
79
|
- - '='
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: 5.
|
|
81
|
+
version: 5.108.0
|
|
82
82
|
email: sharon@noteflakes.com
|
|
83
83
|
executables: []
|
|
84
84
|
extensions:
|