uuid_attribute 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|