mysql-binuuid-rails 1.0.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d8236b24424eb481ae0a04a19a4fc8801868d05b
4
- data.tar.gz: 56fe9da411b6fb733ce53fd70ef9b1ecfeca8853
2
+ SHA256:
3
+ metadata.gz: 8ac0fe31f7165213913151accdd548a6e45df4f89e726984dd708e03bff87cbc
4
+ data.tar.gz: baf18f21d48269fc96ceda3a928b8978e9d6c49a87b2630d3a68b665cd196d33
5
5
  SHA512:
6
- metadata.gz: c96352beab858b8e93ee4c4a872402387781750312388d02b3644f80cc1a6fb12f461fbaf54c0d55582b54efba22bce677b40a6ffb16ba28ee3ea7a8d9bb2ffb
7
- data.tar.gz: b7e9554728d7bd7302bcdf292cc11f7f344951d60cf32c4753e1e0d51a8c2558b4f66b1cbd19e23577293990580209023b2532494971ebc648e4701294cf2065
6
+ metadata.gz: 67638457394097e0a518c3b6743751625b102e1ac4f3c12ed7fd093a8ab12050d7ee6b7c81a7d35e24ffe91a8712a6f67ba59291cdd37f396260cf84d366af1c
7
+ data.tar.gz: 5fb73f55ffbe2b859cafb42afa951863f51e89195d09c3de7d97269da901e459cce32e9d2a3696f1e4ac9e8314dbf0c98fca94067e32652e6ffe9d3801c8d9a6
data/CHANGELOG.md ADDED
@@ -0,0 +1,24 @@
1
+ # 1.3.0
2
+ * Up required Ruby version to 2.6.
3
+
4
+ # 1.2.1
5
+ * Development: Now that we're running Semaphore, no need for Travis (#31)
6
+ * Reduce dependencies listed in gemspec (#30) (Dependency on Rails removed,
7
+ only need to depend on ActiveRecord)
8
+
9
+ # 1.2.0
10
+ * Set minimum Ruby version from 2.3 to 2.4 (2.3 is EOL and no longer maintained)
11
+ * Fixed an issue where a UUID would be unpacked again while it's a perfectly
12
+ fine UUID already. Thanks @sirwolfgang.
13
+
14
+ # 1.1.1
15
+ * Fixes possible SQL injection for ActiveRecord columns typed with
16
+ MySQLBinUUID::Type. Thank you @ejoubaud, @geoffevason and @viraptor.
17
+
18
+ # 1.1.0
19
+ * Set minimum Ruby version from 2.2 to 2.3
20
+ * Set default Ruby version to 2.5.1
21
+ * Updated README shipped with the gem
22
+
23
+ # 1.0.0
24
+ * Initial release.
data/CONTRIBUTORS.md ADDED
@@ -0,0 +1,10 @@
1
+ # Thank you!
2
+
3
+ A word of thanks to all those that have contributed to this project:
4
+
5
+ * Emmanuel Joubaud - [@ejoubaud](https://github.com/ejoubaud)
6
+ * Geoff Evason - [@geoffevason](https://github.com/geoffevason)
7
+ * Mark Oude Veldhuis - [@markoudev](https://github.com/markoudev)
8
+ * Stanisław Pitucha - [@viraptor](https://github.com/viraptor)
9
+ * Tjalling van der Wal - [@tjallingvanderwal](https://github.com/tjallingvanderwal)
10
+ * Zane Wolfgang Pickett - [@sirwolfgang](https://github.com/sirwolfgang)
data/Gemfile.lock CHANGED
@@ -1,113 +1,142 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mysql-binuuid-rails (0.1.0)
5
- rails (>= 5)
4
+ mysql-binuuid-rails (1.2.1)
5
+ activerecord (>= 5)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- actioncable (5.1.2)
11
- actionpack (= 5.1.2)
10
+ actioncable (6.1.3.1)
11
+ actionpack (= 6.1.3.1)
12
+ activesupport (= 6.1.3.1)
12
13
  nio4r (~> 2.0)
13
- websocket-driver (~> 0.6.1)
14
- actionmailer (5.1.2)
15
- actionpack (= 5.1.2)
16
- actionview (= 5.1.2)
17
- activejob (= 5.1.2)
14
+ websocket-driver (>= 0.6.1)
15
+ actionmailbox (6.1.3.1)
16
+ actionpack (= 6.1.3.1)
17
+ activejob (= 6.1.3.1)
18
+ activerecord (= 6.1.3.1)
19
+ activestorage (= 6.1.3.1)
20
+ activesupport (= 6.1.3.1)
21
+ mail (>= 2.7.1)
22
+ actionmailer (6.1.3.1)
23
+ actionpack (= 6.1.3.1)
24
+ actionview (= 6.1.3.1)
25
+ activejob (= 6.1.3.1)
26
+ activesupport (= 6.1.3.1)
18
27
  mail (~> 2.5, >= 2.5.4)
19
28
  rails-dom-testing (~> 2.0)
20
- actionpack (5.1.2)
21
- actionview (= 5.1.2)
22
- activesupport (= 5.1.2)
23
- rack (~> 2.0)
24
- rack-test (~> 0.6.3)
29
+ actionpack (6.1.3.1)
30
+ actionview (= 6.1.3.1)
31
+ activesupport (= 6.1.3.1)
32
+ rack (~> 2.0, >= 2.0.9)
33
+ rack-test (>= 0.6.3)
25
34
  rails-dom-testing (~> 2.0)
26
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
27
- actionview (5.1.2)
28
- activesupport (= 5.1.2)
35
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
36
+ actiontext (6.1.3.1)
37
+ actionpack (= 6.1.3.1)
38
+ activerecord (= 6.1.3.1)
39
+ activestorage (= 6.1.3.1)
40
+ activesupport (= 6.1.3.1)
41
+ nokogiri (>= 1.8.5)
42
+ actionview (6.1.3.1)
43
+ activesupport (= 6.1.3.1)
29
44
  builder (~> 3.1)
30
45
  erubi (~> 1.4)
31
46
  rails-dom-testing (~> 2.0)
32
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
33
- activejob (5.1.2)
34
- activesupport (= 5.1.2)
47
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
48
+ activejob (6.1.3.1)
49
+ activesupport (= 6.1.3.1)
35
50
  globalid (>= 0.3.6)
36
- activemodel (5.1.2)
37
- activesupport (= 5.1.2)
38
- activerecord (5.1.2)
39
- activemodel (= 5.1.2)
40
- activesupport (= 5.1.2)
41
- arel (~> 8.0)
42
- activesupport (5.1.2)
51
+ activemodel (6.1.3.1)
52
+ activesupport (= 6.1.3.1)
53
+ activerecord (6.1.3.1)
54
+ activemodel (= 6.1.3.1)
55
+ activesupport (= 6.1.3.1)
56
+ activestorage (6.1.3.1)
57
+ actionpack (= 6.1.3.1)
58
+ activejob (= 6.1.3.1)
59
+ activerecord (= 6.1.3.1)
60
+ activesupport (= 6.1.3.1)
61
+ marcel (~> 1.0.0)
62
+ mini_mime (~> 1.0.2)
63
+ activesupport (6.1.3.1)
43
64
  concurrent-ruby (~> 1.0, >= 1.0.2)
44
- i18n (~> 0.7)
45
- minitest (~> 5.1)
46
- tzinfo (~> 1.1)
47
- arel (8.0.0)
48
- builder (3.2.3)
49
- concurrent-ruby (1.0.5)
50
- erubi (1.6.1)
51
- globalid (0.4.0)
65
+ i18n (>= 1.6, < 2)
66
+ minitest (>= 5.1)
67
+ tzinfo (~> 2.0)
68
+ zeitwerk (~> 2.3)
69
+ builder (3.2.4)
70
+ concurrent-ruby (1.1.8)
71
+ crass (1.0.6)
72
+ erubi (1.10.0)
73
+ globalid (0.4.2)
52
74
  activesupport (>= 4.2.0)
53
- i18n (0.8.6)
54
- loofah (2.0.3)
75
+ i18n (1.8.10)
76
+ concurrent-ruby (~> 1.0)
77
+ loofah (2.9.0)
78
+ crass (~> 1.0.2)
55
79
  nokogiri (>= 1.5.9)
56
- mail (2.6.6)
57
- mime-types (>= 1.16, < 4)
58
- method_source (0.8.2)
59
- mime-types (3.1)
60
- mime-types-data (~> 3.2015)
61
- mime-types-data (3.2016.0521)
62
- mini_portile2 (2.2.0)
63
- minitest (5.10.3)
64
- minitest-hooks (1.4.0)
65
- minitest-spec-context (0.0.3)
66
- mysql2 (0.4.8)
67
- nio4r (2.1.0)
68
- nokogiri (1.8.0)
69
- mini_portile2 (~> 2.2.0)
70
- rack (2.0.3)
71
- rack-test (0.6.3)
72
- rack (>= 1.0)
73
- rails (5.1.2)
74
- actioncable (= 5.1.2)
75
- actionmailer (= 5.1.2)
76
- actionpack (= 5.1.2)
77
- actionview (= 5.1.2)
78
- activejob (= 5.1.2)
79
- activemodel (= 5.1.2)
80
- activerecord (= 5.1.2)
81
- activesupport (= 5.1.2)
82
- bundler (>= 1.3.0, < 2.0)
83
- railties (= 5.1.2)
80
+ mail (2.7.1)
81
+ mini_mime (>= 0.1.1)
82
+ marcel (1.0.1)
83
+ method_source (1.0.0)
84
+ mini_mime (1.0.3)
85
+ mini_portile2 (2.5.0)
86
+ minitest (5.14.4)
87
+ minitest-hooks (1.5.0)
88
+ minitest (> 5.3)
89
+ minitest-spec-context (0.0.4)
90
+ mysql2 (0.5.3)
91
+ nio4r (2.5.7)
92
+ nokogiri (1.11.2)
93
+ mini_portile2 (~> 2.5.0)
94
+ racc (~> 1.4)
95
+ racc (1.5.2)
96
+ rack (2.2.3)
97
+ rack-test (1.1.0)
98
+ rack (>= 1.0, < 3)
99
+ rails (6.1.3.1)
100
+ actioncable (= 6.1.3.1)
101
+ actionmailbox (= 6.1.3.1)
102
+ actionmailer (= 6.1.3.1)
103
+ actionpack (= 6.1.3.1)
104
+ actiontext (= 6.1.3.1)
105
+ actionview (= 6.1.3.1)
106
+ activejob (= 6.1.3.1)
107
+ activemodel (= 6.1.3.1)
108
+ activerecord (= 6.1.3.1)
109
+ activestorage (= 6.1.3.1)
110
+ activesupport (= 6.1.3.1)
111
+ bundler (>= 1.15.0)
112
+ railties (= 6.1.3.1)
84
113
  sprockets-rails (>= 2.0.0)
85
114
  rails-dom-testing (2.0.3)
86
115
  activesupport (>= 4.2.0)
87
116
  nokogiri (>= 1.6)
88
- rails-html-sanitizer (1.0.3)
89
- loofah (~> 2.0)
90
- railties (5.1.2)
91
- actionpack (= 5.1.2)
92
- activesupport (= 5.1.2)
117
+ rails-html-sanitizer (1.3.0)
118
+ loofah (~> 2.3)
119
+ railties (6.1.3.1)
120
+ actionpack (= 6.1.3.1)
121
+ activesupport (= 6.1.3.1)
93
122
  method_source
94
123
  rake (>= 0.8.7)
95
- thor (>= 0.18.1, < 2.0)
96
- rake (12.0.0)
97
- sprockets (3.7.1)
124
+ thor (~> 1.0)
125
+ rake (13.0.3)
126
+ sprockets (4.0.2)
98
127
  concurrent-ruby (~> 1.0)
99
128
  rack (> 1, < 3)
100
- sprockets-rails (3.2.0)
129
+ sprockets-rails (3.2.2)
101
130
  actionpack (>= 4.0)
102
131
  activesupport (>= 4.0)
103
132
  sprockets (>= 3.0.0)
104
- thor (0.19.4)
105
- thread_safe (0.3.6)
106
- tzinfo (1.2.3)
107
- thread_safe (~> 0.1)
108
- websocket-driver (0.6.5)
133
+ thor (1.1.0)
134
+ tzinfo (2.0.4)
135
+ concurrent-ruby (~> 1.0)
136
+ websocket-driver (0.7.3)
109
137
  websocket-extensions (>= 0.1.0)
110
- websocket-extensions (0.1.2)
138
+ websocket-extensions (0.1.5)
139
+ zeitwerk (2.4.2)
111
140
 
112
141
  PLATFORMS
113
142
  ruby
@@ -119,7 +148,8 @@ DEPENDENCIES
119
148
  minitest-spec-context
120
149
  mysql-binuuid-rails!
121
150
  mysql2
151
+ rails (>= 5)
122
152
  rake
123
153
 
124
154
  BUNDLED WITH
125
- 1.15.3
155
+ 2.1.4
data/README.md CHANGED
@@ -1,13 +1,12 @@
1
- [![Build Status](https://travis-ci.org/nedap/mysql-binuuid-rails.svg?branch=master)](https://travis-ci.org/nedap/mysql-binuuid-rails)
2
- [![Code Climate](https://codeclimate.com/github/nedap/mysql-binuuid-rails/badges/gpa.svg)](https://codeclimate.com/github/nedap/mysql-binuuid-rails)
1
+ [![Maintainability](https://api.codeclimate.com/v1/badges/7bcb6538e7666bc37f9a/maintainability)](https://codeclimate.com/github/nedap/mysql-binuuid-rails/maintainability) [![Build Status](https://nedap.semaphoreci.com/badges/mysql-binuuid-rails/branches/master.svg?style=shields)](https://nedap.semaphoreci.com/projects/mysql-binuuid-rails)
3
2
 
4
3
  # mysql-binuuid-rails
5
4
 
6
- `mysql-binuuid-rails` leverages the Attributes API of Rails 5 and lets you
7
- define attributes of type UUID on your models. By doing so, you can store your
8
- UUIDs as binary values in your database, and still be able to query using
9
- the string representations since the database will take care of the
10
- type conversion.
5
+ `mysql-binuuid-rails` lets you define attributes of a UUID type on your models
6
+ by leveraging the Attributes API that has been available since Rails 5. By doing
7
+ so, you can store your UUIDs as binary values in your database, and still be
8
+ able to query using the string representations since the database will take care
9
+ of the type conversion.
11
10
 
12
11
  As the name suggests, it only supports MySQL. If you're on PostgreSQL, you
13
12
  can use UUIDs the proper way already.
@@ -76,6 +75,73 @@ class Book < ApplicationRecord
76
75
  end
77
76
  ```
78
77
 
78
+ # Migrating from ActiveUUID
79
+
80
+ There's a couple of things you need to take into consideration when you're
81
+ migrating from ActiveUUID to `mysql-binuuid-rails`.
82
+
83
+ ## Replace `include ActiveUUID::UUID` in your models
84
+
85
+ In your models where you did `include ActiveUUID::UUID`, you now have to
86
+ specify the attribute which is a UUID instead:
87
+
88
+ ```ruby
89
+ class Book < ApplicationRecord
90
+ attribute :uuid, MySQLBinUUID::Type.new
91
+ end
92
+ ```
93
+
94
+
95
+ ## No `uuid` column in database migrations
96
+
97
+ ActiveUUID comes with a neat column type that you can use in migrations. Since
98
+ `mysql-binuuid-rails` does not, you will have to change all migrations in which
99
+ you leveraged on that migration column if you want your migrations to keep
100
+ working for new setups.
101
+
102
+ The idea behind *not* providing a `uuid` type for columnns in migrations is
103
+ that you are aware of what the actual type of the column is you're creating,
104
+ and that it is not hidden magic.
105
+
106
+ It's pretty simple:
107
+
108
+
109
+ ```ruby
110
+ # Anywhere where you did this in your migrations...
111
+
112
+ create_table :books do |t|
113
+ t.uuid :reference, ...
114
+ end
115
+
116
+ # ..you should change these kinds of lines into the kind described
117
+ # below. It's what ActiveUUID did for you, but what you now have
118
+ # to do yourself.
119
+
120
+ create_table :books do |t|
121
+ t.binary :reference, limit: 16, ...
122
+ end
123
+ ```
124
+
125
+ ## No UUIDTools
126
+
127
+ ActiveUUID comes with [UUIDTools](https://github.com/sporkmonger/uuidtools).
128
+ `mysql-binuuid-rails` does not. When you retrieve a UUID typed attribute from
129
+ a model when using ActiveUUID, the result is a `UUIDTools::UUID` object. When
130
+ you retrieve a UUID typed attribute from a model when using
131
+ `mysql-binuuid-rails`, you just get a `String` of 36 characters (it includes
132
+ the dashes).
133
+
134
+ Migrating shouldn't be that difficult though. `UUIDTools::UUID` implements
135
+ `#to_s`, which returns precisely the same as `mysql-binuuid-rails` returns
136
+ by default. But it's good to be aware of this in case you're running into
137
+ weirdness.
138
+
139
+
140
+ # Known issues
141
+
142
+ * With Rails 5.0 in combination with uniqueness validations, ActiveRecord generates a wrong query. The `x` in front of the queried value, which casts the value to the proper data type, is missing.
143
+
144
+
79
145
  # Contributing
80
146
 
81
147
  To start coding on `mysql-binuuid-rails`, fork the project, clone it locally
@@ -85,6 +151,23 @@ a console with the changes you made, run `bin/console`.
85
151
  Bug reports and pull requests are welcome on GitHub at
86
152
  https://github.com/nedap/mysql-binuuid-rails
87
153
 
154
+ ## Testing
155
+
156
+ Continuous integration / automated tests run [on Semaphore](https://nedap.semaphoreci.com/projects/mysql-binuuid-rails).
157
+ Tests are run against the latest patch version of every minor ActiveRecord release
158
+ since 5.0, as well as *every* patch version of the latest minor version.
159
+
160
+ Run tests yourself to verify everything is still working:
161
+
162
+ ```
163
+ $ bundle exec rake
164
+ ```
165
+
166
+
167
+ ## Contributors
168
+
169
+ See [CONTRIBUTORS.md](CONTRIBUTORS.md).
170
+
88
171
 
89
172
  # License
90
173
 
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "rails/all"
4
+ require "active_record/railtie"
5
5
  require "mysql-binuuid-rails"
6
6
 
7
7
  # You can add fixtures and/or initialization code here to make experimenting
@@ -1,6 +1,7 @@
1
1
  module MySQLBinUUID
2
- class Type < ActiveModel::Type::Binary
2
+ class InvalidUUID < StandardError; end
3
3
 
4
+ class Type < ActiveModel::Type::Binary
4
5
  def type
5
6
  :uuid
6
7
  end
@@ -12,11 +13,11 @@ module MySQLBinUUID
12
13
  # It could be a Data object, in which case we should add dashes to the
13
14
  # string value from there.
14
15
  add_dashes(value.to_s)
15
- elsif value.is_a?(String) && value.encoding == Encoding::ASCII_8BIT
16
+ elsif value.is_a?(String) && value.encoding == Encoding::ASCII_8BIT && strip_dashes(value).length != 32
16
17
  # We cannot unpack something that looks like a UUID, with or without
17
18
  # dashes. Not entirely sure why ActiveRecord does a weird combination of
18
19
  # cast and serialize before anything needs to be saved..
19
- undashed_uuid = value.unpack("H*")[0]
20
+ undashed_uuid = value.unpack1('H*')
20
21
  add_dashes(undashed_uuid.to_s)
21
22
  else
22
23
  super
@@ -27,7 +28,16 @@ module MySQLBinUUID
27
28
  # it to the database.
28
29
  def serialize(value)
29
30
  return if value.nil?
30
- Data.new(strip_dashes(value))
31
+ undashed_uuid = strip_dashes(value)
32
+
33
+ # To avoid SQL injection, verify that it looks like a UUID. ActiveRecord
34
+ # does not explicity escape the Binary data type. escaping is implicit as
35
+ # the Binary data type always converts its value to a hex string.
36
+ unless valid_undashed_uuid?(undashed_uuid)
37
+ raise MySQLBinUUID::InvalidUUID, "#{value} is not a valid UUID"
38
+ end
39
+
40
+ Data.new(undashed_uuid)
31
41
  end
32
42
 
33
43
  # We're inheriting from the Binary type since ActiveRecord in that case
@@ -73,5 +83,10 @@ module MySQLBinUUID
73
83
  uuid.delete("-")
74
84
  end
75
85
 
86
+ # Verify that the undashed version of a UUID only contains characters that
87
+ # represent a hexadecimal value.
88
+ def valid_undashed_uuid?(value)
89
+ value =~ /\A[[:xdigit:]]{32}\z/
90
+ end
76
91
  end
77
92
  end
@@ -1,3 +1,3 @@
1
1
  module MySQLBinUUID
2
- VERSION = "1.0.0"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -15,13 +15,12 @@ Gem::Specification.new do |spec|
15
15
  spec.license = "MIT"
16
16
 
17
17
  spec.require_paths = ["lib"]
18
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
- f.match(%r{^(test|spec|features)/})
20
- end
18
+ spec.files = Dir["**/*"].select { |f| File.file?(f) }
19
+ .reject { |f| f.end_with?(".gem") }
21
20
 
22
- spec.required_ruby_version = ">= 2.2"
21
+ spec.required_ruby_version = ">= 2.6"
23
22
 
24
- spec.add_runtime_dependency "rails", ENV["RAILS_VERSION"] || ">= 5"
23
+ spec.add_runtime_dependency "activerecord", ENV["RAILS_VERSION"] || ">= 5"
25
24
 
26
25
  spec.add_development_dependency "bundler"
27
26
  spec.add_development_dependency "rake"
@@ -29,4 +28,5 @@ Gem::Specification.new do |spec|
29
28
  spec.add_development_dependency "minitest"
30
29
  spec.add_development_dependency "minitest-spec-context"
31
30
  spec.add_development_dependency "minitest-hooks"
31
+ spec.add_development_dependency "rails", ENV["RAILS_VERSION"] || ">= 5" # required for a console
32
32
  end
@@ -0,0 +1,131 @@
1
+ require_relative '../test_helper'
2
+
3
+ class MyUuidModel < ActiveRecord::Base
4
+ attribute :the_uuid, MySQLBinUUID::Type.new
5
+ end
6
+
7
+ describe MyUuidModel do
8
+ include Minitest::Hooks
9
+
10
+ def connection
11
+ ActiveRecord::Base.connection
12
+ end
13
+
14
+ let(:db_config) do
15
+ { adapter: 'mysql2',
16
+ host: 'localhost',
17
+ username: 'root',
18
+ password: ENV['DATABASE_MYSQL_PASSWORD'] || '',
19
+ database: 'binuuid_rails_test' }
20
+ end
21
+
22
+ before(:all) do
23
+ db_config_without_db_name = db_config.dup
24
+ db_config_without_db_name.delete(:database)
25
+
26
+ # Create a connection without selecting a database first to create the db
27
+ ActiveRecord::Base.establish_connection(db_config_without_db_name)
28
+ connection.create_database(db_config[:database], charset: "utf8mb4")
29
+
30
+ # Then establish a new connection with the database name
31
+ ActiveRecord::Base.establish_connection(db_config)
32
+ connection.create_table("my_uuid_models")
33
+ connection.add_column("my_uuid_models", "the_uuid", :binary, limit: 16)
34
+
35
+ # Uncomment this line to get logging on stdout
36
+ # ActiveRecord::Base.logger = Logger.new(STDOUT)
37
+ end
38
+
39
+ after(:all) do
40
+ connection.drop_database(db_config[:database])
41
+ end
42
+
43
+ let(:sample_uuid) { SecureRandom.uuid }
44
+
45
+ context "without saving" do
46
+ it "does not change the uuid when retrieved without saving" do
47
+ my_model = MyUuidModel.new(the_uuid: sample_uuid)
48
+ assert_equal sample_uuid, my_model.the_uuid
49
+ assert_equal sample_uuid, my_model.attributes["the_uuid"]
50
+ end
51
+ end
52
+
53
+ context "before saving" do
54
+ describe "rails validation" do
55
+
56
+ class MyUuidModelWithValidations < MyUuidModel
57
+ validates :the_uuid, uniqueness: true
58
+ end
59
+
60
+ it "validates uniqueness" do
61
+ skip("Skipping uniqueness validation test, known issue on Rails/ActiveRecord 5.0") if ActiveRecord.version < Gem::Version.new("5.1.0")
62
+
63
+ uuid = sample_uuid
64
+ MyUuidModelWithValidations.create!(the_uuid: uuid)
65
+ duplicate = MyUuidModelWithValidations.new(the_uuid: uuid)
66
+
67
+ assert_equal false, duplicate.valid?
68
+ assert_equal :taken, duplicate.errors.details[:the_uuid].first[:error]
69
+ end
70
+
71
+ end
72
+ end
73
+
74
+ context "after persisting to the database" do
75
+ before do
76
+ @my_model = MyUuidModel.create!(the_uuid: sample_uuid)
77
+ end
78
+
79
+ after do
80
+ MyUuidModel.delete_all
81
+ end
82
+
83
+ it "stores a binary value in the database" do
84
+ raw_value = connection.execute("SELECT * FROM my_uuid_models").to_a.first[1]
85
+ assert_equal raw_value.encoding, Encoding::ASCII_8BIT
86
+ end
87
+
88
+ it "stores a binary value without dashes" do
89
+ raw_value = connection.execute("SELECT * FROM my_uuid_models").to_a.first[1]
90
+
91
+ # Create a version without dashes of the sample uuid
92
+ sample_uuid_no_dashes = sample_uuid.delete("-")
93
+
94
+ # Put it in an array so we can create the binary representation we
95
+ # also get from the database.
96
+ assert_equal [sample_uuid_no_dashes].pack("H*"), raw_value
97
+ end
98
+
99
+ it "can be found using .find_by" do
100
+ find_result = MyUuidModel.find_by(the_uuid: sample_uuid)
101
+ assert_equal find_result, @my_model
102
+ assert_equal find_result.the_uuid, sample_uuid
103
+ end
104
+
105
+ it "can be found using .where" do
106
+ results = MyUuidModel.where(the_uuid: sample_uuid)
107
+ assert_equal results.count, 1
108
+ assert_equal results.first, @my_model
109
+ assert_equal results.first.the_uuid, sample_uuid
110
+ end
111
+
112
+ it "can't be used to inject SQL using .where" do
113
+ assert_raises MySQLBinUUID::InvalidUUID do
114
+ MyUuidModel.where(the_uuid: "' OR ''='").first
115
+ end
116
+ end
117
+
118
+ it "can't be used to inject SQL using .find_by" do
119
+ assert_raises MySQLBinUUID::InvalidUUID do
120
+ MyUuidModel.find_by(the_uuid: "' OR ''='")
121
+ end
122
+ end
123
+
124
+ it "can't be used to inject SQL while creating" do
125
+ assert_raises MySQLBinUUID::InvalidUUID do
126
+ MyUuidModel.create!(the_uuid: "40' + x'40")
127
+ end
128
+ end
129
+ end
130
+
131
+ end
@@ -0,0 +1,13 @@
1
+ require_relative '../test_helper'
2
+
3
+ describe MySQLBinUUID::Type::Data do
4
+
5
+ it "is of kind ActiveModel::Type::Binary::Data" do
6
+ assert_kind_of ActiveModel::Type::Binary::Data, MySQLBinUUID::Type::Data.new(nil)
7
+ end
8
+
9
+ it "returns the raw value as hex value" do
10
+ assert_equal "e7db0d1a", MySQLBinUUID::Type::Data.new("e7db0d1a").hex
11
+ end
12
+
13
+ end
@@ -0,0 +1,55 @@
1
+ require_relative '../test_helper'
2
+
3
+ describe MySQLBinUUID::Type do
4
+
5
+ before do
6
+ @type = MySQLBinUUID::Type.new
7
+ end
8
+
9
+ describe '#type' do
10
+ it 'reports :uuid as its type' do
11
+ assert_equal :uuid, @type.type
12
+ end
13
+ end
14
+
15
+ describe '#cast' do
16
+ it 'returns a dashed uuid if provided with a MySQLBinUUID::Type::Data' do
17
+ uuid = "c5997c21-3355-4603-9e41-4fdc7194fe2d"
18
+ data = MySQLBinUUID::Type::Data.new(uuid)
19
+
20
+ assert_equal uuid, @type.cast(data)
21
+ end
22
+
23
+ it 'returns a dashed uuid if provided with a binary string' do
24
+ uuid = "6d7c7ff2-dca8-45eb-b3a0-3b9a24a5270e"
25
+ binstring = [uuid.delete("-")].pack("H*")
26
+ binstring.force_encoding("ASCII-8BIT")
27
+ assert_equal uuid, @type.cast(binstring)
28
+ end
29
+
30
+ it 'returns the value itself if provided with something else' do
31
+ assert_equal 42, @type.cast(42)
32
+ end
33
+
34
+ it 'returns a uuid if provided with a uuid' do
35
+ uuid = SecureRandom.uuid.encode(Encoding::ASCII_8BIT)
36
+ data = MySQLBinUUID::Type.new.cast(uuid)
37
+
38
+ assert_equal uuid, @type.cast(data)
39
+ end
40
+ end
41
+
42
+ describe '#serialize' do
43
+ it 'returns nil if provided with nil (touché)' do
44
+ assert_nil @type.serialize(nil)
45
+ end
46
+
47
+ it 'returns a MySQLBinUUID::Type::Data with stripped values if provided with a UUID' do
48
+ uuid = "3511f33f-3c93-4806-9846-52b4a7618298"
49
+
50
+ assert_instance_of MySQLBinUUID::Type::Data, @type.serialize(uuid)
51
+ assert_equal "3511f33f3c934806984652b4a7618298", @type.serialize(uuid).to_s
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,10 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require 'minitest-spec-context'
4
+ require 'minitest/hooks'
5
+
6
+ require 'active_record'
7
+ require 'securerandom'
8
+
9
+ require_relative '../lib/mysql-binuuid-rails'
10
+ require_relative '../lib/mysql-binuuid/type'
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mysql-binuuid-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Oude Veldhuis
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-26 00:00:00.000000000 Z
11
+ date: 2021-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -108,16 +108,29 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
- description:
111
+ - !ruby/object:Gem::Dependency
112
+ name: rails
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '5'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '5'
125
+ description:
112
126
  email:
113
127
  - mark.oudeveldhuis@nedap.com
114
128
  executables: []
115
129
  extensions: []
116
130
  extra_rdoc_files: []
117
131
  files:
118
- - ".gitignore"
119
- - ".ruby-version"
120
- - ".travis.yml"
132
+ - CHANGELOG.md
133
+ - CONTRIBUTORS.md
121
134
  - Gemfile
122
135
  - Gemfile.lock
123
136
  - LICENSE.txt
@@ -129,11 +142,15 @@ files:
129
142
  - lib/mysql-binuuid/type.rb
130
143
  - lib/mysql-binuuid/version.rb
131
144
  - mysql-binuuid-rails.gemspec
145
+ - test/integration/mysql_integration_test.rb
146
+ - test/mysql-binuuid/type_data_test.rb
147
+ - test/mysql-binuuid/type_test.rb
148
+ - test/test_helper.rb
132
149
  homepage: https://github.com/nedap/mysql-binuuid-rails
133
150
  licenses:
134
151
  - MIT
135
152
  metadata: {}
136
- post_install_message:
153
+ post_install_message:
137
154
  rdoc_options: []
138
155
  require_paths:
139
156
  - lib
@@ -141,16 +158,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
158
  requirements:
142
159
  - - ">="
143
160
  - !ruby/object:Gem::Version
144
- version: '2.2'
161
+ version: '2.6'
145
162
  required_rubygems_version: !ruby/object:Gem::Requirement
146
163
  requirements:
147
164
  - - ">="
148
165
  - !ruby/object:Gem::Version
149
166
  version: '0'
150
167
  requirements: []
151
- rubyforge_project:
152
- rubygems_version: 2.6.11
153
- signing_key:
168
+ rubygems_version: 3.1.6
169
+ signing_key:
154
170
  specification_version: 4
155
171
  summary: Let ActiveRecord serialize and cast your UUIDs to and from binary columns
156
172
  in your database.
data/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- /.bundle
2
- /.DS_Store
3
- /tmp
4
- /*.gem
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.4.1
data/.travis.yml DELETED
@@ -1,15 +0,0 @@
1
- language: ruby
2
- cache: bundler
3
- rvm:
4
- - 2.2.7
5
- - 2.3.4
6
- - 2.4.1
7
- env:
8
- matrix:
9
- - RAILS_VERSION=5.0.4
10
- - RAILS_VERSION=5.1.0
11
- - RAILS_VERSION=5.1.1
12
- - RAILS_VERSION=5.1.2
13
- before_install:
14
- - gem update bundler
15
- - bundle update rails