sqlite_crypto 2.0.2 → 2.2.0
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/CHANGELOG.md +27 -1
- data/README.md +54 -13
- data/lib/sqlite_crypto/id_types.rb +31 -0
- data/lib/sqlite_crypto/migration_helpers.rb +3 -5
- data/lib/sqlite_crypto/model_extensions.rb +45 -0
- data/lib/sqlite_crypto/schema_dumper.rb +6 -5
- data/lib/sqlite_crypto/sqlite3_adapter_extension.rb +4 -2
- data/lib/sqlite_crypto/version.rb +1 -1
- data/lib/sqlite_crypto.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed3f34d6f260bfcbe3487f7b13489eff823b0e5d0bfc3f0459a166218b76b141
|
|
4
|
+
data.tar.gz: 97ba38c69e755ffe3efee31d377e5e8cf056e833c41bdea26eea5f2bff5af120
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 36e76170a44cb93f67fc21ac758b9a5513a5d372d904564198072b9bc8f578e223f5a176ad8733c525c2db40456d1944f1ecaf68cbd5ea7bf9bb3549ae1e8bfd
|
|
7
|
+
data.tar.gz: 556b244e3c93b4b4d66f450a99d125edf20ede805b4e89831fbd21110054bab971dbf00d9a1b91a94a6891c5cb3ff1b7a01c25e60b1cc2012bb7c0254a43ae10
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.2.0] - 2026-05-08
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Theme-aware README logo**: Added dark-mode/light-mode logo switching via `<picture>` in `README.md`
|
|
12
|
+
- **Shared ID type mapping module**: Added `SqliteCrypto::IdTypes` to centralize UUID/ULID limit and type detection logic
|
|
13
|
+
- Unit specs for `SqliteCrypto::IdTypes`
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Refactored schema dumper, migration helpers, model extensions, and SQLite adapter extension to use `SqliteCrypto::IdTypes`
|
|
17
|
+
- Updated `.ruby-version` from `4.0.0` to `4.0.3`
|
|
18
|
+
- Refreshed README badges and compatibility notes
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- Removed repeated migration fixture loading warning by replacing `load` with `require_relative` in migration integration spec
|
|
22
|
+
|
|
23
|
+
## [2.1.0] - 2026-03-22
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- **Auto primary key generation**: Models with UUID or ULID primary keys now automatically generate
|
|
27
|
+
their primary key on create — no explicit `generates_uuid`/`generates_ulid` call needed
|
|
28
|
+
- `_sqlite_crypto_pk_type` class method for inspecting the detected primary key type (`:uuid`, `:ulid`, or `nil`).
|
|
29
|
+
Detection is based on column schema (string, limit 36 → `:uuid`; limit 26 → `:ulid`) and is cached per class
|
|
30
|
+
|
|
31
|
+
### Acknowledgements
|
|
32
|
+
- Thanks to [@joel](https://github.com/joel) for the contribution in [#20](https://github.com/bart-oz/sqlite_crypto/pull/20)
|
|
33
|
+
|
|
8
34
|
## [2.0.2] - 2026-02-11
|
|
9
35
|
|
|
10
36
|
### Fixed
|
|
@@ -145,4 +171,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
145
171
|
### Fixed
|
|
146
172
|
- Rails version compatibility for migrations (supports Rails 7.1 through 8.1)
|
|
147
173
|
- Schema dumper prepend timing by loading sqlite3_adapter explicitly
|
|
148
|
-
- ULID foreign key detection with proper table name pluralization
|
|
174
|
+
- ULID foreign key detection with proper table name pluralization
|
data/README.md
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset=".github/workflows/logo_dark.svg">
|
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset=".github/workflows/logo_light.svg">
|
|
5
|
+
<img alt="sqlite_crypto logo" src=".github/workflows/logo_light.svg" width="220">
|
|
6
|
+
</picture>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://github.com/bart-oz/sqlite_crypto/releases">
|
|
11
|
+
<img src="https://img.shields.io/badge/version-2.2.0-blue.svg" alt="Version">
|
|
12
|
+
</a>
|
|
13
|
+
<a href="LICENSE.txt">
|
|
14
|
+
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
|
|
15
|
+
</a>
|
|
16
|
+
<a href="https://github.com/bart-oz/sqlite_crypto">
|
|
17
|
+
<img src="https://img.shields.io/badge/types-ULID,_UUIDv7/v4-brightgreen.svg" alt="Types supported">
|
|
18
|
+
</a>
|
|
19
|
+
<a href="https://github.com/bart-oz/sqlite_crypto/actions/workflows/ci.yml">
|
|
20
|
+
<img src="https://github.com/bart-oz/sqlite_crypto/actions/workflows/ci.yml/badge.svg" alt="Tests">
|
|
21
|
+
</a>
|
|
22
|
+
<a href="https://github.com/bart-oz/sqlite_crypto">
|
|
23
|
+
<img src="https://img.shields.io/badge/status-active-success.svg" alt="Status">
|
|
24
|
+
</a>
|
|
25
|
+
</p>
|
|
9
26
|
|
|
10
27
|
## Overview
|
|
11
28
|
|
|
@@ -24,11 +41,11 @@ end
|
|
|
24
41
|
- Automatic foreign key type detection
|
|
25
42
|
- Model-level ID generation
|
|
26
43
|
- Clean schema.rb output
|
|
27
|
-
-
|
|
44
|
+
- Lightweight runtime dependencies (`rails`, `sqlite3`, `ulid`)
|
|
28
45
|
|
|
29
46
|
## Compatibility
|
|
30
47
|
|
|
31
|
-
**Ruby & Rails:**
|
|
48
|
+
**Ruby & Rails tested in CI:**
|
|
32
49
|
|
|
33
50
|
| | Rails 7.1 | Rails 7.2 | Rails 8.0 | Rails 8.1 |
|
|
34
51
|
|-------|-----------|-----------|-----------|-----------|
|
|
@@ -38,6 +55,11 @@ end
|
|
|
38
55
|
| Ruby 3.4 | ✓ | ✓ | ✓ | ✓ |
|
|
39
56
|
| Ruby 4.0 | ✓ | ✓ | ✓ | ✓ |
|
|
40
57
|
|
|
58
|
+
**Upstream lifecycle note (as of 2026-05-08):**
|
|
59
|
+
- Ruby 3.1 is EOL; Ruby 3.2 is EOL.
|
|
60
|
+
- Rails 7.1 is EOL.
|
|
61
|
+
- Rails 7.2 is security-fixes-only; Rails 8.0 and 8.1 are actively supported.
|
|
62
|
+
|
|
41
63
|
**UUID Versions:**
|
|
42
64
|
|
|
43
65
|
| Version | Ruby 3.1/3.2 | Ruby 3.3+ |
|
|
@@ -127,9 +149,28 @@ create_table :posts do |t|
|
|
|
127
149
|
end
|
|
128
150
|
```
|
|
129
151
|
|
|
130
|
-
**
|
|
152
|
+
**Automatic Primary Key Generation**
|
|
153
|
+
|
|
154
|
+
When a table uses `id: :uuid` or `id: :ulid`, the gem automatically generates
|
|
155
|
+
primary key values on record creation. No model-level configuration is needed:
|
|
156
|
+
|
|
157
|
+
```ruby
|
|
158
|
+
# migration
|
|
159
|
+
create_table :users, id: :uuid do |t|
|
|
160
|
+
t.string :email
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# model — no extra code required
|
|
164
|
+
class User < ApplicationRecord
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
user = User.create!(email: "test@example.com")
|
|
168
|
+
user.id # => "018d3f91-8f4a-7000-9e7b-4a5c8d2e1f3a"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Non-Primary-Key Columns**
|
|
131
172
|
|
|
132
|
-
Generate UUIDs or ULIDs for
|
|
173
|
+
Generate UUIDs or ULIDs for additional columns with `generates_uuid` / `generates_ulid`:
|
|
133
174
|
|
|
134
175
|
```ruby
|
|
135
176
|
class User < ApplicationRecord
|
|
@@ -218,4 +259,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/bart-o
|
|
|
218
259
|
|
|
219
260
|
## License
|
|
220
261
|
|
|
221
|
-
The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
|
262
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SqliteCrypto
|
|
4
|
+
module IdTypes
|
|
5
|
+
UUID_LENGTH = 36
|
|
6
|
+
ULID_LENGTH = 26
|
|
7
|
+
|
|
8
|
+
TYPE_TO_LIMIT = {
|
|
9
|
+
uuid: UUID_LENGTH,
|
|
10
|
+
ulid: ULID_LENGTH
|
|
11
|
+
}.freeze
|
|
12
|
+
LIMIT_TO_TYPE = TYPE_TO_LIMIT.invert.freeze
|
|
13
|
+
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
def string_limit_for(type)
|
|
17
|
+
TYPE_TO_LIMIT[type]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def type_from_string_limit(limit)
|
|
21
|
+
LIMIT_TO_TYPE[limit]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def type_from_sql_type(sql_type)
|
|
25
|
+
case sql_type.to_s.downcase
|
|
26
|
+
when "varchar(#{UUID_LENGTH})", "uuid" then :uuid
|
|
27
|
+
when "varchar(#{ULID_LENGTH})", "ulid" then :ulid
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "active_record/connection_adapters/sqlite3_adapter"
|
|
4
|
+
require "sqlite_crypto/id_types"
|
|
4
5
|
|
|
5
6
|
module SqliteCrypto
|
|
6
7
|
module MigrationHelpers
|
|
@@ -21,7 +22,7 @@ module SqliteCrypto
|
|
|
21
22
|
|
|
22
23
|
if (primary_key_type = detect_primary_key_type(ref_table))
|
|
23
24
|
options[:type] ||= :string
|
|
24
|
-
options[:limit] ||= (primary_key_type
|
|
25
|
+
options[:limit] ||= IdTypes.string_limit_for(primary_key_type)
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
super
|
|
@@ -43,10 +44,7 @@ module SqliteCrypto
|
|
|
43
44
|
pk_column = find_primary_key_column(table_name, conn)
|
|
44
45
|
return nil unless pk_column
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
when "varchar(36)", "uuid" then :uuid
|
|
48
|
-
when "varchar(26)", "ulid" then :ulid
|
|
49
|
-
end
|
|
47
|
+
IdTypes.type_from_sql_type(pk_column.sql_type)
|
|
50
48
|
end
|
|
51
49
|
|
|
52
50
|
def find_primary_key_column(table_name, conn)
|
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "ulid"
|
|
4
|
+
require "sqlite_crypto/id_types"
|
|
4
5
|
|
|
5
6
|
module SqliteCrypto
|
|
6
7
|
module ModelExtensions
|
|
7
8
|
extend ActiveSupport::Concern
|
|
8
9
|
|
|
10
|
+
included do
|
|
11
|
+
before_create :_sqlite_crypto_auto_generate_id
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def _sqlite_crypto_auto_generate_id
|
|
17
|
+
pk = self.class.primary_key
|
|
18
|
+
return unless pk
|
|
19
|
+
return if self[pk].present?
|
|
20
|
+
|
|
21
|
+
case self.class._sqlite_crypto_pk_type
|
|
22
|
+
when :uuid
|
|
23
|
+
self[pk] = SqliteCrypto::Generators::Uuid.generate
|
|
24
|
+
when :ulid
|
|
25
|
+
self[pk] = ULID.generate.to_s
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
9
29
|
module ClassMethods
|
|
10
30
|
def generates_uuid(attribute, unique: false)
|
|
11
31
|
before_create do
|
|
@@ -22,6 +42,31 @@ module SqliteCrypto
|
|
|
22
42
|
|
|
23
43
|
validates attribute, uniqueness: true if unique
|
|
24
44
|
end
|
|
45
|
+
|
|
46
|
+
# Detect if primary key is UUID or ULID based on column schema.
|
|
47
|
+
# Cached per class. Returns :uuid, :ulid, or nil.
|
|
48
|
+
def _sqlite_crypto_pk_type
|
|
49
|
+
return @_sqlite_crypto_pk_type if defined?(@_sqlite_crypto_pk_type)
|
|
50
|
+
@_sqlite_crypto_pk_type = _detect_sqlite_crypto_pk_type
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def _detect_sqlite_crypto_pk_type
|
|
56
|
+
return nil if abstract_class?
|
|
57
|
+
return nil unless table_exists?
|
|
58
|
+
|
|
59
|
+
pk = primary_key
|
|
60
|
+
return nil unless pk
|
|
61
|
+
|
|
62
|
+
column = columns_hash[pk]
|
|
63
|
+
return nil unless column
|
|
64
|
+
return nil unless column.type == :string
|
|
65
|
+
|
|
66
|
+
IdTypes.type_from_string_limit(column.limit)
|
|
67
|
+
rescue ActiveRecord::StatementInvalid
|
|
68
|
+
nil
|
|
69
|
+
end
|
|
25
70
|
end
|
|
26
71
|
end
|
|
27
72
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "sqlite_crypto/id_types"
|
|
4
|
+
|
|
3
5
|
module SqliteCrypto
|
|
4
6
|
module SchemaDumper
|
|
5
7
|
private
|
|
@@ -7,11 +9,10 @@ module SqliteCrypto
|
|
|
7
9
|
def column_spec_for_primary_key(column)
|
|
8
10
|
return super unless column.name == "id" && column.type == :string
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
12
|
+
primary_key_type = IdTypes.type_from_string_limit(column.limit)
|
|
13
|
+
return super unless primary_key_type
|
|
14
|
+
|
|
15
|
+
{id: primary_key_type}
|
|
15
16
|
end
|
|
16
17
|
end
|
|
17
18
|
end
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "sqlite_crypto/id_types"
|
|
4
|
+
|
|
3
5
|
module SqliteCrypto
|
|
4
6
|
module Sqlite3AdapterExtension
|
|
5
7
|
def native_database_types
|
|
6
8
|
super.merge(
|
|
7
|
-
uuid: {name: "varchar", limit:
|
|
8
|
-
ulid: {name: "varchar", limit:
|
|
9
|
+
uuid: {name: "varchar", limit: IdTypes::UUID_LENGTH},
|
|
10
|
+
ulid: {name: "varchar", limit: IdTypes::ULID_LENGTH}
|
|
9
11
|
)
|
|
10
12
|
end
|
|
11
13
|
end
|
data/lib/sqlite_crypto.rb
CHANGED
|
@@ -5,6 +5,7 @@ require "sqlite_crypto/configuration"
|
|
|
5
5
|
require "sqlite_crypto/railtie" if defined?(Rails)
|
|
6
6
|
require "sqlite_crypto/schema_dumper" if defined?(ActiveRecord)
|
|
7
7
|
require "sqlite_crypto/schema_definitions"
|
|
8
|
+
require "sqlite_crypto/id_types"
|
|
8
9
|
require "sqlite_crypto/generators/uuid"
|
|
9
10
|
|
|
10
11
|
module SqliteCrypto
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sqlite_crypto
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- BartOz
|
|
@@ -69,6 +69,7 @@ files:
|
|
|
69
69
|
- lib/sqlite_crypto.rb
|
|
70
70
|
- lib/sqlite_crypto/configuration.rb
|
|
71
71
|
- lib/sqlite_crypto/generators/uuid.rb
|
|
72
|
+
- lib/sqlite_crypto/id_types.rb
|
|
72
73
|
- lib/sqlite_crypto/migration_helpers.rb
|
|
73
74
|
- lib/sqlite_crypto/model_extensions.rb
|
|
74
75
|
- lib/sqlite_crypto/railtie.rb
|
|
@@ -98,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
98
99
|
- !ruby/object:Gem::Version
|
|
99
100
|
version: '0'
|
|
100
101
|
requirements: []
|
|
101
|
-
rubygems_version: 4.0.
|
|
102
|
+
rubygems_version: 4.0.6
|
|
102
103
|
specification_version: 4
|
|
103
104
|
summary: UUID (v4/v7) and ULID primary keys for Rails + SQLite3
|
|
104
105
|
test_files: []
|