extralite 2.7.1 → 2.8.1
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/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +17 -4
- data/README.md +79 -42
- data/examples/kv_store.rb +1 -1
- data/examples/pubsub_store_polyphony.rb +7 -7
- data/examples/pubsub_store_threads.rb +3 -3
- data/ext/extralite/changeset.c +1 -1
- data/ext/extralite/common.c +27 -27
- data/ext/extralite/database.c +134 -61
- data/ext/extralite/extralite.h +10 -17
- data/ext/extralite/query.c +17 -17
- data/gemspec.rb +1 -1
- data/lib/extralite/version.rb +1 -1
- data/lib/extralite.rb +158 -3
- data/test/{perf_ary.rb → perf_array.rb} +1 -1
- data/test/perf_splat.rb +63 -0
- data/test/{perf_argv_transform.rb → perf_splat_transform.rb} +7 -7
- data/test/test_database.rb +193 -120
- data/test/test_iterator.rb +12 -12
- data/test/test_query.rb +92 -92
- metadata +7 -7
- data/lib/extralite/sqlite3_constants.rb +0 -157
data/ext/extralite/database.c
CHANGED
@@ -22,12 +22,16 @@ ID ID_to_s;
|
|
22
22
|
ID ID_track;
|
23
23
|
|
24
24
|
VALUE SYM_at_least_once;
|
25
|
+
VALUE SYM_full;
|
25
26
|
VALUE SYM_gvl_release_threshold;
|
26
27
|
VALUE SYM_once;
|
27
28
|
VALUE SYM_none;
|
28
29
|
VALUE SYM_normal;
|
30
|
+
VALUE SYM_passive;
|
29
31
|
VALUE SYM_pragma;
|
30
32
|
VALUE SYM_read_only;
|
33
|
+
VALUE SYM_restart;
|
34
|
+
VALUE SYM_truncate;
|
31
35
|
VALUE SYM_wal;
|
32
36
|
|
33
37
|
struct progress_handler global_progress_handler = {
|
@@ -290,6 +294,8 @@ static inline VALUE Database_perform_query(int argc, VALUE *argv, VALUE self, VA
|
|
290
294
|
prepare_multi_stmt(DB_GVL_MODE(db), db->sqlite3_db, &stmt, sql);
|
291
295
|
RB_GC_GUARD(sql);
|
292
296
|
|
297
|
+
if (stmt == NULL) return Qnil;
|
298
|
+
|
293
299
|
bind_all_parameters(stmt, argc - 1, argv + 1);
|
294
300
|
query_ctx ctx = QUERY_CTX(
|
295
301
|
self, sql, db, stmt, Qnil, transform,
|
@@ -342,18 +348,18 @@ VALUE Database_query(int argc, VALUE *argv, VALUE self) {
|
|
342
348
|
* splatted:
|
343
349
|
*
|
344
350
|
* transform = ->(a, b, c) { a * 100 + b * 10 + c }
|
345
|
-
* db.
|
351
|
+
* db.query_splat(transform, 'select a, b, c from foo where c = ?', 42)
|
346
352
|
*
|
347
|
-
* @overload
|
353
|
+
* @overload query_splat(sql, ...)
|
348
354
|
* @param sql [String] SQL statement
|
349
355
|
* @return [Array<Array, any>, Integer] rows or total changes
|
350
|
-
* @overload
|
356
|
+
* @overload query_splat(transform, sql, ...)
|
351
357
|
* @param transform [Proc] transform proc
|
352
358
|
* @param sql [String] SQL statement
|
353
359
|
* @return [Array<Array, any>, Integer] rows or total changes
|
354
360
|
*/
|
355
|
-
VALUE
|
356
|
-
return Database_perform_query(argc, argv, self,
|
361
|
+
VALUE Database_query_splat(int argc, VALUE *argv, VALUE self) {
|
362
|
+
return Database_perform_query(argc, argv, self, safe_query_splat, QUERY_SPLAT);
|
357
363
|
}
|
358
364
|
|
359
365
|
/* Runs a query returning rows as arrays. If a block is given, it will be called
|
@@ -364,26 +370,26 @@ VALUE Database_query_argv(int argc, VALUE *argv, VALUE self) {
|
|
364
370
|
* parameters are given as an array, the query should specify parameters using
|
365
371
|
* `?`:
|
366
372
|
*
|
367
|
-
* db.
|
373
|
+
* db.query_array('select * from foo where x = ?', 42)
|
368
374
|
*
|
369
375
|
* Named placeholders are specified using `:`. The placeholder values are
|
370
376
|
* specified using a hash, where keys are either strings are symbols. String
|
371
377
|
* keys can include or omit the `:` prefix. The following are equivalent:
|
372
378
|
*
|
373
|
-
* db.
|
374
|
-
* db.
|
375
|
-
* db.
|
379
|
+
* db.query_array('select * from foo where x = :bar', bar: 42)
|
380
|
+
* db.query_array('select * from foo where x = :bar', 'bar' => 42)
|
381
|
+
* db.query_array('select * from foo where x = :bar', ':bar' => 42)
|
376
382
|
*
|
377
|
-
* @overload
|
383
|
+
* @overload query_array(sql, ...)
|
378
384
|
* @param sql [String] SQL statement
|
379
385
|
* @return [Array<Array>, Integer] rows or total changes
|
380
|
-
* @overload
|
386
|
+
* @overload query_array(transform, sql, ...)
|
381
387
|
* @param transform [Proc] transform proc
|
382
388
|
* @param sql [String] SQL statement
|
383
389
|
* @return [Array<Array>, Integer] rows or total changes
|
384
390
|
*/
|
385
|
-
VALUE
|
386
|
-
return Database_perform_query(argc, argv, self,
|
391
|
+
VALUE Database_query_array(int argc, VALUE *argv, VALUE self) {
|
392
|
+
return Database_perform_query(argc, argv, self, safe_query_array, QUERY_ARRAY);
|
387
393
|
}
|
388
394
|
|
389
395
|
/* Runs a query returning a single row as a hash.
|
@@ -419,23 +425,23 @@ VALUE Database_query_single(int argc, VALUE *argv, VALUE self) {
|
|
419
425
|
* parameters are given as an array, the query should specify parameters using
|
420
426
|
* `?`:
|
421
427
|
*
|
422
|
-
* db.
|
428
|
+
* db.query_single_splat('select * from foo where x = ?', 42)
|
423
429
|
*
|
424
430
|
* Named placeholders are specified using `:`. The placeholder values are
|
425
431
|
* specified using keyword arguments:
|
426
432
|
*
|
427
|
-
* db.
|
433
|
+
* db.query_single_splat('select * from foo where x = :bar', bar: 42)
|
428
434
|
*
|
429
|
-
* @overload
|
435
|
+
* @overload query_single_splat(sql, ...) -> row
|
430
436
|
* @param sql [String] SQL statement
|
431
437
|
* @return [Array, any] row
|
432
|
-
* @overload
|
438
|
+
* @overload query_single_splat(transform, sql, ...) -> row
|
433
439
|
* @param transform [Proc] transform proc
|
434
440
|
* @param sql [String] SQL statement
|
435
441
|
* @return [Array, any] row
|
436
442
|
*/
|
437
|
-
VALUE
|
438
|
-
return Database_perform_query(argc, argv, self,
|
443
|
+
VALUE Database_query_single_splat(int argc, VALUE *argv, VALUE self) {
|
444
|
+
return Database_perform_query(argc, argv, self, safe_query_single_row_splat, QUERY_SPLAT);
|
439
445
|
}
|
440
446
|
|
441
447
|
/* Runs a query returning a single row as an array.
|
@@ -445,23 +451,23 @@ VALUE Database_query_single_argv(int argc, VALUE *argv, VALUE self) {
|
|
445
451
|
* parameters are given as an array, the query should specify parameters using
|
446
452
|
* `?`:
|
447
453
|
*
|
448
|
-
* db.
|
454
|
+
* db.query_single_array('select * from foo where x = ?', 42)
|
449
455
|
*
|
450
456
|
* Named placeholders are specified using `:`. The placeholder values are
|
451
457
|
* specified using keyword arguments:
|
452
458
|
*
|
453
|
-
* db.
|
459
|
+
* db.query_single_array('select * from foo where x = :bar', bar: 42)
|
454
460
|
*
|
455
|
-
* @overload
|
461
|
+
* @overload query_single_array(sql, ...) -> row
|
456
462
|
* @param sql [String] SQL statement
|
457
463
|
* @return [Array, any] row
|
458
|
-
* @overload
|
464
|
+
* @overload query_single_array(transform, sql, ...) -> row
|
459
465
|
* @param transform [Proc] transform proc
|
460
466
|
* @param sql [String] SQL statement
|
461
467
|
* @return [Array, any] row
|
462
468
|
*/
|
463
|
-
VALUE
|
464
|
-
return Database_perform_query(argc, argv, self,
|
469
|
+
VALUE Database_query_single_array(int argc, VALUE *argv, VALUE self) {
|
470
|
+
return Database_perform_query(argc, argv, self, safe_query_single_row_array, QUERY_ARRAY);
|
465
471
|
}
|
466
472
|
|
467
473
|
/* call-seq:
|
@@ -481,6 +487,10 @@ VALUE Database_query_single_ary(int argc, VALUE *argv, VALUE self) {
|
|
481
487
|
* specified using keyword arguments:
|
482
488
|
*
|
483
489
|
* db.execute('update foo set x = :bar', bar: 42)
|
490
|
+
*
|
491
|
+
* @param sql [String] query SQL
|
492
|
+
* @param parameters [Array, Hash] parameters to run query with
|
493
|
+
* @return [Integer, nil] Total number of changes effected or `nil` if the query ends with a comment.
|
484
494
|
*/
|
485
495
|
VALUE Database_execute(int argc, VALUE *argv, VALUE self) {
|
486
496
|
return Database_perform_query(argc, argv, self, safe_query_changes, QUERY_HASH);
|
@@ -532,6 +542,8 @@ VALUE Database_batch_execute(VALUE self, VALUE sql, VALUE parameters) {
|
|
532
542
|
/* call-seq:
|
533
543
|
* db.batch_query(sql, params_source) -> rows
|
534
544
|
* db.batch_query(sql, params_source) { |rows| ... } -> changes
|
545
|
+
* db.batch_query_hash(sql, params_source) -> rows
|
546
|
+
* db.batch_query_hash(sql, params_source) { |rows| ... } -> changes
|
535
547
|
*
|
536
548
|
* Executes the given query for each list of parameters in the given paramter
|
537
549
|
* source. If a block is given, it is called with the resulting rows for each
|
@@ -564,8 +576,8 @@ VALUE Database_batch_query(VALUE self, VALUE sql, VALUE parameters) {
|
|
564
576
|
}
|
565
577
|
|
566
578
|
/* call-seq:
|
567
|
-
* db.
|
568
|
-
* db.
|
579
|
+
* db.batch_query_array(sql, params_source) -> rows
|
580
|
+
* db.batch_query_array(sql, params_source) { |rows| ... } -> changes
|
569
581
|
*
|
570
582
|
* Executes the given query for each list of parameters in the given paramter
|
571
583
|
* source. If a block is given, it is called with the resulting rows for each
|
@@ -577,29 +589,29 @@ VALUE Database_batch_query(VALUE self, VALUE sql, VALUE parameters) {
|
|
577
589
|
* [1, 2],
|
578
590
|
* [3, 4]
|
579
591
|
* ]
|
580
|
-
* db.
|
592
|
+
* db.batch_query_array('insert into foo values (?, ?) returning bar, baz', records)
|
581
593
|
* #=> [[1, 2], [3, 4]]
|
582
594
|
* *
|
583
595
|
* @param sql [String] query SQL
|
584
596
|
* @param parameters [Array<Array, Hash>, Enumerable, Enumerator, Callable] parameters to run query with
|
585
597
|
* @return [Array<Array>, Integer] Total number of changes effected
|
586
598
|
*/
|
587
|
-
VALUE
|
599
|
+
VALUE Database_batch_query_array(VALUE self, VALUE sql, VALUE parameters) {
|
588
600
|
Database_t *db = self_to_open_database(self);
|
589
601
|
sqlite3_stmt *stmt;
|
590
602
|
|
591
603
|
prepare_single_stmt(DB_GVL_MODE(db), db->sqlite3_db, &stmt, sql);
|
592
604
|
query_ctx ctx = QUERY_CTX(
|
593
605
|
self, sql, db, stmt, parameters,
|
594
|
-
Qnil,
|
606
|
+
Qnil, QUERY_ARRAY, ROW_MULTI, ALL_ROWS
|
595
607
|
);
|
596
608
|
|
597
|
-
return rb_ensure(SAFE(
|
609
|
+
return rb_ensure(SAFE(safe_batch_query_array), (VALUE)&ctx, SAFE(cleanup_stmt), (VALUE)&ctx);
|
598
610
|
}
|
599
611
|
|
600
612
|
/* call-seq:
|
601
|
-
* db.
|
602
|
-
* db.
|
613
|
+
* db.batch_query_splat(sql, params_source) -> rows
|
614
|
+
* db.batch_query_splat(sql, params_source) { |rows| ... } -> changes
|
603
615
|
*
|
604
616
|
* Executes the given query for each list of parameters in the given paramter
|
605
617
|
* source. If a block is given, it is called with the resulting rows for each
|
@@ -611,24 +623,24 @@ VALUE Database_batch_query_ary(VALUE self, VALUE sql, VALUE parameters) {
|
|
611
623
|
* [1, 2],
|
612
624
|
* [3, 4]
|
613
625
|
* ]
|
614
|
-
* db.
|
626
|
+
* db.batch_query_splat('insert into foo values (?, ?) returning baz', records)
|
615
627
|
* #=> [2, 4]
|
616
628
|
* *
|
617
629
|
* @param sql [String] query SQL
|
618
630
|
* @param parameters [Array<Array, Hash>, Enumerable, Enumerator, Callable] parameters to run query with
|
619
631
|
* @return [Array<any>, Integer] Total number of changes effected
|
620
632
|
*/
|
621
|
-
VALUE
|
633
|
+
VALUE Database_batch_query_splat(VALUE self, VALUE sql, VALUE parameters) {
|
622
634
|
Database_t *db = self_to_open_database(self);
|
623
635
|
sqlite3_stmt *stmt;
|
624
636
|
|
625
637
|
prepare_single_stmt(DB_GVL_MODE(db), db->sqlite3_db, &stmt, sql);
|
626
638
|
query_ctx ctx = QUERY_CTX(
|
627
639
|
self, sql, db, stmt, parameters,
|
628
|
-
Qnil,
|
640
|
+
Qnil, QUERY_SPLAT, ROW_MULTI, ALL_ROWS
|
629
641
|
);
|
630
642
|
|
631
|
-
return rb_ensure(SAFE(
|
643
|
+
return rb_ensure(SAFE(safe_batch_query_splat), (VALUE)&ctx, SAFE(cleanup_stmt), (VALUE)&ctx);
|
632
644
|
}
|
633
645
|
|
634
646
|
/* Returns the column names for the given query, without running it.
|
@@ -738,9 +750,9 @@ VALUE Database_prepare_hash(int argc, VALUE *argv, VALUE self) {
|
|
738
750
|
}
|
739
751
|
|
740
752
|
/* call-seq:
|
741
|
-
* db.
|
742
|
-
* db.
|
743
|
-
* db.
|
753
|
+
* db.prepare_splat(sql) -> Extralite::Query
|
754
|
+
* db.prepare_splat(sql, *params) -> Extralite::Query
|
755
|
+
* db.prepare_splat(sql, *params) { ... } -> Extralite::Query
|
744
756
|
*
|
745
757
|
* Creates a prepared query with the given SQL query in argv mode. If query
|
746
758
|
* parameters are given, they are bound to the query. If a block is given, it is
|
@@ -750,16 +762,16 @@ VALUE Database_prepare_hash(int argc, VALUE *argv, VALUE self) {
|
|
750
762
|
* @param *params [Array<any>] parameters to bind
|
751
763
|
* @return [Extralite::Query] prepared query
|
752
764
|
*/
|
753
|
-
VALUE
|
754
|
-
return Database_prepare(argc, argv, self,
|
765
|
+
VALUE Database_prepare_splat(int argc, VALUE *argv, VALUE self) {
|
766
|
+
return Database_prepare(argc, argv, self, SYM_splat);
|
755
767
|
}
|
756
768
|
|
757
769
|
/* call-seq:
|
758
|
-
* db.
|
759
|
-
* db.
|
760
|
-
* db.
|
770
|
+
* db.prepare_array(sql) -> Extralite::Query
|
771
|
+
* db.prepare_array(sql, *params) -> Extralite::Query
|
772
|
+
* db.prepare_array(sql, *params) { ... } -> Extralite::Query
|
761
773
|
*
|
762
|
-
* Creates a prepared query with the given SQL query in
|
774
|
+
* Creates a prepared query with the given SQL query in array mode. If query
|
763
775
|
* parameters are given, they are bound to the query. If a block is given, it is
|
764
776
|
* used as a transform proc.
|
765
777
|
*
|
@@ -767,8 +779,8 @@ VALUE Database_prepare_argv(int argc, VALUE *argv, VALUE self) {
|
|
767
779
|
* @param *params [Array<any>] parameters to bind
|
768
780
|
* @return [Extralite::Query] prepared query
|
769
781
|
*/
|
770
|
-
VALUE
|
771
|
-
return Database_prepare(argc, argv, self,
|
782
|
+
VALUE Database_prepare_array(int argc, VALUE *argv, VALUE self) {
|
783
|
+
return Database_prepare(argc, argv, self, SYM_array);
|
772
784
|
}
|
773
785
|
|
774
786
|
/* Interrupts a long running query. This method is to be called from a different
|
@@ -853,11 +865,7 @@ VALUE backup_cleanup(VALUE ptr) {
|
|
853
865
|
return Qnil;
|
854
866
|
}
|
855
867
|
|
856
|
-
/*
|
857
|
-
* db.backup(dest, src_db_name = 'main', dst_db_name = 'main') { |remaining, total| ... } -> db
|
858
|
-
*
|
859
|
-
*
|
860
|
-
* Creates a backup of the database to the given destination, which can be
|
868
|
+
/* Creates a backup of the database to the given destination, which can be
|
861
869
|
* either a filename or a database instance. In order to monitor the backup
|
862
870
|
* progress you can pass a block that will be called periodically by the backup
|
863
871
|
* method with two arguments: the remaining page count, and the total page
|
@@ -871,6 +879,8 @@ VALUE backup_cleanup(VALUE ptr) {
|
|
871
879
|
* @param dest [String, Extralite::Database] backup destination
|
872
880
|
* @param src_db_name [String] source database name (default: "main")
|
873
881
|
* @param dst_db_name [String] Destination database name (default: "main")
|
882
|
+
* @yieldparam remaining [Integer] remaining page count
|
883
|
+
* @yieldparam total [Integer] total page count
|
874
884
|
* @return [Extralite::Database] source database
|
875
885
|
*/
|
876
886
|
VALUE Database_backup(int argc, VALUE *argv, VALUE self) {
|
@@ -920,6 +930,13 @@ VALUE Database_backup(int argc, VALUE *argv, VALUE self) {
|
|
920
930
|
/* Returns runtime status values for the given op as an array containing the
|
921
931
|
* current value and the high water mark value. To reset the high water mark,
|
922
932
|
* pass true as reset.
|
933
|
+
*
|
934
|
+
* You can use the various `Extralite::SQLITE_STATUS_xxx` constants with this
|
935
|
+
* method:
|
936
|
+
*
|
937
|
+
* Extralite.runtime_status(Extralite::SQLITE_STATUS_MEMORY_USED)
|
938
|
+
*
|
939
|
+
* For more information see the SQLite docs: https://sqlite.org/c3ref/c_status_malloc_count.html
|
923
940
|
*
|
924
941
|
* @overload runtime_status(op)
|
925
942
|
* @param op [Integer] op
|
@@ -1404,6 +1421,53 @@ VALUE Database_gvl_release_threshold_set(VALUE self, VALUE value) {
|
|
1404
1421
|
return INT2NUM(db->gvl_release_threshold);
|
1405
1422
|
}
|
1406
1423
|
|
1424
|
+
int checkpoint_mode_symbol_to_int(VALUE mode) {
|
1425
|
+
if (mode == SYM_passive) return SQLITE_CHECKPOINT_PASSIVE;
|
1426
|
+
if (mode == SYM_full) return SQLITE_CHECKPOINT_FULL;
|
1427
|
+
if (mode == SYM_restart) return SQLITE_CHECKPOINT_RESTART;
|
1428
|
+
if (mode == SYM_truncate) return SQLITE_CHECKPOINT_TRUNCATE;
|
1429
|
+
|
1430
|
+
rb_raise(eArgumentError, "Invalid WAL checkpoint mode specified");
|
1431
|
+
}
|
1432
|
+
|
1433
|
+
/* Runs a WAL checkpoint operation with the given mode. If a database name is
|
1434
|
+
* given, the checkpoint operation is ran on the corresponding attached
|
1435
|
+
* database, otherwise it is run on the main database. Returns an array
|
1436
|
+
* containing the total number of frames in the WAL file, and the number of
|
1437
|
+
* frames checkpointed. For more information see:
|
1438
|
+
* https://sqlite.org/c3ref/wal_checkpoint_v2.html
|
1439
|
+
*
|
1440
|
+
* @overload wal_checkpoint(mode)
|
1441
|
+
* @param mode [Symbol] checkpoint mode (`:passive`, `:full`, `:restart`, `:truncate`)
|
1442
|
+
* @return [Array<int>] total and checkpointed frame count
|
1443
|
+
* @overload wal_checkpoint(mode, db_name)
|
1444
|
+
* @param mode [Symbol] checkpoint mode (`:passive`, `:full`, `:restart`, `:truncate`)
|
1445
|
+
* @param db_name [String] attached database name
|
1446
|
+
* @return [Array<int>] total and checkpointed frame count
|
1447
|
+
*/
|
1448
|
+
VALUE Database_wal_checkpoint(int argc, VALUE *argv, VALUE self) {
|
1449
|
+
Database_t *db = self_to_open_database(self);
|
1450
|
+
VALUE mode = Qnil;
|
1451
|
+
VALUE db_name = Qnil;
|
1452
|
+
int total_frames;
|
1453
|
+
int checkpointed_frames;
|
1454
|
+
|
1455
|
+
rb_scan_args(argc, argv, "11", &mode, &db_name);
|
1456
|
+
|
1457
|
+
int mode_int = checkpoint_mode_symbol_to_int(mode);
|
1458
|
+
int rc = sqlite3_wal_checkpoint_v2(
|
1459
|
+
db->sqlite3_db,
|
1460
|
+
NIL_P(db_name) ? NULL : StringValueCStr(db_name),
|
1461
|
+
mode_int,
|
1462
|
+
&total_frames,
|
1463
|
+
&checkpointed_frames
|
1464
|
+
);
|
1465
|
+
if (rc != SQLITE_OK)
|
1466
|
+
rb_raise(cError, "Failed to perform WAL checkpoint: %s", sqlite3_errstr(rc));
|
1467
|
+
|
1468
|
+
return rb_ary_new3(2, INT2NUM(total_frames), INT2NUM(checkpointed_frames));
|
1469
|
+
}
|
1470
|
+
|
1407
1471
|
void Init_ExtraliteDatabase(void) {
|
1408
1472
|
VALUE mExtralite = rb_define_module("Extralite");
|
1409
1473
|
rb_define_singleton_method(mExtralite, "runtime_status", Extralite_runtime_status, -1);
|
@@ -1416,8 +1480,8 @@ void Init_ExtraliteDatabase(void) {
|
|
1416
1480
|
rb_define_method(cDatabase, "backup", Database_backup, -1);
|
1417
1481
|
rb_define_method(cDatabase, "batch_execute", Database_batch_execute, 2);
|
1418
1482
|
rb_define_method(cDatabase, "batch_query", Database_batch_query, 2);
|
1419
|
-
rb_define_method(cDatabase, "
|
1420
|
-
rb_define_method(cDatabase, "
|
1483
|
+
rb_define_method(cDatabase, "batch_query_array", Database_batch_query_array, 2);
|
1484
|
+
rb_define_method(cDatabase, "batch_query_splat", Database_batch_query_splat, 2);
|
1421
1485
|
rb_define_method(cDatabase, "batch_query_hash", Database_batch_query, 2);
|
1422
1486
|
rb_define_method(cDatabase, "busy_timeout=", Database_busy_timeout_set, 1);
|
1423
1487
|
rb_define_method(cDatabase, "changes", Database_changes, 0);
|
@@ -1447,21 +1511,22 @@ void Init_ExtraliteDatabase(void) {
|
|
1447
1511
|
|
1448
1512
|
rb_define_method(cDatabase, "on_progress", Database_on_progress, -1);
|
1449
1513
|
rb_define_method(cDatabase, "prepare", Database_prepare_hash, -1);
|
1450
|
-
rb_define_method(cDatabase, "
|
1451
|
-
rb_define_method(cDatabase, "
|
1514
|
+
rb_define_method(cDatabase, "prepare_splat", Database_prepare_splat, -1);
|
1515
|
+
rb_define_method(cDatabase, "prepare_array", Database_prepare_array, -1);
|
1452
1516
|
rb_define_method(cDatabase, "prepare_hash", Database_prepare_hash, -1);
|
1453
1517
|
rb_define_method(cDatabase, "query", Database_query, -1);
|
1454
|
-
rb_define_method(cDatabase, "
|
1455
|
-
rb_define_method(cDatabase, "
|
1518
|
+
rb_define_method(cDatabase, "query_splat", Database_query_splat, -1);
|
1519
|
+
rb_define_method(cDatabase, "query_array", Database_query_array, -1);
|
1456
1520
|
rb_define_method(cDatabase, "query_hash", Database_query, -1);
|
1457
1521
|
rb_define_method(cDatabase, "query_single", Database_query_single, -1);
|
1458
|
-
rb_define_method(cDatabase, "
|
1459
|
-
rb_define_method(cDatabase, "
|
1522
|
+
rb_define_method(cDatabase, "query_single_array", Database_query_single_array, -1);
|
1523
|
+
rb_define_method(cDatabase, "query_single_splat", Database_query_single_splat, -1);
|
1460
1524
|
rb_define_method(cDatabase, "query_single_hash", Database_query_single, -1);
|
1461
1525
|
rb_define_method(cDatabase, "read_only?", Database_read_only_p, 0);
|
1462
1526
|
rb_define_method(cDatabase, "status", Database_status, -1);
|
1463
1527
|
rb_define_method(cDatabase, "total_changes", Database_total_changes, 0);
|
1464
1528
|
rb_define_method(cDatabase, "trace", Database_trace, 0);
|
1529
|
+
rb_define_method(cDatabase, "wal_checkpoint", Database_wal_checkpoint, -1);
|
1465
1530
|
|
1466
1531
|
#ifdef EXTRALITE_ENABLE_CHANGESET
|
1467
1532
|
rb_define_method(cDatabase, "track_changes", Database_track_changes, -1);
|
@@ -1488,21 +1553,29 @@ void Init_ExtraliteDatabase(void) {
|
|
1488
1553
|
ID_track = rb_intern("track");
|
1489
1554
|
|
1490
1555
|
SYM_at_least_once = ID2SYM(rb_intern("at_least_once"));
|
1556
|
+
SYM_full = ID2SYM(rb_intern("full"));
|
1491
1557
|
SYM_gvl_release_threshold = ID2SYM(rb_intern("gvl_release_threshold"));
|
1492
1558
|
SYM_once = ID2SYM(rb_intern("once"));
|
1493
1559
|
SYM_none = ID2SYM(rb_intern("none"));
|
1494
1560
|
SYM_normal = ID2SYM(rb_intern("normal"));
|
1561
|
+
SYM_passive = ID2SYM(rb_intern("passive"));
|
1495
1562
|
SYM_pragma = ID2SYM(rb_intern("pragma"));
|
1496
1563
|
SYM_read_only = ID2SYM(rb_intern("read_only"));
|
1564
|
+
SYM_restart = ID2SYM(rb_intern("restart"));
|
1565
|
+
SYM_truncate = ID2SYM(rb_intern("truncate"));
|
1497
1566
|
SYM_wal = ID2SYM(rb_intern("wal"));
|
1498
1567
|
|
1499
1568
|
rb_gc_register_mark_object(SYM_at_least_once);
|
1569
|
+
rb_gc_register_mark_object(SYM_full);
|
1500
1570
|
rb_gc_register_mark_object(SYM_gvl_release_threshold);
|
1501
1571
|
rb_gc_register_mark_object(SYM_once);
|
1502
1572
|
rb_gc_register_mark_object(SYM_none);
|
1503
1573
|
rb_gc_register_mark_object(SYM_normal);
|
1574
|
+
rb_gc_register_mark_object(SYM_passive);
|
1504
1575
|
rb_gc_register_mark_object(SYM_pragma);
|
1505
1576
|
rb_gc_register_mark_object(SYM_read_only);
|
1577
|
+
rb_gc_register_mark_object(SYM_restart);
|
1578
|
+
rb_gc_register_mark_object(SYM_truncate);
|
1506
1579
|
rb_gc_register_mark_object(SYM_wal);
|
1507
1580
|
|
1508
1581
|
rb_gc_register_mark_object(global_progress_handler.proc);
|
data/ext/extralite/extralite.h
CHANGED
@@ -42,8 +42,8 @@ extern ID ID_strip;
|
|
42
42
|
extern ID ID_to_s;
|
43
43
|
extern ID ID_track;
|
44
44
|
|
45
|
-
extern VALUE
|
46
|
-
extern VALUE
|
45
|
+
extern VALUE SYM_splat;
|
46
|
+
extern VALUE SYM_array;
|
47
47
|
extern VALUE SYM_hash;
|
48
48
|
|
49
49
|
enum progress_handler_mode {
|
@@ -71,8 +71,8 @@ typedef struct {
|
|
71
71
|
|
72
72
|
enum query_mode {
|
73
73
|
QUERY_HASH,
|
74
|
-
|
75
|
-
|
74
|
+
QUERY_SPLAT,
|
75
|
+
QUERY_ARRAY
|
76
76
|
};
|
77
77
|
|
78
78
|
typedef struct {
|
@@ -87,13 +87,6 @@ typedef struct {
|
|
87
87
|
enum query_mode query_mode;
|
88
88
|
} Query_t;
|
89
89
|
|
90
|
-
enum iterator_mode {
|
91
|
-
ITERATOR_HASH,
|
92
|
-
ITERATOR_ARGV,
|
93
|
-
ITERATOR_ARY,
|
94
|
-
ITERATOR_SINGLE_COLUMN
|
95
|
-
};
|
96
|
-
|
97
90
|
typedef struct {
|
98
91
|
VALUE query;
|
99
92
|
} Iterator_t;
|
@@ -165,16 +158,16 @@ typedef VALUE (*safe_query_impl)(query_ctx *);
|
|
165
158
|
|
166
159
|
VALUE safe_batch_execute(query_ctx *ctx);
|
167
160
|
VALUE safe_batch_query(query_ctx *ctx);
|
168
|
-
VALUE
|
169
|
-
VALUE
|
170
|
-
VALUE
|
171
|
-
VALUE
|
161
|
+
VALUE safe_batch_query_splat(query_ctx *ctx);
|
162
|
+
VALUE safe_batch_query_array(query_ctx *ctx);
|
163
|
+
VALUE safe_query_splat(query_ctx *ctx);
|
164
|
+
VALUE safe_query_array(query_ctx *ctx);
|
172
165
|
VALUE safe_query_changes(query_ctx *ctx);
|
173
166
|
VALUE safe_query_columns(query_ctx *ctx);
|
174
167
|
VALUE safe_query_hash(query_ctx *ctx);
|
175
168
|
VALUE safe_query_single_row_hash(query_ctx *ctx);
|
176
|
-
VALUE
|
177
|
-
VALUE
|
169
|
+
VALUE safe_query_single_row_splat(query_ctx *ctx);
|
170
|
+
VALUE safe_query_single_row_array(query_ctx *ctx);
|
178
171
|
|
179
172
|
VALUE Query_each(VALUE self);
|
180
173
|
VALUE Query_next(int argc, VALUE *argv, VALUE self);
|
data/ext/extralite/query.c
CHANGED
@@ -15,8 +15,8 @@ ID ID_inspect;
|
|
15
15
|
ID ID_slice;
|
16
16
|
|
17
17
|
VALUE SYM_hash;
|
18
|
-
VALUE
|
19
|
-
VALUE
|
18
|
+
VALUE SYM_splat;
|
19
|
+
VALUE SYM_array;
|
20
20
|
|
21
21
|
#define DB_GVL_MODE(query) Database_prepare_gvl_mode(query->db_struct)
|
22
22
|
|
@@ -68,8 +68,8 @@ static inline Query_t *self_to_query(VALUE obj) {
|
|
68
68
|
|
69
69
|
static inline enum query_mode symbol_to_query_mode(VALUE sym) {
|
70
70
|
if (sym == SYM_hash) return QUERY_HASH;
|
71
|
-
if (sym ==
|
72
|
-
if (sym ==
|
71
|
+
if (sym == SYM_splat) return QUERY_SPLAT;
|
72
|
+
if (sym == SYM_array) return QUERY_ARRAY;
|
73
73
|
|
74
74
|
rb_raise(cError, "Invalid query mode");
|
75
75
|
}
|
@@ -78,10 +78,10 @@ static inline VALUE query_mode_to_symbol(enum query_mode query_mode) {
|
|
78
78
|
switch (query_mode) {
|
79
79
|
case QUERY_HASH:
|
80
80
|
return SYM_hash;
|
81
|
-
case
|
82
|
-
return
|
83
|
-
case
|
84
|
-
return
|
81
|
+
case QUERY_SPLAT:
|
82
|
+
return SYM_splat;
|
83
|
+
case QUERY_ARRAY:
|
84
|
+
return SYM_array;
|
85
85
|
default:
|
86
86
|
rb_raise(cError, "Invalid mode");
|
87
87
|
}
|
@@ -232,10 +232,10 @@ inline safe_query_impl query_impl(enum query_mode query_mode) {
|
|
232
232
|
switch (query_mode) {
|
233
233
|
case QUERY_HASH:
|
234
234
|
return safe_query_hash;
|
235
|
-
case
|
236
|
-
return
|
237
|
-
case
|
238
|
-
return
|
235
|
+
case QUERY_SPLAT:
|
236
|
+
return safe_query_splat;
|
237
|
+
case QUERY_ARRAY:
|
238
|
+
return safe_query_array;
|
239
239
|
default:
|
240
240
|
rb_raise(cError, "Invalid query mode (query_impl)");
|
241
241
|
}
|
@@ -596,7 +596,7 @@ VALUE Query_mode_get(VALUE self) {
|
|
596
596
|
/* call-seq:
|
597
597
|
* query.mode = mode
|
598
598
|
*
|
599
|
-
* Sets the query mode. This can be one of `:hash`, `:
|
599
|
+
* Sets the query mode. This can be one of `:hash`, `:splat`, `:array`.
|
600
600
|
*
|
601
601
|
* @param mode [Symbol] query mode
|
602
602
|
* @return [Symbol] query mode
|
@@ -642,10 +642,10 @@ void Init_ExtraliteQuery(void) {
|
|
642
642
|
ID_slice = rb_intern("slice");
|
643
643
|
|
644
644
|
SYM_hash = ID2SYM(rb_intern("hash"));
|
645
|
-
|
646
|
-
|
645
|
+
SYM_splat = ID2SYM(rb_intern("splat"));
|
646
|
+
SYM_array = ID2SYM(rb_intern("array"));
|
647
647
|
|
648
648
|
rb_gc_register_mark_object(SYM_hash);
|
649
|
-
rb_gc_register_mark_object(
|
650
|
-
rb_gc_register_mark_object(
|
649
|
+
rb_gc_register_mark_object(SYM_splat);
|
650
|
+
rb_gc_register_mark_object(SYM_array);
|
651
651
|
}
|
data/gemspec.rb
CHANGED
@@ -18,7 +18,7 @@ def common_spec(s)
|
|
18
18
|
s.required_ruby_version = '>= 3.0'
|
19
19
|
|
20
20
|
s.add_development_dependency 'rake-compiler', '1.2.7'
|
21
|
-
s.add_development_dependency 'minitest', '5.
|
21
|
+
s.add_development_dependency 'minitest', '5.22.2'
|
22
22
|
s.add_development_dependency 'simplecov', '0.17.1'
|
23
23
|
s.add_development_dependency 'yard', '0.9.34'
|
24
24
|
s.add_development_dependency 'sequel', '5.77.0'
|
data/lib/extralite/version.rb
CHANGED