uuid_attribute 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,5 @@
1
+ ## Unreleased
2
+
3
+ ## 0.1.1 - 2022-08-19
4
+
5
+ * First public release
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,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UuidAttribute
4
+ VERSION = "0.1.1"
5
+ 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)
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
+ require "uuid/attribute"
5
+
6
+ require "minitest/autorun"
@@ -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