rails-uuid-pk 0.6.0 → 0.8.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: 93efad36dbc0fb3ab34a2a348a5dad4ae0cb75c3f6f62bf7da4580146fbcccb3
4
- data.tar.gz: df2a8e217103e1c732c894fd4ab48333e149e8a42a1a92a08bb023d72673ffa3
3
+ metadata.gz: cda21a747f154d1863e741ecce9b44855009bc202b11524be1a48911c6945ee2
4
+ data.tar.gz: f513b130b54f7d2230a13aa53bd60b707174005eff1bb792c0380a9d2b80a885
5
5
  SHA512:
6
- metadata.gz: '09577137b7dbdd2b488260130f6afd4473292d06fb6646e141176de11a425f243b95ae3c43b8e69e89a7fcf3cb6b72d3f6cdb3b9794b56bf884c05895e4822de'
7
- data.tar.gz: 9a5818221c1251cb137e61a30045fb98a0957af248f9f3e5908e5e9fb6f8d74d4de84dfb60d40135d60028d4d679070c8d295174990f8cc990f58752841a33f0
6
+ metadata.gz: 44070a3cf56eca32a1e83abdb83fa084abcb8c6042d2a2e06f3314bcfbf9df4e12a2794a5fab1e7d50d589455f2242dbf7e141618cd2b2b721b76be92ddfdc0f
7
+ data.tar.gz: 04ca3df41f44ca36bba89849a5c2a515481417b28b995670ecb93fb7a87a90abe5d9bf74bdb1b3a31c109a28127df2b9478bd63adbfa83fb5d0011e0b334a872
data/CHANGELOG.md CHANGED
@@ -5,6 +5,73 @@ 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/v1.0.0.html).
7
7
 
8
+ ## [0.8.0] - 2026-01-12
9
+
10
+ ### Changed
11
+ - **Refactored UUID Type Registration**: Moved from global type map registration to connection-specific registration for improved precision and database compatibility
12
+ - **Enhanced Type Mapping Precision**: UUID types now only map to specific `varchar(36)` and `uuid` SQL types, preventing hijacking of standard string columns
13
+ - **Improved Adapter Extensions**: Enhanced MySQL and SQLite adapter extensions with dedicated `register_uuid_types` methods and proper initialization hooks
14
+
15
+ ### Added
16
+ - **String Column Protection Test**: Added test to ensure standard string columns are not incorrectly mapped to UUID type
17
+
18
+ ### Technical Details
19
+ - Updated Railtie to use `ActiveSupport.on_load` hooks for cleaner adapter extension prepending
20
+ - Implemented connection-aware UUID type registration during adapter initialization and connection setup
21
+ - Enhanced migration helpers compatibility and type detection robustness
22
+
23
+ ## [0.7.0] - 2026-01-12
24
+
25
+ ### Added
26
+ - **SECURITY.md**: Comprehensive security documentation covering UUIDv7-specific security considerations
27
+ - Cryptographic security analysis with timestamp exposure details
28
+ - Database security implications and foreign key considerations
29
+ - Performance-security trade-offs analysis
30
+ - Security vulnerability reporting process
31
+ - Side-channel attack vectors and mitigation strategies
32
+ - Compliance considerations (GDPR, HIPAA, etc.)
33
+ - Security testing recommendations and monitoring guidelines
34
+ - **ARCHITECTURE.md**: Comprehensive architecture documentation
35
+ - Core design principles and architectural decisions
36
+ - App-level vs database-level UUID generation analysis
37
+ - Database compatibility rationale and trade-offs
38
+ - Migration performance implications and caching strategies
39
+ - Database replication and backup considerations
40
+ - ORM and query builder integration details
41
+ - Error handling and resilience patterns
42
+ - Future evolution and extensibility points
43
+ - **PERFORMANCE.md**: Comprehensive performance documentation in dedicated file
44
+ - UUID generation throughput metrics and cryptographic security details
45
+ - Database-specific performance characteristics (PostgreSQL, MySQL, SQLite)
46
+ - Index performance analysis comparing 36-byte UUIDs vs 4-byte integers
47
+ - Scaling recommendations for tables of different sizes (<1M, 1M-10M, >10M records)
48
+ - UUIDv7 vs UUIDv4 performance trade-offs with detailed comparison tables
49
+ - Index fragmentation and cache locality analysis
50
+ - Production monitoring and optimization guidelines
51
+ - **README.md**: Streamlined with concise performance overview and link to PERFORMANCE.md
52
+ - **Comprehensive UUIDv7 Correctness Testing**: Added extensive test suite validating UUIDv7 compliance
53
+ - RFC 9562 version and variant bits validation
54
+ - Timestamp monotonicity and collision resistance testing
55
+ - Format consistency and edge case handling
56
+ - Statistical randomness quality analysis
57
+ - Cross-database compatibility verification
58
+
59
+ ### Changed
60
+ - **Schema Dumper Compatibility**: Replaced fragile `caller` detection with Rails version-aware schema type handling
61
+ - Rails 8.1+: Uses `:uuid` type in schema dumps for native UUID support
62
+ - Rails 8.0.x: Uses `:string` type to avoid "Unknown type 'uuid'" errors
63
+ - Future-proof design that adapts to Rails version changes
64
+ - Added comprehensive test coverage for schema dumping behavior
65
+
66
+ ### Fixed
67
+ - **Schema Dumping Fragility**: Eliminated dependency on Rails internal `caller` stack inspection
68
+ - **Rails Version Compatibility**: Robust handling of UUID types across different Rails versions
69
+
70
+ ### Security
71
+ - Enhanced security posture with professional security documentation
72
+ - Clear vulnerability disclosure process for responsible reporting
73
+ - UUID-specific security guidance for enterprise adoption
74
+
8
75
  ## [0.6.0] - 2026-01-12
9
76
 
10
77
  ### Added
data/README.md CHANGED
@@ -25,7 +25,7 @@ Automatically use UUID v7 for **all primary keys** in Rails applications. Works
25
25
  Add to your `Gemfile`:
26
26
 
27
27
  ```ruby
28
- gem "rails-uuid-pk", "~> 0.6"
28
+ gem "rails-uuid-pk", "~> 0.8"
29
29
  ```
30
30
 
31
31
  Then run:
@@ -90,6 +90,24 @@ end
90
90
  | Zero config after install | Yes | Migration helpers automatically handle foreign key types |
91
91
  | Works with Rails 7.1 – 8+ | Yes | Tested conceptually up to Rails 8.1+ |
92
92
 
93
+ ## Performance Overview
94
+
95
+ **Generation**: ~10,000 UUIDs/second with cryptographic security and monotonic ordering
96
+
97
+ | Database | Storage | Index Performance | Notes |
98
+ |----------|---------|-------------------|--------|
99
+ | **PostgreSQL** | Native UUID (16B) | Excellent | Optimal performance |
100
+ | **MySQL** | VARCHAR(36) (36B) | Good | 2.25x storage overhead |
101
+ | **SQLite** | VARCHAR(36) (36B) | Good | Good for development |
102
+
103
+ **Key Advantages**:
104
+ - **UUIDv7 outperforms UUIDv4** in most scenarios due to monotonic ordering
105
+ - **Better index locality** than random UUIDs with reduced fragmentation
106
+ - **Efficient range queries** for time-based data access
107
+ - **Production-ready scaling** with proper indexing and monitoring
108
+
109
+ For comprehensive performance analysis, scaling strategies, and optimization guides, see [PERFORMANCE.md](PERFORMANCE.md).
110
+
93
111
  ## Why not use native PostgreSQL `uuidv7()`?
94
112
 
95
113
  While PostgreSQL 18+ has excellent native `uuidv7()` support, the **fallback approach** was chosen for maximum compatibility:
@@ -105,12 +123,39 @@ You can still add native PostgreSQL defaults manually if you want maximum perfor
105
123
 
106
124
  ### Devcontainer Setup
107
125
 
108
- This project includes a devcontainer configuration for VS Code. To get started:
126
+ This project includes a devcontainer configuration for VS Code (highly recommended, as it automatically sets up Ruby 3.3, Rails, PostgreSQL, MySQL, and SQLite in an isolated environment). To get started:
109
127
 
110
128
  1. Open the project in VS Code
111
129
  2. When prompted, click "Reopen in Container" (or run `Dev Containers: Reopen in Container` from the command palette)
112
130
  3. The devcontainer will set up Ruby 3.3, Rails, and all dependencies automatically
113
131
 
132
+ #### Devcontainer CLI
133
+
134
+ For terminal-based development or automation, you can use the Devcontainer CLI. The devcontainer will be built and started automatically when you run the exec commands.
135
+
136
+ ##### Installation
137
+
138
+ - **MacOS**: `brew install devcontainer`
139
+ - **Other systems**: `npm install -g @devcontainers/cli`
140
+
141
+ ##### Usage
142
+
143
+ Run commands inside the devcontainer:
144
+
145
+ ```bash
146
+ # Install dependencies
147
+ devcontainer exec --workspace-folder . bundle install
148
+
149
+ # Run tests
150
+ devcontainer exec --workspace-folder . ./bin/test
151
+
152
+ # Run code quality checks
153
+ devcontainer exec --workspace-folder . ./bin/rubocop
154
+
155
+ # Interactive shell
156
+ devcontainer exec --workspace-folder . bash
157
+ ```
158
+
114
159
  ### Running Tests
115
160
 
116
161
  The project includes a comprehensive test suite that runs against SQLite, PostgreSQL, and MySQL.
@@ -156,6 +201,10 @@ For database testing, ensure the respective databases are running and accessible
156
201
 
157
202
  Bug reports and pull requests are welcome on GitHub at https://github.com/seouri/rails-uuid-pk.
158
203
 
204
+ Please see our [Security Policy](SECURITY.md) for information about reporting security vulnerabilities.
205
+
206
+ For detailed architecture documentation, design decisions, and technical rationale, see [ARCHITECTURE.md](ARCHITECTURE.md).
207
+
159
208
  ## License
160
209
 
161
210
  The gem is available as open source under the terms of the [MIT License](MIT-LICENSE).
@@ -5,5 +5,20 @@ module RailsUuidPk
5
5
  uuid: { name: "varchar", limit: 36 }
6
6
  )
7
7
  end
8
+
9
+ def register_uuid_types(m = type_map)
10
+ m.register_type(/varchar\(36\)/i) { RailsUuidPk::Type::Uuid.new }
11
+ m.register_type("uuid") { RailsUuidPk::Type::Uuid.new }
12
+ end
13
+
14
+ def initialize_type_map(m = type_map)
15
+ super
16
+ register_uuid_types(m)
17
+ end
18
+
19
+ def configure_connection
20
+ super
21
+ register_uuid_types
22
+ end
8
23
  end
9
24
  end
@@ -16,17 +16,31 @@ module RailsUuidPk
16
16
  end
17
17
 
18
18
  initializer "rails-uuid-pk.native_types" do
19
+ ActiveSupport.on_load(:active_record_sqlite3adapter) do
20
+ prepend RailsUuidPk::Sqlite3AdapterExtension
21
+ end
22
+
23
+ ActiveSupport.on_load(:active_record_mysql2adapter) do
24
+ prepend RailsUuidPk::Mysql2AdapterExtension
25
+ end
26
+ end
27
+
28
+ config.after_initialize do
19
29
  ActiveSupport.on_load(:active_record) do
20
- case ActiveRecord::Base.connection.adapter_name
21
- when "SQLite"
22
- require "active_record/connection_adapters/sqlite3_adapter"
23
- ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(RailsUuidPk::Sqlite3AdapterExtension)
24
- when "MySQL"
25
- begin
26
- require "active_record/connection_adapters/mysql2_adapter"
27
- ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(RailsUuidPk::Mysql2AdapterExtension)
28
- rescue LoadError
29
- # MySQL adapter not available
30
+ if ActiveRecord::Base.connected?
31
+ ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
32
+ connections = if pool.respond_to?(:connections)
33
+ pool.connections
34
+ else
35
+ # Fallback or older rails
36
+ [ pool.connection ] rescue []
37
+ end
38
+
39
+ connections.each do |conn|
40
+ if conn.respond_to?(:register_uuid_types)
41
+ conn.register_uuid_types
42
+ end
43
+ end
30
44
  end
31
45
  end
32
46
  end
@@ -54,13 +68,6 @@ module RailsUuidPk
54
68
 
55
69
  def self.register_uuid_type(adapter)
56
70
  ActiveRecord::Type.register(:uuid, RailsUuidPk::Type::Uuid, adapter: adapter)
57
-
58
- # Get the connection-specific type map
59
- type_map = ActiveRecord::Base.connection.send(:type_map)
60
- # Map varchar(36) or varchar SQL type to our custom UUID type
61
- type_map.register_type(/varchar/i) { RailsUuidPk::Type::Uuid.new }
62
- # Also map "uuid" SQL type for direct lookups
63
- type_map.register_type("uuid") { RailsUuidPk::Type::Uuid.new }
64
71
  end
65
72
  end
66
73
  end
@@ -5,5 +5,21 @@ module RailsUuidPk
5
5
  uuid: { name: "varchar", limit: 36 }
6
6
  )
7
7
  end
8
+
9
+ def register_uuid_types(m = type_map)
10
+ puts "[RailsUuidPk] Registering UUID types on #{m.class}"
11
+ m.register_type(/varchar\(36\)/i) { RailsUuidPk::Type::Uuid.new }
12
+ m.register_type("uuid") { RailsUuidPk::Type::Uuid.new }
13
+ end
14
+
15
+ def initialize_type_map(m = type_map)
16
+ super
17
+ register_uuid_types(m)
18
+ end
19
+
20
+ def configure_connection
21
+ super
22
+ register_uuid_types
23
+ end
8
24
  end
9
25
  end
@@ -2,12 +2,12 @@ module RailsUuidPk
2
2
  module Type
3
3
  class Uuid < ActiveRecord::Type::String
4
4
  def type
5
- # Return :string during schema dumping to avoid "Unknown type 'uuid'" errors
6
- # Return :uuid for normal operation and tests
7
- if caller.any? { |c| c.include?("schema_dumper") }
8
- :string
9
- else
5
+ # Rails 8.1+ supports UUID types in schema dumping
6
+ # Earlier versions need :string to avoid "Unknown type 'uuid'" errors
7
+ if rails_supports_uuid_in_schema?
10
8
  :uuid
9
+ else
10
+ :string
11
11
  end
12
12
  end
13
13
 
@@ -42,6 +42,13 @@ module RailsUuidPk
42
42
  def valid?(value)
43
43
  value.match?(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)
44
44
  end
45
+
46
+ def rails_supports_uuid_in_schema?
47
+ # Rails 8.1+ supports UUID types in schema dumping
48
+ # Earlier versions (8.0.x) need :string to avoid "Unknown type 'uuid'" errors
49
+ rails_version = Gem::Version.new(Rails::VERSION::STRING)
50
+ rails_version >= Gem::Version.new("8.1.0")
51
+ end
45
52
  end
46
53
  end
47
54
  end
@@ -1,3 +1,3 @@
1
1
  module RailsUuidPk
2
- VERSION = "0.6.0"
2
+ VERSION = "0.8.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-uuid-pk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joon Lee