activerecord-enhancedsqlite3-adapter 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +72 -11
- data/lib/enhanced_sqlite3/adapter.rb +23 -0
- data/lib/enhanced_sqlite3/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24efb62453474faa0b37357d98f5b0f8ba13fa98d7e633b5d3a7de5e16d875f6
|
4
|
+
data.tar.gz: 0de2b8cae842c4262d81932c577df7731e570f347f0a22a2151ef9671bd8648d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a55c35f42fef85b0373df52f06d1b50b66c4191382844ee6a9836049af03386085bfe9616de8bfc259fcfd6325d5a84f4cc8ca396d721ff87fdcfc49c80dae17
|
7
|
+
data.tar.gz: b50f2484872aa18a0681c31abfd4d6a56e044ff9610cb288c73611cb0f56ed8b8242a771b9c4e95a07119ec094aef5bcf6c85f1bc363fd08e59d45a57b162902
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.3.0] - 2023-12-06
|
4
|
+
|
5
|
+
- Added a more performant implementation of the the `timeout` mechanism
|
6
|
+
|
7
|
+
## [0.2.0] - 2023-09-28
|
8
|
+
|
9
|
+
- Added support for deferrable constraints
|
10
|
+
|
3
11
|
## [0.1.0] - 2023-09-28
|
4
12
|
|
5
13
|
- Initial release
|
14
|
+
- Added support for virtual columns
|
15
|
+
- Added support setting PRAGMA statements via the `config/database.yml` file
|
16
|
+
- Added support for loading extensions via the `config/database.yml` file
|
data/README.md
CHANGED
@@ -1,24 +1,85 @@
|
|
1
|
-
#
|
1
|
+
# ActiveRecord Enhanced SQLite3 Adapter
|
2
2
|
|
3
|
-
|
3
|
+
Enhance ActiveRecord's 7.1 SQLite3 adapter. Adds support for:
|
4
4
|
|
5
|
-
|
5
|
+
* generated columns,
|
6
|
+
* deferred foreign keys,
|
7
|
+
* `PRAGMA` tuning,
|
8
|
+
* and extension loading
|
6
9
|
|
7
10
|
## Installation
|
8
11
|
|
9
|
-
TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
|
10
|
-
|
11
12
|
Install the gem and add to the application's Gemfile by executing:
|
12
13
|
|
13
|
-
|
14
|
+
```shell
|
15
|
+
$ bundle add activerecord-enhancedsqlite3-adapter
|
16
|
+
```
|
14
17
|
|
15
|
-
|
18
|
+
## Usage
|
16
19
|
|
17
|
-
|
20
|
+
This gem hooks into your Rails application to enhance the `SQLite3Adapter` automatically. No setup required!
|
18
21
|
|
19
|
-
|
22
|
+
Once installed, you can take advantage of the added features.
|
23
|
+
|
24
|
+
### Generated columns
|
25
|
+
|
26
|
+
You can now create `virtual` columns, both stored and dynamic. The [SQLite docs](https://www.sqlite.org/gencol.html) explain the difference:
|
27
|
+
|
28
|
+
> Generated columns can be either VIRTUAL or STORED. The value of a VIRTUAL column is computed when read, whereas the value of a STORED column is computed when the row is written. STORED columns take up space in the database file, whereas VIRTUAL columns use more CPU cycles when being read.
|
29
|
+
|
30
|
+
The default is to create dynamic/virtual columns.
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
create_table :virtual_columns, force: true do |t|
|
34
|
+
t.string :name
|
35
|
+
t.virtual :upper_name, type: :string, as: "UPPER(name)", stored: true
|
36
|
+
t.virtual :lower_name, type: :string, as: "LOWER(name)", stored: false
|
37
|
+
t.virtual :octet_name, type: :integer, as: "LENGTH(name)"
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
### Deferred foreign keys
|
42
|
+
|
43
|
+
You can now specify whether or not a foreign key should be deferrable, whether `:deferred` or `:immediate`.
|
44
|
+
|
45
|
+
`:deferred` foreign keys mean that the constraint check will be done once the transaction is committed and allows the constraint behavior to change within transaction. `:immediate` means that constraint check is immediate and allows the constraint behavior to change within transaction. The default is `:immediate`.
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
add_reference :person, :alias, foreign_key: { deferrable: :deferred }
|
49
|
+
add_reference :alias, :person, foreign_key: { deferrable: :deferred }
|
50
|
+
```
|
51
|
+
|
52
|
+
### `PRAGMA` tuning
|
53
|
+
|
54
|
+
Pass any [`PRAGMA` key-value pair](https://www.sqlite.org/pragma.html) under a `pragmas` list in your `config/database.yml` file to ensure that these configuration settings are applied to all database connections.
|
55
|
+
|
56
|
+
```yaml
|
57
|
+
default: &default
|
58
|
+
adapter: sqlite3
|
59
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
60
|
+
pragmas:
|
61
|
+
# level of database durability, 2 = "FULL" (sync on every write), other values include 1 = "NORMAL" (sync every 1000 written pages) and 0 = "NONE"
|
62
|
+
# https://www.sqlite.org/pragma.html#pragma_synchronous
|
63
|
+
synchronous: "FULL"
|
64
|
+
```
|
65
|
+
|
66
|
+
### Extension loading
|
67
|
+
|
68
|
+
There are a number of [SQLite extensions available as Ruby gems](https://github.com/asg017/sqlite-ecosystem). In order to load the extensions, you need to install the gem (`bundle add {extension-name}`) and then load it into the database connections. In order to support the latter, this gem enhances the `config/database.yml` file to support an `extensions` array. For example, to install and load [an extension](https://github.com/asg017/sqlite-ulid) for supporting [<abbr title="Universally Unique Lexicographically Sortable Identifiers">ULIDs</abbr>](https://github.com/ulid/spec), we would do:
|
69
|
+
|
70
|
+
```shell
|
71
|
+
$ bundle add sqlite_ulid
|
72
|
+
```
|
73
|
+
|
74
|
+
then
|
20
75
|
|
21
|
-
|
76
|
+
```yaml
|
77
|
+
default: &default
|
78
|
+
adapter: sqlite3
|
79
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
80
|
+
extensions:
|
81
|
+
- sqlite_ulid
|
82
|
+
```
|
22
83
|
|
23
84
|
## Development
|
24
85
|
|
@@ -28,7 +89,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
28
89
|
|
29
90
|
## Contributing
|
30
91
|
|
31
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
92
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/fractaledmind/activerecord-enhancedsqlite3-adapter.
|
32
93
|
|
33
94
|
## License
|
34
95
|
|
@@ -22,6 +22,7 @@ module EnhancedSQLite3
|
|
22
22
|
def configure_connection
|
23
23
|
super
|
24
24
|
|
25
|
+
configure_busy_handler_timeout
|
25
26
|
configure_pragmas
|
26
27
|
configure_extensions
|
27
28
|
|
@@ -31,6 +32,28 @@ module EnhancedSQLite3
|
|
31
32
|
|
32
33
|
private
|
33
34
|
|
35
|
+
def configure_busy_handler_timeout
|
36
|
+
return unless @config.key?(:timeout)
|
37
|
+
|
38
|
+
timeout = self.class.type_cast_config_to_integer(@config[:timeout])
|
39
|
+
@raw_connection.busy_handler do |count|
|
40
|
+
timed_out = false
|
41
|
+
# capture the start time of this blocked write
|
42
|
+
@start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) if count == 0
|
43
|
+
# keep track of elapsed time every 100 iterations (to lower load)
|
44
|
+
if count % 100 == 0
|
45
|
+
@elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start_time
|
46
|
+
# fail if we exceed the timeout value (captured from the timeout config option, converted to seconds)
|
47
|
+
timed_out = @elapsed_time > timeout
|
48
|
+
end
|
49
|
+
if timed_out
|
50
|
+
false # this will cause the BusyException to be raised
|
51
|
+
else
|
52
|
+
sleep 0.001 # sleep 1 millisecond (or whatever)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
34
57
|
def configure_pragmas
|
35
58
|
@config.fetch(:pragmas, []).each do |key, value|
|
36
59
|
execute("PRAGMA #{key} = #{value}", "SCHEMA")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-enhancedsqlite3-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Margheim
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|