extralite 2.7 → 2.8
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/.yardopts +1 -1
- data/CHANGELOG.md +15 -4
- data/README.md +83 -46
- data/examples/kv_store.rb +1 -1
- data/examples/pubsub_store_polyphony.rb +2 -2
- 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 +182 -102
- data/ext/extralite/extralite.h +10 -17
- data/ext/extralite/iterator.c +0 -1
- data/ext/extralite/query.c +45 -44
- data/gemspec.rb +1 -1
- data/lib/extralite/version.rb +1 -1
- data/lib/extralite.rb +158 -4
- 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 +148 -117
- 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 = {
|
@@ -342,18 +346,18 @@ VALUE Database_query(int argc, VALUE *argv, VALUE self) {
|
|
342
346
|
* splatted:
|
343
347
|
*
|
344
348
|
* transform = ->(a, b, c) { a * 100 + b * 10 + c }
|
345
|
-
* db.
|
349
|
+
* db.query_splat(transform, 'select a, b, c from foo where c = ?', 42)
|
346
350
|
*
|
347
|
-
* @overload
|
351
|
+
* @overload query_splat(sql, ...)
|
348
352
|
* @param sql [String] SQL statement
|
349
353
|
* @return [Array<Array, any>, Integer] rows or total changes
|
350
|
-
* @overload
|
354
|
+
* @overload query_splat(transform, sql, ...)
|
351
355
|
* @param transform [Proc] transform proc
|
352
356
|
* @param sql [String] SQL statement
|
353
357
|
* @return [Array<Array, any>, Integer] rows or total changes
|
354
358
|
*/
|
355
|
-
VALUE
|
356
|
-
return Database_perform_query(argc, argv, self,
|
359
|
+
VALUE Database_query_splat(int argc, VALUE *argv, VALUE self) {
|
360
|
+
return Database_perform_query(argc, argv, self, safe_query_splat, QUERY_SPLAT);
|
357
361
|
}
|
358
362
|
|
359
363
|
/* Runs a query returning rows as arrays. If a block is given, it will be called
|
@@ -364,26 +368,26 @@ VALUE Database_query_argv(int argc, VALUE *argv, VALUE self) {
|
|
364
368
|
* parameters are given as an array, the query should specify parameters using
|
365
369
|
* `?`:
|
366
370
|
*
|
367
|
-
* db.
|
371
|
+
* db.query_array('select * from foo where x = ?', 42)
|
368
372
|
*
|
369
373
|
* Named placeholders are specified using `:`. The placeholder values are
|
370
374
|
* specified using a hash, where keys are either strings are symbols. String
|
371
375
|
* keys can include or omit the `:` prefix. The following are equivalent:
|
372
376
|
*
|
373
|
-
* db.
|
374
|
-
* db.
|
375
|
-
* db.
|
377
|
+
* db.query_array('select * from foo where x = :bar', bar: 42)
|
378
|
+
* db.query_array('select * from foo where x = :bar', 'bar' => 42)
|
379
|
+
* db.query_array('select * from foo where x = :bar', ':bar' => 42)
|
376
380
|
*
|
377
|
-
* @overload
|
381
|
+
* @overload query_array(sql, ...)
|
378
382
|
* @param sql [String] SQL statement
|
379
383
|
* @return [Array<Array>, Integer] rows or total changes
|
380
|
-
* @overload
|
384
|
+
* @overload query_array(transform, sql, ...)
|
381
385
|
* @param transform [Proc] transform proc
|
382
386
|
* @param sql [String] SQL statement
|
383
387
|
* @return [Array<Array>, Integer] rows or total changes
|
384
388
|
*/
|
385
|
-
VALUE
|
386
|
-
return Database_perform_query(argc, argv, self,
|
389
|
+
VALUE Database_query_array(int argc, VALUE *argv, VALUE self) {
|
390
|
+
return Database_perform_query(argc, argv, self, safe_query_array, QUERY_ARRAY);
|
387
391
|
}
|
388
392
|
|
389
393
|
/* Runs a query returning a single row as a hash.
|
@@ -419,23 +423,23 @@ VALUE Database_query_single(int argc, VALUE *argv, VALUE self) {
|
|
419
423
|
* parameters are given as an array, the query should specify parameters using
|
420
424
|
* `?`:
|
421
425
|
*
|
422
|
-
* db.
|
426
|
+
* db.query_single_splat('select * from foo where x = ?', 42)
|
423
427
|
*
|
424
428
|
* Named placeholders are specified using `:`. The placeholder values are
|
425
429
|
* specified using keyword arguments:
|
426
430
|
*
|
427
|
-
* db.
|
431
|
+
* db.query_single_splat('select * from foo where x = :bar', bar: 42)
|
428
432
|
*
|
429
|
-
* @overload
|
433
|
+
* @overload query_single_splat(sql, ...) -> row
|
430
434
|
* @param sql [String] SQL statement
|
431
435
|
* @return [Array, any] row
|
432
|
-
* @overload
|
436
|
+
* @overload query_single_splat(transform, sql, ...) -> row
|
433
437
|
* @param transform [Proc] transform proc
|
434
438
|
* @param sql [String] SQL statement
|
435
439
|
* @return [Array, any] row
|
436
440
|
*/
|
437
|
-
VALUE
|
438
|
-
return Database_perform_query(argc, argv, self,
|
441
|
+
VALUE Database_query_single_splat(int argc, VALUE *argv, VALUE self) {
|
442
|
+
return Database_perform_query(argc, argv, self, safe_query_single_row_splat, QUERY_SPLAT);
|
439
443
|
}
|
440
444
|
|
441
445
|
/* Runs a query returning a single row as an array.
|
@@ -445,23 +449,23 @@ VALUE Database_query_single_argv(int argc, VALUE *argv, VALUE self) {
|
|
445
449
|
* parameters are given as an array, the query should specify parameters using
|
446
450
|
* `?`:
|
447
451
|
*
|
448
|
-
* db.
|
452
|
+
* db.query_single_array('select * from foo where x = ?', 42)
|
449
453
|
*
|
450
454
|
* Named placeholders are specified using `:`. The placeholder values are
|
451
455
|
* specified using keyword arguments:
|
452
456
|
*
|
453
|
-
* db.
|
457
|
+
* db.query_single_array('select * from foo where x = :bar', bar: 42)
|
454
458
|
*
|
455
|
-
* @overload
|
459
|
+
* @overload query_single_array(sql, ...) -> row
|
456
460
|
* @param sql [String] SQL statement
|
457
461
|
* @return [Array, any] row
|
458
|
-
* @overload
|
462
|
+
* @overload query_single_array(transform, sql, ...) -> row
|
459
463
|
* @param transform [Proc] transform proc
|
460
464
|
* @param sql [String] SQL statement
|
461
465
|
* @return [Array, any] row
|
462
466
|
*/
|
463
|
-
VALUE
|
464
|
-
return Database_perform_query(argc, argv, self,
|
467
|
+
VALUE Database_query_single_array(int argc, VALUE *argv, VALUE self) {
|
468
|
+
return Database_perform_query(argc, argv, self, safe_query_single_row_array, QUERY_ARRAY);
|
465
469
|
}
|
466
470
|
|
467
471
|
/* call-seq:
|
@@ -532,6 +536,8 @@ VALUE Database_batch_execute(VALUE self, VALUE sql, VALUE parameters) {
|
|
532
536
|
/* call-seq:
|
533
537
|
* db.batch_query(sql, params_source) -> rows
|
534
538
|
* db.batch_query(sql, params_source) { |rows| ... } -> changes
|
539
|
+
* db.batch_query_hash(sql, params_source) -> rows
|
540
|
+
* db.batch_query_hash(sql, params_source) { |rows| ... } -> changes
|
535
541
|
*
|
536
542
|
* Executes the given query for each list of parameters in the given paramter
|
537
543
|
* source. If a block is given, it is called with the resulting rows for each
|
@@ -564,8 +570,8 @@ VALUE Database_batch_query(VALUE self, VALUE sql, VALUE parameters) {
|
|
564
570
|
}
|
565
571
|
|
566
572
|
/* call-seq:
|
567
|
-
* db.
|
568
|
-
* db.
|
573
|
+
* db.batch_query_array(sql, params_source) -> rows
|
574
|
+
* db.batch_query_array(sql, params_source) { |rows| ... } -> changes
|
569
575
|
*
|
570
576
|
* Executes the given query for each list of parameters in the given paramter
|
571
577
|
* source. If a block is given, it is called with the resulting rows for each
|
@@ -577,29 +583,29 @@ VALUE Database_batch_query(VALUE self, VALUE sql, VALUE parameters) {
|
|
577
583
|
* [1, 2],
|
578
584
|
* [3, 4]
|
579
585
|
* ]
|
580
|
-
* db.
|
586
|
+
* db.batch_query_array('insert into foo values (?, ?) returning bar, baz', records)
|
581
587
|
* #=> [[1, 2], [3, 4]]
|
582
588
|
* *
|
583
589
|
* @param sql [String] query SQL
|
584
590
|
* @param parameters [Array<Array, Hash>, Enumerable, Enumerator, Callable] parameters to run query with
|
585
591
|
* @return [Array<Array>, Integer] Total number of changes effected
|
586
592
|
*/
|
587
|
-
VALUE
|
593
|
+
VALUE Database_batch_query_array(VALUE self, VALUE sql, VALUE parameters) {
|
588
594
|
Database_t *db = self_to_open_database(self);
|
589
595
|
sqlite3_stmt *stmt;
|
590
596
|
|
591
597
|
prepare_single_stmt(DB_GVL_MODE(db), db->sqlite3_db, &stmt, sql);
|
592
598
|
query_ctx ctx = QUERY_CTX(
|
593
599
|
self, sql, db, stmt, parameters,
|
594
|
-
Qnil,
|
600
|
+
Qnil, QUERY_ARRAY, ROW_MULTI, ALL_ROWS
|
595
601
|
);
|
596
602
|
|
597
|
-
return rb_ensure(SAFE(
|
603
|
+
return rb_ensure(SAFE(safe_batch_query_array), (VALUE)&ctx, SAFE(cleanup_stmt), (VALUE)&ctx);
|
598
604
|
}
|
599
605
|
|
600
606
|
/* call-seq:
|
601
|
-
* db.
|
602
|
-
* db.
|
607
|
+
* db.batch_query_splat(sql, params_source) -> rows
|
608
|
+
* db.batch_query_splat(sql, params_source) { |rows| ... } -> changes
|
603
609
|
*
|
604
610
|
* Executes the given query for each list of parameters in the given paramter
|
605
611
|
* source. If a block is given, it is called with the resulting rows for each
|
@@ -611,24 +617,24 @@ VALUE Database_batch_query_ary(VALUE self, VALUE sql, VALUE parameters) {
|
|
611
617
|
* [1, 2],
|
612
618
|
* [3, 4]
|
613
619
|
* ]
|
614
|
-
* db.
|
620
|
+
* db.batch_query_splat('insert into foo values (?, ?) returning baz', records)
|
615
621
|
* #=> [2, 4]
|
616
622
|
* *
|
617
623
|
* @param sql [String] query SQL
|
618
624
|
* @param parameters [Array<Array, Hash>, Enumerable, Enumerator, Callable] parameters to run query with
|
619
625
|
* @return [Array<any>, Integer] Total number of changes effected
|
620
626
|
*/
|
621
|
-
VALUE
|
627
|
+
VALUE Database_batch_query_splat(VALUE self, VALUE sql, VALUE parameters) {
|
622
628
|
Database_t *db = self_to_open_database(self);
|
623
629
|
sqlite3_stmt *stmt;
|
624
630
|
|
625
631
|
prepare_single_stmt(DB_GVL_MODE(db), db->sqlite3_db, &stmt, sql);
|
626
632
|
query_ctx ctx = QUERY_CTX(
|
627
633
|
self, sql, db, stmt, parameters,
|
628
|
-
Qnil,
|
634
|
+
Qnil, QUERY_SPLAT, ROW_MULTI, ALL_ROWS
|
629
635
|
);
|
630
636
|
|
631
|
-
return rb_ensure(SAFE(
|
637
|
+
return rb_ensure(SAFE(safe_batch_query_splat), (VALUE)&ctx, SAFE(cleanup_stmt), (VALUE)&ctx);
|
632
638
|
}
|
633
639
|
|
634
640
|
/* Returns the column names for the given query, without running it.
|
@@ -721,15 +727,16 @@ static inline VALUE Database_prepare(int argc, VALUE *argv, VALUE self, VALUE mo
|
|
721
727
|
}
|
722
728
|
|
723
729
|
/* call-seq:
|
724
|
-
* db.prepare(sql) ->
|
725
|
-
* db.prepare(sql,
|
726
|
-
* db.prepare(sql,
|
730
|
+
* db.prepare(sql) -> query
|
731
|
+
* db.prepare(sql, *params) -> query
|
732
|
+
* db.prepare(sql, *params) { ... } -> query
|
727
733
|
*
|
728
734
|
* Creates a prepared query with the given SQL query in hash mode. If query
|
729
735
|
* parameters are given, they are bound to the query. If a block is given, it is
|
730
736
|
* used as a transform proc.
|
731
737
|
*
|
732
738
|
* @param sql [String] SQL statement
|
739
|
+
* @param *params [Array<any>] parameters to bind
|
733
740
|
* @return [Extralite::Query] prepared query
|
734
741
|
*/
|
735
742
|
VALUE Database_prepare_hash(int argc, VALUE *argv, VALUE self) {
|
@@ -737,35 +744,37 @@ VALUE Database_prepare_hash(int argc, VALUE *argv, VALUE self) {
|
|
737
744
|
}
|
738
745
|
|
739
746
|
/* call-seq:
|
740
|
-
* db.
|
741
|
-
* db.
|
742
|
-
* db.
|
747
|
+
* db.prepare_splat(sql) -> Extralite::Query
|
748
|
+
* db.prepare_splat(sql, *params) -> Extralite::Query
|
749
|
+
* db.prepare_splat(sql, *params) { ... } -> Extralite::Query
|
743
750
|
*
|
744
751
|
* Creates a prepared query with the given SQL query in argv mode. If query
|
745
752
|
* parameters are given, they are bound to the query. If a block is given, it is
|
746
753
|
* used as a transform proc.
|
747
754
|
*
|
748
755
|
* @param sql [String] SQL statement
|
756
|
+
* @param *params [Array<any>] parameters to bind
|
749
757
|
* @return [Extralite::Query] prepared query
|
750
758
|
*/
|
751
|
-
VALUE
|
752
|
-
return Database_prepare(argc, argv, self,
|
759
|
+
VALUE Database_prepare_splat(int argc, VALUE *argv, VALUE self) {
|
760
|
+
return Database_prepare(argc, argv, self, SYM_splat);
|
753
761
|
}
|
754
762
|
|
755
763
|
/* call-seq:
|
756
|
-
* db.
|
757
|
-
* db.
|
758
|
-
* db.
|
764
|
+
* db.prepare_array(sql) -> Extralite::Query
|
765
|
+
* db.prepare_array(sql, *params) -> Extralite::Query
|
766
|
+
* db.prepare_array(sql, *params) { ... } -> Extralite::Query
|
759
767
|
*
|
760
|
-
* Creates a prepared query with the given SQL query in
|
768
|
+
* Creates a prepared query with the given SQL query in array mode. If query
|
761
769
|
* parameters are given, they are bound to the query. If a block is given, it is
|
762
770
|
* used as a transform proc.
|
763
771
|
*
|
764
772
|
* @param sql [String] SQL statement
|
773
|
+
* @param *params [Array<any>] parameters to bind
|
765
774
|
* @return [Extralite::Query] prepared query
|
766
775
|
*/
|
767
|
-
VALUE
|
768
|
-
return Database_prepare(argc, argv, self,
|
776
|
+
VALUE Database_prepare_array(int argc, VALUE *argv, VALUE self) {
|
777
|
+
return Database_prepare(argc, argv, self, SYM_array);
|
769
778
|
}
|
770
779
|
|
771
780
|
/* Interrupts a long running query. This method is to be called from a different
|
@@ -862,6 +871,10 @@ VALUE backup_cleanup(VALUE ptr) {
|
|
862
871
|
* end
|
863
872
|
*
|
864
873
|
* @param dest [String, Extralite::Database] backup destination
|
874
|
+
* @param src_db_name [String] source database name (default: "main")
|
875
|
+
* @param dst_db_name [String] Destination database name (default: "main")
|
876
|
+
* @yieldparam remaining [Integer] remaining page count
|
877
|
+
* @yieldparam total [Integer] total page count
|
865
878
|
* @return [Extralite::Database] source database
|
866
879
|
*/
|
867
880
|
VALUE Database_backup(int argc, VALUE *argv, VALUE self) {
|
@@ -911,6 +924,13 @@ VALUE Database_backup(int argc, VALUE *argv, VALUE self) {
|
|
911
924
|
/* Returns runtime status values for the given op as an array containing the
|
912
925
|
* current value and the high water mark value. To reset the high water mark,
|
913
926
|
* pass true as reset.
|
927
|
+
*
|
928
|
+
* You can use the various `Extralite::SQLITE_STATUS_xxx` constants with this
|
929
|
+
* method:
|
930
|
+
*
|
931
|
+
* Extralite.runtime_status(Extralite::SQLITE_STATUS_MEMORY_USED)
|
932
|
+
*
|
933
|
+
* For more information see the SQLite docs: https://sqlite.org/c3ref/c_status_malloc_count.html
|
914
934
|
*
|
915
935
|
* @overload runtime_status(op)
|
916
936
|
* @param op [Integer] op
|
@@ -1030,7 +1050,10 @@ VALUE Database_trace(VALUE self) {
|
|
1030
1050
|
}
|
1031
1051
|
|
1032
1052
|
#ifdef EXTRALITE_ENABLE_CHANGESET
|
1033
|
-
/*
|
1053
|
+
/* call-seq:
|
1054
|
+
* db.track_changes(*tables) { ... } -> changeset
|
1055
|
+
*
|
1056
|
+
* Tracks changes to the database and returns a changeset. The changeset can
|
1034
1057
|
* then be used to store the changes to a file, apply them to another database,
|
1035
1058
|
* or undo the changes. The given table names specify which tables should be
|
1036
1059
|
* tracked for changes. Passing a value of nil causes all tables to be tracked.
|
@@ -1041,7 +1064,7 @@ VALUE Database_trace(VALUE self) {
|
|
1041
1064
|
*
|
1042
1065
|
* File.open('my.changes', 'w+') { |f| f << changeset.to_blob }
|
1043
1066
|
*
|
1044
|
-
* @param
|
1067
|
+
* @param *tables [Array<String, Symbol>] table(s) to track
|
1045
1068
|
* @return [Extralite::Changeset] changeset
|
1046
1069
|
*/
|
1047
1070
|
VALUE Database_track_changes(int argc, VALUE *argv, VALUE self) {
|
@@ -1185,7 +1208,7 @@ struct progress_handler parse_progress_handler_opts(VALUE opts) {
|
|
1185
1208
|
* @option opts [Integer] :period period value (`1000` by default)
|
1186
1209
|
* @option opts [Integer] :tick tick value (`10` by default)
|
1187
1210
|
* @option opts [Symbol] :mode progress handler mode (`:normal` by default)
|
1188
|
-
* @
|
1211
|
+
* @return [Extralite::Database] database
|
1189
1212
|
*/
|
1190
1213
|
VALUE Database_on_progress(int argc, VALUE *argv, VALUE self) {
|
1191
1214
|
Database_t *db = self_to_open_database(self);
|
@@ -1220,7 +1243,10 @@ VALUE Database_on_progress(int argc, VALUE *argv, VALUE self) {
|
|
1220
1243
|
return self;
|
1221
1244
|
}
|
1222
1245
|
|
1223
|
-
/*
|
1246
|
+
/* call-seq:
|
1247
|
+
* Extralite.on_progress(**opts) { ... }
|
1248
|
+
*
|
1249
|
+
* Installs or removes a global progress handler that will be executed
|
1224
1250
|
* periodically while a query is running. This method can be used to support
|
1225
1251
|
* switching between fibers and threads or implementing timeouts for running
|
1226
1252
|
* queries.
|
@@ -1275,7 +1301,7 @@ VALUE Database_on_progress(int argc, VALUE *argv, VALUE self) {
|
|
1275
1301
|
* @option opts [Integer] :period period value (`1000` by default)
|
1276
1302
|
* @option opts [Integer] :tick tick value (`10` by default)
|
1277
1303
|
* @option opts [Symbol] :mode progress handler mode (`:normal` by default)
|
1278
|
-
* @
|
1304
|
+
* @return [Extralite::Database] database
|
1279
1305
|
*/
|
1280
1306
|
VALUE Extralite_on_progress(int argc, VALUE *argv, VALUE self) {
|
1281
1307
|
VALUE opts;
|
@@ -1361,7 +1387,7 @@ VALUE Database_gvl_release_threshold_get(VALUE self) {
|
|
1361
1387
|
* A value of nil sets the threshold to the default value, which is
|
1362
1388
|
* currently 1000.
|
1363
1389
|
*
|
1364
|
-
* @param [Integer, nil] GVL release threshold
|
1390
|
+
* @param threshold [Integer, nil] GVL release threshold
|
1365
1391
|
* @return [Integer] GVL release threshold
|
1366
1392
|
*/
|
1367
1393
|
VALUE Database_gvl_release_threshold_set(VALUE self, VALUE value) {
|
@@ -1389,6 +1415,53 @@ VALUE Database_gvl_release_threshold_set(VALUE self, VALUE value) {
|
|
1389
1415
|
return INT2NUM(db->gvl_release_threshold);
|
1390
1416
|
}
|
1391
1417
|
|
1418
|
+
int checkpoint_mode_symbol_to_int(VALUE mode) {
|
1419
|
+
if (mode == SYM_passive) return SQLITE_CHECKPOINT_PASSIVE;
|
1420
|
+
if (mode == SYM_full) return SQLITE_CHECKPOINT_FULL;
|
1421
|
+
if (mode == SYM_restart) return SQLITE_CHECKPOINT_RESTART;
|
1422
|
+
if (mode == SYM_truncate) return SQLITE_CHECKPOINT_TRUNCATE;
|
1423
|
+
|
1424
|
+
rb_raise(eArgumentError, "Invalid WAL checkpoint mode specified");
|
1425
|
+
}
|
1426
|
+
|
1427
|
+
/* Runs a WAL checkpoint operation with the given mode. If a database name is
|
1428
|
+
* given, the checkpoint operation is ran on the corresponding attached
|
1429
|
+
* database, otherwise it is run on the main database. Returns an array
|
1430
|
+
* containing the total number of frames in the WAL file, and the number of
|
1431
|
+
* frames checkpointed. For more information see:
|
1432
|
+
* https://sqlite.org/c3ref/wal_checkpoint_v2.html
|
1433
|
+
*
|
1434
|
+
* @overload wal_checkpoint(mode)
|
1435
|
+
* @param mode [Symbol] checkpoint mode (`:passive`, `:full`, `:restart`, `:truncate`)
|
1436
|
+
* @return [Array<int>] total and checkpointed frame count
|
1437
|
+
* @overload wal_checkpoint(mode, db_name)
|
1438
|
+
* @param mode [Symbol] checkpoint mode (`:passive`, `:full`, `:restart`, `:truncate`)
|
1439
|
+
* @param db_name [String] attached database name
|
1440
|
+
* @return [Array<int>] total and checkpointed frame count
|
1441
|
+
*/
|
1442
|
+
VALUE Database_wal_checkpoint(int argc, VALUE *argv, VALUE self) {
|
1443
|
+
Database_t *db = self_to_open_database(self);
|
1444
|
+
VALUE mode = Qnil;
|
1445
|
+
VALUE db_name = Qnil;
|
1446
|
+
int total_frames;
|
1447
|
+
int checkpointed_frames;
|
1448
|
+
|
1449
|
+
rb_scan_args(argc, argv, "11", &mode, &db_name);
|
1450
|
+
|
1451
|
+
int mode_int = checkpoint_mode_symbol_to_int(mode);
|
1452
|
+
int rc = sqlite3_wal_checkpoint_v2(
|
1453
|
+
db->sqlite3_db,
|
1454
|
+
NIL_P(db_name) ? NULL : StringValueCStr(db_name),
|
1455
|
+
mode_int,
|
1456
|
+
&total_frames,
|
1457
|
+
&checkpointed_frames
|
1458
|
+
);
|
1459
|
+
if (rc != SQLITE_OK)
|
1460
|
+
rb_raise(cError, "Failed to perform WAL checkpoint: %s", sqlite3_errstr(rc));
|
1461
|
+
|
1462
|
+
return rb_ary_new3(2, INT2NUM(total_frames), INT2NUM(checkpointed_frames));
|
1463
|
+
}
|
1464
|
+
|
1392
1465
|
void Init_ExtraliteDatabase(void) {
|
1393
1466
|
VALUE mExtralite = rb_define_module("Extralite");
|
1394
1467
|
rb_define_singleton_method(mExtralite, "runtime_status", Extralite_runtime_status, -1);
|
@@ -1398,63 +1471,62 @@ void Init_ExtraliteDatabase(void) {
|
|
1398
1471
|
cDatabase = rb_define_class_under(mExtralite, "Database", rb_cObject);
|
1399
1472
|
rb_define_alloc_func(cDatabase, Database_allocate);
|
1400
1473
|
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
DEF("errcode", Database_errcode, 0);
|
1415
|
-
DEF("errmsg", Database_errmsg, 0);
|
1474
|
+
rb_define_method(cDatabase, "backup", Database_backup, -1);
|
1475
|
+
rb_define_method(cDatabase, "batch_execute", Database_batch_execute, 2);
|
1476
|
+
rb_define_method(cDatabase, "batch_query", Database_batch_query, 2);
|
1477
|
+
rb_define_method(cDatabase, "batch_query_array", Database_batch_query_array, 2);
|
1478
|
+
rb_define_method(cDatabase, "batch_query_splat", Database_batch_query_splat, 2);
|
1479
|
+
rb_define_method(cDatabase, "batch_query_hash", Database_batch_query, 2);
|
1480
|
+
rb_define_method(cDatabase, "busy_timeout=", Database_busy_timeout_set, 1);
|
1481
|
+
rb_define_method(cDatabase, "changes", Database_changes, 0);
|
1482
|
+
rb_define_method(cDatabase, "close", Database_close, 0);
|
1483
|
+
rb_define_method(cDatabase, "closed?", Database_closed_p, 0);
|
1484
|
+
rb_define_method(cDatabase, "columns", Database_columns, 1);
|
1485
|
+
rb_define_method(cDatabase, "errcode", Database_errcode, 0);
|
1486
|
+
rb_define_method(cDatabase, "errmsg", Database_errmsg, 0);
|
1416
1487
|
|
1417
1488
|
#ifdef HAVE_SQLITE3_ERROR_OFFSET
|
1418
|
-
|
1489
|
+
rb_define_method(cDatabase, "error_offset", Database_error_offset, 0);
|
1419
1490
|
#endif
|
1420
1491
|
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1492
|
+
rb_define_method(cDatabase, "execute", Database_execute, -1);
|
1493
|
+
rb_define_method(cDatabase, "filename", Database_filename, -1);
|
1494
|
+
rb_define_method(cDatabase, "gvl_release_threshold", Database_gvl_release_threshold_get, 0);
|
1495
|
+
rb_define_method(cDatabase, "gvl_release_threshold=", Database_gvl_release_threshold_set, 1);
|
1496
|
+
rb_define_method(cDatabase, "initialize", Database_initialize, -1);
|
1497
|
+
rb_define_method(cDatabase, "inspect", Database_inspect, 0);
|
1498
|
+
rb_define_method(cDatabase, "interrupt", Database_interrupt, 0);
|
1499
|
+
rb_define_method(cDatabase, "last_insert_rowid", Database_last_insert_rowid, 0);
|
1500
|
+
rb_define_method(cDatabase, "limit", Database_limit, -1);
|
1430
1501
|
|
1431
1502
|
#ifdef HAVE_SQLITE3_LOAD_EXTENSION
|
1432
|
-
|
1503
|
+
rb_define_method(cDatabase, "load_extension", Database_load_extension, 1);
|
1433
1504
|
#endif
|
1434
1505
|
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1506
|
+
rb_define_method(cDatabase, "on_progress", Database_on_progress, -1);
|
1507
|
+
rb_define_method(cDatabase, "prepare", Database_prepare_hash, -1);
|
1508
|
+
rb_define_method(cDatabase, "prepare_splat", Database_prepare_splat, -1);
|
1509
|
+
rb_define_method(cDatabase, "prepare_array", Database_prepare_array, -1);
|
1510
|
+
rb_define_method(cDatabase, "prepare_hash", Database_prepare_hash, -1);
|
1511
|
+
rb_define_method(cDatabase, "query", Database_query, -1);
|
1512
|
+
rb_define_method(cDatabase, "query_splat", Database_query_splat, -1);
|
1513
|
+
rb_define_method(cDatabase, "query_array", Database_query_array, -1);
|
1514
|
+
rb_define_method(cDatabase, "query_hash", Database_query, -1);
|
1515
|
+
rb_define_method(cDatabase, "query_single", Database_query_single, -1);
|
1516
|
+
rb_define_method(cDatabase, "query_single_array", Database_query_single_array, -1);
|
1517
|
+
rb_define_method(cDatabase, "query_single_splat", Database_query_single_splat, -1);
|
1518
|
+
rb_define_method(cDatabase, "query_single_hash", Database_query_single, -1);
|
1519
|
+
rb_define_method(cDatabase, "read_only?", Database_read_only_p, 0);
|
1520
|
+
rb_define_method(cDatabase, "status", Database_status, -1);
|
1521
|
+
rb_define_method(cDatabase, "total_changes", Database_total_changes, 0);
|
1522
|
+
rb_define_method(cDatabase, "trace", Database_trace, 0);
|
1523
|
+
rb_define_method(cDatabase, "wal_checkpoint", Database_wal_checkpoint, -1);
|
1452
1524
|
|
1453
1525
|
#ifdef EXTRALITE_ENABLE_CHANGESET
|
1454
|
-
|
1526
|
+
rb_define_method(cDatabase, "track_changes", Database_track_changes, -1);
|
1455
1527
|
#endif
|
1456
1528
|
|
1457
|
-
|
1529
|
+
rb_define_method(cDatabase, "transaction_active?", Database_transaction_active_p, 0);
|
1458
1530
|
|
1459
1531
|
cBlob = rb_define_class_under(mExtralite, "Blob", rb_cString);
|
1460
1532
|
cError = rb_define_class_under(mExtralite, "Error", rb_eStandardError);
|
@@ -1475,21 +1547,29 @@ void Init_ExtraliteDatabase(void) {
|
|
1475
1547
|
ID_track = rb_intern("track");
|
1476
1548
|
|
1477
1549
|
SYM_at_least_once = ID2SYM(rb_intern("at_least_once"));
|
1550
|
+
SYM_full = ID2SYM(rb_intern("full"));
|
1478
1551
|
SYM_gvl_release_threshold = ID2SYM(rb_intern("gvl_release_threshold"));
|
1479
1552
|
SYM_once = ID2SYM(rb_intern("once"));
|
1480
1553
|
SYM_none = ID2SYM(rb_intern("none"));
|
1481
1554
|
SYM_normal = ID2SYM(rb_intern("normal"));
|
1555
|
+
SYM_passive = ID2SYM(rb_intern("passive"));
|
1482
1556
|
SYM_pragma = ID2SYM(rb_intern("pragma"));
|
1483
1557
|
SYM_read_only = ID2SYM(rb_intern("read_only"));
|
1558
|
+
SYM_restart = ID2SYM(rb_intern("restart"));
|
1559
|
+
SYM_truncate = ID2SYM(rb_intern("truncate"));
|
1484
1560
|
SYM_wal = ID2SYM(rb_intern("wal"));
|
1485
1561
|
|
1486
1562
|
rb_gc_register_mark_object(SYM_at_least_once);
|
1563
|
+
rb_gc_register_mark_object(SYM_full);
|
1487
1564
|
rb_gc_register_mark_object(SYM_gvl_release_threshold);
|
1488
1565
|
rb_gc_register_mark_object(SYM_once);
|
1489
1566
|
rb_gc_register_mark_object(SYM_none);
|
1490
1567
|
rb_gc_register_mark_object(SYM_normal);
|
1568
|
+
rb_gc_register_mark_object(SYM_passive);
|
1491
1569
|
rb_gc_register_mark_object(SYM_pragma);
|
1492
1570
|
rb_gc_register_mark_object(SYM_read_only);
|
1571
|
+
rb_gc_register_mark_object(SYM_restart);
|
1572
|
+
rb_gc_register_mark_object(SYM_truncate);
|
1493
1573
|
rb_gc_register_mark_object(SYM_wal);
|
1494
1574
|
|
1495
1575
|
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/iterator.c
CHANGED