activeuuid 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
1
  --colour
2
2
  --format documentation
3
3
  --backtrace
4
+ --order random
@@ -0,0 +1,27 @@
1
+ before_script:
2
+ - mysql -e 'create database activeuuid_test;'
3
+ - psql -c 'create database activeuuid_test;' -U postgres
4
+
5
+ rvm:
6
+ - 1.9.2
7
+ - 1.9.3
8
+ - 2.0.0
9
+ - rbx-19mode
10
+
11
+ gemfile:
12
+ - Gemfile
13
+ - gemfiles/Gemfile.rails-3-1
14
+ - gemfiles/Gemfile.rails-3-2
15
+ - gemfiles/Gemfile.rails-head
16
+
17
+ env:
18
+ - DB=sqlite3
19
+ - DB=mysql
20
+ - DB=postgresql
21
+
22
+ matrix:
23
+ allow_failures:
24
+ - gemfile: gemfiles/Gemfile.rails-head
25
+ exclude:
26
+ - rvm: 1.9.2
27
+ gemfile: gemfiles/Gemfile.rails-head
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in activeuuid.gemspec
4
4
  gemspec
5
+
6
+ gem "activerecord"
data/README.mkd CHANGED
@@ -1,6 +1,8 @@
1
+ [![Build Status](https://travis-ci.org/jashmenn/activeuuid.png)](http://travis-ci.org/jashmenn/activeuuid)
2
+
1
3
  # activeuuid
2
4
 
3
- Add `binary(16)` UUIDs to ActiveRecord.
5
+ Add `binary(16)` UUIDs to ActiveRecord.
4
6
 
5
7
  ## Example
6
8
 
@@ -48,20 +50,15 @@ require 'spec_helper'
48
50
  describe Email do
49
51
 
50
52
  context "when using uuid's as keys" do
51
- before(:each) do
52
- Email.delete_all
53
- @guid = "1dd74dd0-d116-11e0-99c7-5ac5d975667e"
54
- @e = Email.new(:subject => "hello", :body => "world") {|e| e.id = UUIDTools::UUID.parse(@guid) }
55
- @e.save
56
- end
53
+ let(:guid) { "1dd74dd0-d116-11e0-99c7-5ac5d975667e" }
54
+ let(:email) { Fabricate :email }
57
55
 
58
56
  it "the id guid should be equal to the uuid" do
59
- @e.id.to_s.should eql(@guid)
57
+ email.id.to_s.should eql(guid)
60
58
  end
61
59
 
62
60
  it "should be able to find an email by the uuid" do
63
- f = Email.find(UUIDTools::UUID.parse(@guid))
64
- f.id.to_s.should eql(@guid)
61
+ Email.find(guid).id.to_s.should == guid
65
62
  end
66
63
 
67
64
  end
@@ -73,9 +70,9 @@ end
73
70
  From [2]:
74
71
 
75
72
  > [Here is a] UUID: 1e8ef774-581c-102c-bcfe-f1ab81872213
76
- >
73
+ >
77
74
  > A UUID like the one above is 36 characters long, including dashes. If you store this VARCHAR(36), you're going to decrease compare performance dramatically. This is your primary key, you don't want it to be slow.
78
- >
75
+ >
79
76
  > At its bit level, a UUID is 128 bits, which means it will fit into
80
77
  > 16 bytes, note this is not very human readable, but it will keep
81
78
  > storage low, and is only 4 times larger than a 32-bit int, or 2
@@ -98,10 +95,9 @@ application the keys are represented by a UUIDTools::UUID object.
98
95
  * more transparent support for natural and composite keys
99
96
  * support for MySQLs `INSERT ... ON DUPLICATE KEY UPDATE` syntax
100
97
  * support a primary column name other than `id`
101
- * work on other databases (Postgres, etc)
102
98
  * tests
103
99
 
104
- ## Inspiration
100
+ ## Inspiration
105
101
  James Golick's `friendly` is a great gem for NoSQL on MySQL. It's
106
102
  a great gateway drug to systems like Cassandra for teams that are
107
103
  already familiar with the ins-and-outs of MySQL.
@@ -114,35 +110,17 @@ Add this to your `Gemfile`
114
110
 
115
111
  Or get the code here: https://github.com/jashmenn/activeuuid
116
112
 
117
- ## Notes
118
-
119
- ### Fixtures
120
-
121
- You can use `activeuuid` in fixtures by using the `!!binary` directive in YAML.
122
- The trick is to base64 encode the raw bytes of the hexdigest.
123
-
124
- ```yaml
125
- devin_ifttt_new_tweet:
126
- id: !!binary "<%= Base64.encode64(UUIDTools::UUID.parse_hexdigest('2D79B402CBA811E1AA7C14DAE903E06A').raw) %>"
127
- data:
128
- user_id: 1
129
- source_id: 1
130
- recipe_id: 1
131
- created_at: Mon, 09 Jul 2012 14:06:21 -0700
132
- body: Nice blog entry!
133
- ```
134
113
 
135
114
  ## References
136
115
  * [1] http://bret.appspot.com/entry/how-friendfeed-uses-mysql
137
- * [2] http://kekoav.com/blog/36-computers/58-uuids-as-primary-keys-in-mysql.html
116
+ * [2] http://kekoav.com/blog/36-computers/58-uuids-as-primary-keys-in-mysql.html
138
117
  * [3] https://gist.github.com/937739
139
118
  * [4] http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html
140
119
  * [5] http://krow.livejournal.com/497839.html
141
120
  * [6] https://github.com/jamesgolick/friendly
142
121
 
143
122
  ## Dependencies
144
- Rails ~> 3.1.0 - It uses the custom column serialization Aaron
145
- Patterson introduced in Rails 3.1.
123
+ Rails ~> 3.1.0
146
124
 
147
125
  ## Author
148
126
 
data/Rakefile CHANGED
@@ -4,3 +4,5 @@ require 'rspec/core'
4
4
  require 'rspec/core/rake_task'
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.version = Activeuuid::VERSION
8
8
  s.authors = ["Nate Murray"]
9
9
  s.email = ["nate@natemurray.com"]
10
- s.homepage = "http://www.eigenjoy.com"
10
+ s.homepage = "https://github.com/jashmenn/activeuuid"
11
11
  s.summary = %q{Add binary UUIDs to ActiveRecord in MySQL}
12
12
  s.description = %q{Add binary (not string) UUIDs to ActiveRecord in MySQL}
13
13
 
@@ -27,5 +27,5 @@ Gem::Specification.new do |s|
27
27
  s.add_development_dependency "mysql2"
28
28
 
29
29
  s.add_runtime_dependency "uuidtools"
30
- s.add_runtime_dependency "activerecord"
30
+ s.add_runtime_dependency "activerecord", '>= 3.1'
31
31
  end
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'activerecord', '~> 3.1.0'
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'activerecord', '~> 3.2.0'
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'activerecord', github: 'rails/rails'
@@ -1,9 +1,12 @@
1
+ require 'active_record'
2
+ require 'active_support/concern'
3
+
4
+
1
5
  module ActiveUUID
2
6
  module Patches
3
7
  module Migrations
4
- def uuid(*args)
5
- options = args.extract_options!
6
- column_names = args
8
+ def uuid(*column_names)
9
+ options = column_names.extract_options!
7
10
  column_names.each do |name|
8
11
  type = @base.adapter_name.downcase == 'postgresql' ? 'uuid' : 'binary(16)'
9
12
  column(name, "#{type}#{' PRIMARY KEY' if options.delete(:primary_key)}", options)
@@ -11,22 +14,65 @@ module ActiveUUID
11
14
  end
12
15
  end
13
16
 
17
+ module Column
18
+ extend ActiveSupport::Concern
19
+
20
+ included do
21
+ def type_cast_with_uuid(value)
22
+ return UUIDTools::UUID.serialize(value) if type == :uuid
23
+ type_cast_without_uuid(value)
24
+ end
25
+
26
+ def type_cast_code_with_uuid(var_name)
27
+ return "UUIDTools::UUID.serialize(#{var_name})" if type == :uuid
28
+ type_cast_code_without_uuid(var_name)
29
+ end
30
+
31
+ def simplified_type_with_uuid(field_type)
32
+ return :uuid if field_type == 'binary(16)'
33
+ simplified_type_without_uuid(field_type)
34
+ end
35
+
36
+ alias_method_chain :type_cast, :uuid
37
+ alias_method_chain :type_cast_code, :uuid
38
+ alias_method_chain :simplified_type, :uuid
39
+ end
40
+ end
41
+
42
+ module PostgreSQLColumn
43
+ extend ActiveSupport::Concern
44
+
45
+ included do
46
+ def simplified_type_with_pguuid(field_type)
47
+ return :uuid if field_type == 'uuid'
48
+ simplified_type_without_pguuid(field_type)
49
+ end
50
+
51
+ alias_method_chain :simplified_type, :pguuid
52
+ end
53
+ end
54
+
14
55
  module Quoting
15
56
  extend ActiveSupport::Concern
16
57
 
17
58
  included do
18
59
  def quote_with_visiting(value, column = nil)
19
- value = ActiveUUID::UUIDSerializer.new.load(value) if column && column.sql_type == 'binary(16)'
60
+ value = UUIDTools::UUID.serialize(value) if column && column.type == :uuid
20
61
  quote_without_visiting(value, column)
21
62
  end
22
63
 
23
64
  def type_cast_with_visiting(value, column = nil)
24
- value = ActiveUUID::UUIDSerializer.new.load(value) if column && column.sql_type == 'binary(16)'
65
+ value = UUIDTools::UUID.serialize(value) if column && column.type == :uuid
25
66
  type_cast_without_visiting(value, column)
26
67
  end
27
68
 
69
+ def native_database_types_with_uuid
70
+ @native_database_types ||= native_database_types_without_uuid.merge(uuid: { name: 'binary', limit: 16 })
71
+ end
72
+
28
73
  alias_method_chain :quote, :visiting
29
74
  alias_method_chain :type_cast, :visiting
75
+ alias_method_chain :native_database_types, :uuid
30
76
  end
31
77
  end
32
78
 
@@ -35,24 +81,35 @@ module ActiveUUID
35
81
 
36
82
  included do
37
83
  def quote_with_visiting(value, column = nil)
38
- value = ActiveUUID::UUIDSerializer.new.load(value).to_s if column && column.sql_type == 'uuid'
84
+ value = UUIDTools::UUID.serialize(value) if column && column.type == :uuid
85
+ value = value.to_s if value.is_a? UUIDTools::UUID
39
86
  quote_without_visiting(value, column)
40
87
  end
41
88
 
42
89
  def type_cast_with_visiting(value, column = nil)
43
- value = ActiveUUID::UUIDSerializer.new.load(value).to_s if column && column.sql_type == 'uuid'
90
+ value = UUIDTools::UUID.serialize(value) if column && column.type == :uuid
91
+ value = value.to_s if value.is_a? UUIDTools::UUID
44
92
  type_cast_without_visiting(value, column)
45
93
  end
46
94
 
95
+ def native_database_types_with_pguuid
96
+ @native_database_types ||= native_database_types_without_pguuid.merge(uuid: { name: 'uuid' })
97
+ end
98
+
47
99
  alias_method_chain :quote, :visiting
48
100
  alias_method_chain :type_cast, :visiting
101
+ alias_method_chain :native_database_types, :pguuid
49
102
  end
50
103
  end
51
104
 
52
105
  def self.apply!
53
106
  ActiveRecord::ConnectionAdapters::Table.send :include, Migrations if defined? ActiveRecord::ConnectionAdapters::Table
54
107
  ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Migrations if defined? ActiveRecord::ConnectionAdapters::TableDefinition
55
- ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.send :include, Quoting if defined? ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
108
+
109
+ ActiveRecord::ConnectionAdapters::Column.send :include, Column
110
+ ActiveRecord::ConnectionAdapters::PostgreSQLColumn.send :include, PostgreSQLColumn if defined? ActiveRecord::ConnectionAdapters::PostgreSQLColumn
111
+
112
+ ActiveRecord::ConnectionAdapters::Mysql2Adapter.send :include, Quoting if defined? ActiveRecord::ConnectionAdapters::Mysql2Adapter
56
113
  ActiveRecord::ConnectionAdapters::SQLite3Adapter.send :include, Quoting if defined? ActiveRecord::ConnectionAdapters::SQLite3Adapter
57
114
  ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send :include, PostgreSQLQuoting if defined? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
58
115
  end
@@ -1,10 +1,13 @@
1
1
  require 'uuidtools'
2
2
 
3
+ # monkey-patch Friendly::UUID to serialize UUIDs
3
4
  module UUIDTools
4
5
  class UUID
5
- # monkey-patch Friendly::UUID to serialize UUIDs to MySQL
6
6
  alias_method :id, :raw
7
7
 
8
+ # duck typing activerecord 3.1 dirty hack )
9
+ def gsub *; self; end
10
+
8
11
  def quoted_id
9
12
  s = raw.unpack("H*")[0]
10
13
  "x'#{s}'"
@@ -17,6 +20,30 @@ module UUIDTools
17
20
  def to_param
18
21
  hexdigest.upcase
19
22
  end
23
+
24
+ def self.serialize(value)
25
+ case value
26
+ when self
27
+ value
28
+ when String
29
+ parse_string value
30
+ else
31
+ nil
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def self.parse_string(str)
38
+ return nil if str.length == 0
39
+ if str.length == 36
40
+ parse str
41
+ elsif str.length == 32
42
+ parse_hexdigest str
43
+ else
44
+ parse_raw str
45
+ end
46
+ end
20
47
  end
21
48
  end
22
49
 
@@ -49,89 +76,53 @@ module Arel
49
76
  end
50
77
 
51
78
  module ActiveUUID
52
- class UUIDSerializer
53
- def load(binary)
54
- case binary
55
- when UUIDTools::UUID
56
- binary
57
- when String
58
- parse_string(binary)
59
- else
60
- nil
61
- end
62
- end
63
-
64
- def dump(uuid)
65
- case uuid
66
- when UUIDTools::UUID
67
- uuid.raw
68
- when String
69
- parse_string(uuid).try(:raw)
70
- else
71
- nil
72
- end
73
- end
74
-
75
- private
76
-
77
- def parse_string str
78
- return nil if str.blank?
79
- if str.length == 36
80
- UUIDTools::UUID.parse str
81
- elsif str.length == 32
82
- UUIDTools::UUID.parse_hexdigest str
83
- else
84
- UUIDTools::UUID.parse_raw str
85
- end
86
- end
87
- end
88
-
89
79
  module UUID
90
80
  extend ActiveSupport::Concern
91
81
 
92
82
  included do
93
- class_attribute :uuid_attributes, :instance_writer => true
94
- uuids :id
83
+ class_attribute :_natural_key, instance_writer: false
84
+ class_attribute :_uuid_generator, instance_writer: false
85
+ self._uuid_generator = :random
86
+
87
+ singleton_class.alias_method_chain :instantiate, :uuid
95
88
  before_create :generate_uuids_if_needed
96
89
  end
97
90
 
98
91
  module ClassMethods
99
- def natural_key_attributes
100
- @_activeuuid_natural_key_attributes
101
- end
102
-
103
92
  def natural_key(*attributes)
104
- @_activeuuid_natural_key_attributes = attributes
93
+ self._natural_key = attributes
105
94
  end
106
95
 
107
- def uuid_generator(generator_name=nil)
108
- @_activeuuid_kind = generator_name if generator_name
109
- @_activeuuid_kind || :random
96
+ def uuid_generator(generator_name)
97
+ self._uuid_generator = generator_name
110
98
  end
111
99
 
112
100
  def uuids(*attributes)
113
- self.uuid_attributes = attributes.collect(&:intern).each do |attribute|
114
- serialize attribute, ActiveUUID::UUIDSerializer.new
115
- # serializing attributes on the fly
116
- define_method "#{attribute}=" do |value|
117
- write_attribute attribute, serialized_attributes[attribute.to_s].load(value)
118
- end
101
+ ActiveSupport::Deprecation.warn <<-EOS
102
+ ActiveUUID detects uuid columns independently.
103
+ There is no more need to use uuid method.
104
+ EOS
105
+ end
106
+
107
+ def instantiate_with_uuid(record)
108
+ uuid_columns.each do |uuid_column|
109
+ record[uuid_column] = UUIDTools::UUID.serialize(record[uuid_column]).to_s if record[uuid_column]
119
110
  end
120
- #class_eval <<-eos
121
- # # def #{@association_name}
122
- # # @_#{@association_name} ||= self.class.associations[:#{@association_name}].new_proxy(self)
123
- # # end
124
- #eos
111
+ instantiate_without_uuid(record)
112
+ end
113
+
114
+ def uuid_columns
115
+ @uuid_columns ||= columns.select { |c| c.type == :uuid }.map(&:name)
125
116
  end
126
117
  end
127
118
 
128
119
  def create_uuid
129
- if nka = self.class.natural_key_attributes
120
+ if _natural_key
130
121
  # TODO if all the attributes return nil you might want to warn about this
131
- chained = nka.collect{|a| self.send(a).to_s}.join("-")
122
+ chained = _natural_key.map { |attribute| self.send(attribute) }.join('-')
132
123
  UUIDTools::UUID.sha1_create(UUIDTools::UUID_OID_NAMESPACE, chained)
133
124
  else
134
- case self.class.uuid_generator
125
+ case _uuid_generator
135
126
  when :random
136
127
  UUIDTools::UUID.random_create
137
128
  when :time
@@ -141,8 +132,9 @@ module ActiveUUID
141
132
  end
142
133
 
143
134
  def generate_uuids_if_needed
144
- (uuid_attributes & [self.class.primary_key.intern]).each do |attr|
145
- self.send("#{attr}=", create_uuid) unless self.send(attr)
135
+ primary_key = self.class.primary_key
136
+ if self.class.columns_hash[primary_key].type == :uuid
137
+ send("#{primary_key}=", create_uuid) unless send("#{primary_key}?")
146
138
  end
147
139
  end
148
140
 
@@ -1,3 +1,3 @@
1
1
  module Activeuuid
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,16 +1,78 @@
1
1
  require 'spec_helper'
2
2
 
3
+ describe ActiveRecord::Base do
4
+ context '.connection' do
5
+ let!(:connection) { ActiveRecord::Base.connection }
6
+ let(:table_name) { :test_uuid_field_creation }
7
+
8
+ before do
9
+ connection.drop_table(table_name) if connection.table_exists?(table_name)
10
+ connection.create_table(table_name)
11
+ end
12
+
13
+ after do
14
+ connection.drop_table table_name
15
+ end
16
+
17
+ specify { connection.table_exists?(table_name).should be_true }
18
+
19
+ context '#add_column' do
20
+ let(:column_name) { :uuid_column }
21
+ let(:column) { connection.columns(table_name).detect { |c| c.name.to_sym == column_name } }
22
+
23
+ before { connection.add_column table_name, column_name, :uuid }
24
+
25
+ specify { connection.column_exists?(table_name, column_name).should be_true }
26
+ specify { column.should_not be_nil }
27
+
28
+ it 'should have proper sql type' do
29
+ spec_for_adapter do |adapters|
30
+ adapters.sqlite3 { column.sql_type.should == 'binary(16)' }
31
+ adapters.mysql2 { column.sql_type.should == 'binary(16)' }
32
+ adapters.postgresql { column.sql_type.should == 'uuid' }
33
+ end
34
+ end
35
+ end
36
+
37
+ context '#change_column' do
38
+ let(:column_name) { :string_col }
39
+ let(:column) { connection.columns(table_name).detect { |c| c.name.to_sym == column_name } }
40
+
41
+ before do
42
+ connection.add_column table_name, column_name, :string
43
+ spec_for_adapter do |adapters|
44
+ adapters.sqlite3 { connection.change_column table_name, column_name, :uuid }
45
+ adapters.mysql2 { connection.change_column table_name, column_name, :uuid }
46
+ # adapters.postgresql { connection.change_column table_name, column_name, :uuid }
47
+ end
48
+ end
49
+
50
+ it 'support changing type from string to uuid' do
51
+ spec_for_adapter do |adapters|
52
+ adapters.sqlite3 { column.sql_type.should == 'binary(16)' }
53
+ adapters.mysql2 { column.sql_type.should == 'binary(16)' }
54
+ adapters.postgresql { pending('postgresql can`t change column type to uuid') }
55
+ end
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+
3
62
  describe Article do
4
63
  let!(:article) { Fabricate :article }
5
64
  let(:id) { article.id }
6
65
  let(:model) { Article }
66
+ subject { model }
67
+
68
+ context 'model' do
69
+ its(:all) { should == [article] }
70
+ its(:first) { should == article }
71
+ end
7
72
 
8
73
  context 'existance' do
9
- specify { article.id.should be_a Integer }
10
- it "should create record" do
11
- model.all.should == [article]
12
- model.first.should == article
13
- end
74
+ subject { article }
75
+ its(:id) { should be_a Integer }
14
76
  end
15
77
 
16
78
  context '.find' do
@@ -18,28 +80,40 @@ describe Article do
18
80
  end
19
81
 
20
82
  context '.where' do
21
- specify { model.where(:id => id).first.should == article }
83
+ specify { model.where(id: id).first.should == article }
22
84
  end
23
85
 
24
- context '.destroy' do
25
- specify { article.delete.should be_true }
26
- specify { article.destroy.should be_true }
86
+ context '#destroy' do
87
+ subject { article }
88
+ its(:delete) { should be_true }
89
+ its(:destroy) { should be_true }
27
90
  end
28
91
  end
29
92
 
30
93
  describe UuidArticle do
31
94
  let!(:article) { Fabricate :uuid_article }
32
- let(:id) { article.id }
33
- let(:model) { UuidArticle }
95
+ let!(:id) { article.id }
96
+ let(:model) { described_class }
97
+ subject { model }
34
98
 
35
- specify { model.primary_key.should == 'id' }
99
+ context 'model' do
100
+ its(:primary_key) { should == 'id' }
101
+ its(:all) { should == [article] }
102
+ its(:first) { should == article }
103
+ end
36
104
 
37
105
  context 'existance' do
38
- specify { article.id.should be_a UUIDTools::UUID }
39
- it "should create record" do
40
- model.all.should == [article]
41
- model.first.should == article
42
- end
106
+ subject { article }
107
+ its(:id) { should be_a UUIDTools::UUID }
108
+ end
109
+
110
+ context 'interpolation' do
111
+ specify { model.where("id = :id", id: article.id) }
112
+ end
113
+
114
+ context 'batch interpolation' do
115
+ before { model.update_all(["title = CASE WHEN id = :id THEN 'Passed' ELSE 'Nothing' END", id: article.id]) }
116
+ specify { article.reload.title.should == 'Passed' }
43
117
  end
44
118
 
45
119
  context '.find' do
@@ -50,14 +124,64 @@ describe UuidArticle do
50
124
  end
51
125
 
52
126
  context '.where' do
53
- specify { model.where(:id => article).first.should == article }
54
- specify { model.where(:id => id).first.should == article }
55
- specify { model.where(:id => id.to_s).first.should == article }
56
- specify { model.where(:id => id.raw).first.should == article }
127
+ specify { model.where(id: article).first.should == article }
128
+ specify { model.where(id: id).first.should == article }
129
+ specify { model.where(id: id.to_s).first.should == article }
130
+ specify { model.where(id: id.raw).first.should == article }
57
131
  end
58
132
 
59
- context '.destroy' do
60
- specify { article.delete.should be_true }
61
- specify { article.destroy.should be_true }
133
+ context '#destroy' do
134
+ subject { article }
135
+ its(:delete) { should be_true }
136
+ its(:destroy) { should be_true }
137
+ end
138
+
139
+ context '#reload' do
140
+ subject { article }
141
+ its(:'reload.id') { should == id }
142
+ specify { subject.reload(:select => :another_uuid).id.should == id }
143
+ end
144
+
145
+ context 'columns' do
146
+ [:id, :another_uuid].each do |column|
147
+ context column do
148
+ subject { model.columns_hash[column.to_s] }
149
+ its(:type) { should == :uuid }
150
+ end
151
+ end
152
+ end
153
+
154
+ context 'typecasting' do
155
+ let(:uuid) { UUIDTools::UUID.random_create }
156
+ let(:string) { uuid.to_s }
157
+ context 'primary' do
158
+ before { article.id = string }
159
+ specify do
160
+ article.id.should == uuid
161
+ article.id_before_type_cast.should == string
162
+ end
163
+ specify do
164
+ article.id_before_type_cast.should == string
165
+ article.id.should == uuid
166
+ end
167
+ end
168
+
169
+ context 'non-primary' do
170
+ before { article.another_uuid = string }
171
+ specify do
172
+ article.another_uuid.should == uuid
173
+ article.another_uuid_before_type_cast.should == string
174
+ end
175
+ specify do
176
+ article.another_uuid_before_type_cast.should == string
177
+ article.another_uuid.should == uuid
178
+ end
179
+ specify do
180
+ article.save
181
+ article.reload
182
+ article.another_uuid_before_type_cast.should == string
183
+ article.another_uuid.should == uuid
184
+ end
185
+ end
62
186
  end
63
187
  end
@@ -1,37 +1,29 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe UUIDTools::UUID do
4
+ let(:input) { "e4618518-cb9f-11e1-aa7c-14dae903e06a" }
5
+ let(:hex) { "E4618518CB9F11E1AA7C14DAE903E06A" }
6
+ let(:uuid) { described_class.parse input }
4
7
 
5
- before do
6
- input = "e4618518-cb9f-11e1-aa7c-14dae903e06a"
7
- @sql_out = "x'e4618518cb9f11e1aa7c14dae903e06a'"
8
- @param_out = "E4618518CB9F11E1AA7C14DAE903E06A"
8
+ context 'instance methods' do
9
+ subject { uuid }
10
+ let(:sql_out) { "x'e4618518cb9f11e1aa7c14dae903e06a'" }
9
11
 
10
- @uuid = UUIDTools::UUID.parse input
12
+ its(:quoted_id) {should == sql_out}
13
+ its(:as_json) {should == hex}
14
+ its(:to_param) {should == hex}
11
15
  end
12
16
 
13
- it 'adds methods to the UUID class' do
14
- [:quoted_id, :as_json, :to_param].each do |meth|
15
- @uuid.should respond_to(meth)
16
- end
17
+ describe '.serialize' do
18
+ subject { described_class }
19
+ let(:raw) { uuid.raw }
20
+
21
+ specify { subject.serialize(uuid).should == uuid }
22
+ specify { subject.serialize(input).should == uuid }
23
+ specify { subject.serialize(hex).should == uuid }
24
+ specify { subject.serialize(raw).should == uuid }
25
+ specify { subject.serialize(nil).should be_nil }
26
+ specify { subject.serialize('').should be_nil }
27
+ specify { subject.serialize(5).should be_nil }
17
28
  end
18
-
19
- describe '#quoted_id' do
20
- it 'returns the SQL binary representation for the uuid' do
21
- @uuid.quoted_id.should eql(@sql_out)
22
- end
23
- end
24
-
25
- describe '#as_json' do
26
- it 'returns the uppercase hexdigest' do
27
- @uuid.as_json.should eql(@param_out)
28
- end
29
- end
30
-
31
- describe '#to_param' do
32
- it 'also returns the uppercase hexdigest' do
33
- @uuid.to_param.should eql(@param_out)
34
- end
35
- end
36
-
37
29
  end
@@ -13,6 +13,7 @@ ActiveRecord::Base.establish_connection(ENV["DB"] || "sqlite3")
13
13
  require 'activeuuid'
14
14
 
15
15
  ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + "/support/migrate")
16
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, STDOUT)
16
17
 
17
18
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
18
19
  Dir["#{File.dirname(__FILE__)}/fabricators/**/*.rb"].each { |f| require f }
@@ -38,4 +39,10 @@ RSpec.configure do |config|
38
39
  config.after(:each) do
39
40
  DatabaseCleaner.clean
40
41
  end
42
+
43
+ def spec_for_adapter(&block)
44
+ switcher = ActiveUUID::SpecSupport::SpecForAdapter.new()
45
+ yield switcher
46
+ switcher.run(connection)
47
+ end
41
48
  end
@@ -3,13 +3,10 @@ sqlite3:
3
3
  database: ":memory:"
4
4
  postgresql:
5
5
  adapter: postgresql
6
- username: postgres
7
- password:
6
+ host: localhost
8
7
  database: activeuuid_test
9
- min_messages: ERROR
10
8
  mysql:
11
9
  adapter: mysql2
12
- host: localhost
13
10
  username: root
14
- password:
15
- database: activeuuid_test
11
+ database: activeuuid_test
12
+ encoding: utf8
@@ -4,6 +4,7 @@ class CreateUuidArticles < ActiveRecord::Migration
4
4
  t.uuid :id, :primary_key => true
5
5
  t.string :title
6
6
  t.text :body
7
+ t.uuid :another_uuid
7
8
 
8
9
  t.timestamps
9
10
  end
@@ -1,4 +1,3 @@
1
1
  class UuidArticle < ActiveRecord::Base
2
2
  include ActiveUUID::UUID
3
-
4
3
  end
@@ -0,0 +1,20 @@
1
+ require 'activeuuid'
2
+
3
+ module ActiveUUID::SpecSupport
4
+ class SpecForAdapter
5
+ def initialize
6
+ @specs = {}
7
+ end
8
+
9
+ [:sqlite3, :mysql2, :postgresql].each do |name|
10
+ send :define_method, name do |&block|
11
+ @specs[name] = block
12
+ end
13
+ end
14
+
15
+ def run(connection)
16
+ name = connection.adapter_name.downcase.to_sym
17
+ @specs[name].call() if(@specs.include? name)
18
+ end
19
+ end
20
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeuuid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-05 00:00:00.000000000 Z
12
+ date: 2013-02-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -178,7 +178,7 @@ dependencies:
178
178
  requirements:
179
179
  - - ! '>='
180
180
  - !ruby/object:Gem::Version
181
- version: '0'
181
+ version: '3.1'
182
182
  type: :runtime
183
183
  prerelease: false
184
184
  version_requirements: !ruby/object:Gem::Requirement
@@ -186,7 +186,7 @@ dependencies:
186
186
  requirements:
187
187
  - - ! '>='
188
188
  - !ruby/object:Gem::Version
189
- version: '0'
189
+ version: '3.1'
190
190
  description: Add binary (not string) UUIDs to ActiveRecord in MySQL
191
191
  email:
192
192
  - nate@natemurray.com
@@ -197,10 +197,14 @@ files:
197
197
  - .gitignore
198
198
  - .rspec
199
199
  - .rvmrc
200
+ - .travis.yml
200
201
  - Gemfile
201
202
  - README.mkd
202
203
  - Rakefile
203
204
  - activeuuid.gemspec
205
+ - gemfiles/Gemfile.rails-3-1
206
+ - gemfiles/Gemfile.rails-3-2
207
+ - gemfiles/Gemfile.rails-head
204
208
  - lib/activeuuid.rb
205
209
  - lib/activeuuid/patches.rb
206
210
  - lib/activeuuid/railtie.rb
@@ -209,7 +213,6 @@ files:
209
213
  - spec/fabricators/article_fabricator.rb
210
214
  - spec/fabricators/uuid_article_fabricator.rb
211
215
  - spec/lib/activerecord_spec.rb
212
- - spec/lib/serializer_spec.rb
213
216
  - spec/lib/uuid_mokeypatch_spec.rb
214
217
  - spec/spec_helper.rb
215
218
  - spec/support/database.yml
@@ -217,7 +220,8 @@ files:
217
220
  - spec/support/migrate/20120817081813_create_uuid_articles.rb
218
221
  - spec/support/models/article.rb
219
222
  - spec/support/models/uuid_article.rb
220
- homepage: http://www.eigenjoy.com
223
+ - spec/support/spec_for_adapter.rb
224
+ homepage: https://github.com/jashmenn/activeuuid
221
225
  licenses: []
222
226
  post_install_message:
223
227
  rdoc_options: []
@@ -231,7 +235,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
231
235
  version: '0'
232
236
  segments:
233
237
  - 0
234
- hash: -2357852166137688430
238
+ hash: 852897539311025223
235
239
  required_rubygems_version: !ruby/object:Gem::Requirement
236
240
  none: false
237
241
  requirements:
@@ -240,7 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
240
244
  version: '0'
241
245
  segments:
242
246
  - 0
243
- hash: -2357852166137688430
247
+ hash: 852897539311025223
244
248
  requirements: []
245
249
  rubyforge_project:
246
250
  rubygems_version: 1.8.24
@@ -251,7 +255,6 @@ test_files:
251
255
  - spec/fabricators/article_fabricator.rb
252
256
  - spec/fabricators/uuid_article_fabricator.rb
253
257
  - spec/lib/activerecord_spec.rb
254
- - spec/lib/serializer_spec.rb
255
258
  - spec/lib/uuid_mokeypatch_spec.rb
256
259
  - spec/spec_helper.rb
257
260
  - spec/support/database.yml
@@ -259,3 +262,4 @@ test_files:
259
262
  - spec/support/migrate/20120817081813_create_uuid_articles.rb
260
263
  - spec/support/models/article.rb
261
264
  - spec/support/models/uuid_article.rb
265
+ - spec/support/spec_for_adapter.rb
@@ -1,76 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveUUID::UUIDSerializer do
4
-
5
- before do
6
- @input = "2d79b402-cba8-11e1-aa7c-14dae903e06a"
7
- @hex = "2D79B402CBA811E1AA7C14DAE903E06A"
8
- @uuid = UUIDTools::UUID.parse @input
9
- @raw = @uuid.raw
10
- @serializer = ActiveUUID::UUIDSerializer.new
11
- end
12
-
13
- describe '#load' do
14
- it 'returns a UUID type verbatim' do
15
- @serializer.load(@uuid).should eql(@uuid)
16
- end
17
-
18
- describe 'loads a given uuid' do
19
- it 'handles uuid string' do
20
- @serializer.load(@input).should eql(@uuid)
21
- end
22
-
23
- it 'handles uuid hexdigest string' do
24
- @serializer.load(@hex).should eql(@uuid)
25
- end
26
-
27
- it 'handles raw uuid data' do
28
- @serializer.load(@raw).should eql(@uuid)
29
- end
30
- end
31
-
32
- it 'returns nil for nil' do
33
- @serializer.load(nil).should be_nil
34
- end
35
-
36
- it 'returns nil for ""' do
37
- @serializer.load('').should be_nil
38
- end
39
-
40
- it 'returns nil for other types' do
41
- @serializer.load(5).should be_nil
42
- end
43
- end
44
-
45
- describe '#dump' do
46
- it 'returns the raw value of a passed uuid' do
47
- @serializer.dump(@uuid).should eql(@raw)
48
- end
49
-
50
- describe 'loads a given uuid' do
51
- it 'handles uuid string' do
52
- @serializer.dump(@input).should eql(@raw)
53
- end
54
-
55
- it 'handles uuid hexdigest string' do
56
- @serializer.dump(@hex).should eql(@raw)
57
- end
58
-
59
- it 'handles raw uuid data' do
60
- @serializer.dump(@raw).should eql(@raw)
61
- end
62
- end
63
-
64
- it 'returns nil for nil' do
65
- @serializer.dump(nil).should be_nil
66
- end
67
-
68
- it 'returns nil for ""' do
69
- @serializer.dump('').should be_nil
70
- end
71
-
72
- it 'returns nil for other types' do
73
- @serializer.dump(5).should be_nil
74
- end
75
- end
76
- end