extralite 1.7 → 1.10

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: cf088c359bb74b23020c8cb290cb6c65d06cedd885e4421c3e81f3c21a31ca33
4
- data.tar.gz: a14199c2f5d07068a1a57eb0b24119964aa7a9960f23e6cb58bac39fe535dbfa
3
+ metadata.gz: e1dbf79f19c8e1a1b31da57db9e1b20eb32efed2a510dfd1a19df048ecdf6532
4
+ data.tar.gz: 633afbfd7042dedb38a5275d525bf9876a8cd194e6b6f95db183d78019c53816
5
5
  SHA512:
6
- metadata.gz: '009ccdd0998a39df02718feeecf981eb03dbf55d0dd6b2d0b8bcfb66754a0ec8fcc2ee9e4e9a2b421a63ed6fa89ae29f7c748ca370d32dae2199a01e50febabc'
7
- data.tar.gz: e0fc9eb0f8a69dd2017c4d821430a861535fecc2c51e937c58d471098cc0c815867f514a357e2a0572eb848e02e97fac9454116b3cac2ff21abb0e479241552e
6
+ metadata.gz: 9987a2e1b14e9213a289d04d79a0914e6d3a843c5af94e4d57d6839f193b8294b57b280141dd4784419d9f920d8b1ee32f9a21efee56a85ff524128bc4262aed
7
+ data.tar.gz: 2b53f9dd796f37e7c901f88b5bfe2b28463c0465ff5aaf0ade160b1ecf95f0beb7b0cd56496e3c76bd4f754ef7649bf8a704ff7eb94053a7b7f1b1099cf31a5b
@@ -0,0 +1 @@
1
+ github: ciconia
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 1.10 2021-12-15
2
+
3
+ - Fix mutliple parameter binding with hash
4
+
5
+ ## 1.9 2021-12-15
6
+
7
+ - Add support for reading BLOBs
8
+
9
+ ## 1.8.2 2021-12-15
10
+
11
+ - Add documentation
12
+
1
13
  ## 1.7 2021-12-13
2
14
 
3
15
  - Add extralite Sequel adapter
data/Gemfile.lock CHANGED
@@ -1,60 +1,37 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- extralite (1.7)
4
+ extralite (1.10)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- ast (2.4.2)
10
- coderay (1.1.3)
11
9
  docile (1.4.0)
12
10
  json (2.5.1)
13
- method_source (1.0.0)
14
- minitest (5.14.4)
15
- parallel (1.20.1)
16
- parser (3.0.1.1)
17
- ast (~> 2.4.1)
18
- pry (0.13.1)
19
- coderay (~> 1.1)
20
- method_source (~> 1.0)
21
- rainbow (3.0.0)
22
- rake (13.0.3)
23
- rake-compiler (1.1.1)
11
+ minitest (5.15.0)
12
+ rake (13.0.6)
13
+ rake-compiler (1.1.6)
24
14
  rake
25
- regexp_parser (2.1.1)
26
- rexml (3.2.5)
27
- rubocop (0.85.1)
28
- parallel (~> 1.10)
29
- parser (>= 2.7.0.1)
30
- rainbow (>= 2.2.2, < 4.0)
31
- regexp_parser (>= 1.7)
32
- rexml
33
- rubocop-ast (>= 0.0.3)
34
- ruby-progressbar (~> 1.7)
35
- unicode-display_width (>= 1.4.0, < 2.0)
36
- rubocop-ast (1.5.0)
37
- parser (>= 3.0.1.1)
38
- ruby-progressbar (1.11.0)
39
15
  sequel (5.51.0)
40
16
  simplecov (0.17.1)
41
17
  docile (~> 1.1)
42
18
  json (>= 1.8, < 3)
43
19
  simplecov-html (~> 0.10.0)
44
20
  simplecov-html (0.10.2)
45
- unicode-display_width (1.7.0)
21
+ webrick (1.7.0)
22
+ yard (0.9.27)
23
+ webrick (~> 1.7.0)
46
24
 
47
25
  PLATFORMS
48
26
  ruby
49
27
 
50
28
  DEPENDENCIES
51
29
  extralite!
52
- minitest (= 5.14.4)
53
- pry (= 0.13.1)
54
- rake-compiler (= 1.1.1)
55
- rubocop (= 0.85.1)
30
+ minitest (= 5.15.0)
31
+ rake-compiler (= 1.1.6)
56
32
  sequel (= 5.51.0)
57
33
  simplecov (= 0.17.1)
34
+ yard (= 0.9.27)
58
35
 
59
36
  BUNDLED WITH
60
37
  2.1.4
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Extralite - a Ruby gem for working with SQLite3 databases
1
+ # Extralite - a fast Ruby gem for working with SQLite3 databases
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/extralite.svg)](http://rubygems.org/gems/extralite)
4
4
  [![Modulation Test](https://github.com/digital-fabric/extralite/workflows/Tests/badge.svg)](https://github.com/digital-fabric/extralite/actions?query=workflow%3ATests)
@@ -6,9 +6,9 @@
6
6
 
7
7
  ## What is Extralite?
8
8
 
9
- Extralite is an extra-lightweight (less than 430 lines of C-code) SQLite3
10
- wrapper for Ruby. It provides a single class with a minimal set of methods to
11
- interact with an SQLite3 database.
9
+ Extralite is a fast, extra-lightweight (less than 460 lines of C-code) SQLite3
10
+ wrapper for Ruby. It provides a single class with a minimal set of methods for
11
+ interacting with an SQLite3 database.
12
12
 
13
13
  ## Features
14
14
 
@@ -73,7 +73,7 @@ db.query('select * from foo where bar = :bar', 'bar' => 42)
73
73
  db.query('select * from foo where bar = :bar', ':bar' => 42)
74
74
 
75
75
  # get last insert rowid
76
- rowid = db.last_insert_id
76
+ rowid = db.last_insert_rowid
77
77
 
78
78
  # get number of rows changed in last query
79
79
  number_of_rows_affected = db.changes
@@ -127,7 +127,7 @@ Here's a table summarizing the differences between the two gems:
127
127
  |custom collations|yes|no|
128
128
  |custom aggregate functions|yes|no|
129
129
  |Multithread friendly|no|[yes](#what-about-concurrency)|
130
- |Code size|~2650LoC|~500LoC|
130
+ |Code size|~2650LoC|~530LoC|
131
131
  |Performance|1x|1.5x to 12.5x (see [below](#performance))|
132
132
 
133
133
  ## What about concurrency?
@@ -140,23 +140,33 @@ performance:
140
140
 
141
141
  ## Performance
142
142
 
143
- A benchmark script is
144
- [included](https://github.com/digital-fabric/extralite/blob/main/test/perf.rb),
145
- creating a table of various row counts, then fetching the entire table using
146
- either `sqlite3` or `extralite`. This benchmark shows Extralite to be up to 12.5
147
- times faster than `sqlite3` when fetching a large number of rows. Here are the
148
- results (using the `sqlite3` gem performance as baseline):
143
+ A benchmark script is included, creating a table of various row counts, then
144
+ fetching the entire table using either `sqlite3` or `extralite`. This benchmark
145
+ shows Extralite to be up to 12.5 times faster than `sqlite3` when fetching a
146
+ large number of rows. Here are the [results for fetching rows as hashes](https://github.com/digital-fabric/extralite/blob/main/test/perf_hash.rb):
149
147
 
150
- |Row count|sqlite3-ruby (baseline)|Extralite (relative - rounded)|
151
- |-:|-:|-:|
152
- |10|1x|1.5x|
153
- |1K|1x|7x|
154
- |100K|1x|12.5x|
148
+ |Row count|sqlite3-ruby|Extralite|Advantage|
149
+ |-:|-:|-:|-:|
150
+ |10|57620 rows/s|95340 rows/s|__1.65x__|
151
+ |1K|286.8K rows/s|2106.4 rows/s|__7.35x__|
152
+ |100K|181K rows/s|2275.3K rows/s|__12.53x__|
153
+
154
+ When [fetching rows as arrays](https://github.com/digital-fabric/extralite/blob/main/test/perf_ary.rb) Extralite also significantly outperforms sqlite3-ruby:
155
+
156
+ |Row count|sqlite3-ruby|Extralite|Advantage|
157
+ |-:|-:|-:|-:|
158
+ |10|64365 rows/s|94031 rows/s|__1.46x__|
159
+ |1K|498.9K rows/s|2478.2K rows/s|__4.97x__|
160
+ |100K|441.1K rows/s|3023.4K rows/s|__6.85x__|
155
161
 
156
162
  (If you're interested in checking this yourself, just run the script and let me
157
- know if your results are different.)
163
+ know if your results are better/worse.)
164
+
165
+ As those benchmarks show, Extralite is capabale of reading more than 3M
166
+ rows/second (when fetching rows as arrays), and more than 2.2M rows/second (when
167
+ fetching rows as hashes.)
158
168
 
159
169
  ## Contributing
160
170
 
161
171
  Contributions in the form of issues, PRs or comments will be greatly
162
- appreciated!
172
+ appreciated!
data/Rakefile CHANGED
@@ -1,18 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
4
- require "rake/clean"
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/clean'
5
5
 
6
- require "rake/extensiontask"
7
- Rake::ExtensionTask.new("extralite_ext") do |ext|
8
- ext.ext_dir = "ext/extralite"
6
+ require 'rake/extensiontask'
7
+ Rake::ExtensionTask.new('extralite_ext') do |ext|
8
+ ext.ext_dir = 'ext/extralite'
9
9
  end
10
10
 
11
11
  task :recompile => [:clean, :compile]
12
12
 
13
- task :default => [:compile, :test]
13
+ task :default => [:compile, :doc, :test]
14
+ task :doc => :yard
14
15
  task :test do
15
16
  exec 'ruby test/run.rb'
16
17
  end
17
18
 
18
- CLEAN.include "**/*.o", "**/*.so", "**/*.so.*", "**/*.a", "**/*.bundle", "**/*.jar", "pkg", "tmp"
19
+ CLEAN.include '**/*.o', '**/*.so', '**/*.so.*', '**/*.a', '**/*.bundle', '**/*.jar', 'pkg', 'tmp'
20
+
21
+ require 'yard'
22
+ YARD_FILES = FileList['ext/extralite/extralite.c', 'lib/extralite.rb', 'lib/sequel/adapters/extralite.rb']
23
+
24
+ YARD::Rake::YardocTask.new do |t|
25
+ t.files = YARD_FILES
26
+ t.options = %w(-o doc --readme README.md)
27
+ end
@@ -51,6 +51,10 @@ static VALUE Database_allocate(VALUE klass) {
51
51
  } \
52
52
  }
53
53
 
54
+ /* call-seq: initialize(path)
55
+ *
56
+ * Initializes a new SQLite database with the given path.
57
+ */
54
58
 
55
59
  VALUE Database_initialize(VALUE self, VALUE path) {
56
60
  int rc;
@@ -72,6 +76,10 @@ VALUE Database_initialize(VALUE self, VALUE path) {
72
76
  return Qnil;
73
77
  }
74
78
 
79
+ /* call-seq: close
80
+ *
81
+ * Closes the database.
82
+ */
75
83
  VALUE Database_close(VALUE self) {
76
84
  int rc;
77
85
  Database_t *db;
@@ -86,6 +94,10 @@ VALUE Database_close(VALUE self) {
86
94
  return self;
87
95
  }
88
96
 
97
+ /* call-seq: closed?
98
+ *
99
+ * Returns true if the database is closed.
100
+ */
89
101
  VALUE Database_closed_p(VALUE self) {
90
102
  Database_t *db;
91
103
  GetDatabase(self, db);
@@ -104,7 +116,7 @@ inline VALUE get_column_value(sqlite3_stmt *stmt, int col, int type) {
104
116
  case SQLITE_TEXT:
105
117
  return rb_str_new_cstr((char *)sqlite3_column_text(stmt, col));
106
118
  case SQLITE_BLOB:
107
- rb_raise(cError, "BLOB reading not yet implemented");
119
+ return rb_str_new((const char *)sqlite3_column_blob(stmt, col), (long)sqlite3_column_bytes(stmt, col));
108
120
  default:
109
121
  rb_raise(cError, "Unknown column type: %d", type);
110
122
  }
@@ -124,16 +136,16 @@ static inline void bind_hash_parameter_values(sqlite3_stmt *stmt, VALUE hash) {
124
136
  switch (TYPE(k)) {
125
137
  case T_FIXNUM:
126
138
  bind_parameter_value(stmt, NUM2INT(k), v);
127
- return;
139
+ break;
128
140
  case T_SYMBOL:
129
141
  k = rb_funcall(k, ID_TO_S, 0);
130
142
  case T_STRING:
131
143
  if(RSTRING_PTR(k)[0] != ':') k = rb_str_plus(rb_str_new2(":"), k);
132
144
  int pos = sqlite3_bind_parameter_index(stmt, StringValuePtr(k));
133
145
  bind_parameter_value(stmt, pos, v);
134
- return;
146
+ break;
135
147
  default:
136
- rb_raise(cError, "Cannot bind hash key value idx %d", i);
148
+ rb_raise(cError, "Cannot bind hash key value idx %d", i);
137
149
  }
138
150
  }
139
151
  RB_GC_GUARD(keys);
@@ -342,6 +354,29 @@ VALUE safe_query_hash(VALUE arg) {
342
354
  return result;
343
355
  }
344
356
 
357
+ /* call-seq:
358
+ * query(sql, *parameters, &block)
359
+ * query_hash(sql, *parameters, &block)
360
+ *
361
+ * Runs a query returning rows as hashes (with symbol keys). If a block is
362
+ * given, it will be called for each row. Otherwise, an array containing all
363
+ * rows is returned.
364
+ *
365
+ * Query parameters to be bound to placeholders in the query can be specified as
366
+ * a list of values or as a hash mapping parameter names to values. When
367
+ * parameters are given as a least, the query should specify parameters using
368
+ * `?`:
369
+ *
370
+ * db.query('select * from foo where x = ?', 42)
371
+ *
372
+ * Named placeholders are specified using `:`. The placeholder values are
373
+ * specified using a hash, where keys are either strings are symbols. String
374
+ * keys can include or omit the `:` prefix. The following are equivalent:
375
+ *
376
+ * db.query('select * from foo where x = :bar', bar: 42)
377
+ * db.query('select * from foo where x = :bar', 'bar' => 42)
378
+ * db.query('select * from foo where x = :bar', ':bar' => 42)
379
+ */
345
380
  VALUE Database_query_hash(int argc, VALUE *argv, VALUE self) {
346
381
  query_ctx ctx = { self, argc, argv, 0 };
347
382
  return rb_ensure(safe_query_hash, (VALUE)&ctx, cleanup_stmt, (VALUE)&ctx);
@@ -376,6 +411,26 @@ VALUE safe_query_ary(VALUE arg) {
376
411
  return result;
377
412
  }
378
413
 
414
+ /* call-seq: query_ary(sql, *parameters, &block)
415
+ *
416
+ * Runs a query returning rows as arrays. If a block is given, it will be called
417
+ * for each row. Otherwise, an array containing all rows is returned.
418
+ *
419
+ * Query parameters to be bound to placeholders in the query can be specified as
420
+ * a list of values or as a hash mapping parameter names to values. When
421
+ * parameters are given as a least, the query should specify parameters using
422
+ * `?`:
423
+ *
424
+ * db.query_ary('select * from foo where x = ?', 42)
425
+ *
426
+ * Named placeholders are specified using `:`. The placeholder values are
427
+ * specified using a hash, where keys are either strings are symbols. String
428
+ * keys can include or omit the `:` prefix. The following are equivalent:
429
+ *
430
+ * db.query_ary('select * from foo where x = :bar', bar: 42)
431
+ * db.query_ary('select * from foo where x = :bar', 'bar' => 42)
432
+ * db.query_ary('select * from foo where x = :bar', ':bar' => 42)
433
+ */
379
434
  VALUE Database_query_ary(int argc, VALUE *argv, VALUE self) {
380
435
  query_ctx ctx = { self, argc, argv, 0 };
381
436
  return rb_ensure(safe_query_ary, (VALUE)&ctx, cleanup_stmt, (VALUE)&ctx);
@@ -405,6 +460,25 @@ VALUE safe_query_single_row(VALUE arg) {
405
460
  return row;
406
461
  }
407
462
 
463
+ /* call-seq: query_single_row(sql, *parameters)
464
+ *
465
+ * Runs a query returning a single row as a hash.
466
+ *
467
+ * Query parameters to be bound to placeholders in the query can be specified as
468
+ * a list of values or as a hash mapping parameter names to values. When
469
+ * parameters are given as a least, the query should specify parameters using
470
+ * `?`:
471
+ *
472
+ * db.query_single_row('select * from foo where x = ?', 42)
473
+ *
474
+ * Named placeholders are specified using `:`. The placeholder values are
475
+ * specified using a hash, where keys are either strings are symbols. String
476
+ * keys can include or omit the `:` prefix. The following are equivalent:
477
+ *
478
+ * db.query_single_row('select * from foo where x = :bar', bar: 42)
479
+ * db.query_single_row('select * from foo where x = :bar', 'bar' => 42)
480
+ * db.query_single_row('select * from foo where x = :bar', ':bar' => 42)
481
+ */
408
482
  VALUE Database_query_single_row(int argc, VALUE *argv, VALUE self) {
409
483
  query_ctx ctx = { self, argc, argv, 0 };
410
484
  return rb_ensure(safe_query_single_row, (VALUE)&ctx, cleanup_stmt, (VALUE)&ctx);
@@ -442,6 +516,26 @@ VALUE safe_query_single_column(VALUE arg) {
442
516
  return result;
443
517
  }
444
518
 
519
+ /* call-seq: query_single_column(sql, *parameters, &block)
520
+ *
521
+ * Runs a query returning single column values. If a block is given, it will be called
522
+ * for each value. Otherwise, an array containing all values is returned.
523
+ *
524
+ * Query parameters to be bound to placeholders in the query can be specified as
525
+ * a list of values or as a hash mapping parameter names to values. When
526
+ * parameters are given as a least, the query should specify parameters using
527
+ * `?`:
528
+ *
529
+ * db.query_single_column('select x from foo where x = ?', 42)
530
+ *
531
+ * Named placeholders are specified using `:`. The placeholder values are
532
+ * specified using a hash, where keys are either strings are symbols. String
533
+ * keys can include or omit the `:` prefix. The following are equivalent:
534
+ *
535
+ * db.query_single_column('select x from foo where x = :bar', bar: 42)
536
+ * db.query_single_column('select x from foo where x = :bar', 'bar' => 42)
537
+ * db.query_single_column('select x from foo where x = :bar', ':bar' => 42)
538
+ */
445
539
  VALUE Database_query_single_column(int argc, VALUE *argv, VALUE self) {
446
540
  query_ctx ctx = { self, argc, argv, 0 };
447
541
  return rb_ensure(safe_query_single_column, (VALUE)&ctx, cleanup_stmt, (VALUE)&ctx);
@@ -470,11 +564,34 @@ VALUE safe_query_single_value(VALUE arg) {
470
564
  return value;
471
565
  }
472
566
 
567
+ /* call-seq: query_single_value(sql, *parameters)
568
+ *
569
+ * Runs a query returning a single value from the first row.
570
+ *
571
+ * Query parameters to be bound to placeholders in the query can be specified as
572
+ * a list of values or as a hash mapping parameter names to values. When
573
+ * parameters are given as a least, the query should specify parameters using
574
+ * `?`:
575
+ *
576
+ * db.query_single_value('select x from foo where x = ?', 42)
577
+ *
578
+ * Named placeholders are specified using `:`. The placeholder values are
579
+ * specified using a hash, where keys are either strings are symbols. String
580
+ * keys can include or omit the `:` prefix. The following are equivalent:
581
+ *
582
+ * db.query_single_value('select x from foo where x = :bar', bar: 42)
583
+ * db.query_single_value('select x from foo where x = :bar', 'bar' => 42)
584
+ * db.query_single_value('select x from foo where x = :bar', ':bar' => 42)
585
+ */
473
586
  VALUE Database_query_single_value(int argc, VALUE *argv, VALUE self) {
474
587
  query_ctx ctx = { self, argc, argv, 0 };
475
588
  return rb_ensure(safe_query_single_value, (VALUE)&ctx, cleanup_stmt, (VALUE)&ctx);
476
589
  }
477
590
 
591
+ /* call-seq: last_insert_rowid
592
+ *
593
+ * Returns the rowid of the last inserted row.
594
+ */
478
595
  VALUE Database_last_insert_rowid(VALUE self) {
479
596
  Database_t *db;
480
597
  GetOpenDatabase(self, db);
@@ -482,6 +599,10 @@ VALUE Database_last_insert_rowid(VALUE self) {
482
599
  return INT2NUM(sqlite3_last_insert_rowid(db->sqlite3_db));
483
600
  }
484
601
 
602
+ /* call-seq: changes
603
+ *
604
+ * Returns the number of changes made to the database by the last operation.
605
+ */
485
606
  VALUE Database_changes(VALUE self) {
486
607
  Database_t *db;
487
608
  GetOpenDatabase(self, db);
@@ -489,6 +610,10 @@ VALUE Database_changes(VALUE self) {
489
610
  return INT2NUM(sqlite3_changes(db->sqlite3_db));
490
611
  }
491
612
 
613
+ /* call-seq: filename
614
+ *
615
+ * Returns the database filename.
616
+ */
492
617
  VALUE Database_filename(int argc, VALUE *argv, VALUE self) {
493
618
  const char *db_name;
494
619
  const char *filename;
@@ -501,6 +626,10 @@ VALUE Database_filename(int argc, VALUE *argv, VALUE self) {
501
626
  return filename ? rb_str_new_cstr(filename) : Qnil;
502
627
  }
503
628
 
629
+ /* call-seq: transaction_active?
630
+ *
631
+ * Returns true if a transaction is currently in progress.
632
+ */
504
633
  VALUE Database_transaction_active_p(VALUE self) {
505
634
  Database_t *db;
506
635
  GetOpenDatabase(self, db);
@@ -508,6 +637,10 @@ VALUE Database_transaction_active_p(VALUE self) {
508
637
  return sqlite3_get_autocommit(db->sqlite3_db) ? Qfalse : Qtrue;
509
638
  }
510
639
 
640
+ /* call-seq: load_extension(path)
641
+ *
642
+ * Loads an extension with the given path.
643
+ */
511
644
  VALUE Database_load_extension(VALUE self, VALUE path) {
512
645
  Database_t *db;
513
646
  GetOpenDatabase(self, db);
data/extralite.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.homepage = 'https://github.com/digital-fabric/extralite'
12
12
  s.metadata = {
13
13
  "source_code_uri" => "https://github.com/digital-fabric/extralite",
14
- "documentation_uri" => "https://github.com/digital-fabric/extralite",
14
+ "documentation_uri" => "https://www.rubydoc.info/gems/extralite",
15
15
  "homepage_uri" => "https://github.com/digital-fabric/extralite",
16
16
  "changelog_uri" => "https://github.com/digital-fabric/extralite/blob/master/CHANGELOG.md"
17
17
  }
@@ -21,10 +21,10 @@ Gem::Specification.new do |s|
21
21
  s.require_paths = ["lib"]
22
22
  s.required_ruby_version = '>= 2.6'
23
23
 
24
- s.add_development_dependency 'rake-compiler', '1.1.1'
25
- s.add_development_dependency 'minitest', '5.14.4'
24
+ s.add_development_dependency 'rake-compiler', '1.1.6'
25
+ s.add_development_dependency 'minitest', '5.15.0'
26
26
  s.add_development_dependency 'simplecov', '0.17.1'
27
- s.add_development_dependency 'rubocop', '0.85.1'
28
- s.add_development_dependency 'pry', '0.13.1'
27
+ s.add_development_dependency 'yard', '0.9.27'
28
+
29
29
  s.add_development_dependency 'sequel', '5.51.0'
30
30
  end
@@ -1,3 +1,3 @@
1
1
  module Extralite
2
- VERSION = '1.7'
2
+ VERSION = '1.10'
3
3
  end
data/lib/extralite.rb CHANGED
@@ -1 +1,21 @@
1
1
  require_relative './extralite_ext'
2
+
3
+ # Extralite is a Ruby gem for working with SQLite databases
4
+ module Extralite
5
+ # A base class for Extralite exceptions
6
+ class Error < RuntimeError
7
+ end
8
+
9
+ # An exception representing an SQL error emitted by SQLite
10
+ class SQLError < Error
11
+ end
12
+
13
+ # An exception raised when an SQLite database is busy (locked by another
14
+ # thread or process)
15
+ class BusyError < Error
16
+ end
17
+
18
+ # An SQLite database
19
+ class Database
20
+ end
21
+ end
@@ -1,5 +1,9 @@
1
1
  # frozen-string-literal: true
2
2
 
3
+ # This file was adapted from the SQLite adapter included in Sequel:
4
+ # https://github.com/jeremyevans/sequel
5
+ # (distributed under the MIT license)
6
+
3
7
  require 'extralite'
4
8
  require 'sequel/adapters/shared/sqlite'
5
9
 
data/test/perf_ary.rb ADDED
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+ gem 'sqlite3'
8
+ gem 'extralite', path: '..'
9
+ gem 'benchmark-ips'
10
+ end
11
+
12
+ require 'benchmark/ips'
13
+ require 'fileutils'
14
+
15
+ DB_PATH = '/tmp/extralite_sqlite3_perf.db'
16
+
17
+ def prepare_database(count)
18
+ FileUtils.rm(DB_PATH) rescue nil
19
+ db = Extralite::Database.new(DB_PATH)
20
+ db.query('create table foo ( a integer primary key, b text )')
21
+ db.query('begin')
22
+ count.times { db.query('insert into foo (b) values (?)', "hello#{rand(1000)}" )}
23
+ db.query('commit')
24
+ end
25
+
26
+ def sqlite3_run(count)
27
+ db = SQLite3::Database.new(DB_PATH)
28
+ results = db.execute('select * from foo')
29
+ raise unless results.size == count
30
+ end
31
+
32
+ def extralite_run(count)
33
+ db = Extralite::Database.new(DB_PATH)
34
+ results = db.query_ary('select * from foo')
35
+ raise unless results.size == count
36
+ end
37
+
38
+ [10, 1000, 100000].each do |c|
39
+ puts; puts; puts "Record count: #{c}"
40
+
41
+ prepare_database(c)
42
+
43
+ Benchmark.ips do |x|
44
+ x.config(:time => 3, :warmup => 1)
45
+
46
+ x.report("sqlite3") { sqlite3_run(c) }
47
+ x.report("extralite") { extralite_run(c) }
48
+
49
+ x.compare!
50
+ end
51
+ end
File without changes
@@ -138,6 +138,31 @@ end
138
138
  r = @db.query('select x, y, z from t where z = :bazzz', ':bazzz' => 6)
139
139
  assert_equal [{ x: 4, y: 5, z: 6 }], r
140
140
  end
141
+
142
+ def test_parameter_binding_with_index_key
143
+ r = @db.query('select x, y, z from t where z = ?', 1 => 3)
144
+ assert_equal [{ x: 1, y: 2, z: 3 }], r
145
+
146
+ r = @db.query('select x, y, z from t where x = ?2', 1 => 42, 2 => 4)
147
+ assert_equal [{ x: 4, y: 5, z: 6 }], r
148
+ end
149
+
150
+ def test_value_casting
151
+ r = @db.query_single_value("select 'abc'")
152
+ assert_equal 'abc', r
153
+
154
+ r = @db.query_single_value('select 123')
155
+ assert_equal 123, r
156
+
157
+ r = @db.query_single_value('select 12.34')
158
+ assert_equal 12.34, r
159
+
160
+ r = @db.query_single_value('select zeroblob(4)')
161
+ assert_equal "\x00\x00\x00\x00", r
162
+
163
+ r = @db.query_single_value('select null')
164
+ assert_nil r
165
+ end
141
166
  end
142
167
 
143
168
  class ScenarioTest < MiniTest::Test
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extralite
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.7'
4
+ version: '1.10'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-13 00:00:00.000000000 Z
11
+ date: 2021-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 1.1.1
19
+ version: 1.1.6
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 1.1.1
26
+ version: 1.1.6
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 5.14.4
33
+ version: 5.15.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 5.14.4
40
+ version: 5.15.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: simplecov
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,33 +53,19 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.17.1
55
55
  - !ruby/object:Gem::Dependency
56
- name: rubocop
56
+ name: yard
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 0.85.1
61
+ version: 0.9.27
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 0.85.1
69
- - !ruby/object:Gem::Dependency
70
- name: pry
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - '='
74
- - !ruby/object:Gem::Version
75
- version: 0.13.1
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - '='
81
- - !ruby/object:Gem::Version
82
- version: 0.13.1
68
+ version: 0.9.27
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: sequel
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -102,6 +88,7 @@ extensions:
102
88
  extra_rdoc_files:
103
89
  - README.md
104
90
  files:
91
+ - ".github/FUNDING.yml"
105
92
  - ".github/workflows/test.yml"
106
93
  - ".gitignore"
107
94
  - CHANGELOG.md
@@ -119,7 +106,8 @@ files:
119
106
  - lib/extralite/version.rb
120
107
  - lib/sequel/adapters/extralite.rb
121
108
  - test/helper.rb
122
- - test/perf.rb
109
+ - test/perf_ary.rb
110
+ - test/perf_hash.rb
123
111
  - test/run.rb
124
112
  - test/test_database.rb
125
113
  - test/test_sequel.rb
@@ -128,7 +116,7 @@ licenses:
128
116
  - MIT
129
117
  metadata:
130
118
  source_code_uri: https://github.com/digital-fabric/extralite
131
- documentation_uri: https://github.com/digital-fabric/extralite
119
+ documentation_uri: https://www.rubydoc.info/gems/extralite
132
120
  homepage_uri: https://github.com/digital-fabric/extralite
133
121
  changelog_uri: https://github.com/digital-fabric/extralite/blob/master/CHANGELOG.md
134
122
  post_install_message: