active_record_uuid 0.0.1 → 0.1.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.
- data/.rvmrc +1 -1
- data/README.md +126 -22
- data/active_record_uuid.gemspec +4 -3
- data/lib/active_record_uuid.rb +10 -4
- data/lib/active_record_uuid/association_methods.rb +52 -0
- data/lib/active_record_uuid/config.rb +37 -0
- data/lib/active_record_uuid/extensions/quoting_extension.rb +31 -0
- data/lib/active_record_uuid/model.rb +66 -0
- data/lib/active_record_uuid/rails/db.rake +25 -0
- data/lib/active_record_uuid/rails/railtie.rb +19 -0
- data/lib/active_record_uuid/serializer.rb +50 -0
- data/lib/active_record_uuid/uuid_base.rb +12 -4
- data/lib/active_record_uuid/uuid_base_helper.rb +6 -83
- data/lib/active_record_uuid/version.rb +1 -1
- data/spec/lib/association_spec.rb +1 -1
- data/spec/lib/base64_uuid_spec.rb +57 -0
- data/spec/lib/binary_uuid_spec.rb +69 -0
- data/spec/lib/config_spec.rb +41 -0
- data/spec/lib/deprecation_spec.rb +17 -0
- data/spec/lib/hexdigest_uuid_spec.rb +57 -0
- data/spec/lib/serializer_spec.rb +11 -0
- data/spec/lib/string_uuid_spec.rb +57 -0
- data/spec/lib/uuid_config_spec.rb +100 -0
- data/spec/spec_helper.rb +24 -5
- data/spec/support/models.rb +60 -8
- data/spec/support/schema.rb +30 -0
- metadata +48 -12
- data/lib/active_record_uuid/railtie.rb +0 -7
- data/lib/active_record_uuid/tasks/db.rake +0 -26
- data/spec/lib/uuid_base_helper_spec.rb +0 -69
- data/spec/lib/uuid_base_spec.rb +0 -68
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveRecordUuid
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
config.active_record.schema_format = :sql
|
4
|
+
|
5
|
+
initializer :after => 'active_record.initialize_database' do
|
6
|
+
|
7
|
+
ActiveSupport.on_load(:active_record) do |app|
|
8
|
+
require 'active_record_uuid/extensions/quoting_extension'
|
9
|
+
|
10
|
+
::ActiveRecord::Base.connection.class.send :include, ActiveRecordUuid::QuotingExtension
|
11
|
+
::ActiveRecord::Base.send(:include, ActiveRecordUuid::Model)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
rake_tasks do
|
16
|
+
load "active_record_uuid/rails/db.rake"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ActiveRecordUuid
|
2
|
+
class Serializer
|
3
|
+
attr_reader :type
|
4
|
+
def initialize(type)
|
5
|
+
@type = type
|
6
|
+
end
|
7
|
+
|
8
|
+
def load(value)
|
9
|
+
return nil if value.nil?
|
10
|
+
|
11
|
+
begin
|
12
|
+
uuid = case type
|
13
|
+
when :binary
|
14
|
+
UUIDTools::UUID.parse_raw(value)
|
15
|
+
when :base64
|
16
|
+
UUIDTools::UUID.parse_raw(Base64.decode64(value))
|
17
|
+
when :hexdigest
|
18
|
+
UUIDTools::UUID.parse_hexdigest(value)
|
19
|
+
when :string
|
20
|
+
UUIDTools::UUID.parse(value)
|
21
|
+
end
|
22
|
+
raise ArgumentError unless uuid.valid?
|
23
|
+
|
24
|
+
uuid.to_s
|
25
|
+
rescue ArgumentError, TypeError
|
26
|
+
raise ActiveRecord::SerializationTypeMismatch,
|
27
|
+
"Attribute was supposed to be a valid uuid, but was #{value}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def dump(value)
|
32
|
+
uuid = begin
|
33
|
+
UUIDTools::UUID.parse(value)
|
34
|
+
rescue ArgumentError, TypeError
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
case type
|
39
|
+
when :binary
|
40
|
+
uuid.raw
|
41
|
+
when :base64
|
42
|
+
Base64.encode64(uuid.raw).strip
|
43
|
+
when :hexdigest
|
44
|
+
uuid.hexdigest
|
45
|
+
when :string
|
46
|
+
uuid.to_s
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,18 +1,26 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "uuid_base_helper.rb")
|
2
2
|
|
3
3
|
class ActiveRecord::UuidBase < ::ActiveRecord::Base
|
4
|
-
include UuidBaseHelper
|
5
|
-
|
6
4
|
class << self
|
7
5
|
def inherited_with_uuid(kls)
|
8
6
|
inherited_without_uuid kls
|
9
|
-
|
7
|
+
warn "[DEPRECATION] `UuidBaseHelper` and `ActiveRecord::UuidBase` are deprecated. Please inherit from `ActiveRecord::Base` and use `uuid_config` instead."
|
8
|
+
kls.uuid_config do
|
9
|
+
primary_key true
|
10
|
+
association true
|
11
|
+
hook :before_create
|
12
|
+
end
|
10
13
|
end
|
11
14
|
alias_method_chain :inherited, :uuid
|
12
15
|
end
|
13
16
|
|
14
17
|
self.descendants.each do |kls|
|
15
|
-
|
18
|
+
warn "[DEPRECATION] `UuidBaseHelper` and `ActiveRecord::UuidBase` are deprecated. Please inherit from `ActiveRecord::Base` and use `uuid_config` instead."
|
19
|
+
kls.uuid_config do
|
20
|
+
primary_key true
|
21
|
+
association true
|
22
|
+
hook :before_create
|
23
|
+
end
|
16
24
|
end
|
17
25
|
|
18
26
|
self.abstract_class = true
|
@@ -1,89 +1,12 @@
|
|
1
1
|
module UuidBaseHelper
|
2
|
-
UUID_REG = /^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{2})([0-9a-f]{2})-([0-9a-f]{12})$/
|
3
|
-
|
4
2
|
def self.included(base)
|
5
|
-
|
6
|
-
base.send(:extend, AssociationMethods)
|
7
|
-
base.send(:include, InstanceMethods)
|
8
|
-
base.assign_defaults
|
9
|
-
end
|
10
|
-
|
11
|
-
module InstanceMethods
|
12
|
-
def assign_uuid
|
13
|
-
self.id = UUIDTools::UUID.timestamp_create().to_s
|
14
|
-
end
|
15
|
-
|
16
|
-
def assign_uuid!
|
17
|
-
assign_uuid
|
18
|
-
save!
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
def assign_uuid_when_blank
|
23
|
-
assign_uuid if self.id.blank?
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
module ClassMethods
|
28
|
-
def generate_uuid
|
29
|
-
UUIDTools::UUID.send("timestamp_create").to_s
|
30
|
-
end
|
31
|
-
|
32
|
-
def assign_defaults
|
33
|
-
self.primary_key = 'uuid'
|
34
|
-
self.before_create :assign_uuid_when_blank
|
35
|
-
self.validates_format_of :uuid, :with => UUID_REG, :if => Proc.new { |r| r.id.present? }
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
module AssociationMethods
|
40
|
-
def has_many(name, options = {}, &extension)
|
41
|
-
options = uuid_assoc_options(:has_many, name, options)
|
42
|
-
super
|
43
|
-
end
|
44
|
-
|
45
|
-
def has_one(name, options = {})
|
46
|
-
options = uuid_assoc_options(:has_one, name, options)
|
47
|
-
super
|
48
|
-
end
|
49
|
-
|
50
|
-
def belongs_to(name, options = {})
|
51
|
-
options = uuid_assoc_options(:belongs_to, name, options)
|
52
|
-
super
|
53
|
-
end
|
54
|
-
|
55
|
-
def has_and_belongs_to_many(name, options = {}, &extension)
|
56
|
-
options = uuid_assoc_options(:has_and_belongs_to_many, name, options)
|
57
|
-
super
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
def uuid_assoc_options(macro, association_name, options)
|
62
|
-
opts = {}
|
63
|
-
|
64
|
-
# Set class_name only if not a has-through relation or poly relation
|
65
|
-
if options[:through].blank? and options[:as].blank? and options[:class_name].blank? and !self.name.match(/::/)
|
66
|
-
opts[:class_name] = "::#{association_name.to_s.singularize.camelize}"
|
67
|
-
end
|
68
|
-
|
69
|
-
# Set foreign_key only if not passed
|
70
|
-
if options[:foreign_key].blank?
|
71
|
-
case macro
|
72
|
-
when :has_many, :has_one
|
73
|
-
opts[:foreign_key] = uuid_foreign_key(self.name)
|
74
|
-
when :belongs_to
|
75
|
-
opts[:foreign_key] = uuid_foreign_key(association_name)
|
76
|
-
when :has_and_belongs_to_many
|
77
|
-
opts[:foreign_key] = uuid_foreign_key(self.name)
|
78
|
-
opts[:association_foreign_key] = uuid_foreign_key(association_name)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
options.merge(opts)
|
83
|
-
end
|
3
|
+
warn "[DEPRECATION] `UuidBaseHelper` and `ActiveRecord::UuidBase` are deprecated. Please inherit from `ActiveRecord::Base` and use `uuid_config` instead."
|
84
4
|
|
85
|
-
|
86
|
-
|
5
|
+
base.send(:include, ActiveRecordUuid::Model)
|
6
|
+
base.uuid_config do
|
7
|
+
primary_key true
|
8
|
+
association true
|
9
|
+
hook :before_create
|
87
10
|
end
|
88
11
|
end
|
89
12
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Base64 Uuid" do
|
4
|
+
context "configure: PostBase64 model" do
|
5
|
+
it "should have uuid as primary key based config" do
|
6
|
+
PostBase64.primary_key.should eq('uuid')
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should store uuid as base64" do
|
10
|
+
post = PostBase64.create(:text => "Base64 uuid1")
|
11
|
+
post.reload
|
12
|
+
|
13
|
+
post.attributes_before_type_cast["uuid"]["value"].bytesize.should eq(24)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should retreive back as uuid string from base64" do
|
17
|
+
post = PostBase64.create(:text => "Base64 uuid2")
|
18
|
+
post.reload
|
19
|
+
|
20
|
+
post.uuid.should be_present
|
21
|
+
post.uuid.should be_instance_of(String)
|
22
|
+
post.uuid.length.should eq(36)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should retreive uuid back with the same value that was assigned" do
|
26
|
+
post = PostBase64.new(:text => "Base64 uuid2")
|
27
|
+
post.uuid = "b360c78e-b62e-11e1-9870-0026b90faf3c"
|
28
|
+
post.save
|
29
|
+
post.reload
|
30
|
+
|
31
|
+
post.uuid.should eq("b360c78e-b62e-11e1-9870-0026b90faf3c")
|
32
|
+
post.uuid.should be_instance_of(String)
|
33
|
+
post.uuid.length.should eq(36)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should find by uuid column" do
|
37
|
+
post = PostBase64.create(:text => "Base64 uuid3")
|
38
|
+
|
39
|
+
PostBase64.find_by_uuid(post.uuid).should eq(post)
|
40
|
+
PostBase64.where(:uuid => post.uuid).should eq([post])
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should find by primary key" do
|
44
|
+
post = PostBase64.create(:text => "Base64 uuid4")
|
45
|
+
|
46
|
+
PostBase64.find(post).should eq(post)
|
47
|
+
PostBase64.find(post.uuid).should eq(post)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should find by array of primary keys" do
|
51
|
+
post1 = PostBase64.create(:text => "Base64 uuid5")
|
52
|
+
post2 = PostBase64.create(:text => "Base64 uuid6")
|
53
|
+
|
54
|
+
PostBase64.find([post1.uuid, post2.uuid]).should eq([post1, post2])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Binary Uuid" do
|
4
|
+
context "configure: PostBinary model" do
|
5
|
+
it "should have uuid as primary key based config" do
|
6
|
+
PostBinary.primary_key.should eq('uuid')
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have uuid association" do
|
10
|
+
PostBinary.reflections[:comments].options[:foreign_key].should eq("post_binary_uuid")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should store uuid as binary" do
|
14
|
+
post = PostBinary.create(:text => "Binary uuid1")
|
15
|
+
post.reload
|
16
|
+
|
17
|
+
post.attributes_before_type_cast["uuid"]["value"].bytesize.should eq(16)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should retreive back as uuid string from binary" do
|
21
|
+
post = PostBinary.create(:text => "Binary uuid2")
|
22
|
+
post.reload
|
23
|
+
|
24
|
+
post.uuid.should be_present
|
25
|
+
post.uuid.should be_instance_of(String)
|
26
|
+
post.uuid.length.should eq(36)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should retreive uuid back with the same value that was assigned" do
|
30
|
+
post = PostBinary.new(:text => "Binary uuid2")
|
31
|
+
post.uuid = "b360c78e-b62e-11e1-9870-0026b90faf3c"
|
32
|
+
post.save
|
33
|
+
post.reload
|
34
|
+
|
35
|
+
post.uuid.should eq("b360c78e-b62e-11e1-9870-0026b90faf3c")
|
36
|
+
post.uuid.should be_instance_of(String)
|
37
|
+
post.uuid.length.should eq(36)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should find by uuid column" do
|
41
|
+
post = PostBinary.create(:text => "Binary uuid3")
|
42
|
+
|
43
|
+
PostBinary.find_by_uuid(post.uuid).should eq(post)
|
44
|
+
PostBinary.where(:uuid => post.uuid).should eq([post])
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should find by primary key" do
|
48
|
+
post = PostBinary.create(:text => "Binary uuid4")
|
49
|
+
|
50
|
+
PostBinary.find(post).should eq(post)
|
51
|
+
PostBinary.find(post.uuid).should eq(post)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should find by array of primary keys" do
|
55
|
+
post1 = PostBinary.create(:text => "Binary uuid5")
|
56
|
+
post2 = PostBinary.create(:text => "Binary uuid6")
|
57
|
+
|
58
|
+
PostBinary.find([post1.uuid, post2.uuid]).should eq([post1, post2])
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should save association" do
|
62
|
+
blog = Blog.create(:name => "Blog 1")
|
63
|
+
article = blog.articles.create(:title => "Blog Association 1")
|
64
|
+
|
65
|
+
blog.articles.count.should eq(1)
|
66
|
+
blog.articles[0].should eq(article)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Uuid Config" do
|
4
|
+
it "should initialize with default values" do
|
5
|
+
@config = ActiveRecordUuid::Config.new
|
6
|
+
|
7
|
+
@config.column.should eq(:uuid)
|
8
|
+
@config.primary_key.should eq(false)
|
9
|
+
@config.association.should eq(false)
|
10
|
+
@config.generator.should eq(:timestamp)
|
11
|
+
@config.store_as.should eq(:string)
|
12
|
+
@config.hook.should eq(:before_validation)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should validate options: generator" do
|
16
|
+
@config = ActiveRecordUuid::Config.new
|
17
|
+
|
18
|
+
@config.generator(:abc)
|
19
|
+
lambda {
|
20
|
+
@config.validate_options!
|
21
|
+
}.should raise_error ArgumentError, /^Expected :timestamp/
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should validate options: store_as" do
|
25
|
+
@config = ActiveRecordUuid::Config.new
|
26
|
+
|
27
|
+
@config.store_as(:abc)
|
28
|
+
lambda {
|
29
|
+
@config.validate_options!
|
30
|
+
}.should raise_error ArgumentError, /^Expected :binary/
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should validate options: hook" do
|
34
|
+
@config = ActiveRecordUuid::Config.new
|
35
|
+
|
36
|
+
@config.hook(:abc)
|
37
|
+
lambda {
|
38
|
+
@config.validate_options!
|
39
|
+
}.should raise_error ArgumentError, /^Expected :before_validation/
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Depreciation: ActiveRecord::UuidBase" do
|
4
|
+
it "should create uuid" do
|
5
|
+
article = ArticleUuidBase.create(:title => "uuid base1")
|
6
|
+
|
7
|
+
article.uuid.length.should eq(36)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should not use primary_key" do
|
11
|
+
ArticleUuidBase.primary_key.should eq("uuid")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should not set association" do
|
15
|
+
ArticleUuidBase.reflections[:comments].options[:foreign_key].should eq("article_uuid_base_uuid")
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "HexDigest Uuid" do
|
4
|
+
context "configure: PostHexDigest model" do
|
5
|
+
it "should have uuid as primary key based config" do
|
6
|
+
PostHexDigest.primary_key.should eq('uuid')
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should store uuid as HexDigest" do
|
10
|
+
post = PostHexDigest.create(:text => "HexDigest uuid1")
|
11
|
+
post.reload
|
12
|
+
|
13
|
+
post.attributes_before_type_cast["uuid"]["value"].bytesize.should eq(32)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should retreive back as uuid string from HexDigest" do
|
17
|
+
post = PostHexDigest.create(:text => "HexDigest uuid2")
|
18
|
+
post.reload
|
19
|
+
|
20
|
+
post.uuid.should be_present
|
21
|
+
post.uuid.should be_instance_of(String)
|
22
|
+
post.uuid.length.should eq(36)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should retreive uuid back with the same value that was assigned" do
|
26
|
+
post = PostHexDigest.new(:text => "HexDigest uuid2")
|
27
|
+
post.uuid = "b360c78e-b62e-11e1-9870-0026b90faf3c"
|
28
|
+
post.save
|
29
|
+
post.reload
|
30
|
+
|
31
|
+
post.uuid.should eq("b360c78e-b62e-11e1-9870-0026b90faf3c")
|
32
|
+
post.uuid.should be_instance_of(String)
|
33
|
+
post.uuid.length.should eq(36)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should find by uuid column" do
|
37
|
+
post = PostHexDigest.create(:text => "HexDigest uuid3")
|
38
|
+
|
39
|
+
PostHexDigest.find_by_uuid(post.uuid).should eq(post)
|
40
|
+
PostHexDigest.where(:uuid => post.uuid).should eq([post])
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should find by primary key" do
|
44
|
+
post = PostHexDigest.create(:text => "HexDigest uuid4")
|
45
|
+
|
46
|
+
PostHexDigest.find(post).should eq(post)
|
47
|
+
PostHexDigest.find(post.uuid).should eq(post)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should find by array of primary keys" do
|
51
|
+
post1 = PostHexDigest.create(:text => "HexDigest uuid5")
|
52
|
+
post2 = PostHexDigest.create(:text => "HexDigest uuid6")
|
53
|
+
|
54
|
+
PostHexDigest.find([post1.uuid, post2.uuid]).should eq([post1, post2])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|