uuid_attribute 0.1.1
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 +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.md +20 -0
- data/README.md +47 -0
- data/lib/uuid_attribute/active_model.rb +45 -0
- data/lib/uuid_attribute/railtie.rb +58 -0
- data/lib/uuid_attribute/utils.rb +77 -0
- data/lib/uuid_attribute/uuid.rb +30 -0
- data/lib/uuid_attribute/version.rb +5 -0
- data/lib/uuid_attribute.rb +33 -0
- data/test/test_helper.rb +6 -0
- data/test/uuid/test_attribute.rb +15 -0
- metadata +75 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 96777961184916d3e999bd877f58959ffd45b7cd035a3dd8855d346836b55545
|
4
|
+
data.tar.gz: 21e62fa72b4cde23fbb4ca5e4e86500b4e5e1bc2d1ea2a79a8929a52ab762f3c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5f2d0911425daadb52f2cbdf4411c84900508257f4d37ca6bd064f322e11eadc3242294f05a5e5725ed8c113723c449488c67b6a3a38c52a9f8102bda46ea9bd
|
7
|
+
data.tar.gz: f4d8b3adccf186c4f60cb23eb0b6d53e55badb7c9405a994fa883e3f8f430a837f513b1f70254238d9159971a6b051d9b7400bd2497be853e3d3d07d61696603
|
data/CHANGELOG.md
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012-2022 Iugu IP SA.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# UUID::Attribute
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
Install the gem and add to the application's Gemfile by executing:
|
6
|
+
|
7
|
+
$ bundle add activerecord-uuid-attribute
|
8
|
+
|
9
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
10
|
+
|
11
|
+
$ gem install activerecord-uuid-attribute
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
TODO: Write usage instructions here
|
16
|
+
|
17
|
+
```
|
18
|
+
class YourModel < ApplicationRecord
|
19
|
+
# Need to put attribute manually
|
20
|
+
attribute :id, :uuid, default: -> { SecureRandom.uuid }
|
21
|
+
end
|
22
|
+
|
23
|
+
UuidAttribute.setup do |config|
|
24
|
+
# Configure generators to use UUID as primary key (defaults to true)
|
25
|
+
config.default_primary_id = true
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
## Development
|
30
|
+
|
31
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
32
|
+
|
33
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To
|
34
|
+
release a new version, update the version number in `version.rb`, and then run
|
35
|
+
`bundle exec rake release`, which will create a git tag for the version, push
|
36
|
+
git commits and the created tag, and push the `.gem` file to
|
37
|
+
[rubygems.org](https://rubygems.org).
|
38
|
+
|
39
|
+
## TODO
|
40
|
+
|
41
|
+
Write tests for each supported rails versions. See examples at:
|
42
|
+
https://github.com/rails/rails/tree/main/activerecord
|
43
|
+
https://github.com/heartcombo/simple_form/tree/main/gemfiles
|
44
|
+
|
45
|
+
## Contributing
|
46
|
+
|
47
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/pnegri/activerecord-uuid-attribute.
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UuidAttribute
|
4
|
+
# ActiveModel modifications
|
5
|
+
module ActiveModel
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
=begin
|
9
|
+
included do
|
10
|
+
alias_method :initialize_without_uuid, :initialize
|
11
|
+
alias_method :initialize, :uuid_initializer
|
12
|
+
end
|
13
|
+
|
14
|
+
def uuid_initializer(*args)
|
15
|
+
auto_detect_uuids
|
16
|
+
initialize_without_uuid(*args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def binary16_structure?(field_info)
|
20
|
+
field_info.type == :binary && field_info.limit == 16
|
21
|
+
end
|
22
|
+
|
23
|
+
def binary16?(field)
|
24
|
+
field_info = self.class.attribute_types[field]
|
25
|
+
binary16_structure?(field_info) && respond_to?("#{field}?")
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid_default_rails_ids?(att)
|
29
|
+
att.eql?("id") || att.end_with?("_id")
|
30
|
+
end
|
31
|
+
|
32
|
+
def auto_detect_uuids
|
33
|
+
return unless UuidAttribute.auto_detect_binary_ids
|
34
|
+
|
35
|
+
self.class.attribute_names.each do |att|
|
36
|
+
next unless valid_default_rails_ids?(att) && binary16?(att)
|
37
|
+
|
38
|
+
default = nil
|
39
|
+
default = -> { SecureRandom.uuid } if att.eql? "id"
|
40
|
+
self.class.define_attribute att, ::UuidAttribute::UUID.new, default: default
|
41
|
+
end
|
42
|
+
end
|
43
|
+
=end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/railtie"
|
4
|
+
|
5
|
+
module UuidAttribute
|
6
|
+
# Rails Initializer
|
7
|
+
class Railtie < Rails::Railtie
|
8
|
+
railtie_name :uuid_attribute_railtie
|
9
|
+
config.eager_load_namespaces << ::UuidAttribute
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def binary16_structure?(field_info)
|
13
|
+
field_info.type == :binary && field_info.limit == 16
|
14
|
+
end
|
15
|
+
|
16
|
+
def binary16?(field)
|
17
|
+
field_info = self.class.attribute_types[field]
|
18
|
+
binary16_structure?(field_info) && respond_to?("#{field}?")
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid_default_rails_ids?(att)
|
22
|
+
att.eql?("id") || att.end_with?("_id")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
=begin
|
27
|
+
all_models = ObjectSpace.each_object(Class).select { |c| c < ApplicationRecord}.select(&:name)
|
28
|
+
all_models.each do |model|
|
29
|
+
puts model
|
30
|
+
model.attribute_names.each do |att|
|
31
|
+
next unless valid_default_rails_ids?(att) && binary16?(att)
|
32
|
+
|
33
|
+
default = nil
|
34
|
+
default = -> { SecureRandom.uuid } if att.eql? "id"
|
35
|
+
self.class.define_attribute att, ::UuidAttribute::UUID.new, default: default
|
36
|
+
end
|
37
|
+
end
|
38
|
+
=end
|
39
|
+
|
40
|
+
config.after_initialize do
|
41
|
+
# unless SimpleForm.configured?
|
42
|
+
# warn '[Simple Form] Simple Form is not configured in the application and will use the default values.' +
|
43
|
+
# ' Use `rails generate simple_form:install` to generate the Simple Form configuration.'
|
44
|
+
# end
|
45
|
+
|
46
|
+
ActiveRecord::Type.register(:uuid, ::UuidAttribute::UUID)
|
47
|
+
|
48
|
+
ActiveRecord::Base.include ::UuidAttribute::ActiveModel if defined? ActiveRecord::Base
|
49
|
+
|
50
|
+
if UuidAttribute.default_primary_id
|
51
|
+
# Configure UUID as Default Primary Key
|
52
|
+
Rails.application.config.generators do |g|
|
53
|
+
g.orm :active_record, primary_key_type: "binary, limit: 16"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UuidAttribute
|
4
|
+
# UUID Utils
|
5
|
+
class Utils
|
6
|
+
class << self
|
7
|
+
def normalize(uuid_string)
|
8
|
+
uuid_string.gsub("-", "").upcase
|
9
|
+
end
|
10
|
+
|
11
|
+
def hex_from_binary(bytes)
|
12
|
+
bytes.unpack1("H*")
|
13
|
+
end
|
14
|
+
|
15
|
+
def mysql_value(value)
|
16
|
+
"x'#{value}'"
|
17
|
+
end
|
18
|
+
|
19
|
+
def raw_bytes(uuid_string)
|
20
|
+
[uuid_string].pack("H*")
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse(str)
|
24
|
+
return nil if str.length.zero?
|
25
|
+
|
26
|
+
case str.length
|
27
|
+
when 36
|
28
|
+
normalize(str)
|
29
|
+
when 16
|
30
|
+
normalize(hex_from_binary(str))
|
31
|
+
when 20, 21, 22
|
32
|
+
unshort(str)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
DEFAULT_BASE62 = %w[
|
37
|
+
0 1 2 3 4 5 6 7 8 9
|
38
|
+
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
|
39
|
+
a b c d e f g h i j k l m n o p q r s t u v w x y z
|
40
|
+
].freeze
|
41
|
+
|
42
|
+
def shorten(decimal, alphabet = DEFAULT_BASE62)
|
43
|
+
alphabet = alphabet.to_a
|
44
|
+
radix = alphabet.length
|
45
|
+
normalized_decimal = normalize(decimal).to_i(16)
|
46
|
+
i = normalized_decimal.to_i
|
47
|
+
out = []
|
48
|
+
return alphabet[0] if i.zero?
|
49
|
+
|
50
|
+
loop do
|
51
|
+
break if i.zero?
|
52
|
+
|
53
|
+
out.unshift(alphabet[i % radix])
|
54
|
+
i /= radix
|
55
|
+
end
|
56
|
+
out.join.rjust(22, "0")
|
57
|
+
end
|
58
|
+
|
59
|
+
def unshort(word, alphabet = DEFAULT_BASE62)
|
60
|
+
num = 0
|
61
|
+
radix = alphabet.length
|
62
|
+
word.chars.to_a.reverse.each_with_index do |char, index|
|
63
|
+
num += alphabet.index(char) * (radix**index)
|
64
|
+
end
|
65
|
+
|
66
|
+
uuid = num.to_s(16).rjust(32, "0")
|
67
|
+
[
|
68
|
+
uuid[0..7],
|
69
|
+
uuid[8..11],
|
70
|
+
uuid[12..15],
|
71
|
+
uuid[16..19],
|
72
|
+
uuid[20..31]
|
73
|
+
].join("-")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UuidAttribute
|
4
|
+
# UUID Attribute
|
5
|
+
class UUID < ActiveModel::Type::Binary
|
6
|
+
def type
|
7
|
+
:uuid
|
8
|
+
end
|
9
|
+
|
10
|
+
def serialize(value)
|
11
|
+
return if value.blank?
|
12
|
+
|
13
|
+
ActiveRecord::Type::Binary::Data.new(
|
14
|
+
Utils.raw_bytes(Utils.normalize(Utils.parse(value)))
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def deserialize(value)
|
19
|
+
return nil if value.nil?
|
20
|
+
|
21
|
+
Utils.shorten(Utils.parse(value.to_s))
|
22
|
+
end
|
23
|
+
|
24
|
+
def cast(value)
|
25
|
+
return if value.nil?
|
26
|
+
|
27
|
+
Utils.shorten(Utils.parse(value.to_s))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_model"
|
4
|
+
require "active_model/type"
|
5
|
+
require_relative "uuid_attribute/version"
|
6
|
+
require_relative "uuid_attribute/uuid"
|
7
|
+
require_relative "uuid_attribute/active_model"
|
8
|
+
require_relative "uuid_attribute/utils"
|
9
|
+
|
10
|
+
# UUID::Attribute is a module that provides a UUID attribute for ActiveRecord
|
11
|
+
module UuidAttribute
|
12
|
+
extend ActiveSupport::Autoload
|
13
|
+
|
14
|
+
eager_autoload do
|
15
|
+
UUID
|
16
|
+
end
|
17
|
+
|
18
|
+
class Error < StandardError; end
|
19
|
+
|
20
|
+
## CONFIGURATION OPTIONS
|
21
|
+
|
22
|
+
mattr_accessor :auto_detect_binary_ids
|
23
|
+
self.auto_detect_binary_ids = true
|
24
|
+
|
25
|
+
mattr_accessor :default_primary_id
|
26
|
+
self.default_primary_id = true
|
27
|
+
|
28
|
+
def self.setup
|
29
|
+
yield self
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require_relative "uuid_attribute/railtie" if defined?(Rails)
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
module UUID
|
6
|
+
class TestAttribute < Minitest::Test
|
7
|
+
def test_that_it_has_a_version_number
|
8
|
+
refute_nil ::UUID::Attribute::VERSION
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_it_does_something_useful
|
12
|
+
assert false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: uuid_attribute
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Patrick Negri
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-08-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activemodel
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.2'
|
27
|
+
description: Another one
|
28
|
+
email:
|
29
|
+
- patrick@iugu.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- CHANGELOG.md
|
35
|
+
- LICENSE.md
|
36
|
+
- README.md
|
37
|
+
- lib/uuid_attribute.rb
|
38
|
+
- lib/uuid_attribute/active_model.rb
|
39
|
+
- lib/uuid_attribute/railtie.rb
|
40
|
+
- lib/uuid_attribute/utils.rb
|
41
|
+
- lib/uuid_attribute/uuid.rb
|
42
|
+
- lib/uuid_attribute/version.rb
|
43
|
+
- test/test_helper.rb
|
44
|
+
- test/uuid/test_attribute.rb
|
45
|
+
homepage: https://github.com/iugu/activerecord-uuid-attribute
|
46
|
+
licenses:
|
47
|
+
- MIT
|
48
|
+
metadata:
|
49
|
+
homepage_uri: https://github.com/iugu/activerecord-uuid-attribute
|
50
|
+
documentation_uri: https://rubydoc.info/github/iugu/simple_form/activerecord-uuid-attribute
|
51
|
+
changelog_uri: https://github.com/iugu/activerecord-uuid-attribute/blob/main/CHANGELOG.md
|
52
|
+
source_code_uri: https://github.com/iugu/activerecord-uuid-attribute
|
53
|
+
bug_tracker_uri: https://github.com/iugu/activerecord-uuid-attribute/issues
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 2.6.0
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubygems_version: 3.2.32
|
70
|
+
signing_key:
|
71
|
+
specification_version: 4
|
72
|
+
summary: Write a short summary, because RubyGems requires one.
|
73
|
+
test_files:
|
74
|
+
- test/test_helper.rb
|
75
|
+
- test/uuid/test_attribute.rb
|