extralite 1.4 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b112a3c34429f8b44c4b4a922c4e038387f6c1db54e6f01377200d7a60324dd4
4
- data.tar.gz: a664bc81719347079fdfbbffdf2e665bd2772fe8dcf9c30b3ec18c6238a8888a
3
+ metadata.gz: 149ddf21bc7feaf4d7c3a19011ac9a515fe83d5f57b88c507783bee8c6d5e096
4
+ data.tar.gz: 55507a0acbd8efeb89d5dfcf652441081285a670a5968a96f2696d3073844975
5
5
  SHA512:
6
- metadata.gz: '053783bb3f186130fc92b0a57403f0f9472a98e6ce45b1fbb128c5e43914b2a6ec56d39a5e6b10e16f5e6b46f8e9d586837860f63e7538ad238fc0a7aa0995c3'
7
- data.tar.gz: '058538866f9b2c6a5a0116c8ed3a801aa7bbb8ef8f911eff6d94d7a9cfa98861ad98f4d27e06a736b18c4b62e3c2369a4a306492cc562693da0282363e00f208'
6
+ metadata.gz: c7cdc5d0179c26c3deddc8439e4aaa5f91429ed3839cffc2224fefd8e90c78f0db9c4768f9534b693638572ec5e99ab0317a948f037c654262eca6d801a438f9
7
+ data.tar.gz: 4ae156e6850e5485b31b1f701597c0692608b59facd1473ca064d0b23ca8b5d2d84995f4fe4c99800b3e01815fb32e21481290e369506e5d2c4e9794af8fe853
@@ -8,7 +8,7 @@ jobs:
8
8
  fail-fast: false
9
9
  matrix:
10
10
  os: [ubuntu-latest]
11
- ruby: [2.6, 2.7, 3.0]
11
+ ruby: [2.6, 2.7, '3.0']
12
12
 
13
13
  name: >-
14
14
  ${{matrix.os}}, ${{matrix.ruby}}
@@ -16,15 +16,10 @@ jobs:
16
16
  runs-on: ${{matrix.os}}
17
17
  steps:
18
18
  - uses: actions/checkout@v1
19
- - uses: actions/setup-ruby@v1
19
+ - uses: ruby/setup-ruby@v1
20
20
  with:
21
21
  ruby-version: ${{matrix.ruby}}
22
- - name: Install dependencies
23
- run: |
24
- gem install bundler
25
- bundle install
26
- - name: Show Linux kernel version
27
- run: uname -r
22
+ bundler-cache: true # 'bundle install' and cache
28
23
  - name: Compile C-extension
29
24
  run: bundle exec rake compile
30
25
  - name: Run tests
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## 1.8 2021-12-15
2
+
3
+ - Add documentation
4
+
5
+ ## 1.7 2021-12-13
6
+
7
+ - Add extralite Sequel adapter
8
+ - Add support for binding hash parameters
9
+
10
+ ## 1.6 2021-12-13
11
+
12
+ - Release GVL while fetching rows
13
+
14
+ ## 1.5 2021-12-13
15
+
16
+ - Release GVL while preparing statements
17
+ - Use `sqlite3_prepare_v2` instead of deprecated `sqlite_prepare`
18
+
1
19
  ## 1.4 2021-08-25
2
20
 
3
21
  - Fix possible segfault in cleanup_stmt
data/Gemfile.lock CHANGED
@@ -1,58 +1,37 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- extralite (1.4)
4
+ extralite (1.8)
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)
15
+ sequel (5.51.0)
39
16
  simplecov (0.17.1)
40
17
  docile (~> 1.1)
41
18
  json (>= 1.8, < 3)
42
19
  simplecov-html (~> 0.10.0)
43
20
  simplecov-html (0.10.2)
44
- unicode-display_width (1.7.0)
21
+ webrick (1.7.0)
22
+ yard (0.9.27)
23
+ webrick (~> 1.7.0)
45
24
 
46
25
  PLATFORMS
47
26
  ruby
48
27
 
49
28
  DEPENDENCIES
50
29
  extralite!
51
- minitest (= 5.14.4)
52
- pry (= 0.13.1)
53
- rake-compiler (= 1.1.1)
54
- rubocop (= 0.85.1)
30
+ minitest (= 5.15.0)
31
+ rake-compiler (= 1.1.6)
32
+ sequel (= 5.51.0)
55
33
  simplecov (= 0.17.1)
34
+ yard (= 0.9.27)
56
35
 
57
36
  BUNDLED WITH
58
37
  2.1.4
data/README.md CHANGED
@@ -6,22 +6,29 @@
6
6
 
7
7
  ## What is Extralite?
8
8
 
9
- Extralite is an extra-lightweight (less than 400 lines of C-code) SQLite3 wrapper for
10
- Ruby. It provides a single class with a minimal set of methods to interact with
11
- an SQLite3 database.
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.
12
12
 
13
13
  ## Features
14
14
 
15
- - A variety of methods for different data access patterns: row as hash, row as
16
- array, single single row, single column, single value.
15
+ - A variety of methods for different data access patterns: rows as hashes, rows
16
+ as arrays, single row, single column, single value.
17
+ - Super fast - [up to 12.5x faster](#performance) than the
18
+ [sqlite3](https://github.com/sparklemotion/sqlite3-ruby) gem (see also
19
+ [comparison](#why-not-just-use-the-sqlite3-gem).)
20
+ - Improved [concurrency](#what-about-concurrency) for multithreaded apps: the
21
+ Ruby GVL is released while preparing SQL statements and while iterating over
22
+ results.
17
23
  - Iterate over records with a block, or collect records into an array.
18
24
  - Parameter binding.
19
- - Correctly execute strings with multiple semicolon-separated queries (handy for
20
- creating/modifying schemas).
25
+ - Automatically execute SQL strings containing multiple semicolon-separated
26
+ queries (handy for creating/modifying schemas).
21
27
  - Get last insert rowid.
22
28
  - Get number of rows changed by last query.
23
29
  - Load extensions (loading of extensions is autmatically enabled. You can find
24
30
  some useful extensions here: https://github.com/nalgeon/sqlean.)
31
+ - Includes a [Sequel adapter](#usage-with-sequel) (an ActiveRecord)
25
32
 
26
33
  ## Usage
27
34
 
@@ -60,8 +67,13 @@ db.query_single_value("select 'foo'") #=> "foo"
60
67
  # parameter binding (works for all query_xxx methods)
61
68
  db.query_hash('select ? as foo, ? as bar', 1, 2) #=> [{ :foo => 1, :bar => 2 }]
62
69
 
70
+ # parameter binding of named parameters
71
+ db.query('select * from foo where bar = :bar', bar: 42)
72
+ db.query('select * from foo where bar = :bar', 'bar' => 42)
73
+ db.query('select * from foo where bar = :bar', ':bar' => 42)
74
+
63
75
  # get last insert rowid
64
- rowid = db.last_insert_id
76
+ rowid = db.last_insert_rowid
65
77
 
66
78
  # get number of rows changed in last query
67
79
  number_of_rows_affected = db.changes
@@ -77,23 +89,74 @@ db.close
77
89
  db.closed? #=> true
78
90
  ```
79
91
 
92
+ ## Usage with Sequel
93
+
94
+ Extralite includes an adapter for
95
+ [Sequel](https://github.com/jeremyevans/sequel). To use the Extralite adapter,
96
+ just use the `extralite` scheme instead of `sqlite`:
97
+
98
+ ```ruby
99
+ DB = Sequel.connect('extralite:blog.db')
100
+ articles = DB[:articles]
101
+ p articles.to_a
102
+ ```
103
+
104
+ (Make sure you include `extralite` as a dependency in your `Gemfile`.)
105
+
80
106
  ## Why not just use the sqlite3 gem?
81
107
 
82
- The sqlite3-ruby gem is a popular, solid, well-maintained project, used by
83
- thousands of developers. I've been doing a lot of work with SQLite3 lately, and
84
- wanted to have a simpler API that gives me query results in a variety of ways.
85
- Thus extralite was born.
108
+ The [sqlite3-ruby](https://github.com/sparklemotion/sqlite3-ruby) gem is a
109
+ popular, solid, well-maintained project, used by thousands of developers. I've
110
+ been doing a lot of work with SQLite3 databases lately, and wanted to have a
111
+ simpler API that gives me query results in a variety of ways. Thus extralite was
112
+ born.
113
+
114
+ Extralite is quite a bit [faster](#performance) than sqlite3-ruby and is also
115
+ [thread-friendly](#what-about-concurrency). On the other hand, Extralite does
116
+ not have support for defining custom functions, aggregates and collations. If
117
+ you're using those features, you'll need to stick with sqlite3-ruby.
118
+
119
+ Here's a table summarizing the differences between the two gems:
120
+
121
+ | |sqlite3-ruby|Extralite|
122
+ |-|-|-|
123
+ |API design|multiple classes|single class|
124
+ |Query results|row as hash, row as array, single row, single value|row as hash, row as array, __single column__, single row, single value|
125
+ |execute multiple statements|separate API (#execute_batch)|integrated|
126
+ |custom functions in Ruby|yes|no|
127
+ |custom collations|yes|no|
128
+ |custom aggregate functions|yes|no|
129
+ |Multithread friendly|no|[yes](#what-about-concurrency)|
130
+ |Code size|~2650LoC|~500LoC|
131
+ |Performance|1x|1.5x to 12.5x (see [below](#performance))|
86
132
 
87
133
  ## What about concurrency?
88
134
 
89
- Extralite currently does not release the GVL. This means that even if queries
90
- are executed on a separate thread, no other Ruby threads will be scheduled while
91
- SQLite3 is busy fetching the next record.
135
+ Extralite releases the GVL while making blocking calls to the sqlite3 library,
136
+ that is while preparing SQL statements and fetching rows. Releasing the GVL
137
+ allows other threads to run while the sqlite3 library is busy compiling SQL into
138
+ bytecode, or fetching the next row. This does not seem to hurt Extralite's
139
+ performance:
140
+
141
+ ## Performance
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):
149
+
150
+ |Row count|sqlite3-ruby (baseline)|Extralite (relative - rounded)|
151
+ |-:|-:|-:|
152
+ |10|1x|1.5x|
153
+ |1K|1x|7x|
154
+ |100K|1x|12.5x|
92
155
 
93
- In the future Extralite might be changed to release the GVL each time
94
- `sqlite3_step` is called.
156
+ (If you're interested in checking this yourself, just run the script and let me
157
+ know if your results are different.)
95
158
 
96
- ## Can I use it with an ORM like ActiveRecord or Sequel?
159
+ ## Contributing
97
160
 
98
- Not yet, but you are welcome to contribute adapters for those projects. I will
99
- be releasing my own not-an-ORM tool in the near future.
161
+ Contributions in the form of issues, PRs or comments will be greatly
162
+ 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
- exec 'ruby test/test_database.rb'
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