extralite 2.8.1 → 2.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49fbb44a887747091953d2ec2239050036dd1c5c37290d9f651521b47a84fdfb
4
- data.tar.gz: 5200205e84f47abad1a9e3c936999edd77defa53e187941d81d50a91926cd520
3
+ metadata.gz: a7adc40dd1b275c571a25ff887b4d7a82e25c0a562b878cfd9f8988828d105ce
4
+ data.tar.gz: c7dea7923b4c861a8aefe839c2395ec12fc84715514006e7961e96a728921861
5
5
  SHA512:
6
- metadata.gz: 1fd77a5ebe191923ba6159eb79b6c60ac5c8311280a5a8513262e6ff6accf2020422a9394df25308718971b98ff25ab50409f50bf81c931cb41274f7401334e4
7
- data.tar.gz: 0dde4d327858617ae1b3ad88432a705593303a312e93177a91c2fc25029cf505eaf952ce98a2cbbd4cced57d733a5a2c045cbf9d7909899c42972ca2c59e1cbd
6
+ metadata.gz: e4113425b3651e5875f44085691ce4e7bc7186391bf968d0882de07196908415c73af58add1367bad4a992ed6c3c30c2dd0ae115b56071a7ef20287febe35a6f
7
+ data.tar.gz: a4ab94ee82dddf6ed6c0edcb0127b7213101a41606a2995343d50fb14998bd5f84f01b9ad5c6c03a45e8b50fa189951d5bdd7097ac3392a389cde9e32ec3fb19
@@ -11,11 +11,13 @@ jobs:
11
11
  strategy:
12
12
  fail-fast: false
13
13
  matrix:
14
- os: [ubuntu-latest, macos-latest]
15
- ruby: ['3.0', '3.1', '3.2', '3.3']
14
+ # macos-latest uses arm64, macos-13 uses x86
15
+ os: [ubuntu-latest, macos-latest, macos-13]
16
+ ruby: ['3.0', '3.1', '3.2', '3.3', 'head']
16
17
 
17
- name: >-
18
- ${{matrix.os}}, ${{matrix.ruby}}
18
+ name: ${{matrix.os}}, ${{matrix.ruby}}
19
+
20
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
19
21
 
20
22
  runs-on: ${{matrix.os}}
21
23
  steps:
@@ -12,10 +12,11 @@ jobs:
12
12
  fail-fast: false
13
13
  matrix:
14
14
  os: [ubuntu-latest, macos-latest]
15
- ruby: ['3.0', '3.1', '3.2', '3.3', 'head']
15
+ ruby: ['3.2', '3.3', '3.4', 'head']
16
16
 
17
- name: >-
18
- ${{matrix.os}}, ${{matrix.ruby}}
17
+ name: ${{matrix.os}}, ${{matrix.ruby}}
18
+
19
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
19
20
 
20
21
  runs-on: ${{matrix.os}}
21
22
  steps:
@@ -23,7 +24,8 @@ jobs:
23
24
  - uses: ruby/setup-ruby@v1
24
25
  with:
25
26
  ruby-version: ${{matrix.ruby}}
26
- bundler-cache: true # 'bundle install' and cache
27
+ bundler-cache: true
28
+ apt-get: libsqlite3-dev
27
29
  - name: Compile C-extension
28
30
  run: bundle exec rake compile
29
31
  - name: Run tests
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 2.10 2025-02-17
2
+
3
+ - Update bundled SQLite to version 3.49.0.
4
+
5
+ ## 2.9 2025-01-18
6
+
7
+ - Update dependencies, test matrix.
8
+ - Update bundled SQLite to version 3.48.0.
9
+ - Optimize getting column names when returning rows as hashes.
10
+
11
+ ## 2.8.2 2024-06-02
12
+
13
+ - Update bundled SQLite to version 3.46.0. [#74](https://github.com/digital-fabric/extralite/pull/74)
14
+
1
15
  ## 2.8.1 2024-04-15
2
16
 
3
17
  - Update bundled sqlite to version 3.45.3.
data/README.md CHANGED
@@ -32,7 +32,7 @@ databases.
32
32
  Extralite comes in two flavors: the `extralite` gem which uses the
33
33
  system-installed sqlite3 library, and the `extralite-bundle` gem which bundles
34
34
  the latest version of SQLite
35
- ([3.45.3](https://sqlite.org/releaselog/3_45_3.html)), offering access to the
35
+ ([3.49.0](https://sqlite.org/releaselog/3_49_0.html)), offering access to the
36
36
  latest features and enhancements.
37
37
 
38
38
  ## Features
@@ -135,7 +135,44 @@ inline void bind_all_parameters_from_object(sqlite3_stmt *stmt, VALUE obj) {
135
135
  bind_parameter_value(stmt, 1, obj);
136
136
  }
137
137
 
138
- static inline VALUE get_column_names(sqlite3_stmt *stmt, int column_count) {
138
+ #define MAX_EMBEDDED_COLUMN_NAMES 12
139
+
140
+ struct column_names {
141
+ int count;
142
+ union {
143
+ VALUE array;
144
+ VALUE names[MAX_EMBEDDED_COLUMN_NAMES];
145
+ };
146
+ };
147
+
148
+ static inline void column_names_setup(struct column_names *names, int count) {
149
+ names->count = count;
150
+ names->array = (count > MAX_EMBEDDED_COLUMN_NAMES) ? rb_ary_new2(count) : Qnil;
151
+ }
152
+
153
+ static inline void column_names_set(struct column_names *names, int idx, VALUE value) {
154
+ if (names->count <= MAX_EMBEDDED_COLUMN_NAMES)
155
+ names->names[idx] = value;
156
+ else
157
+ rb_ary_push(names->array, value);
158
+ }
159
+
160
+ static inline VALUE column_names_get(struct column_names *names, int idx) {
161
+ return (names->count <= MAX_EMBEDDED_COLUMN_NAMES) ?
162
+ names->names[idx] : RARRAY_AREF(names->array, idx);
163
+ }
164
+
165
+ static inline struct column_names get_column_names(sqlite3_stmt *stmt, int column_count) {
166
+ struct column_names names;
167
+ column_names_setup(&names, column_count);
168
+ for (int i = 0; i < column_count; i++) {
169
+ VALUE name = ID2SYM(rb_intern(sqlite3_column_name(stmt, i)));
170
+ column_names_set(&names, i, name);
171
+ }
172
+ return names;
173
+ }
174
+
175
+ static inline VALUE get_column_names_array(sqlite3_stmt *stmt, int column_count) {
139
176
  VALUE arr = rb_ary_new2(column_count);
140
177
  for (int i = 0; i < column_count; i++) {
141
178
  VALUE name = ID2SYM(rb_intern(sqlite3_column_name(stmt, i)));
@@ -144,11 +181,19 @@ static inline VALUE get_column_names(sqlite3_stmt *stmt, int column_count) {
144
181
  return arr;
145
182
  }
146
183
 
147
- static inline VALUE row_to_hash(sqlite3_stmt *stmt, int column_count, VALUE column_names) {
184
+ static inline VALUE row_to_hash(sqlite3_stmt *stmt, int column_count, struct column_names *names) {
148
185
  VALUE row = rb_hash_new();
149
- for (int i = 0; i < column_count; i++) {
150
- VALUE value = get_column_value(stmt, i, sqlite3_column_type(stmt, i));
151
- rb_hash_aset(row, RARRAY_AREF(column_names, i), value);
186
+ if (names->count <= MAX_EMBEDDED_COLUMN_NAMES) {
187
+ for (int i = 0; i < column_count; i++) {
188
+ VALUE value = get_column_value(stmt, i, sqlite3_column_type(stmt, i));
189
+ rb_hash_aset(row, names->names[i], value);
190
+ }
191
+ }
192
+ else {
193
+ for (int i = 0; i < column_count; i++) {
194
+ VALUE value = get_column_value(stmt, i, sqlite3_column_type(stmt, i));
195
+ rb_hash_aset(row, RARRAY_AREF(names->array, i), value);
196
+ }
152
197
  }
153
198
  return row;
154
199
  }
@@ -327,12 +372,12 @@ VALUE safe_query_hash(query_ctx *ctx) {
327
372
  VALUE array = ROW_MULTI_P(ctx->row_mode) ? rb_ary_new() : Qnil;
328
373
  VALUE row = Qnil;
329
374
  int column_count = sqlite3_column_count(ctx->stmt);
330
- VALUE column_names = get_column_names(ctx->stmt, column_count);
375
+ struct column_names names = get_column_names(ctx->stmt, column_count);
331
376
  int row_count = 0;
332
377
  int do_transform = !NIL_P(ctx->transform_proc);
333
378
 
334
379
  while (stmt_iterate(ctx)) {
335
- row = row_to_hash(ctx->stmt, column_count, column_names);
380
+ row = row_to_hash(ctx->stmt, column_count, &names);
336
381
  if (do_transform)
337
382
  row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
338
383
  row_count++;
@@ -350,7 +395,7 @@ VALUE safe_query_hash(query_ctx *ctx) {
350
395
  return ROW_MULTI_P(ctx->row_mode) ? array : ctx->self;
351
396
  }
352
397
 
353
- RB_GC_GUARD(column_names);
398
+ RB_GC_GUARD(names.array);
354
399
  RB_GC_GUARD(row);
355
400
  RB_GC_GUARD(array);
356
401
  return ROW_MULTI_P(ctx->row_mode) ? array : Qnil;
@@ -445,21 +490,18 @@ VALUE safe_query_array(query_ctx *ctx) {
445
490
  }
446
491
 
447
492
  VALUE safe_query_single_row_hash(query_ctx *ctx) {
448
- int column_count;
493
+ int column_count = sqlite3_column_count(ctx->stmt);
449
494
  VALUE row = Qnil;
450
- VALUE column_names;
451
-
452
- column_count = sqlite3_column_count(ctx->stmt);
453
- column_names = get_column_names(ctx->stmt, column_count);
495
+ struct column_names names = get_column_names(ctx->stmt, column_count);
454
496
 
455
497
  if (stmt_iterate(ctx)) {
456
- row = row_to_hash(ctx->stmt, column_count, column_names);
498
+ row = row_to_hash(ctx->stmt, column_count, &names);
457
499
  if (!NIL_P(ctx->transform_proc))
458
500
  row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
459
501
  }
460
502
 
461
503
  RB_GC_GUARD(row);
462
- RB_GC_GUARD(column_names);
504
+ RB_GC_GUARD(names.array);
463
505
  return row;
464
506
  }
465
507
 
@@ -506,17 +548,17 @@ static inline VALUE batch_iterate_hash(query_ctx *ctx) {
506
548
  VALUE rows = rb_ary_new();
507
549
  VALUE row = Qnil;
508
550
  int column_count = sqlite3_column_count(ctx->stmt);
509
- VALUE column_names = get_column_names(ctx->stmt, column_count);
551
+ struct column_names names = get_column_names(ctx->stmt, column_count);
510
552
  const int do_transform = !NIL_P(ctx->transform_proc);
511
553
 
512
554
  while (stmt_iterate(ctx)) {
513
- row = row_to_hash(ctx->stmt, column_count, column_names);
555
+ row = row_to_hash(ctx->stmt, column_count, &names);
514
556
  if (do_transform)
515
557
  row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
516
558
  rb_ary_push(rows, row);
517
559
  }
518
560
 
519
- RB_GC_GUARD(column_names);
561
+ RB_GC_GUARD(names.array);
520
562
  RB_GC_GUARD(row);
521
563
  RB_GC_GUARD(rows);
522
564
  return rows;
@@ -733,7 +775,7 @@ VALUE safe_batch_query_splat(query_ctx *ctx) {
733
775
  }
734
776
 
735
777
  VALUE safe_query_columns(query_ctx *ctx) {
736
- return get_column_names(ctx->stmt, sqlite3_column_count(ctx->stmt));
778
+ return get_column_names_array(ctx->stmt, sqlite3_column_count(ctx->stmt));
737
779
  }
738
780
 
739
781
  VALUE safe_query_changes(query_ctx *ctx) {
data/gemspec.rb CHANGED
@@ -17,9 +17,9 @@ def common_spec(s)
17
17
  s.require_paths = ['lib']
18
18
  s.required_ruby_version = '>= 3.0'
19
19
 
20
- s.add_development_dependency 'rake-compiler', '1.2.7'
21
- s.add_development_dependency 'minitest', '5.22.2'
22
- s.add_development_dependency 'simplecov', '0.17.1'
23
- s.add_development_dependency 'yard', '0.9.34'
24
- s.add_development_dependency 'sequel', '5.77.0'
20
+ s.add_development_dependency 'rake-compiler', '1.2.9'
21
+ s.add_development_dependency 'minitest', '5.25.4'
22
+ s.add_development_dependency 'simplecov', '0.22.0'
23
+ s.add_development_dependency 'yard', '0.9.37'
24
+ s.add_development_dependency 'sequel', '5.88.0'
25
25
  end
@@ -1,4 +1,4 @@
1
1
  module Extralite
2
2
  # Extralite version
3
- VERSION = '2.8.1'
3
+ VERSION = '2.10'
4
4
  end
Binary file
Binary file
Binary file
@@ -40,6 +40,19 @@ class DatabaseTest < Minitest::Test
40
40
  assert_equal [], r
41
41
  end
42
42
 
43
+ def test_query_hash_with_many_columns
44
+ # this tests correct processing cof column names when column count is more than
45
+ # MAX_EMBEDDED_COLUMN_NAMES
46
+ r = @db.query_hash("
47
+ select 1 as a, 2 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i, 10 as j,
48
+ 11 as k, 12 as l, 13 as m, 14 as n, 15 as o, 16 as p, 17 as q, 18 as r, 19 as s, 20 as t
49
+ ")
50
+ assert_equal [{
51
+ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10,
52
+ k: 11, l: 12, m: 13, n: 14, o: 15, p: 16, q: 17, r: 18, s: 19, t: 20
53
+ }], r
54
+ end
55
+
43
56
  def test_query_array
44
57
  r = @db.query_array('select * from t')
45
58
  assert_equal [[1, 2, 3], [4, 5, 6]], r
@@ -277,10 +290,14 @@ class DatabaseTest < Minitest::Test
277
290
 
278
291
  def test_extension_loading
279
292
  case RUBY_PLATFORM
280
- when /linux/
281
- @db.load_extension(File.join(__dir__, 'extensions/text.so'))
282
- when /darwin/
283
- @db.load_extension(File.join(__dir__, 'extensions/text.dylib'))
293
+ when /aarch64-linux/
294
+ @db.load_extension(File.join(__dir__, 'extensions/arm64/text.so'))
295
+ when /x86_64-linux/
296
+ @db.load_extension(File.join(__dir__, 'extensions/x86/text.so'))
297
+ when /arm64-darwin/
298
+ @db.load_extension(File.join(__dir__, 'extensions/arm64/text.dylib'))
299
+ when /x86_64-darwin/
300
+ @db.load_extension(File.join(__dir__, 'extensions/x86/text.dylib'))
284
301
  end
285
302
 
286
303
  r = @db.query_single_splat("select reverse('abcd')")
@@ -359,7 +376,6 @@ class DatabaseTest < Minitest::Test
359
376
  [1, '2', 3],
360
377
  ['4', 5, 6]
361
378
  ]
362
-
363
379
  changes = @db.batch_execute('insert into foo values (?, ?, ?)', records)
364
380
 
365
381
  assert_equal 2, changes
@@ -369,6 +385,23 @@ class DatabaseTest < Minitest::Test
369
385
  ], @db.query('select * from foo')
370
386
  end
371
387
 
388
+ def test_batch_execute_with_array_of_hashes
389
+ @db.query('create table foo (a, b, c)')
390
+ assert_equal [], @db.query('select * from foo')
391
+
392
+ records = [
393
+ { a: 1, b: '2', c: 3 },
394
+ { a: '4', b: 5, c: 6 }
395
+ ]
396
+ changes = @db.batch_execute('insert into foo values (:a, :b, :c)', records)
397
+
398
+ # assert_equal 2, changes
399
+ assert_equal [
400
+ { a: 1, b: '2', c: 3 },
401
+ { a: '4', b: 5, c: 6 }
402
+ ], @db.query('select * from foo')
403
+ end
404
+
372
405
  def test_batch_execute_single_values
373
406
  @db.query('create table foo (bar)')
374
407
  assert_equal [], @db.query('select * from foo')
@@ -1355,6 +1388,12 @@ class ConcurrencyTest < Minitest::Test
1355
1388
  def test_progress_handler_simple
1356
1389
  db = Extralite::Database.new(':memory:')
1357
1390
 
1391
+ # SQLite's behaviour post 3.46.0 has changed, such that the first time the
1392
+ # query is ran, the progress handler is called more times than in later
1393
+ # invocations, so here we run it once before measuring, in order to have
1394
+ # reliable figures.
1395
+ result = db.query_single('select 1 as a, 2 as b, 3 as c')
1396
+
1358
1397
  buf = []
1359
1398
  db.on_progress(period: 1) { buf << :progress }
1360
1399
 
@@ -1373,6 +1412,12 @@ class ConcurrencyTest < Minitest::Test
1373
1412
  def test_progress_handler_normal_mode
1374
1413
  db = Extralite::Database.new(':memory:')
1375
1414
 
1415
+ # SQLite's behaviour post 3.46.0 has changed, such that the first time the
1416
+ # query is ran, the progress handler is called more times than in later
1417
+ # invocations, so here we run it once before measuring, in order to have
1418
+ # reliable figures.
1419
+ db.query('select 1 as a')
1420
+
1376
1421
  count = 0
1377
1422
  db.on_progress(period: 1) { count += 1 }
1378
1423
  db.query('select 1 as a')
@@ -1393,6 +1438,12 @@ class ConcurrencyTest < Minitest::Test
1393
1438
  def test_progress_handler_at_least_once_mode
1394
1439
  db = Extralite::Database.new(':memory:')
1395
1440
 
1441
+ # SQLite's behaviour post 3.46.0 has changed, such that the first time the
1442
+ # query is ran, the progress handler is called more times than in later
1443
+ # invocations, so here we run it once before measuring, in order to have
1444
+ # reliable figures.
1445
+ db.query('select 1 as a')
1446
+
1396
1447
  count = 0
1397
1448
  db.on_progress(period: 1) { count += 1 }
1398
1449
  db.query('select 1 as a')
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extralite
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.1
4
+ version: '2.10'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-04-16 00:00:00.000000000 Z
10
+ date: 2025-02-17 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rake-compiler
@@ -16,71 +15,70 @@ dependencies:
16
15
  requirements:
17
16
  - - '='
18
17
  - !ruby/object:Gem::Version
19
- version: 1.2.7
18
+ version: 1.2.9
20
19
  type: :development
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - '='
25
24
  - !ruby/object:Gem::Version
26
- version: 1.2.7
25
+ version: 1.2.9
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: minitest
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - '='
32
31
  - !ruby/object:Gem::Version
33
- version: 5.22.2
32
+ version: 5.25.4
34
33
  type: :development
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - '='
39
38
  - !ruby/object:Gem::Version
40
- version: 5.22.2
39
+ version: 5.25.4
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: simplecov
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
44
  - - '='
46
45
  - !ruby/object:Gem::Version
47
- version: 0.17.1
46
+ version: 0.22.0
48
47
  type: :development
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
51
  - - '='
53
52
  - !ruby/object:Gem::Version
54
- version: 0.17.1
53
+ version: 0.22.0
55
54
  - !ruby/object:Gem::Dependency
56
55
  name: yard
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
58
  - - '='
60
59
  - !ruby/object:Gem::Version
61
- version: 0.9.34
60
+ version: 0.9.37
62
61
  type: :development
63
62
  prerelease: false
64
63
  version_requirements: !ruby/object:Gem::Requirement
65
64
  requirements:
66
65
  - - '='
67
66
  - !ruby/object:Gem::Version
68
- version: 0.9.34
67
+ version: 0.9.37
69
68
  - !ruby/object:Gem::Dependency
70
69
  name: sequel
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
72
  - - '='
74
73
  - !ruby/object:Gem::Version
75
- version: 5.77.0
74
+ version: 5.88.0
76
75
  type: :development
77
76
  prerelease: false
78
77
  version_requirements: !ruby/object:Gem::Requirement
79
78
  requirements:
80
79
  - - '='
81
80
  - !ruby/object:Gem::Version
82
- version: 5.77.0
83
- description:
81
+ version: 5.88.0
84
82
  email: sharon@noteflakes.com
85
83
  executables: []
86
84
  extensions:
@@ -123,8 +121,10 @@ files:
123
121
  - lib/extralite.rb
124
122
  - lib/extralite/version.rb
125
123
  - lib/sequel/adapters/extralite.rb
126
- - test/extensions/text.dylib
127
- - test/extensions/text.so
124
+ - test/extensions/arm64/text.dylib
125
+ - test/extensions/arm64/text.so
126
+ - test/extensions/x86/text.dylib
127
+ - test/extensions/x86/text.so
128
128
  - test/fixtures/image.png
129
129
  - test/helper.rb
130
130
  - test/issue-38.rb
@@ -151,7 +151,6 @@ metadata:
151
151
  homepage_uri: https://github.com/digital-fabric/extralite
152
152
  documentation_uri: https://www.rubydoc.info/gems/extralite
153
153
  changelog_uri: https://github.com/digital-fabric/extralite/blob/master/CHANGELOG.md
154
- post_install_message:
155
154
  rdoc_options:
156
155
  - "--title"
157
156
  - Extralite
@@ -170,8 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
170
169
  - !ruby/object:Gem::Version
171
170
  version: '0'
172
171
  requirements: []
173
- rubygems_version: 3.5.3
174
- signing_key:
172
+ rubygems_version: 3.6.2
175
173
  specification_version: 4
176
174
  summary: Extra-lightweight SQLite3 wrapper for Ruby
177
175
  test_files: []
Binary file