extralite-bundle 2.8.2 → 2.11

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: 5308b46b6b15860563f1ae4064e0be95da162885743940a8aa8e9f24e7abfb6f
4
- data.tar.gz: a4a672e3a45b1cb47f819ebdb288d04bcf5a78af630da28108a67adc1b9994be
3
+ metadata.gz: 1542a432d7813d5bcdc27667661e0a1d2c1f0f85716c9c3b7ceebb6b6452baa6
4
+ data.tar.gz: 5ae2a6c6ed93943f964aaf472da3d14ae09c12ab42da94e1d3a635ae699d1f61
5
5
  SHA512:
6
- metadata.gz: 625acad5183577de37248ccfdffc5184d25aee62235b0862378e8199c2738f68fa2bd37187f0eb5a03d45c0d0a3a8dfb33569bf0141915d745bf185c47b58d67
7
- data.tar.gz: 25655a268ff6bd068c782488ea66e90d19f78483206a5ac0560c9eb157d13e09459e11522eaae3c8281090797538f8bace09f05e99a2e0f871bd6238e6b750b0
6
+ metadata.gz: 5a704616c0b2641461a3d565e503694d7ebfe30619afbfafd71bbda481f8f962c87b9fb8f15b0266c6ff49a79f504bbef767937d97bbd15dd96a7fef1215f74c
7
+ data.tar.gz: 9c3d99dd4a328b00100c1118840022a167f3fc7a863a52fcfa0d07e09c2859043300e66b77edfb9e69a8583e07577daed411c2fd623431d4bd3807a1cdd382da
@@ -13,7 +13,7 @@ jobs:
13
13
  matrix:
14
14
  # macos-latest uses arm64, macos-13 uses x86
15
15
  os: [ubuntu-latest, macos-latest, macos-13]
16
- ruby: ['3.0', '3.1', '3.2', '3.3', 'head']
16
+ ruby: ['3.2', '3.3', '3.4', 'head']
17
17
 
18
18
  name: ${{matrix.os}}, ${{matrix.ruby}}
19
19
 
@@ -11,9 +11,8 @@ jobs:
11
11
  strategy:
12
12
  fail-fast: false
13
13
  matrix:
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']
14
+ os: [ubuntu-latest, macos-latest]
15
+ ruby: ['3.2', '3.3', '3.4', 'head']
17
16
 
18
17
  name: ${{matrix.os}}, ${{matrix.ruby}}
19
18
 
@@ -25,7 +24,8 @@ jobs:
25
24
  - uses: ruby/setup-ruby@v1
26
25
  with:
27
26
  ruby-version: ${{matrix.ruby}}
28
- bundler-cache: true # 'bundle install' and cache
27
+ bundler-cache: true
28
+ apt-get: libsqlite3-dev
29
29
  - name: Compile C-extension
30
30
  run: bundle exec rake compile
31
31
  - name: Run tests
data/CHANGELOG.md CHANGED
@@ -1,6 +1,21 @@
1
+ ## 2.11 2025-03-14
2
+
3
+ - Remove support for Ruby versions older than 3.2.
4
+ - Expand SQL given to trace proc [#80](https://github.com/digital-fabric/extralite/issues/80)
5
+
6
+ ## 2.10 2025-02-17
7
+
8
+ - Update bundled SQLite to version 3.49.0.
9
+
10
+ ## 2.9 2025-01-18
11
+
12
+ - Update dependencies, test matrix.
13
+ - Update bundled SQLite to version 3.48.0.
14
+ - Optimize getting column names when returning rows as hashes.
15
+
1
16
  ## 2.8.2 2024-06-02
2
17
 
3
- - Update bundled SQLite to version 3.46.0
18
+ - Update bundled SQLite to version 3.46.0. [#74](https://github.com/digital-fabric/extralite/pull/74)
4
19
 
5
20
  ## 2.8.1 2024-04-15
6
21
 
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.46.0](https://sqlite.org/releaselog/3_46_0.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;
@@ -587,7 +629,7 @@ static inline VALUE batch_run_array(query_ctx *ctx, enum batch_mode batch_mode)
587
629
  for (int i = 0; i < count; i++) {
588
630
  sqlite3_reset(ctx->stmt);
589
631
  sqlite3_clear_bindings(ctx->stmt);
590
- Database_issue_query(ctx->db, ctx->sql);
632
+ Database_issue_query(ctx->db, ctx->stmt);
591
633
  bind_all_parameters_from_object(ctx->stmt, RARRAY_AREF(ctx->params, i));
592
634
 
593
635
  batch_iterate(ctx, batch_mode, &rows);
@@ -624,7 +666,7 @@ static VALUE batch_run_each_iter(RB_BLOCK_CALL_FUNC_ARGLIST(yield_value, vctx))
624
666
 
625
667
  sqlite3_reset(each_ctx->ctx->stmt);
626
668
  sqlite3_clear_bindings(each_ctx->ctx->stmt);
627
- Database_issue_query(each_ctx->ctx->db, each_ctx->ctx->sql);
669
+ Database_issue_query(each_ctx->ctx->db, each_ctx->ctx->stmt);
628
670
  bind_all_parameters_from_object(each_ctx->ctx->stmt, yield_value);
629
671
 
630
672
  batch_iterate(each_ctx->ctx, each_ctx->batch_mode, &rows);
@@ -670,7 +712,7 @@ static inline VALUE batch_run_proc(query_ctx *ctx, enum batch_mode batch_mode) {
670
712
 
671
713
  sqlite3_reset(ctx->stmt);
672
714
  sqlite3_clear_bindings(ctx->stmt);
673
- Database_issue_query(ctx->db, ctx->sql);
715
+ Database_issue_query(ctx->db, ctx->stmt);
674
716
  bind_all_parameters_from_object(ctx->stmt, params);
675
717
 
676
718
  batch_iterate(ctx, batch_mode, &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) {
@@ -289,14 +289,16 @@ static inline VALUE Database_perform_query(int argc, VALUE *argv, VALUE self, VA
289
289
 
290
290
  sql = rb_funcall(argv[0], ID_strip, 0);
291
291
  if (RSTRING_LEN(sql) == 0) return Qnil;
292
+ // sql = argv[0];
292
293
 
293
- Database_issue_query(db, sql);
294
294
  prepare_multi_stmt(DB_GVL_MODE(db), db->sqlite3_db, &stmt, sql);
295
295
  RB_GC_GUARD(sql);
296
296
 
297
297
  if (stmt == NULL) return Qnil;
298
298
 
299
299
  bind_all_parameters(stmt, argc - 1, argv + 1);
300
+ Database_issue_query(db, stmt);
301
+
300
302
  query_ctx ctx = QUERY_CTX(
301
303
  self, sql, db, stmt, Qnil, transform,
302
304
  query_mode, ROW_YIELD_OR_MODE(ROW_MULTI), ALL_ROWS
@@ -1102,8 +1104,12 @@ static inline enum progress_handler_mode symbol_to_progress_mode(VALUE mode) {
1102
1104
  rb_raise(eArgumentError, "Invalid progress handler mode");
1103
1105
  }
1104
1106
 
1105
- inline void Database_issue_query(Database_t *db, VALUE sql) {
1106
- if (db->trace_proc != Qnil) rb_funcall(db->trace_proc, ID_call, 1, sql);
1107
+ inline void Database_issue_query(Database_t *db, sqlite3_stmt *stmt) {
1108
+ if (db->trace_proc != Qnil) {
1109
+ VALUE sql = rb_str_new_cstr(sqlite3_expanded_sql(stmt));
1110
+ rb_funcall(db->trace_proc, ID_call, 1, sql);
1111
+ RB_GC_GUARD(sql);
1112
+ }
1107
1113
  switch (db->progress_handler.mode) {
1108
1114
  case PROGRESS_AT_LEAST_ONCE:
1109
1115
  case PROGRESS_ONCE:
@@ -180,7 +180,7 @@ void bind_all_parameters_from_object(sqlite3_stmt *stmt, VALUE obj);
180
180
  int stmt_iterate(query_ctx *ctx);
181
181
  VALUE cleanup_stmt(query_ctx *ctx);
182
182
 
183
- void Database_issue_query(Database_t *db, VALUE sql);
183
+ void Database_issue_query(Database_t *db, sqlite3_stmt *stmt);
184
184
  sqlite3 *Database_sqlite3_db(VALUE self);
185
185
  enum gvl_mode Database_prepare_gvl_mode(Database_t *db);
186
186
  Database_t *self_to_database(VALUE self);
@@ -123,7 +123,7 @@ VALUE Query_initialize(VALUE self, VALUE db, VALUE sql, VALUE mode) {
123
123
  static inline void query_reset(Query_t *query) {
124
124
  if (!query->stmt)
125
125
  prepare_single_stmt(DB_GVL_MODE(query), query->sqlite3_db, &query->stmt, query->sql);
126
- Database_issue_query(query->db_struct, query->sql);
126
+ Database_issue_query(query->db_struct, query->stmt);
127
127
  sqlite3_reset(query->stmt);
128
128
  query->eof = 0;
129
129
  }
@@ -131,7 +131,7 @@ static inline void query_reset(Query_t *query) {
131
131
  static inline void query_reset_and_bind(Query_t *query, int argc, VALUE * argv) {
132
132
  if (!query->stmt)
133
133
  prepare_single_stmt(DB_GVL_MODE(query), query->sqlite3_db, &query->stmt, query->sql);
134
- Database_issue_query(query->db_struct, query->sql);
134
+ Database_issue_query(query->db_struct, query->stmt);
135
135
  sqlite3_reset(query->stmt);
136
136
  query->eof = 0;
137
137
  if (argc > 0) {