extralite 1.4 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
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