extralite 3.1.3 → 3.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49e8816c10db2687c32a0339d55c3027c1e8c071692bd83de6dfa0be4972a3b8
4
- data.tar.gz: 9910eaa68101d1099981f22476488b743b287008fc4d9b2c16d1e553c7fad684
3
+ metadata.gz: 5281aeb88afdc13d5ab8997ef3d268b5c2f23bba5c10121d82d93fa1b0c6683e
4
+ data.tar.gz: 98c7ebcc643f1c228e7dd154530363d2b590c32e8c6ec2048ab680e6ef8dff29
5
5
  SHA512:
6
- metadata.gz: 5c26195a522ab6a4b356f70b230f17dd76e49635f44a22e0a40e18ac4ee380357c7b2879c45b2d7e9e96c3fac85831dfa1791b0d13939c16c2cb1c898c73e0b7
7
- data.tar.gz: 8c9c0e088738ef416c56e9dd429a2b6597b7a75c74557a3b7f353ddc521a24c72b31ef2d7cfff787347260f2cadcbc9d1a38557883ebe495ab48a4bd2d0e0f21
6
+ metadata.gz: 500b76bae6913d602bfea5a611e0dab55a36563b665afc9ad48143c379cd6c7cfffa768a35dfaec966286197dbc1e1bdf02a4d7203bab6f3adf4b10c14ff92e3
7
+ data.tar.gz: d93b59540dfd75a7ddb1d0477e48cf064d49e1c8800f18b7953f7a04e58a756c48f6e3dac71e6d3d8df4463faa3a573aafb942bbf3e93170a630e5dcaf9dad12
@@ -0,0 +1,37 @@
1
+ name: Tests (AddressSanitizer)
2
+
3
+ on: [push, pull_request]
4
+
5
+ concurrency:
6
+ group: tests-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
7
+ cancel-in-progress: true
8
+
9
+ jobs:
10
+ asan:
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ include:
15
+ # Ruby is not instrumented, rake test:asan preloads libasan
16
+ - { ruby: '3.4', os: ubuntu-latest, test_task: 'test:asan' }
17
+ - { ruby: '4.0', os: ubuntu-latest, test_task: 'test:asan' }
18
+ # Ruby built with ASan (latest stable release), only on ubuntu-24.04
19
+ - { ruby: 'asan-release', os: ubuntu-24.04, test_task: 'test' }
20
+
21
+ name: ASan, ${{matrix.ruby}}
22
+
23
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
24
+
25
+ runs-on: ${{matrix.os}}
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+ - uses: ruby/setup-ruby@v1
29
+ with:
30
+ ruby-version: ${{matrix.ruby}}
31
+ bundler-cache: true
32
+ - name: Compile C-extension with ASan (bundled SQLite)
33
+ run: EXTRALITE_BUNDLE=1 EXTRALITE_ASAN=1 bundle exec rake compile
34
+ - name: Run tests
35
+ run: bundle exec rake ${{matrix.test_task}}
36
+ - name: Run tests with GC.stress
37
+ run: EXTRALITE_GC_STRESS=1 bundle exec rake ${{matrix.test_task}}
data/.gitignore CHANGED
@@ -51,7 +51,7 @@ build-iPhoneSimulator/
51
51
  # for a library or gem, you might want to ignore these files since the code is
52
52
  # intended to run in multiple environments; otherwise, check them in:
53
53
  # Gemfile.lock
54
- # .ruby-version
54
+ .ruby-version
55
55
  # .ruby-gemset
56
56
 
57
57
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 3.1.4 2026-11-07
2
+
3
+ - Fix loading of extension on some systems running Ruby from distro packages (#96)
4
+
1
5
  # 3.1.3 2026-10-03
2
6
 
3
7
  - Fix database finalization of stmts (on free/close)
data/Rakefile CHANGED
@@ -15,6 +15,38 @@ task :test do
15
15
  exec 'ruby test/run.rb'
16
16
  end
17
17
 
18
+ namespace :test do
19
+ # Runs the tests against an extension built with AddressSanitizer:
20
+ #
21
+ # bundle exec rake clean
22
+ # EXTRALITE_BUNDLE=1 EXTRALITE_ASAN=1 bundle exec rake compile
23
+ # bundle exec rake test:asan
24
+ #
25
+ # Set TEST_FILES (comma separated) to run only some test files.
26
+ #
27
+ # Ruby itself is not built with ASan, so libasan has to be preloaded.
28
+ # use_sigaltstack=0: Ruby installs its own signal stack for each thread,
29
+ # which makes ASan fail when it unmaps its own signal stack on thread exit.
30
+ # Leak detection is off because Ruby does not free everything on exit.
31
+ desc 'Run tests with an ASan build of the extension (Linux only)'
32
+ task :asan do
33
+ so = Dir['lib/extralite_ext.{so,bundle}'].first
34
+ libasan = so && `ldd #{so}`[/^\s*libasan\S*\s*=>\s*(\S+)/, 1]
35
+ abort 'The extension is not built with EXTRALITE_ASAN=1' unless libasan
36
+
37
+ env = {
38
+ 'LD_PRELOAD' => libasan,
39
+ 'ASAN_OPTIONS' => "detect_leaks=0:use_sigaltstack=0:abort_on_error=1:#{ENV['ASAN_OPTIONS']}"
40
+ }
41
+ files = ENV['TEST_FILES']&.split(',')
42
+ if files
43
+ exec env, 'ruby', '-Itest', '-e', files.map { "require './#{it}'" }.join(';')
44
+ else
45
+ exec env, 'ruby test/run.rb'
46
+ end
47
+ end
48
+ end
49
+
18
50
  CLEAN.include 'lib/*.o', 'lib/*.so', 'lib/*.so.*', 'lib/*.a', 'lib/*.bundle', 'lib/*.jar', 'pkg', 'tmp'
19
51
 
20
52
  require 'yard'
@@ -237,11 +237,12 @@ VALUE Database_initialize(int argc, VALUE *argv, VALUE self) {
237
237
  sqlite3_db_config(db->sqlite3_db ,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, NULL);
238
238
  #endif
239
239
 
240
- db->stmt_cache = rb_hash_new();
240
+ RB_OBJ_WRITE(self, &db->stmt_cache, rb_hash_new());
241
241
  db->trace_proc = Qnil;
242
242
  db->gvl_release_threshold = DEFAULT_GVL_RELEASE_THRESHOLD;
243
243
 
244
244
  db->progress_handler = global_progress_handler;
245
+ RB_OBJ_WRITTEN(self, Qundef, db->progress_handler.proc);
245
246
  db->progress_handler.tick_count = 0;
246
247
  db->progress_handler.call_count = 0;
247
248
  if (db->progress_handler.mode != PROGRESS_NONE) {
@@ -627,7 +628,7 @@ VALUE Database_batch_query(VALUE self, VALUE sql, VALUE parameters) {
627
628
  sqlite3_stmt *stmt;
628
629
 
629
630
  stmt_ctx stmt_ctx;
630
- make_stmt_ctx(&stmt_ctx, db, &stmt, sql, RARRAY_LEN(parameters), NULL);
631
+ make_stmt_ctx(&stmt_ctx, db, &stmt, sql, (TYPE(parameters) == T_ARRAY) ? RARRAY_LEN(parameters) : 0, NULL);
631
632
  prep_single_stmt(&stmt_ctx);
632
633
  // prepare_xsingle_stmt(DB_GVL_MODE(db), db->stmt_cache, db->sqlite3_db, &stmt, sql, 0, NULL);
633
634
  query_ctx ctx = QUERY_CTX(
@@ -664,7 +665,7 @@ VALUE Database_batch_query_array(VALUE self, VALUE sql, VALUE parameters) {
664
665
  sqlite3_stmt *stmt;
665
666
 
666
667
  stmt_ctx stmt_ctx;
667
- make_stmt_ctx(&stmt_ctx, db, &stmt, sql, RARRAY_LEN(parameters), NULL);
668
+ make_stmt_ctx(&stmt_ctx, db, &stmt, sql, (TYPE(parameters) == T_ARRAY) ? RARRAY_LEN(parameters) : 0, NULL);
668
669
  prep_single_stmt(&stmt_ctx);
669
670
  // prepare_xsingle_stmt(DB_GVL_MODE(db), db->stmt_cache, db->sqlite3_db, &stmt, sql, 0, NULL);
670
671
  query_ctx ctx = QUERY_CTX(
@@ -701,7 +702,7 @@ VALUE Database_batch_query_splat(VALUE self, VALUE sql, VALUE parameters) {
701
702
  sqlite3_stmt *stmt;
702
703
 
703
704
  stmt_ctx stmt_ctx;
704
- make_stmt_ctx(&stmt_ctx, db, &stmt, sql, RARRAY_LEN(parameters), NULL);
705
+ make_stmt_ctx(&stmt_ctx, db, &stmt, sql, (TYPE(parameters) == T_ARRAY) ? RARRAY_LEN(parameters) : 0, NULL);
705
706
  prep_single_stmt(&stmt_ctx);
706
707
  // prepare_xsingle_stmt(DB_GVL_MODE(db), db->stmt_cache, db->sqlite3_db, &stmt, sql, 0, NULL);
707
708
  query_ctx ctx = QUERY_CTX(
@@ -1736,7 +1737,9 @@ void Init_ExtraliteDatabase(void) {
1736
1737
  rb_gc_register_mark_object(SYM_truncate);
1737
1738
  rb_gc_register_mark_object(SYM_wal);
1738
1739
 
1739
- rb_gc_register_mark_object(global_progress_handler.proc);
1740
+ // the proc is replaced by Extralite.on_progress, so register the address,
1741
+ // not the current value
1742
+ rb_gc_register_address(&global_progress_handler.proc);
1740
1743
 
1741
1744
  UTF8_ENCODING = rb_utf8_encoding();
1742
1745
  }
@@ -6,6 +6,24 @@ $CFLAGS << ' -Wno-undef'
6
6
  $CFLAGS << ' -Wno-discarded-qualifiers'
7
7
  $CFLAGS << ' -Wno-unused-function'
8
8
 
9
+ # Development only: build with AddressSanitizer (EXTRALITE_ASAN=1), then run
10
+ # the tests with `bundle exec rake test:asan` (see Rakefile).
11
+ #
12
+ # -fgnu89-inline: several non-static functions in the C files are declared
13
+ # `inline` without an extern definition, which only links when every call is
14
+ # inlined (as with the default -O3).
15
+ if ENV['EXTRALITE_ASAN']
16
+ $CFLAGS << ' -fsanitize=address -fno-omit-frame-pointer -O1 -g -fgnu89-inline'
17
+ $LDFLAGS << ' -fsanitize=address'
18
+ # No stack instrumentation: Ruby raises exceptions with longjmp, which
19
+ # leaves poisoned stack redzones behind and causes false reports later.
20
+ # It also keeps local VALUEs on the real stack, where the GC can see them.
21
+ $CFLAGS << (try_cflags('--param=asan-stack=0') ? ' --param=asan-stack=0' : ' -mllvm -asan-stack=0')
22
+ # SQLite serves small allocations (including statements) from its own
23
+ # lookaside pool, which hides use-after-free bugs from ASan.
24
+ $defs << '-DSQLITE_DEFAULT_LOOKASIDE=0,0'
25
+ end
26
+
9
27
  # enable the session extension
10
28
  $defs << '-DSQLITE_ENABLE_SESSION'
11
29
  $defs << '-DSQLITE_ENABLE_PREUPDATE_HOOK'
@@ -48,6 +48,21 @@ else
48
48
  dir_config('sqlite3', cppflags, ldflags)
49
49
  end
50
50
 
51
+ # Development only: build with AddressSanitizer (EXTRALITE_ASAN=1), then run
52
+ # the tests with `bundle exec rake test:asan` (see Rakefile).
53
+ #
54
+ # -fgnu89-inline: several non-static functions in the C files are declared
55
+ # `inline` without an extern definition, which only links when every call is
56
+ # inlined (as with the default -O3).
57
+ if ENV['EXTRALITE_ASAN']
58
+ $CFLAGS << ' -fsanitize=address -fno-omit-frame-pointer -O1 -g -fgnu89-inline'
59
+ $LDFLAGS << ' -fsanitize=address'
60
+ # No stack instrumentation: Ruby raises exceptions with longjmp, which
61
+ # leaves poisoned stack redzones behind and causes false reports later.
62
+ # It also keeps local VALUEs on the real stack, where the GC can see them.
63
+ $CFLAGS << (try_cflags('--param=asan-stack=0') ? ' --param=asan-stack=0' : ' -mllvm -asan-stack=0')
64
+ end
65
+
51
66
  if RbConfig::CONFIG['host_os'] =~ /mswin/
52
67
  $CFLAGS << ' -W3'
53
68
  end
@@ -54,7 +54,7 @@ static inline Iterator_t *self_to_iterator(VALUE obj) {
54
54
  */
55
55
  VALUE Iterator_initialize(VALUE self, VALUE query) {
56
56
  Iterator_t *iterator = self_to_iterator(self);
57
- iterator->query = query;
57
+ RB_OBJ_WRITE(self, &iterator->query, query);
58
58
  return Qnil;
59
59
  }
60
60
 
@@ -649,7 +649,7 @@ VALUE Query_transform_get(VALUE self) {
649
649
  */
650
650
  VALUE Query_transform_set(VALUE self, VALUE transform) {
651
651
  Query_t *query = self_to_query(self);
652
- query->transform = transform;
652
+ RB_OBJ_WRITE(self, &query->transform, transform);
653
653
  query->transform_object = rb_obj_is_instance_of(transform, cTransform);
654
654
  return self;
655
655
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Extralite
4
- VERSION = '3.1.3'
4
+ VERSION = '3.1.4'
5
5
  end
data/lib/extralite.rb CHANGED
@@ -1,4 +1,4 @@
1
- require_relative './extralite_ext'
1
+ require 'extralite_ext'
2
2
 
3
3
  # Extralite is a Ruby gem for working with SQLite databases
4
4
  module Extralite
data/test/helper.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'bundler/setup'
4
4
  require 'extralite'
5
5
  require 'minitest/autorun'
6
+ require 'tempfile'
6
7
 
7
8
  puts "sqlite3 version: #{Extralite.sqlite3_version}"
8
9
 
@@ -22,7 +23,43 @@ module TestExtensions
22
23
  @db = nil
23
24
  GC.start
24
25
  super
26
+ ensure
27
+ @tempfiles&.each(&:close!)
28
+ end
29
+
30
+ # Returns the path of a new temp file. The Tempfile is kept until teardown,
31
+ # otherwise GC may delete the file while a database is still using it.
32
+ def tempfile_path(name)
33
+ (@tempfiles ||= []) << (tmp = Tempfile.new(name))
34
+ tmp.path
25
35
  end
26
36
  end
27
37
 
28
38
  Minitest::Test.prepend(TestExtensions)
39
+
40
+ # EXTRALITE_GC_STRESS=1 runs every test with GC.stress enabled, which makes GC
41
+ # bugs in the C extension (objects freed too early, wrong free order) show up
42
+ # reliably. It's slow, so you may want to run only some test files, e.g.:
43
+ #
44
+ # EXTRALITE_GC_STRESS=1 ruby test/test_stmt_cache.rb
45
+ if ENV['EXTRALITE_GC_STRESS']
46
+ module GCStressExtensions
47
+ def before_setup
48
+ super
49
+ GC.stress = true
50
+ end
51
+
52
+ def after_teardown
53
+ GC.stress = false
54
+ super
55
+ end
56
+ end
57
+
58
+ Minitest::Test.prepend(GCStressExtensions)
59
+ end
60
+
61
+ module Minitest::Assertions
62
+ def skip_with_gc_stress
63
+ skip 'timing-sensitive, too slow with GC.stress' if ENV['EXTRALITE_GC_STRESS']
64
+ end
65
+ end
@@ -347,7 +347,7 @@ class DatabaseTest < Minitest::Test
347
347
 
348
348
  assert_raises { @db.tables('foo') }
349
349
 
350
- fn = Tempfile.new('extralite_test_tables_with_db_name').path
350
+ fn = tempfile_path('extralite_test_tables_with_db_name')
351
351
  @db.execute "attach database '#{fn}' as foo"
352
352
 
353
353
  assert_equal [], @db.tables('foo')
@@ -382,7 +382,7 @@ class DatabaseTest < Minitest::Test
382
382
  end
383
383
 
384
384
  def test_integrity_check_damaged
385
- fn = Tempfile.new('extralite_test_integrity_check_damaged').path
385
+ fn = tempfile_path('extralite_test_integrity_check_damaged')
386
386
  db = Extralite::Database.new(fn)
387
387
 
388
388
  db.execute <<~SQL
@@ -422,7 +422,7 @@ class DatabaseTest < Minitest::Test
422
422
  end
423
423
 
424
424
  def test_quick_check_damaged
425
- fn = Tempfile.new('extralite_test_quick_check_damaged').path
425
+ fn = tempfile_path('extralite_test_quick_check_damaged')
426
426
  db = Extralite::Database.new(fn)
427
427
 
428
428
  db.execute <<~SQL
@@ -882,7 +882,8 @@ class DatabaseTest < Minitest::Test
882
882
  end
883
883
 
884
884
  def test_database_busy_timeout
885
- fn = Tempfile.new('extralite_test_database_busy_timeout').path
885
+ skip_with_gc_stress
886
+ fn = tempfile_path('extralite_test_database_busy_timeout')
886
887
  db1 = Extralite::Database.new(fn)
887
888
  db2 = Extralite::Database.new(fn)
888
889
 
@@ -978,13 +979,13 @@ class DatabaseTest < Minitest::Test
978
979
  db = Extralite::Database.new(':memory:', gvl_release_threshold: 23)
979
980
  assert_equal 23, db.gvl_release_threshold
980
981
 
981
- fn = Tempfile.new('extralite_test_database_initialize_modern').path
982
+ fn = tempfile_path('extralite_test_database_initialize_modern')
982
983
  db = Extralite::Database.new(fn)
983
984
  assert_equal 'wal', db.pragma(:journal_mode)
984
985
  assert_equal 1, db.pragma(:synchronous)
985
986
  assert_equal 1, db.pragma(:foreign_keys)
986
987
 
987
- fn = Tempfile.new('extralite_test_database_initialize_legacy').path
988
+ fn = tempfile_path('extralite_test_database_initialize_legacy')
988
989
  db = Extralite::Database.new(fn, legacy: true)
989
990
  assert_equal 'delete', db.pragma(:journal_mode)
990
991
  assert_equal 2, db.pragma(:synchronous)
@@ -1011,7 +1012,7 @@ class DatabaseTest < Minitest::Test
1011
1012
  end
1012
1013
 
1013
1014
  def test_database_transaction_commit
1014
- path = Tempfile.new('extralite_test_database_transaction_commit').path
1015
+ path = tempfile_path('extralite_test_database_transaction_commit')
1015
1016
  db1 = Extralite::Database.new(path)
1016
1017
  db2 = Extralite::Database.new(path)
1017
1018
 
@@ -1165,7 +1166,7 @@ class DatabaseTest < Minitest::Test
1165
1166
  end
1166
1167
 
1167
1168
  def test_wal_checkpoint
1168
- fn = Tempfile.new('extralite_test_wal_checkpoint').path
1169
+ fn = tempfile_path('extralite_test_wal_checkpoint')
1169
1170
 
1170
1171
  db = Extralite::Database.new(fn)
1171
1172
 
@@ -1258,7 +1259,7 @@ end
1258
1259
 
1259
1260
  class ScenarioTest < Minitest::Test
1260
1261
  def setup
1261
- @fn = Tempfile.new('extralite_scenario_test').path
1262
+ @fn = tempfile_path('extralite_scenario_test')
1262
1263
  @db = Extralite::Database.new(@fn, legacy: true)
1263
1264
  @db.query('create table if not exists t (x,y,z)')
1264
1265
  @db.query('delete from t')
@@ -1411,7 +1412,7 @@ class BackupTest < Minitest::Test
1411
1412
  end
1412
1413
 
1413
1414
  def test_backup_with_fn
1414
- tmp_fn = Tempfile.new('extralite_test_backup_with_fn').path
1415
+ tmp_fn = tempfile_path('extralite_test_backup_with_fn')
1415
1416
  @src.backup(tmp_fn)
1416
1417
 
1417
1418
  db = Extralite::Database.new(tmp_fn)
@@ -1438,6 +1439,7 @@ class ConcurrencyTest < Minitest::Test
1438
1439
  end
1439
1440
 
1440
1441
  def test_gvl_always_release
1442
+ skip_with_gc_stress
1441
1443
  skip if !IS_LINUX
1442
1444
 
1443
1445
  delays = []
@@ -1522,6 +1524,7 @@ class ConcurrencyTest < Minitest::Test
1522
1524
  end
1523
1525
 
1524
1526
  def test_progress_handler_simple
1527
+ skip_with_gc_stress
1525
1528
  db = Extralite::Database.new(':memory:')
1526
1529
 
1527
1530
  # SQLite's behaviour post 3.46.0 has changed, such that the first time the
@@ -1714,6 +1717,7 @@ class ConcurrencyTest < Minitest::Test
1714
1717
  SQL
1715
1718
 
1716
1719
  def test_progress_handler_timeout_interrupt
1720
+ skip_with_gc_stress
1717
1721
  db = Extralite::Database.new(':memory:')
1718
1722
  t0 = Time.now
1719
1723
  db.on_progress do
@@ -1756,6 +1760,7 @@ class ConcurrencyTest < Minitest::Test
1756
1760
  end
1757
1761
 
1758
1762
  def test_progress_handler_timeout_raise
1763
+ skip_with_gc_stress
1759
1764
  db = Extralite::Database.new(':memory:')
1760
1765
  t0 = Time.now
1761
1766
  db.on_progress do
@@ -1795,7 +1800,8 @@ class ConcurrencyTest < Minitest::Test
1795
1800
  end
1796
1801
 
1797
1802
  def test_progress_handler_busy_timeout
1798
- fn = Tempfile.new('extralite_test_progress_handler_busy_timeout').path
1803
+ skip_with_gc_stress
1804
+ fn = tempfile_path('extralite_test_progress_handler_busy_timeout')
1799
1805
  db1 = Extralite::Database.new(fn)
1800
1806
  db2 = Extralite::Database.new(fn)
1801
1807
 
@@ -1865,7 +1871,7 @@ class RactorTest < Minitest::Test
1865
1871
  def test_ractor_simple
1866
1872
  skip if SKIP_RACTOR_TESTS
1867
1873
 
1868
- fn = Tempfile.new('extralite_test_database_in_ractor').path
1874
+ fn = tempfile_path('extralite_test_database_in_ractor')
1869
1875
 
1870
1876
  r = Ractor.new do
1871
1877
  path = receive
@@ -1917,7 +1923,7 @@ class RactorTest < Minitest::Test
1917
1923
  def test_ractor_stress
1918
1924
  skip if SKIP_RACTOR_TESTS
1919
1925
 
1920
- fn = Tempfile.new('extralite_test_ractor_stress').path
1926
+ fn = tempfile_path('extralite_test_ractor_stress')
1921
1927
  random = Random.new.freeze
1922
1928
 
1923
1929
  ractors = (0..9).map do |ractor_number|
@@ -2307,7 +2313,7 @@ class StmtCacheText < Minitest::Test
2307
2313
  end
2308
2314
 
2309
2315
  def test_stmt_cache_close
2310
- fn = Tempfile.new('extralite_test_stmt_cache_close').path
2316
+ fn = tempfile_path('extralite_test_stmt_cache_close')
2311
2317
 
2312
2318
  db = Extralite::Database.new(fn)
2313
2319
  db.query('create table t (x)')
@@ -2324,7 +2330,7 @@ class StmtCacheText < Minitest::Test
2324
2330
  end
2325
2331
 
2326
2332
  def test_stmt_cache_gc
2327
- fn = Tempfile.new('extralite_test_stmt_cache_gc').path
2333
+ fn = tempfile_path('extralite_test_stmt_cache_gc')
2328
2334
 
2329
2335
  db = Extralite::Database.new(fn)
2330
2336
  db.query('create table t (x)')
@@ -2343,7 +2349,7 @@ class StmtCacheText < Minitest::Test
2343
2349
 
2344
2350
  def test_stmt_cache_concurrent_access
2345
2351
  # https://github.com/digital-fabric/extralite/issues/88
2346
- fn = Tempfile.new('extralite_test_stmt_cache_concurrent_access').path
2352
+ fn = tempfile_path('extralite_test_stmt_cache_concurrent_access')
2347
2353
 
2348
2354
  a = Extralite::Database.new(fn)
2349
2355
  a.execute("pragma journal_mode=wal")
@@ -2360,7 +2366,7 @@ class StmtCacheText < Minitest::Test
2360
2366
 
2361
2367
  def test_stmt_cache_concurrent_transactions
2362
2368
  # https://github.com/digital-fabric/extralite/issues/89
2363
- fn = Tempfile.new('extralite_test_stmt_cache_concurrent_access').path
2369
+ fn = tempfile_path('extralite_test_stmt_cache_concurrent_access')
2364
2370
 
2365
2371
  a = Extralite::Database.new(fn)
2366
2372
  a.execute('create table t (x)')
@@ -118,7 +118,7 @@ class IteratorTest < Minitest::Test
118
118
  end
119
119
 
120
120
  def test_return_from_block_issue_26
121
- fn = Tempfile.new('extralite_test_return_from_block_issue_26').path
121
+ fn = tempfile_path('extralite_test_return_from_block_issue_26')
122
122
  db = Extralite::Database.new(fn)
123
123
 
124
124
  λ = ->(sql) {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extralite
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.3
4
+ version: 3.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
@@ -88,6 +88,7 @@ extra_rdoc_files:
88
88
  files:
89
89
  - ".editorconfig"
90
90
  - ".github/FUNDING.yml"
91
+ - ".github/workflows/test-asan.yml"
91
92
  - ".github/workflows/test-bundle.yml"
92
93
  - ".github/workflows/test.yml"
93
94
  - ".gitignore"
@@ -174,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
175
  - !ruby/object:Gem::Version
175
176
  version: '0'
176
177
  requirements: []
177
- rubygems_version: 4.0.6
178
+ rubygems_version: 4.0.20
178
179
  specification_version: 4
179
180
  summary: Extra-lightweight SQLite3 wrapper for Ruby
180
181
  test_files: []