leifcr-activeuuid 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.hound.yml +3 -0
- data/.rspec +4 -0
- data/.rubocop.tb.yml +640 -0
- data/.rubocop.yml +12 -0
- data/.rvmrc +1 -0
- data/.travis.yml +52 -0
- data/Gemfile +6 -0
- data/LICENSE.md +19 -0
- data/README.mkd +167 -0
- data/Rakefile +15 -0
- data/activeuuid.gemspec +40 -0
- data/gemfiles/Gemfile.rails-4-0 +6 -0
- data/gemfiles/Gemfile.rails-4-1 +6 -0
- data/gemfiles/Gemfile.rails-4-2 +5 -0
- data/gemfiles/Gemfile.rails-5-0 +5 -0
- data/gemfiles/Gemfile.rails-5-1 +5 -0
- data/gemfiles/Gemfile.rails-head +5 -0
- data/lib/activeuuid/patches.rb +226 -0
- data/lib/activeuuid/railtie.rb +12 -0
- data/lib/activeuuid/uuid.rb +166 -0
- data/lib/activeuuid/version.rb +3 -0
- data/lib/activeuuid.rb +10 -0
- data/spec/fabricators/article_fabricator.rb +4 -0
- data/spec/fabricators/uuid_article_fabricator.rb +4 -0
- data/spec/fabricators/uuid_article_with_namespace_fabricator.rb +4 -0
- data/spec/fabricators/uuid_article_with_natural_key_fabricator.rb +4 -0
- data/spec/lib/activerecord_spec.rb +224 -0
- data/spec/lib/uuid_mokeypatch_spec.rb +30 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/database.yml +12 -0
- data/spec/support/migrate/20111117081813_create_articles.rb +13 -0
- data/spec/support/migrate/20120817081813_create_uuid_articles.rb +15 -0
- data/spec/support/migrate/20141017204945_add_array_to_articles.rb +8 -0
- data/spec/support/models/article.rb +3 -0
- data/spec/support/models/uuid_article.rb +3 -0
- data/spec/support/models/uuid_article_with_namespace.rb +6 -0
- data/spec/support/models/uuid_article_with_natural_key.rb +5 -0
- data/spec/support/spec_for_adapter.rb +20 -0
- metadata +250 -0
data/.travis.yml
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
before_script:
|
2
|
+
- mysql -e 'create database activeuuid_test;'
|
3
|
+
- psql -c 'create database activeuuid_test;' -U postgres
|
4
|
+
|
5
|
+
rvm:
|
6
|
+
- 2.3.6
|
7
|
+
- 2.4.3
|
8
|
+
- jruby-9.1.15.0
|
9
|
+
|
10
|
+
gemfile:
|
11
|
+
- Gemfile
|
12
|
+
- gemfiles/Gemfile.rails-4-0
|
13
|
+
- gemfiles/Gemfile.rails-4-1
|
14
|
+
- gemfiles/Gemfile.rails-4-2
|
15
|
+
- gemfiles/Gemfile.rails-5-0
|
16
|
+
- gemfiles/Gemfile.rails-5-1
|
17
|
+
- gemfiles/Gemfile.rails-head
|
18
|
+
|
19
|
+
env:
|
20
|
+
- DB=sqlite3
|
21
|
+
- DB=mysql
|
22
|
+
- DB=postgresql
|
23
|
+
|
24
|
+
matrix:
|
25
|
+
allow_failures:
|
26
|
+
- gemfile: gemfiles/Gemfile.rails-head
|
27
|
+
- rvm: jruby-9.1.15.0
|
28
|
+
gemfile: Gemfile
|
29
|
+
- rvm: jruby-9.1.15.0
|
30
|
+
gemfile: gemfiles/Gemfile.rails-4-0
|
31
|
+
- rvm: jruby-9.1.15.0
|
32
|
+
gemfile: gemfiles/Gemfile.rails-4-1
|
33
|
+
- rvm: jruby-9.1.15.0
|
34
|
+
gemfile: gemfiles/Gemfile.rails-4-2
|
35
|
+
- rvm: jruby-9.1.15.0
|
36
|
+
gemfile: gemfiles/Gemfile.rails-5-0
|
37
|
+
- rvm: jruby-9.1.15.0
|
38
|
+
gemfile: gemfiles/Gemfile.rails-5-1
|
39
|
+
exclude:
|
40
|
+
- rvm: 2.3.6
|
41
|
+
gemfile: gemfiles/Gemfile.rails-3-1
|
42
|
+
- rvm: jruby
|
43
|
+
gemfile: gemfiles/Gemfile.rails-3-1
|
44
|
+
env: DB=postgresql
|
45
|
+
- rvm: 2.3.6
|
46
|
+
gemfile: gemfiles/Gemfile.rails-3-2
|
47
|
+
- rvm: 2.4.3
|
48
|
+
gemfile: gemfiles/Gemfile.rails-4-0
|
49
|
+
- rvm: 2.4.3
|
50
|
+
gemfile: gemfiles/Gemfile.rails-4-1
|
51
|
+
- rvm: 2.4.3
|
52
|
+
gemfile: gemfiles/Gemfile.rails-4-2
|
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.mkd
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/riboseinc/activeuuid.svg?branch=master)](https://travis-ci.org/riboseinc/activeuuid)
|
2
|
+
[![Code Climate Quality](https://codeclimate.com/github/riboseinc/activeuuid/badges/gpa.svg)](https://codeclimate.com/github/riboseinc/activeuuid)
|
3
|
+
[![Code Climate Coverage](https://codeclimate.com/github/riboseinc/activeuuid/badges/coverage.svg)](https://codeclimate.com/github/riboseinc/activeuuid/coverage)
|
4
|
+
|
5
|
+
# activeuuid
|
6
|
+
|
7
|
+
Add `binary(16)` UUIDs to ActiveRecord.
|
8
|
+
|
9
|
+
Does not work with recently releaded version 1.0 of `pg` gem (yet).
|
10
|
+
|
11
|
+
## Example
|
12
|
+
|
13
|
+
### Create a Migration
|
14
|
+
|
15
|
+
`activeuuid` adds the `uuid` type to your migrations. Example:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
class CreateEmails < ActiveRecord::Migration
|
19
|
+
def self.up
|
20
|
+
create_table :emails, :id => false do |t|
|
21
|
+
t.uuid :id, :primary_key => true
|
22
|
+
t.uuid :sender_id # belongs_to :sender
|
23
|
+
|
24
|
+
t.string :subject
|
25
|
+
t.text :body
|
26
|
+
|
27
|
+
t.timestamp :sent_at
|
28
|
+
t.timestamps
|
29
|
+
end
|
30
|
+
add_index :emails, :id
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.down
|
34
|
+
drop_table :emails
|
35
|
+
end
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
### include ActiveUUID::UUID in your model
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
class Email < ActiveRecord::Base
|
43
|
+
include ActiveUUID::UUID
|
44
|
+
belongs_to :sender
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
### specify a natural key for generating the UUID based on one or more columns
|
49
|
+
```ruby
|
50
|
+
class Email < ActiveRecord::Base
|
51
|
+
include ActiveUUID::UUID
|
52
|
+
natural_key :sender_id, :received_at
|
53
|
+
belongs_to :sender
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
`natural_key` generates a SHA1-based UUID in the ISO OID namespace by default. [7]
|
58
|
+
|
59
|
+
### specify a custom UUID namespace for the natural key
|
60
|
+
```ruby
|
61
|
+
class Email < ActiveRecord::Base
|
62
|
+
include ActiveUUID::UUID
|
63
|
+
uuid_namespace "1dd74dd0-d116-11e0-99c7-5ac5d975667e"
|
64
|
+
natural_key :sender_id, :received_at
|
65
|
+
belongs_to :sender
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
`uuid_namespace` can either be a UUID in string format, or a UUIDTools::UUID object.
|
70
|
+
|
71
|
+
### use it:
|
72
|
+
Here are some example specs:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
require 'spec_helper'
|
76
|
+
|
77
|
+
describe Email do
|
78
|
+
|
79
|
+
context "when using uuid's as keys" do
|
80
|
+
let(:guid) { "1dd74dd0-d116-11e0-99c7-5ac5d975667e" }
|
81
|
+
let(:email) { Fabricate :email }
|
82
|
+
|
83
|
+
it "the id guid should be equal to the uuid" do
|
84
|
+
email.id.to_s.should eql(guid)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should be able to find an email by the uuid" do
|
88
|
+
Email.find(guid).id.to_s.should == guid
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
## Motivation
|
96
|
+
|
97
|
+
From [2]:
|
98
|
+
|
99
|
+
> [Here is a] UUID: 1e8ef774-581c-102c-bcfe-f1ab81872213
|
100
|
+
>
|
101
|
+
> 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.
|
102
|
+
>
|
103
|
+
> At its bit level, a UUID is 128 bits, which means it will fit into
|
104
|
+
> 16 bytes, note this is not very human readable, but it will keep
|
105
|
+
> storage low, and is only 4 times larger than a 32-bit int, or 2
|
106
|
+
> times larger than a 64-bit int.
|
107
|
+
|
108
|
+
Many of the existing examples of how to use UUIDs as primary keys
|
109
|
+
in Rails use strings rather than bytes (e.g. [3]).
|
110
|
+
|
111
|
+
However, this plugin stores the primary keys as bytes. To the
|
112
|
+
application the keys are represented by a UUIDTools::UUID object.
|
113
|
+
|
114
|
+
## Benefits of UUIDs as primary key
|
115
|
+
|
116
|
+
* no id conflict during multi-master write
|
117
|
+
* no locking due to auto-increment
|
118
|
+
* with time-based UUIDs you can store a timestamp within your UUID
|
119
|
+
* you can create natural keys (based on the SHA of model attributes)
|
120
|
+
|
121
|
+
## Future work
|
122
|
+
* more transparent support for natural and composite keys
|
123
|
+
* support for MySQLs `INSERT ... ON DUPLICATE KEY UPDATE` syntax
|
124
|
+
* support a primary column name other than `id`
|
125
|
+
* tests
|
126
|
+
|
127
|
+
## Inspiration
|
128
|
+
James Golick's `friendly` is a great gem for NoSQL on MySQL. It's
|
129
|
+
a great gateway drug to systems like Cassandra for teams that are
|
130
|
+
already familiar with the ins-and-outs of MySQL.
|
131
|
+
|
132
|
+
## Installation
|
133
|
+
|
134
|
+
Add this to your `Gemfile`
|
135
|
+
|
136
|
+
gem "activeuuid"
|
137
|
+
|
138
|
+
Or get the code here: https://github.com/inbeom/activeuuid
|
139
|
+
|
140
|
+
|
141
|
+
## References
|
142
|
+
* [1] http://bret.appspot.com/entry/how-friendfeed-uses-mysql
|
143
|
+
* [2] http://kekoav.com/blog/36-computers/58-uuids-as-primary-keys-in-mysql.html
|
144
|
+
* [3] https://gist.github.com/937739
|
145
|
+
* [4] http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html
|
146
|
+
* [5] http://krow.livejournal.com/497839.html
|
147
|
+
* [6] https://github.com/jamesgolick/friendly
|
148
|
+
* [7] http://tools.ietf.org/html/rfc4122.html#appendix-C
|
149
|
+
|
150
|
+
## Dependencies
|
151
|
+
Rails >= 4.0.0
|
152
|
+
|
153
|
+
## Authors
|
154
|
+
|
155
|
+
- Nate Murray
|
156
|
+
- pyromaniac
|
157
|
+
- Andrew Kane
|
158
|
+
- Devin Foley
|
159
|
+
- Arkadiy Zabazhanov
|
160
|
+
- Jean-Denis Koeck
|
161
|
+
- Florian Staudacher
|
162
|
+
- Schuyler Erle
|
163
|
+
- Florian Schwab
|
164
|
+
- Thomas Guillory
|
165
|
+
- Daniel Blanco Rojas
|
166
|
+
- Olivier Amblet
|
167
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require "rspec/core"
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
|
6
|
+
module TempFixForRakeLastComment
|
7
|
+
def last_comment
|
8
|
+
last_description
|
9
|
+
end
|
10
|
+
end
|
11
|
+
Rake::Application.send :include, TempFixForRakeLastComment
|
12
|
+
|
13
|
+
RSpec::Core::RakeTask.new(:spec)
|
14
|
+
|
15
|
+
task default: :spec
|
data/activeuuid.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$:.push File.expand_path("../lib", __FILE__)
|
4
|
+
require "activeuuid/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "leifcr-activeuuid"
|
8
|
+
s.version = Activeuuid::VERSION
|
9
|
+
s.authors = ["Nate Murray"]
|
10
|
+
s.email = ["nate@natemurray.com"]
|
11
|
+
s.homepage = "https://github.com/jashmenn/activeuuid"
|
12
|
+
s.summary = "Add binary UUIDs to ActiveRecord in MySQL"
|
13
|
+
s.description = "Add binary (not string) UUIDs to ActiveRecord in MySQL"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_development_dependency "activesupport"
|
21
|
+
s.add_development_dependency "database_cleaner"
|
22
|
+
s.add_development_dependency "fabrication"
|
23
|
+
s.add_development_dependency "forgery"
|
24
|
+
s.add_development_dependency "rake"
|
25
|
+
s.add_development_dependency "rspec", "~> 3.5.0"
|
26
|
+
s.add_development_dependency "rspec-its"
|
27
|
+
|
28
|
+
if RUBY_ENGINE == "jruby"
|
29
|
+
s.add_development_dependency "activerecord-jdbcmysql-adapter"
|
30
|
+
s.add_development_dependency "activerecord-jdbcpostgresql-adapter"
|
31
|
+
s.add_development_dependency "activerecord-jdbcsqlite3-adapter"
|
32
|
+
else
|
33
|
+
s.add_development_dependency "mysql2"
|
34
|
+
s.add_development_dependency "pg", "< 1.0"
|
35
|
+
s.add_development_dependency "sqlite3"
|
36
|
+
end
|
37
|
+
|
38
|
+
s.add_runtime_dependency "activerecord", ">= 4.0"
|
39
|
+
s.add_runtime_dependency "uuidtools"
|
40
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require "active_record"
|
2
|
+
require "active_support/concern"
|
3
|
+
|
4
|
+
if (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 2) ||
|
5
|
+
(ActiveRecord::VERSION::MAJOR == 5)
|
6
|
+
module ActiveRecord
|
7
|
+
module Type
|
8
|
+
class UUID < Binary # :nodoc:
|
9
|
+
def type
|
10
|
+
:uuid
|
11
|
+
end
|
12
|
+
|
13
|
+
def serialize(value)
|
14
|
+
return if value.nil?
|
15
|
+
UUIDTools::UUID.serialize(value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def cast_value(value)
|
19
|
+
UUIDTools::UUID.serialize(value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def cast(value)
|
23
|
+
cast_value value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module ActiveRecord
|
30
|
+
module ConnectionAdapters
|
31
|
+
module PostgreSQL
|
32
|
+
module OID # :nodoc:
|
33
|
+
class Uuid < Type::Value # :nodoc:
|
34
|
+
def type_cast_from_user(value)
|
35
|
+
UUIDTools::UUID.serialize(value) if value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module ActiveUUID
|
45
|
+
module Patches
|
46
|
+
module Migrations
|
47
|
+
def uuid(*column_names)
|
48
|
+
options = column_names.extract_options!
|
49
|
+
column_names.each do |name|
|
50
|
+
type = ActiveRecord::Base.connection.adapter_name.casecmp("postgresql").zero? ? "uuid" : "binary(16)"
|
51
|
+
column(name, "#{type}#{' PRIMARY KEY' if options.delete(:primary_key)}", options)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module Column
|
57
|
+
extend ActiveSupport::Concern
|
58
|
+
|
59
|
+
def self.prepended(_klass)
|
60
|
+
def type_cast(value)
|
61
|
+
return UUIDTools::UUID.serialize(value) if type == :uuid
|
62
|
+
super
|
63
|
+
end
|
64
|
+
|
65
|
+
def type_cast_code(var_name)
|
66
|
+
return "UUIDTools::UUID.serialize(#{var_name})" if type == :uuid
|
67
|
+
super
|
68
|
+
end
|
69
|
+
|
70
|
+
def simplified_type(field_type)
|
71
|
+
return :uuid if field_type == "binary(16)" || field_type == "binary(16,0)"
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
module MysqlJdbcColumn
|
78
|
+
extend ActiveSupport::Concern
|
79
|
+
|
80
|
+
included do
|
81
|
+
# This is a really hacky solution, but it's the only way to support the
|
82
|
+
# MySql JDBC adapter without breaking backwards compatibility.
|
83
|
+
# It would be a lot easier if AR had support for custom defined types.
|
84
|
+
#
|
85
|
+
# Here's the path of execution:
|
86
|
+
# (1) JdbcColumn calls ActiveRecord::ConnectionAdapters::Column super constructor
|
87
|
+
# (2) super constructor calls simplified_type from MysqlJdbcColumn, since it's redefined here
|
88
|
+
# (3) if it's not a uuid, it calls original_simplified_type from ArJdbc::MySQL::Column module
|
89
|
+
# (4) if there's no match ArJdbc::MySQL::Column calls super (ActiveUUID::Column.simplified_type_with_uuid)
|
90
|
+
# (5) Since it's no a uuid (see step 3), simplified_type_without_uuid is called,
|
91
|
+
# which maps to AR::ConnectionAdapters::Column.simplified_type (which has no super call, so we're good)
|
92
|
+
#
|
93
|
+
alias_method :original_simplified_type, :simplified_type
|
94
|
+
|
95
|
+
def simplified_type(field_type)
|
96
|
+
return :uuid if field_type == "binary(16)" || field_type == "binary(16,0)"
|
97
|
+
original_simplified_type(field_type)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
module PostgreSQLColumn
|
103
|
+
extend ActiveSupport::Concern
|
104
|
+
|
105
|
+
def self.prepended(_klass)
|
106
|
+
def type_cast(value)
|
107
|
+
return UUIDTools::UUID.serialize(value) if type == :uuid
|
108
|
+
super
|
109
|
+
end
|
110
|
+
|
111
|
+
def simplified_type(field_type)
|
112
|
+
return :uuid if field_type == "uuid"
|
113
|
+
super
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
module Quoting
|
119
|
+
extend ActiveSupport::Concern
|
120
|
+
|
121
|
+
def self.prepended(_klass)
|
122
|
+
def quote(value, column = nil)
|
123
|
+
value = UUIDTools::UUID.serialize(value) if column&.type == :uuid
|
124
|
+
case method(__method__).super_method.arity
|
125
|
+
when 1 then super(value)
|
126
|
+
else super
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def type_cast(value, column = nil)
|
131
|
+
value = UUIDTools::UUID.serialize(value) if column&.type == :uuid
|
132
|
+
super
|
133
|
+
end
|
134
|
+
|
135
|
+
def native_database_types
|
136
|
+
super.merge(uuid: { name: "binary", limit: 16 })
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
module PostgreSQLQuoting
|
142
|
+
extend ActiveSupport::Concern
|
143
|
+
|
144
|
+
def self.prepended(_klass)
|
145
|
+
def quote(value, column = nil)
|
146
|
+
value = UUIDTools::UUID.serialize(value) if column&.type == :uuid
|
147
|
+
value = value.to_s if value.is_a? UUIDTools::UUID
|
148
|
+
case method(__method__).super_method.arity
|
149
|
+
when 1 then super(value)
|
150
|
+
else super
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def type_cast(value, column = nil, *args)
|
155
|
+
value = UUIDTools::UUID.serialize(value) if column&.type == :uuid
|
156
|
+
value = value.to_s if value.is_a? UUIDTools::UUID
|
157
|
+
super
|
158
|
+
end
|
159
|
+
|
160
|
+
def native_database_types
|
161
|
+
super.merge(uuid: { name: "uuid" })
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
module PostgresqlTypeOverride
|
167
|
+
def deserialize(value)
|
168
|
+
UUIDTools::UUID.serialize(value) if value
|
169
|
+
end
|
170
|
+
|
171
|
+
alias_method :cast, :deserialize
|
172
|
+
end
|
173
|
+
|
174
|
+
module TypeMapOverride
|
175
|
+
def initialize_type_map(m)
|
176
|
+
super
|
177
|
+
|
178
|
+
register_class_with_limit m, /binary\(16(,0)?\)/i, ::ActiveRecord::Type::UUID
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
module MysqlTypeToSqlOverride
|
183
|
+
def type_to_sql(*args)
|
184
|
+
args.first.to_s == "uuid" ? "binary(16)" : super
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
module ConnectionHandling
|
189
|
+
def establish_connection(_ = nil)
|
190
|
+
super
|
191
|
+
|
192
|
+
aca = ActiveRecord::ConnectionAdapters
|
193
|
+
|
194
|
+
aca::Table.send :include, Migrations if defined? aca::Table
|
195
|
+
aca::TableDefinition.send :include, Migrations if defined? aca::TableDefinition
|
196
|
+
|
197
|
+
if ActiveRecord::VERSION::MAJOR >= 5
|
198
|
+
if defined? aca::AbstractMysqlAdapter
|
199
|
+
aca::AbstractMysqlAdapter.prepend TypeMapOverride
|
200
|
+
aca::AbstractMysqlAdapter.prepend MysqlTypeToSqlOverride
|
201
|
+
end
|
202
|
+
|
203
|
+
aca::SQLite3Adapter.prepend TypeMapOverride if defined? aca::SQLite3Adapter
|
204
|
+
aca::PostgreSQL::OID::Uuid.prepend PostgresqlTypeOverride if defined? aca::PostgreSQLAdapter
|
205
|
+
|
206
|
+
elsif ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 2
|
207
|
+
aca::Mysql2Adapter.prepend TypeMapOverride if defined? aca::Mysql2Adapter
|
208
|
+
aca::SQLite3Adapter.prepend TypeMapOverride if defined? aca::SQLite3Adapter
|
209
|
+
|
210
|
+
else
|
211
|
+
aca::Column.send :prepend, Column
|
212
|
+
aca::PostgreSQLColumn.send :prepend, PostgreSQLColumn if defined? aca::PostgreSQLColumn
|
213
|
+
end
|
214
|
+
|
215
|
+
aca::MysqlAdapter.send :prepend, Quoting if defined? aca::MysqlAdapter
|
216
|
+
aca::Mysql2Adapter.send :prepend, Quoting if defined? aca::Mysql2Adapter
|
217
|
+
aca::SQLite3Adapter.send :prepend, Quoting if defined? aca::SQLite3Adapter
|
218
|
+
aca::PostgreSQLAdapter.send :prepend, PostgreSQLQuoting if defined? aca::PostgreSQLAdapter
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def self.apply!
|
223
|
+
ActiveRecord::Base.singleton_class.prepend ConnectionHandling
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|