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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80e11f5e0be719e1757f5c97c3702cc6a9f590cc098a28b530edd10b19a30c9f
4
- data.tar.gz: 4d93d3d9e8c4f1dcb266a9c5a20e0534e1f24e85373e2e4316630ab508ef3577
3
+ metadata.gz: ed3f34d6f260bfcbe3487f7b13489eff823b0e5d0bfc3f0459a166218b76b141
4
+ data.tar.gz: 97ba38c69e755ffe3efee31d377e5e8cf056e833c41bdea26eea5f2bff5af120
5
5
  SHA512:
6
- metadata.gz: f675ad1e8b7b0b389a322bc2b023c488f268f2b212ac6520c550c32b0d15095a72bc163d6c3dc57716a4f04e49aa4e9689743ed3c0b11bcbbd8ac05aa5b37f3b
7
- data.tar.gz: cc05e8bc9a4e36a20ddd15a28b95222a7ccc61329b31012acc69789c6760e3feca81a34fdfee07dab4488adc0f056c648b256c5fa7de9158e0142a55c6fcd6cb
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
- # SQLite Crypto
2
-
3
- [![Version](https://img.shields.io/badge/version-2.0.2-blue.svg)](https://github.com/bart-oz/sqlite_crypto/releases)
4
- [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.txt)
5
- [![types supported](https://img.shields.io/badge/types-ULID,_UUIDv7/v4-brightgreen.svg)](https://github.com/bart-oz/sqlite_crypto)
6
- [![Tests](https://img.shields.io/badge/tests-passing-brightgreen.svg)](https://github.com/bart-oz/sqlite_crypto/actions)
7
- [![Coverage](https://img.shields.io/badge/coverage-98.06%25-brightgreen.svg)](https://github.com/bart-oz/sqlite_crypto/actions)
8
- [![Status](https://img.shields.io/badge/status-active-success.svg)](https://github.com/bart-oz/sqlite_crypto)
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
- - Zero external dependencies
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
- **Model-Level Generation**
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 any column:
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 == :uuid) ? 36 : 26
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
- case pk_column.sql_type.downcase
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
- case column.limit
11
- when 36 then {id: :uuid}
12
- when 26 then {id: :ulid}
13
- else super
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: 36},
8
- ulid: {name: "varchar", limit: 26}
9
+ uuid: {name: "varchar", limit: IdTypes::UUID_LENGTH},
10
+ ulid: {name: "varchar", limit: IdTypes::ULID_LENGTH}
9
11
  )
10
12
  end
11
13
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SqliteCrypto
4
- VERSION = "2.0.2"
4
+ VERSION = "2.2.0"
5
5
  RUBY_MINIMUM_VERSION = "3.1.0"
6
6
  RAILS_MINIMUM_VERSION = "7.1.0"
7
7
  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.2
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.3
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: []