ksuid 0.4.0 → 1.0.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 +22 -0
- data/CONTRIBUTING.md +2 -2
- data/LICENSE.md +1 -1
- data/README.md +21 -92
- data/UPGRADING.md +26 -0
- data/ksuid.gemspec +3 -1
- data/lib/ksuid/base62.rb +4 -4
- data/lib/ksuid/configuration.rb +4 -1
- data/lib/ksuid/prefixed.rb +242 -0
- data/lib/ksuid/type.rb +0 -3
- data/lib/ksuid/utils.rb +1 -1
- data/lib/ksuid/version.rb +1 -1
- data/lib/ksuid.rb +47 -4
- metadata +7 -9
- data/lib/ksuid/activerecord/binary_type.rb +0 -58
- data/lib/ksuid/activerecord/table_definition.rb +0 -56
- data/lib/ksuid/activerecord/type.rb +0 -57
- data/lib/ksuid/activerecord.rb +0 -75
- data/lib/ksuid/railtie.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c97a36378134ab6cdd674866a6744e5b84ff5976db6575d5364cc844cc9dbf4f
|
4
|
+
data.tar.gz: c5ebfa42d22044e518a63f9508924517a5b7ec83a9e3059c64ecb8075ee88e07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6743031c8702c60e3be6d58f2bde58b1290abc1943afb110adf3a9a2066017d24a453a826373312539175629b2ed9a612ed257abdad22e0cef74a88e045a12e5
|
7
|
+
data.tar.gz: c2c504f17a31fe7d0c25475b606045424868aca2aa0015e78ff41da89828a7e1eb5b88bcf88a8e0da34a81945d5c68b3cbfb1d4acead1d9227c423cc89ece0ae
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,28 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [1.0.0](https://github.com/michaelherold/ksuid/compare/v0.5.0...v1.0.0) - 2023-02-25
|
8
|
+
|
9
|
+
### Removed
|
10
|
+
|
11
|
+
- Extracted the ActiveRecord functionality into its own gem, `activerecord-ksuid`. It is API-compatible with v0.5.0 so to restore functionality, you should only need to add the new gem to your application. See [the upgrading notice](./UPGRADING.md) for more information.
|
12
|
+
|
13
|
+
## [0.5.0](https://github.com/michaelherold/ksuid/compare/v0.4.0...v0.5.0) - 2022-08-18
|
14
|
+
|
15
|
+
### Added
|
16
|
+
|
17
|
+
- If you'd rather deal in KSUID strings instead of `KSUID::Type`s, you can now generate them simply with `KSUID.string`. It takes the same arguments, `payload` and `time` as `KSUID.new`, but returns a string instead of a `KSUID::Type`.
|
18
|
+
- `KSUID.prefixed` and the `KSUID::Prefixed` class now can generate prefixed KSUIDs to make them visually identifiable for their source. You cannot prefix a binary-encoded KSUID, only base 62-encoded ones.
|
19
|
+
- `ActiveRecord::KSUID` now accepts a `prefix:` argument for handling prefixed KSUIDs. In addition, the `ksuid` column type also accepts a `prefix:` argument to calculate the intended size of the column with the prefix.
|
20
|
+
|
21
|
+
### Deprecated
|
22
|
+
|
23
|
+
- `KSUID::ActiveRecord` is now `ActiveRecord::KSUID`. The original constant will continue to work until v1.0.0, but will emit a warning upon boot of your application. To silence the deprecation, change all uses of `KSUID::ActiveRecord` to the new constant, `ActiveRecord::KSUID`. See the [upgrading notice][./UPGRADING.md] for more information.
|
24
|
+
|
25
|
+
### Miscellaneous
|
26
|
+
|
27
|
+
- The compatibility check for the Base62 implementation in the gem is about 10x faster now. The original optimization did not optimize as much due to an error with the benchmark. This change has a tested benchmark that shows a great improvement. Note that this is a micro-optimization and we see no real performance gain in the parsing of KSUID strings.
|
28
|
+
|
7
29
|
## [0.4.0](https://github.com/michaelherold/ksuid/compare/v0.3.0...v0.4.0) - 2022-07-29
|
8
30
|
|
9
31
|
### Added
|
data/CONTRIBUTING.md
CHANGED
@@ -28,9 +28,9 @@ Ideally, a bug report should include a pull request with failing specs.
|
|
28
28
|
1. [Fork the repository].
|
29
29
|
2. [Create a topic branch].
|
30
30
|
3. Add specs for your unimplemented feature or bug fix.
|
31
|
-
4. Run `
|
31
|
+
4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
|
32
32
|
5. Implement your feature or bug fix.
|
33
|
-
6. Run `
|
33
|
+
6. Run `bundle exec rake`. If your specs or any of the linters fail, return to step 5.
|
34
34
|
7. Open `coverage/index.html`. If your changes are not completely covered by your tests, return to step 3.
|
35
35
|
8. Add documentation for your feature or bug fix.
|
36
36
|
9. Commit and push your changes.
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -100,114 +100,43 @@ KSUID.configure do |config|
|
|
100
100
|
end
|
101
101
|
```
|
102
102
|
|
103
|
-
###
|
103
|
+
### Prefixed KSUIDs
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
#### Adding to an existing model
|
108
|
-
|
109
|
-
Within a Rails project, it is very easy to get started using KSUIDs within your models. You can use the `ksuid` column type in a Rails migration to add a column to an existing model:
|
110
|
-
|
111
|
-
rails generate migration add_ksuid_to_events ksuid:ksuid
|
112
|
-
|
113
|
-
This will generate a migration like the following:
|
114
|
-
|
115
|
-
```ruby
|
116
|
-
class AddKsuidToEvents < ActiveRecord::Migration[5.2]
|
117
|
-
def change
|
118
|
-
add_column :events, :unique_id, :ksuid
|
119
|
-
end
|
120
|
-
end
|
121
|
-
```
|
122
|
-
|
123
|
-
Then, to add proper handling to the field, you will want to mix a module into the model:
|
124
|
-
|
125
|
-
```ruby
|
126
|
-
class Event < ApplicationRecord
|
127
|
-
include KSUID::ActiveRecord[:unique_id]
|
128
|
-
end
|
129
|
-
```
|
130
|
-
|
131
|
-
#### Creating a new model
|
132
|
-
|
133
|
-
To create a new model with a `ksuid` field that is stored as a KSUID, use the `ksuid` column type. Using the Rails generators, this looks like:
|
134
|
-
|
135
|
-
rails generate model Event my_field_name:ksuid
|
136
|
-
|
137
|
-
If you would like to add a KSUID to an existing model, you can do so with the following:
|
138
|
-
|
139
|
-
```ruby
|
140
|
-
class AddKsuidToEvents < ActiveRecord::Migration[5.2]
|
141
|
-
change_table :events do |table|
|
142
|
-
table.ksuid :my_field_name
|
143
|
-
end
|
144
|
-
end
|
145
|
-
```
|
146
|
-
|
147
|
-
Once you have generated the table that you will use for your model, you will need to include a module into the model class, as follows:
|
148
|
-
|
149
|
-
```ruby
|
150
|
-
class Event < ApplicationRecord
|
151
|
-
include KSUID::ActiveRecord[:my_field_name]
|
152
|
-
end
|
153
|
-
```
|
154
|
-
|
155
|
-
##### With a KSUID primary key
|
156
|
-
|
157
|
-
You can also use a KSUID as the primary key on a table, much like you can use a UUID in vanilla Rails. To do so requires a little more finagling than you can manage through the generators. When hand-writing the migration, it will look like this:
|
105
|
+
If you use KSUIDs in multiple contexts, you can prefix them to make them easily identifiable.
|
158
106
|
|
159
107
|
```ruby
|
160
|
-
|
161
|
-
create_table :events, id: false do |table|
|
162
|
-
table.ksuid :id, primary_key: true
|
163
|
-
end
|
164
|
-
end
|
108
|
+
ksuid = KSUID.prefixed('evt_')
|
165
109
|
```
|
166
110
|
|
167
|
-
|
111
|
+
Just like a normal KSUID, you can use a specific timestamp:
|
168
112
|
|
169
|
-
```ruby
|
170
|
-
|
171
|
-
include KSUID::ActiveRecord[:id]
|
172
|
-
end
|
113
|
+
``` ruby
|
114
|
+
ksuid = KSUID.prefixed('evt_', time: time) # where time is a Time-like object
|
173
115
|
```
|
174
116
|
|
175
|
-
|
176
|
-
|
177
|
-
Outside of Rails, you cannot rely on the Railtie to load the appropriate files for you automatically. Toward the start of your application's boot process, you will want to require the following:
|
117
|
+
You can also parse a prefixed KSUID from a string that you received:
|
178
118
|
|
179
119
|
```ruby
|
180
|
-
|
181
|
-
|
182
|
-
# If you will be using the ksuid column type in a migration
|
183
|
-
require 'ksuid/activerecord/table_definition'
|
120
|
+
ksuid = KSUID::Prefixed.from_base62(base62_string, prefix: 'evt_')
|
184
121
|
```
|
185
122
|
|
186
|
-
|
123
|
+
Prefixed KSUIDs order themselves with non-prefixed KSUIDs as if their prefix did not exist. With other prefixed KSUIDs, they order first by their prefix, then their timestamp.
|
187
124
|
|
188
|
-
|
125
|
+
### Integrations
|
189
126
|
|
190
|
-
|
127
|
+
KSUID for Ruby can integrate with other systems through adapter gems. Below is a sample of these adapter gems.
|
191
128
|
|
192
|
-
|
193
|
-
|
194
|
-
```ruby
|
195
|
-
class Event < ApplicationRecord
|
196
|
-
include KSUID::ActiveRecord[:my_field_name, binary: true]
|
197
|
-
end
|
198
|
-
```
|
129
|
+
#### ActiveRecord
|
199
130
|
|
200
|
-
|
131
|
+
If you want to include KSUID columns in your ActiveRecord models, install the `activerecord-ksuid` gem. If you are using it within a Rails app, run the following:
|
201
132
|
|
202
|
-
|
133
|
+
bundle add activerecord-ksuid --require active_record/ksuid/railtie
|
134
|
+
|
135
|
+
If you are using it outside of Rails, add this to your Gemfile:
|
203
136
|
|
204
|
-
|
205
|
-
class Event < ApplicationRecord
|
206
|
-
include KSUID::ActiveRecord[:my_field_name, created_at: true]
|
207
|
-
end
|
208
|
-
```
|
137
|
+
gem 'activerecord-ksuid', require: ['ksuid', 'active_record/ksuid', 'active_record/ksuid/table_definition']
|
209
138
|
|
210
|
-
|
139
|
+
See [the readme for the integration](https://github.com/michaelherold/ksuid-ruby/blob/main/activerecord-ksuid/README.md) for more information.
|
211
140
|
|
212
141
|
## Contributing
|
213
142
|
|
@@ -217,10 +146,10 @@ So you’re interested in contributing to KSUID? Check out our [contributing gui
|
|
217
146
|
|
218
147
|
This library aims to support and is [tested against][actions] the following Ruby versions:
|
219
148
|
|
220
|
-
* Ruby 2.5
|
221
|
-
* Ruby 2.6
|
222
149
|
* Ruby 2.7
|
223
|
-
*
|
150
|
+
* Ruby 3.0
|
151
|
+
* Ruby 3.1
|
152
|
+
* JRuby 9.3
|
224
153
|
|
225
154
|
If something doesn't work on one of these versions, it's a bug.
|
226
155
|
|
data/UPGRADING.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Upgrading instructions for KSUID for Ruby
|
2
|
+
|
3
|
+
## v1.0.0
|
4
|
+
|
5
|
+
### Extracted `ActiveRecord::KSUID` into its own gem
|
6
|
+
|
7
|
+
That KSUID for Ruby included ActiveRecord support directly in its gem has always been a regret of mine. It adds ActiveRecord and Rails concerns to a gem that you can use in any context. It makes running the test suite more complicated for no real gain. And it makes it kludgy to add support for more systems, like Sequel, since you have conflicting concerns in the same gem.
|
8
|
+
|
9
|
+
To remove this problem, v1.0.0 extracts the ActiveRecord behavior into its own gem, `activerecord-ksuid`. This version is a straight extraction with an improved test suite so it _should_ mean that the only change you have to make when upgrading from v0.5.0 is to do the following in your Gemfile:
|
10
|
+
|
11
|
+
```diff
|
12
|
+
- gem 'ksuid'
|
13
|
+
+ gem 'activerecord-ksuid'
|
14
|
+
```
|
15
|
+
|
16
|
+
If you are still on a version prior to v0.5.0, upgrade to that version first, solve the deprecation notice below, ensure your app still works, and then upgrade to v1.0.0.
|
17
|
+
|
18
|
+
## v0.5.0
|
19
|
+
|
20
|
+
### Deprecated `KSUID::ActiveRecord` in favor of `ActiveRecord::KSUID`
|
21
|
+
|
22
|
+
This version deprecates the original constant for the ActiveRecord integration, `KSUID::ActiveRecord`. This change is in preparation for extracting the ActiveRecord integration into its own gem. Continuing to use the original constant will show deprecation warnings upon boot of your application.
|
23
|
+
|
24
|
+
Migrating for this version should be quick: simply do a global replace of `KSUID::ActiveRecord` for `ActiveRecord::KSUID`. No other changes should be necessary.
|
25
|
+
|
26
|
+
In the future release of v1.0.0, you will need to also include `activerecord-ksuid` your Gemfile. This gem is as-yet unreleased, with a release intended concurrently with v1.0.0 of KSUID for Ruby.
|
data/ksuid.gemspec
CHANGED
@@ -13,10 +13,12 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = 'https://github.com/michaelherold/ksuid-ruby'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
|
-
spec.files = %w[CHANGELOG.md CONTRIBUTING.md LICENSE.md README.md]
|
16
|
+
spec.files = %w[CHANGELOG.md CONTRIBUTING.md LICENSE.md README.md UPGRADING.md]
|
17
17
|
spec.files += %w[ksuid.gemspec]
|
18
18
|
spec.files += Dir['lib/**/*.rb']
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
22
|
+
|
21
23
|
spec.add_development_dependency 'bundler', '>= 1.15'
|
22
24
|
end
|
data/lib/ksuid/base62.rb
CHANGED
@@ -35,7 +35,7 @@ module KSUID
|
|
35
35
|
# @param string [String] the string to check for compatibility
|
36
36
|
# @return [Boolean]
|
37
37
|
def self.compatible?(string)
|
38
|
-
|
38
|
+
!MATCHER.match?(string)
|
39
39
|
end
|
40
40
|
|
41
41
|
# Decodes a base 62-encoded string into an integer
|
@@ -51,12 +51,12 @@ module KSUID
|
|
51
51
|
def self.decode(ksuid)
|
52
52
|
result = 0
|
53
53
|
|
54
|
-
ksuid.
|
54
|
+
ksuid.chars.each_with_index do |char, position|
|
55
55
|
unless (digit = CHARSET.index(char))
|
56
56
|
raise(ArgumentError, "#{ksuid} is not a base 62 number")
|
57
57
|
end
|
58
58
|
|
59
|
-
result += digit * BASE**(ksuid.length - (position + 1))
|
59
|
+
result += digit * (BASE**(ksuid.length - (position + 1)))
|
60
60
|
end
|
61
61
|
|
62
62
|
result
|
@@ -76,7 +76,7 @@ module KSUID
|
|
76
76
|
chars = encode_without_padding(number)
|
77
77
|
|
78
78
|
chars << padding if chars.empty?
|
79
|
-
chars.reverse.join
|
79
|
+
chars.reverse.join.rjust(STRING_LENGTH, padding)
|
80
80
|
end
|
81
81
|
|
82
82
|
# Encodes a byte string or byte array into base 62
|
data/lib/ksuid/configuration.rb
CHANGED
@@ -87,8 +87,11 @@ module KSUID
|
|
87
87
|
def assert_payload_size(generator)
|
88
88
|
return if (length = generator.call.length) == (expected_length = BYTES[:payload])
|
89
89
|
|
90
|
-
raise
|
90
|
+
raise(
|
91
|
+
ConfigurationError,
|
92
|
+
'Random generator generates the wrong number of bytes ' \
|
91
93
|
"(#{length} generated, #{expected_length} expected)"
|
94
|
+
)
|
92
95
|
end
|
93
96
|
end
|
94
97
|
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KSUID
|
4
|
+
# Encapsulates the data type for a prefixed KSUID
|
5
|
+
#
|
6
|
+
# When you have different types of KSUIDs in your application, it can be
|
7
|
+
# helpful to add an identifier to the front of them to give you an idea for
|
8
|
+
# what kind of object the KSUID belongs to.
|
9
|
+
#
|
10
|
+
# For example, you might use KSUIDs to identify both Events and Customers. For
|
11
|
+
# an Event, you could prefix the KSUID with the string `evt_`. Likewise, for
|
12
|
+
# Customers, you could prefix them with the string `cus_`.
|
13
|
+
#
|
14
|
+
# {KSUID::Prefixed} gives you affordances for doing just this.
|
15
|
+
#
|
16
|
+
# ## Ordering
|
17
|
+
#
|
18
|
+
# {KSUID::Prefixed}s are partially orderable with {KSUID::Type} by their
|
19
|
+
# timestamps. When ordering them with other {KSUID::Prefixed} instances, they
|
20
|
+
# order first by prefix, then by timestamp. This means that in a mixed
|
21
|
+
# collection, all Customer KSUIDs (prefix: `cus_`) would be grouped before all
|
22
|
+
# Event KSUIDs (prefix `evt_`).
|
23
|
+
#
|
24
|
+
# ## Interface
|
25
|
+
#
|
26
|
+
# You typically will not instantiate this class directly, but instead use the
|
27
|
+
# {KSUID.prefixed} builder method to save some typing.
|
28
|
+
#
|
29
|
+
# The most commonly used helper methods for the {KSUID} module also exist on
|
30
|
+
# {KSUID::Prefixed} for converting between different forms of output.
|
31
|
+
#
|
32
|
+
# ## Differences from {KSUID::Type}
|
33
|
+
#
|
34
|
+
# One other thing to note is that {KSUID::Prefixed} is not intended to handle
|
35
|
+
# binary data because the prefix does not make sense in either the byte string
|
36
|
+
# or packed array formats.
|
37
|
+
#
|
38
|
+
# @since 0.5.0
|
39
|
+
class Prefixed < Type
|
40
|
+
include Comparable
|
41
|
+
|
42
|
+
# Converts a KSUID-compatible value into a {KSUID::Prefixed}
|
43
|
+
#
|
44
|
+
# @api public
|
45
|
+
#
|
46
|
+
# @example Converts a base 62 KSUID string into a {KSUID::Prefixed}
|
47
|
+
# KSUID::Prefixed.call('15Ew2nYeRDscBipuJicYjl970D1', prefix: 'evt_')
|
48
|
+
#
|
49
|
+
# @param ksuid [String, KSUID::Prefixed, KSUID::Type] the prefixed KSUID-compatible value
|
50
|
+
# @return [KSUID::Prefixed] the converted, prefixed KSUID
|
51
|
+
# @raise [ArgumentError] if the value is not prefixed KSUID-compatible
|
52
|
+
def self.call(ksuid, prefix:)
|
53
|
+
return unless ksuid && prefix
|
54
|
+
|
55
|
+
case ksuid
|
56
|
+
when KSUID::Prefixed then from_base62(ksuid.to_ksuid.to_s, prefix: prefix)
|
57
|
+
when KSUID::Type then from_base62(ksuid.to_s, prefix: prefix)
|
58
|
+
when String then cast_string(ksuid, prefix: prefix)
|
59
|
+
else
|
60
|
+
raise ArgumentError, "Cannot convert #{ksuid.inspect} to KSUID::Prefixed"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Converts a base 62-encoded string into a {KSUID::Prefixed}
|
65
|
+
#
|
66
|
+
# @api public
|
67
|
+
#
|
68
|
+
# @example Parse a KSUID string into a prefixed object
|
69
|
+
# KSUID::Prefixed.from_base62('0vdbMgWkU6slGpLVCqEFwkkZvuW', prefix: 'evt_')
|
70
|
+
#
|
71
|
+
# @param string [String] the base 62-encoded KSUID to convert into an object
|
72
|
+
# @param prefix [String] the prefix to add to the KSUID
|
73
|
+
# @return [KSUID::Prefixed] the prefixed KSUID generated from the string
|
74
|
+
def self.from_base62(string, prefix:)
|
75
|
+
string = string.sub(/\A#{prefix}/, '')
|
76
|
+
int = Base62.decode(string)
|
77
|
+
bytes = Utils.int_to_bytes(int, 160)
|
78
|
+
|
79
|
+
from_bytes(bytes, prefix: prefix)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Casts a string into a {KSUID::Prefixed}
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
#
|
86
|
+
# @param ksuid [String] the string to convert into a {KSUID::Prefixed}
|
87
|
+
# @param prefix [String] the prefix to prepend to the KSUID
|
88
|
+
# @return [KSUID::Prefixed] the converted, prefixed KSUID
|
89
|
+
def self.cast_string(ksuid, prefix:)
|
90
|
+
ksuid = ksuid[-KSUID::BYTES[:base62]..-1] if ksuid.length >= KSUID::BYTES[:base62]
|
91
|
+
|
92
|
+
unless Base62.compatible?(ksuid)
|
93
|
+
raise ArgumentError, 'Prefixed KSUIDs cannot be binary strings'
|
94
|
+
end
|
95
|
+
|
96
|
+
from_base62(ksuid, prefix: prefix)
|
97
|
+
end
|
98
|
+
private_class_method :cast_string
|
99
|
+
|
100
|
+
# Converts a byte string or byte array into a KSUID
|
101
|
+
#
|
102
|
+
# @api private
|
103
|
+
#
|
104
|
+
# @param bytes [String] the byte string to convert into an object
|
105
|
+
# @return [KSUID::Prefixed] the prefixed KSUID generated from the bytes
|
106
|
+
def self.from_bytes(bytes, prefix:)
|
107
|
+
bytes = bytes.bytes
|
108
|
+
timestamp = Utils.int_from_bytes(bytes.first(KSUID::BYTES[:timestamp]))
|
109
|
+
payload = Utils.byte_string_from_array(bytes.last(KSUID::BYTES[:payload]))
|
110
|
+
|
111
|
+
new(prefix, payload: payload, time: Time.at(timestamp + EPOCH_TIME))
|
112
|
+
end
|
113
|
+
private_class_method :from_bytes
|
114
|
+
|
115
|
+
# Instantiates a new {KSUID::Prefixed}
|
116
|
+
#
|
117
|
+
# @api semipublic
|
118
|
+
#
|
119
|
+
# @example Generate a new {KSUID::Prefixed} for the current second
|
120
|
+
# KSUID::Prefixed.new('evt_')
|
121
|
+
#
|
122
|
+
# @example Generate a new {KSUID::Prefixed} for a given timestamp
|
123
|
+
# KSUID::Prefixed.new('cus_', time: Time.parse('2017-11-05 15:00:04 UTC'))
|
124
|
+
#
|
125
|
+
# @param prefix [String] the prefix to add to the KSUID
|
126
|
+
# @param payload [String, Array<Integer>, nil] the payload for the KSUID
|
127
|
+
# @param time [Time] the timestamp to use for the KSUID
|
128
|
+
# @return [KSUID::Prefix] the generated, prefixed KSUID
|
129
|
+
def initialize(prefix, payload: nil, time: Time.now)
|
130
|
+
raise ArgumentError, 'requires a prefix' unless prefix
|
131
|
+
|
132
|
+
super(payload: payload, time: time)
|
133
|
+
|
134
|
+
@prefix = prefix
|
135
|
+
end
|
136
|
+
|
137
|
+
# The prefix in front of the KSUID
|
138
|
+
#
|
139
|
+
# @api semipublic
|
140
|
+
#
|
141
|
+
# @example Getting the prefix to create a similar {KSUID::Prefixed}
|
142
|
+
# ksuid1 = KSUID.prefixed('cus_')
|
143
|
+
# ksuid2 = KSUID.prefixed(ksuid1.prefix)
|
144
|
+
#
|
145
|
+
# @return [String] the prefix of the {KSUID::Prefixed}
|
146
|
+
attr_reader :prefix
|
147
|
+
|
148
|
+
# Implements the Comparable interface for sorting {KSUID::Prefixed}s
|
149
|
+
#
|
150
|
+
# @api private
|
151
|
+
#
|
152
|
+
# @param other [KSUID::Type] the other object to compare against
|
153
|
+
# @return [Integer, nil] nil for uncomparable, -1 for less than other,
|
154
|
+
# 0 for equal to, 1 for greater than other
|
155
|
+
def <=>(other)
|
156
|
+
return unless other.is_a?(Type)
|
157
|
+
return super if other.instance_of?(Type)
|
158
|
+
|
159
|
+
if (result = prefix <=> other.prefix).nonzero?
|
160
|
+
result
|
161
|
+
else
|
162
|
+
super
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Checks whether this {KSUID::Prefixed} is equal to another
|
167
|
+
#
|
168
|
+
# @api semipublic
|
169
|
+
#
|
170
|
+
# @example Checks whether two KSUIDs are equal
|
171
|
+
# KSUID.prefixed('evt_') == KSUID.prefixed('evt_')
|
172
|
+
#
|
173
|
+
# @param other [KSUID::Prefixed] the other {KSUID::Prefixed} to check against
|
174
|
+
# @return [Boolean]
|
175
|
+
def ==(other)
|
176
|
+
other.is_a?(Prefixed) &&
|
177
|
+
prefix == other.prefix &&
|
178
|
+
super
|
179
|
+
end
|
180
|
+
|
181
|
+
# Generates the key to use when using a {KSUID::Prefixed} as a hash key
|
182
|
+
#
|
183
|
+
# @api semipublic
|
184
|
+
#
|
185
|
+
# @example Using a KSUID as a Hash key
|
186
|
+
# ksuid1 = KSUID.prefixed('evt_')
|
187
|
+
# ksuid2 = ksuid1.dup
|
188
|
+
# values_by_ksuid = {}
|
189
|
+
#
|
190
|
+
# values_by_ksuid[ksuid1] = "example"
|
191
|
+
# values_by_ksuid[ksuid2] #=> "example"
|
192
|
+
#
|
193
|
+
# @return [Integer]
|
194
|
+
def hash
|
195
|
+
[prefix, @uid].hash
|
196
|
+
end
|
197
|
+
|
198
|
+
# The {KSUID::Prefixed} as a prefixed, hex-encoded string
|
199
|
+
#
|
200
|
+
# This is generally useful for comparing against the Go tool.
|
201
|
+
#
|
202
|
+
# @api public
|
203
|
+
#
|
204
|
+
# @example
|
205
|
+
# ksuid = KSUID::Prefixed.from_base62('0vdbMgWkU6slGpLVCqEFwkkZvuW', prefix: 'evt_')
|
206
|
+
#
|
207
|
+
# ksuid.raw #=> "evt_0683F789049CC215C099D42B784DBE99341BD79C"
|
208
|
+
#
|
209
|
+
# @return [String] a prefixed, hex-encoded string
|
210
|
+
def raw
|
211
|
+
super.prepend(prefix)
|
212
|
+
end
|
213
|
+
|
214
|
+
# Converts the {KSUID::Prefixed} into a {KSUID::Type} by dropping the prefix
|
215
|
+
#
|
216
|
+
# @api public
|
217
|
+
#
|
218
|
+
# @example Convert an Event KSUID into a plain KSUID
|
219
|
+
# ksuid = KSUID.prefixed('evt_')
|
220
|
+
#
|
221
|
+
# ksuid.to_ksuid
|
222
|
+
#
|
223
|
+
# @return [KSUID::Type] the non-prefixed KSUID
|
224
|
+
def to_ksuid
|
225
|
+
KSUID.from_base62(to_s.sub(/\A#{prefix}/, ''))
|
226
|
+
end
|
227
|
+
|
228
|
+
# The {KSUID::Prefixed} as a base 62-encoded string
|
229
|
+
#
|
230
|
+
# @api public
|
231
|
+
#
|
232
|
+
# @example
|
233
|
+
# ksuid = KSUID::Prefixed.from_base62('0vdbMgWkU6slGpLVCqEFwkkZvuW', prefix: 'evt_')
|
234
|
+
#
|
235
|
+
# ksuid.to_s #=> "evt_0vdbMgWkU6slGpLVCqEFwkkZvuW"
|
236
|
+
#
|
237
|
+
# @return [String] the prefixed, base 62-encoded string for the {KSUID::Prefixed}
|
238
|
+
def to_s
|
239
|
+
super.prepend(prefix)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
data/lib/ksuid/type.rb
CHANGED
data/lib/ksuid/utils.rb
CHANGED
data/lib/ksuid/version.rb
CHANGED
data/lib/ksuid.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'ksuid/configuration'
|
4
|
-
require_relative 'ksuid/type'
|
5
4
|
require_relative 'ksuid/version'
|
6
5
|
|
7
6
|
# The K-Sortable Unique IDentifier (KSUID)
|
@@ -41,6 +40,9 @@ require_relative 'ksuid/version'
|
|
41
40
|
# @example Generate a new KSUID
|
42
41
|
# KSUID.new
|
43
42
|
#
|
43
|
+
# @example Generate a KSUID prefixed by `evt_`
|
44
|
+
# KSUID.prefixed('evt_')
|
45
|
+
#
|
44
46
|
# @example Parse a KSUID string that you have received
|
45
47
|
# KSUID.from_base62('aWgEPTl1tmebfsQzFP4bxwgy80V')
|
46
48
|
#
|
@@ -63,7 +65,7 @@ module KSUID
|
|
63
65
|
# The number of bytes that are used to represent each part of a KSUID
|
64
66
|
#
|
65
67
|
# @return [Hash{Symbol => Integer}] the map of data type to number of bytes
|
66
|
-
BYTES = { payload: 16, timestamp: 4, total: 20 }.freeze
|
68
|
+
BYTES = { base62: 27, payload: 16, timestamp: 4, total: 20 }.freeze
|
67
69
|
|
68
70
|
# The number of characters in a base 62-encoded KSUID
|
69
71
|
#
|
@@ -75,6 +77,11 @@ module KSUID
|
|
75
77
|
# @return [String]
|
76
78
|
MAX_STRING_ENCODED = 'aWgEPTl1tmebfsQzFP4bxwgy80V'
|
77
79
|
|
80
|
+
autoload :Base62, 'ksuid/base62'
|
81
|
+
autoload :Prefixed, 'ksuid/prefixed'
|
82
|
+
autoload :Type, 'ksuid/type'
|
83
|
+
autoload :Utils, 'ksuid/utils'
|
84
|
+
|
78
85
|
# Converts a KSUID-compatible value into an actual KSUID
|
79
86
|
#
|
80
87
|
# @api public
|
@@ -89,6 +96,7 @@ module KSUID
|
|
89
96
|
return unless ksuid
|
90
97
|
|
91
98
|
case ksuid
|
99
|
+
when KSUID::Prefixed then ksuid.to_ksuid
|
92
100
|
when KSUID::Type then ksuid
|
93
101
|
when Array then KSUID.from_bytes(ksuid)
|
94
102
|
when String then cast_string(ksuid)
|
@@ -190,6 +198,43 @@ module KSUID
|
|
190
198
|
Type.new(payload: payload, time: time)
|
191
199
|
end
|
192
200
|
|
201
|
+
# Instantiates a new {KSUID::Prefixed}
|
202
|
+
#
|
203
|
+
# @api public
|
204
|
+
# @since 0.5.0
|
205
|
+
#
|
206
|
+
# @example Generate a new prefixed KSUID for the current second
|
207
|
+
# KSUID.prefixed('evt_')
|
208
|
+
#
|
209
|
+
# @example Generate a new prefixed KSUID for a given timestamp
|
210
|
+
# KSUID.prefixed('cus_', time: Time.parse('2022-08-16 10:36:00 UTC'))
|
211
|
+
#
|
212
|
+
# @param prefix [String] the prefix to apply to the KSUID
|
213
|
+
# @param payload [String, Array<Integer>, nil] the payload for the KSUID
|
214
|
+
# @param time [Time] the timestamp to use for the KSUID
|
215
|
+
# @return [KSUID::Prefixed] the generated, prefixed KSUID
|
216
|
+
def self.prefixed(prefix, payload: nil, time: Time.now)
|
217
|
+
Prefixed.new(prefix, payload: payload, time: time)
|
218
|
+
end
|
219
|
+
|
220
|
+
# Generates a KSUID string
|
221
|
+
#
|
222
|
+
# @api public
|
223
|
+
# @since 0.5.0
|
224
|
+
#
|
225
|
+
# @example Generate a new KSUID string for the current second
|
226
|
+
# KSUID.string
|
227
|
+
#
|
228
|
+
# @example Generate a new KSUID string for a given timestamp
|
229
|
+
# KSUID.string(time: Time.parse('2017-11-05 15:00:04 UTC'))
|
230
|
+
#
|
231
|
+
# @param payload [String, Array<Integer>, nil] the payload for the KSUID string
|
232
|
+
# @param time [Time] the timestamp to use for the KSUID string
|
233
|
+
# @return [String] the generated string
|
234
|
+
def self.string(payload: nil, time: Time.now)
|
235
|
+
Type.new(payload: payload, time: time).to_s
|
236
|
+
end
|
237
|
+
|
193
238
|
# Casts a string into a KSUID
|
194
239
|
#
|
195
240
|
# @api private
|
@@ -205,5 +250,3 @@ module KSUID
|
|
205
250
|
end
|
206
251
|
private_class_method :cast_string
|
207
252
|
end
|
208
|
-
|
209
|
-
require 'ksuid/railtie' if defined?(Rails)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ksuid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Herold
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -35,22 +35,20 @@ files:
|
|
35
35
|
- CONTRIBUTING.md
|
36
36
|
- LICENSE.md
|
37
37
|
- README.md
|
38
|
+
- UPGRADING.md
|
38
39
|
- ksuid.gemspec
|
39
40
|
- lib/ksuid.rb
|
40
|
-
- lib/ksuid/activerecord.rb
|
41
|
-
- lib/ksuid/activerecord/binary_type.rb
|
42
|
-
- lib/ksuid/activerecord/table_definition.rb
|
43
|
-
- lib/ksuid/activerecord/type.rb
|
44
41
|
- lib/ksuid/base62.rb
|
45
42
|
- lib/ksuid/configuration.rb
|
46
|
-
- lib/ksuid/
|
43
|
+
- lib/ksuid/prefixed.rb
|
47
44
|
- lib/ksuid/type.rb
|
48
45
|
- lib/ksuid/utils.rb
|
49
46
|
- lib/ksuid/version.rb
|
50
47
|
homepage: https://github.com/michaelherold/ksuid-ruby
|
51
48
|
licenses:
|
52
49
|
- MIT
|
53
|
-
metadata:
|
50
|
+
metadata:
|
51
|
+
rubygems_mfa_required: 'true'
|
54
52
|
post_install_message:
|
55
53
|
rdoc_options: []
|
56
54
|
require_paths:
|
@@ -66,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
64
|
- !ruby/object:Gem::Version
|
67
65
|
version: '0'
|
68
66
|
requirements: []
|
69
|
-
rubygems_version: 3.
|
67
|
+
rubygems_version: 3.3.7
|
70
68
|
signing_key:
|
71
69
|
specification_version: 4
|
72
70
|
summary: Ruby implementation of the K-Sortable Unique IDentifier
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module KSUID
|
4
|
-
module ActiveRecord
|
5
|
-
# A binary-serialized KSUID for storage within an ActiveRecord database
|
6
|
-
#
|
7
|
-
# @api private
|
8
|
-
#
|
9
|
-
# @example Set an attribute as a KSUID using the verbose syntax
|
10
|
-
# class Event < ActiveRecord::Base
|
11
|
-
# attribute :ksuid, KSUID::ActiveRecord::BinaryType.new, default: -> { KSUID.new }
|
12
|
-
# end
|
13
|
-
#
|
14
|
-
# @example Set an attribute as a KSUID using the pre-registered type
|
15
|
-
# class Event < ActiveRecord::Base
|
16
|
-
# attribute :ksuid, :ksuid_binary, default: -> { KSUID.new }
|
17
|
-
# end
|
18
|
-
class BinaryType < ::ActiveRecord::Type::Binary
|
19
|
-
# Casts a value from user input into a KSUID
|
20
|
-
#
|
21
|
-
# Type casting happens via the attribute setter and can take input from
|
22
|
-
# many places, including:
|
23
|
-
#
|
24
|
-
# 1. The Rails form builder
|
25
|
-
# 2. Directly from the attribute setter
|
26
|
-
# 3. From the model initializer
|
27
|
-
#
|
28
|
-
# @param value [String, Array<Integer>, KSUID::Type] the value to cast into a KSUID
|
29
|
-
# @return [KSUID::Type] the type-casted value
|
30
|
-
def cast(value)
|
31
|
-
KSUID.call(value)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Converts a value from database input to a KSUID
|
35
|
-
#
|
36
|
-
# @param value [String, nil] the database-serialized KSUID to convert
|
37
|
-
# @return [KSUID::Type] the deserialized KSUID
|
38
|
-
def deserialize(value)
|
39
|
-
return unless value
|
40
|
-
|
41
|
-
value = value.to_s if value.is_a?(::ActiveRecord::Type::Binary::Data)
|
42
|
-
KSUID.call(value)
|
43
|
-
end
|
44
|
-
|
45
|
-
# Casts the value from a KSUID into a database-understandable format
|
46
|
-
#
|
47
|
-
# @param value [KSUID::Type, nil] the KSUID in Ruby format
|
48
|
-
# @return [String, nil] the base 62-encoded KSUID for storage in the database
|
49
|
-
def serialize(value)
|
50
|
-
return unless value
|
51
|
-
|
52
|
-
super(KSUID.call(value).to_bytes)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
ActiveRecord::Type.register(:ksuid_binary, KSUID::ActiveRecord::BinaryType)
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module KSUID
|
4
|
-
module ActiveRecord
|
5
|
-
# Extends ActiveRecord's table definition language for KSUIDs
|
6
|
-
module TableDefinition
|
7
|
-
# Defines a field as a string-based KSUID
|
8
|
-
#
|
9
|
-
# @example Define a KSUID field as a non-primary key
|
10
|
-
# ActiveRecord::Schema.define do
|
11
|
-
# create_table :events, force: true do |table|
|
12
|
-
# table.ksuid :ksuid, index: true, unique: true
|
13
|
-
# end
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# @example Define a KSUID field as a primary key
|
17
|
-
# ActiveRecord::Schema.define do
|
18
|
-
# create_table :events, force: true, id: false do |table|
|
19
|
-
# table.ksuid :id, primary_key: true
|
20
|
-
# end
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# @param args [Array<Symbol>] the list of fields to define as KSUIDs
|
24
|
-
# @param options [Hash] see {ActiveRecord::ConnectionAdapters::TableDefinition}
|
25
|
-
# @return [void]
|
26
|
-
def ksuid(*args, **options)
|
27
|
-
args.each { |name| column(name, :string, **options.merge(limit: 27)) }
|
28
|
-
end
|
29
|
-
|
30
|
-
# Defines a field as a binary-based KSUID
|
31
|
-
#
|
32
|
-
# @example Define a KSUID field as a non-primary key
|
33
|
-
# ActiveRecord::Schema.define do
|
34
|
-
# create_table :events, force: true do |table|
|
35
|
-
# table.ksuid_binary :ksuid, index: true, unique: true
|
36
|
-
# end
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
# @example Define a KSUID field as a primary key
|
40
|
-
# ActiveRecord::Schema.define do
|
41
|
-
# create_table :events, force: true, id: false do |table|
|
42
|
-
# table.ksuid_binary :id, primary_key: true
|
43
|
-
# end
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# @param args [Array<Symbol>] the list of fields to define as KSUIDs
|
47
|
-
# @param options [Hash] see {ActiveRecord::ConnectionAdapters::TableDefinition}
|
48
|
-
# @return [void]
|
49
|
-
def ksuid_binary(*args, **options)
|
50
|
-
args.each { |name| column(name, :binary, **options.merge(limit: 20)) }
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
ActiveRecord::ConnectionAdapters::TableDefinition.include(KSUID::ActiveRecord::TableDefinition)
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module KSUID
|
4
|
-
module ActiveRecord
|
5
|
-
# A string-serialized KSUID for storage within an ActiveRecord database
|
6
|
-
#
|
7
|
-
# @api private
|
8
|
-
#
|
9
|
-
# @example Set an attribute as a KSUID using the verbose syntax
|
10
|
-
# class Event < ActiveRecord::Base
|
11
|
-
# attribute :ksuid, KSUID::ActiveRecord::Type.new, default: -> { KSUID.new }
|
12
|
-
# end
|
13
|
-
#
|
14
|
-
# @example Set an attribute as a KSUID using the pre-registered type
|
15
|
-
# class Event < ActiveRecord::Base
|
16
|
-
# attribute :ksuid, :ksuid, default: -> { KSUID.new }
|
17
|
-
# end
|
18
|
-
class Type < ::ActiveRecord::Type::String
|
19
|
-
# Casts a value from user input into a KSUID
|
20
|
-
#
|
21
|
-
# Type casting happens via the attribute setter and can take input from
|
22
|
-
# many places, including:
|
23
|
-
#
|
24
|
-
# 1. The Rails form builder
|
25
|
-
# 2. Directly from the attribute setter
|
26
|
-
# 3. From the model initializer
|
27
|
-
#
|
28
|
-
# @param value [String, Array<Integer>, KSUID::Type] the value to cast into a KSUID
|
29
|
-
# @return [KSUID::Type] the type-casted value
|
30
|
-
def cast(value)
|
31
|
-
KSUID.call(value)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Converts a value from database input to a KSUID
|
35
|
-
#
|
36
|
-
# @param value [String, nil] the database-serialized KSUID to convert
|
37
|
-
# @return [KSUID::Type] the deserialized KSUID
|
38
|
-
def deserialize(value)
|
39
|
-
return unless value
|
40
|
-
|
41
|
-
KSUID.from_base62(value)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Casts the value from a KSUID into a database-understandable format
|
45
|
-
#
|
46
|
-
# @param value [KSUID::Type, nil] the KSUID in Ruby format
|
47
|
-
# @return [String, nil] the base 62-encoded KSUID for storage in the database
|
48
|
-
def serialize(value)
|
49
|
-
return unless value
|
50
|
-
|
51
|
-
KSUID.call(value).to_s
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
ActiveRecord::Type.register(:ksuid, KSUID::ActiveRecord::Type)
|
data/lib/ksuid/activerecord.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'ksuid/activerecord/binary_type'
|
4
|
-
require 'ksuid/activerecord/type'
|
5
|
-
|
6
|
-
module KSUID
|
7
|
-
# Enables an Active Record model to have a KSUID attribute
|
8
|
-
#
|
9
|
-
# @api public
|
10
|
-
module ActiveRecord
|
11
|
-
# Builds a module to include into the model
|
12
|
-
#
|
13
|
-
# @api public
|
14
|
-
#
|
15
|
-
# @example Add a `#ksuid` attribute to a model
|
16
|
-
# class Event < ActiveRecord::Base
|
17
|
-
# include KSUID::ActiveRecord[:ksuid]
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
# @example Add a `#remote_id` attribute to a model and overrides `#created_at` to use the KSUID
|
21
|
-
# class Event < ActiveRecord::Base
|
22
|
-
# include KSUID::ActiveRecord[:remote_id, created_at: true]
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# @param field [String, Symbol] the name of the field to use as a KSUID
|
26
|
-
# @param created_at [Boolean] whether to override the `#created_at` method
|
27
|
-
# @param binary [Boolean] whether to store the KSUID as a binary or a string
|
28
|
-
# @return [Module] the module to include into the model
|
29
|
-
def self.[](field, created_at: false, binary: false)
|
30
|
-
Module
|
31
|
-
.new
|
32
|
-
.tap do |mod|
|
33
|
-
define_attribute(field, mod, binary)
|
34
|
-
define_created_at(field, mod) if created_at
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# Defines the attribute method that will be written in the module
|
39
|
-
#
|
40
|
-
# @api private
|
41
|
-
#
|
42
|
-
# @param field [String, Symbol] the name of the field to set as an attribute
|
43
|
-
# @param mod [Module] the module to extend
|
44
|
-
# @return [void]
|
45
|
-
def self.define_attribute(field, mod, binary)
|
46
|
-
type = 'ksuid'
|
47
|
-
type = 'ksuid_binary' if binary
|
48
|
-
|
49
|
-
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
50
|
-
def self.included(base)
|
51
|
-
base.__send__(:attribute, :#{field}, :#{type}, default: -> { KSUID.new })
|
52
|
-
end
|
53
|
-
RUBY
|
54
|
-
end
|
55
|
-
private_class_method :define_attribute
|
56
|
-
|
57
|
-
# Defines the `#created_at` method that will be written in the module
|
58
|
-
#
|
59
|
-
# @api private
|
60
|
-
#
|
61
|
-
# @param field [String, Symbol] the name of the KSUID attribute field
|
62
|
-
# @param mod [Module] the module to extend
|
63
|
-
# @return [void]
|
64
|
-
def self.define_created_at(field, mod)
|
65
|
-
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
66
|
-
def created_at
|
67
|
-
return unless #{field}
|
68
|
-
|
69
|
-
#{field}.to_time
|
70
|
-
end
|
71
|
-
RUBY
|
72
|
-
end
|
73
|
-
private_class_method :define_created_at
|
74
|
-
end
|
75
|
-
end
|
data/lib/ksuid/railtie.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module KSUID
|
4
|
-
# Enables the usage of KSUID types within ActiveRecord when Rails is loaded
|
5
|
-
#
|
6
|
-
# @api private
|
7
|
-
class Railtie < ::Rails::Railtie
|
8
|
-
initializer 'ksuid' do
|
9
|
-
ActiveSupport.on_load :active_record do
|
10
|
-
require 'ksuid/activerecord'
|
11
|
-
require 'ksuid/activerecord/table_definition'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|