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 +4 -4
- data/.github/workflows/test.yml +3 -8
- data/CHANGELOG.md +18 -0
- data/Gemfile.lock +12 -33
- data/README.md +83 -20
- data/Rakefile +17 -8
- data/ext/extralite/extralite.c +239 -26
- data/extralite.gemspec +5 -5
- data/lib/extralite/version.rb +1 -1
- data/lib/extralite.rb +20 -0
- data/lib/sequel/adapters/extralite.rb +380 -0
- data/test/perf.rb +51 -0
- data/test/run.rb +5 -0
- data/test/test_database.rb +108 -3
- data/test/test_sequel.rb +24 -0
- metadata +16 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 149ddf21bc7feaf4d7c3a19011ac9a515fe83d5f57b88c507783bee8c6d5e096
|
4
|
+
data.tar.gz: 55507a0acbd8efeb89d5dfcf652441081285a670a5968a96f2696d3073844975
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7cdc5d0179c26c3deddc8439e4aaa5f91429ed3839cffc2224fefd8e90c78f0db9c4768f9534b693638572ec5e99ab0317a948f037c654262eca6d801a438f9
|
7
|
+
data.tar.gz: 4ae156e6850e5485b31b1f701597c0692608b59facd1473ca064d0b23ca8b5d2d84995f4fe4c99800b3e01815fb32e21481290e369506e5d2c4e9794af8fe853
|
data/.github/workflows/test.yml
CHANGED
@@ -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:
|
19
|
+
- uses: ruby/setup-ruby@v1
|
20
20
|
with:
|
21
21
|
ruby-version: ${{matrix.ruby}}
|
22
|
-
|
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
|
+
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
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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
|
-
|
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.
|
52
|
-
|
53
|
-
|
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
|
10
|
-
Ruby. It provides a single class with a minimal set of methods to
|
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:
|
16
|
-
|
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
|
-
-
|
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.
|
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
|
83
|
-
thousands of developers. I've
|
84
|
-
|
85
|
-
Thus extralite was
|
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
|
90
|
-
|
91
|
-
|
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
|
-
|
94
|
-
|
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
|
-
##
|
159
|
+
## Contributing
|
97
160
|
|
98
|
-
|
99
|
-
|
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
|
4
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/clean'
|
5
5
|
|
6
|
-
require
|
7
|
-
Rake::ExtensionTask.new(
|
8
|
-
ext.ext_dir =
|
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/
|
16
|
+
exec 'ruby test/run.rb'
|
16
17
|
end
|
17
18
|
|
18
|
-
CLEAN.include
|
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
|