declare_schema 0.6.1 → 0.7.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +38 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +58 -54
- data/lib/declare_schema/field_declaration_dsl.rb +3 -4
- data/lib/declare_schema/model.rb +1 -2
- data/lib/declare_schema/model/column.rb +167 -0
- data/lib/declare_schema/model/field_spec.rb +59 -143
- data/lib/declare_schema/model/foreign_key_definition.rb +36 -25
- data/lib/declare_schema/version.rb +1 -1
- data/lib/generators/declare_schema/migration/migration_generator.rb +1 -1
- data/lib/generators/declare_schema/migration/migrator.rb +111 -133
- data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +1 -1
- data/spec/lib/declare_schema/field_spec_spec.rb +142 -38
- data/spec/lib/declare_schema/migration_generator_spec.rb +73 -69
- data/spec/lib/declare_schema/model/column_spec.rb +141 -0
- data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +93 -0
- data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +2 -11
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6317ef2d7c038120278bbff6547c042a3418369d1e0bd8527f10ab57d58aef62
|
4
|
+
data.tar.gz: 66ce3ad03f6fde8365b287deb682d85b4fd7e983d283447af769aed0ade61571
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a87ecf0479b94324f43c42d309f254e8a3ca10f3766cc90a756b94505cb559406871eee47a58fa376640ad85acda3e81d771cb03ab92dc08f5253d81bd88079
|
7
|
+
data.tar.gz: 4cd449cb9543819dd78e51267357f676a7439c89f2ad021f59a5d0f49664a8c8b8141eeebde4184e3eaf1f3f616dfef8a7092f59cc6382c73504de5ffeb41dc3
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,39 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
4
4
|
|
5
5
|
Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [0.7.1] - 2021-02-17
|
8
|
+
### Fixed
|
9
|
+
- Exclude unknown options from FieldSpec#sql_options and #schema_attributes.
|
10
|
+
- Fixed a bug where fk_field_options were getting merged into spec_attrs after checking for equivalence,
|
11
|
+
leading to phantom migrations with no changes, or missing migrations when just the fk_field_options changed.
|
12
|
+
|
13
|
+
## [0.7.0] - 2021-02-14
|
14
|
+
### Changed
|
15
|
+
- Use `schema_attributes` for generating both up and down change migrations, so they are guaranteed to be symmetrical.
|
16
|
+
Note: Rails schema dumper is still used for the down migration to replace a model that has been dropped.
|
17
|
+
|
18
|
+
## [0.6.4] - 2021-02-08
|
19
|
+
- Fixed a bug where the generated call to add_foreign_key() was not setting `column:`,
|
20
|
+
so it only worked in cases where Rails could infer the foreign key by convention.
|
21
|
+
|
22
|
+
## [0.6.3] - 2021-01-21
|
23
|
+
### Added
|
24
|
+
- Added `add_foreign_key` native rails call in `DeclareSchema::Model::ForeignKeyDefinition#to_add_statement`.
|
25
|
+
|
26
|
+
### Fixed
|
27
|
+
- Fixed a bug in migration generation caused by `DeclareSchema::Migration#create_constraints`
|
28
|
+
calling `DeclareSchema::Model::ForeignKeyDefinition#to_add_statement` with unused parameters.
|
29
|
+
|
30
|
+
- Fixed a bug in `DeclareSchema::Migration#remove_foreign_key` where special characters would not be quoted properly.
|
31
|
+
|
32
|
+
## [0.6.2] - 2021-01-06
|
33
|
+
### Added
|
34
|
+
- Added `sqlite3` as dev dependency for local development
|
35
|
+
|
36
|
+
### Fixed
|
37
|
+
- Fixed a bug in migration generation caused by `DeclareSchema::Model::ForeignKeyDefinition#to_add_statement`
|
38
|
+
not being passed proper arguments.
|
39
|
+
|
7
40
|
## [0.6.1] - 2021-01-06
|
8
41
|
### Added
|
9
42
|
- Added Appraisals for MySQL as well as SQLite.
|
@@ -92,6 +125,11 @@ using the appropriate Rails configuration attributes.
|
|
92
125
|
### Added
|
93
126
|
- Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
|
94
127
|
|
128
|
+
[0.7.1]: https://github.com/Invoca/declare_schema/compare/v0.7.0...v0.7.1
|
129
|
+
[0.7.0]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.7.0
|
130
|
+
[0.6.4]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.6.4
|
131
|
+
[0.6.3]: https://github.com/Invoca/declare_schema/compare/v0.6.2...v0.6.3
|
132
|
+
[0.6.2]: https://github.com/Invoca/declare_schema/compare/v0.6.1...v0.6.2
|
95
133
|
[0.6.1]: https://github.com/Invoca/declare_schema/compare/v0.6.0...v0.6.1
|
96
134
|
[0.6.0]: https://github.com/Invoca/declare_schema/compare/v0.5.0...v0.6.0
|
97
135
|
[0.5.0]: https://github.com/Invoca/declare_schema/compare/v0.4.2...v0.5.0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,49 +1,49 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
declare_schema (0.
|
4
|
+
declare_schema (0.7.1)
|
5
5
|
rails (>= 4.2)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
actioncable (5.2.4.
|
11
|
-
actionpack (= 5.2.4.
|
10
|
+
actioncable (5.2.4.5)
|
11
|
+
actionpack (= 5.2.4.5)
|
12
12
|
nio4r (~> 2.0)
|
13
13
|
websocket-driver (>= 0.6.1)
|
14
|
-
actionmailer (5.2.4.
|
15
|
-
actionpack (= 5.2.4.
|
16
|
-
actionview (= 5.2.4.
|
17
|
-
activejob (= 5.2.4.
|
14
|
+
actionmailer (5.2.4.5)
|
15
|
+
actionpack (= 5.2.4.5)
|
16
|
+
actionview (= 5.2.4.5)
|
17
|
+
activejob (= 5.2.4.5)
|
18
18
|
mail (~> 2.5, >= 2.5.4)
|
19
19
|
rails-dom-testing (~> 2.0)
|
20
|
-
actionpack (5.2.4.
|
21
|
-
actionview (= 5.2.4.
|
22
|
-
activesupport (= 5.2.4.
|
20
|
+
actionpack (5.2.4.5)
|
21
|
+
actionview (= 5.2.4.5)
|
22
|
+
activesupport (= 5.2.4.5)
|
23
23
|
rack (~> 2.0, >= 2.0.8)
|
24
24
|
rack-test (>= 0.6.3)
|
25
25
|
rails-dom-testing (~> 2.0)
|
26
26
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
27
|
-
actionview (5.2.4.
|
28
|
-
activesupport (= 5.2.4.
|
27
|
+
actionview (5.2.4.5)
|
28
|
+
activesupport (= 5.2.4.5)
|
29
29
|
builder (~> 3.1)
|
30
30
|
erubi (~> 1.4)
|
31
31
|
rails-dom-testing (~> 2.0)
|
32
32
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
33
|
-
activejob (5.2.4.
|
34
|
-
activesupport (= 5.2.4.
|
33
|
+
activejob (5.2.4.5)
|
34
|
+
activesupport (= 5.2.4.5)
|
35
35
|
globalid (>= 0.3.6)
|
36
|
-
activemodel (5.2.4.
|
37
|
-
activesupport (= 5.2.4.
|
38
|
-
activerecord (5.2.4.
|
39
|
-
activemodel (= 5.2.4.
|
40
|
-
activesupport (= 5.2.4.
|
36
|
+
activemodel (5.2.4.5)
|
37
|
+
activesupport (= 5.2.4.5)
|
38
|
+
activerecord (5.2.4.5)
|
39
|
+
activemodel (= 5.2.4.5)
|
40
|
+
activesupport (= 5.2.4.5)
|
41
41
|
arel (>= 9.0)
|
42
|
-
activestorage (5.2.4.
|
43
|
-
actionpack (= 5.2.4.
|
44
|
-
activerecord (= 5.2.4.
|
42
|
+
activestorage (5.2.4.5)
|
43
|
+
actionpack (= 5.2.4.5)
|
44
|
+
activerecord (= 5.2.4.5)
|
45
45
|
marcel (~> 0.3.1)
|
46
|
-
activesupport (5.2.4.
|
46
|
+
activesupport (5.2.4.5)
|
47
47
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
48
48
|
i18n (>= 0.7, < 2)
|
49
49
|
minitest (~> 5.1)
|
@@ -54,25 +54,25 @@ GEM
|
|
54
54
|
thor (>= 0.14.0)
|
55
55
|
arel (9.0.0)
|
56
56
|
ast (2.4.1)
|
57
|
-
bootsnap (1.
|
57
|
+
bootsnap (1.7.2)
|
58
58
|
msgpack (~> 1.0)
|
59
59
|
builder (3.2.4)
|
60
60
|
byebug (11.1.3)
|
61
61
|
climate_control (0.2.0)
|
62
62
|
coderay (1.1.3)
|
63
|
-
concurrent-ruby (1.1.
|
63
|
+
concurrent-ruby (1.1.8)
|
64
64
|
crass (1.0.6)
|
65
65
|
diff-lcs (1.4.4)
|
66
|
-
erubi (1.
|
67
|
-
ffi (1.
|
66
|
+
erubi (1.10.0)
|
67
|
+
ffi (1.14.2)
|
68
68
|
globalid (0.4.2)
|
69
69
|
activesupport (>= 4.2.0)
|
70
|
-
i18n (1.8.
|
70
|
+
i18n (1.8.9)
|
71
71
|
concurrent-ruby (~> 1.0)
|
72
|
-
listen (3.
|
72
|
+
listen (3.4.1)
|
73
73
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
74
74
|
rb-inotify (~> 0.9, >= 0.9.10)
|
75
|
-
loofah (2.
|
75
|
+
loofah (2.9.0)
|
76
76
|
crass (~> 1.0.2)
|
77
77
|
nokogiri (>= 1.5.9)
|
78
78
|
mail (2.7.1)
|
@@ -82,12 +82,13 @@ GEM
|
|
82
82
|
method_source (1.0.0)
|
83
83
|
mimemagic (0.3.5)
|
84
84
|
mini_mime (1.0.2)
|
85
|
-
mini_portile2 (2.
|
86
|
-
minitest (5.14.
|
87
|
-
msgpack (1.
|
88
|
-
nio4r (2.5.
|
89
|
-
nokogiri (1.
|
90
|
-
mini_portile2 (~> 2.
|
85
|
+
mini_portile2 (2.5.0)
|
86
|
+
minitest (5.14.3)
|
87
|
+
msgpack (1.4.2)
|
88
|
+
nio4r (2.5.5)
|
89
|
+
nokogiri (1.11.1)
|
90
|
+
mini_portile2 (~> 2.5.0)
|
91
|
+
racc (~> 1.4)
|
91
92
|
parallel (1.19.2)
|
92
93
|
parser (2.7.1.4)
|
93
94
|
ast (~> 2.4.1)
|
@@ -97,35 +98,36 @@ GEM
|
|
97
98
|
pry-byebug (3.9.0)
|
98
99
|
byebug (~> 11.0)
|
99
100
|
pry (~> 0.13.0)
|
101
|
+
racc (1.5.2)
|
100
102
|
rack (2.2.3)
|
101
103
|
rack-test (1.1.0)
|
102
104
|
rack (>= 1.0, < 3)
|
103
|
-
rails (5.2.4.
|
104
|
-
actioncable (= 5.2.4.
|
105
|
-
actionmailer (= 5.2.4.
|
106
|
-
actionpack (= 5.2.4.
|
107
|
-
actionview (= 5.2.4.
|
108
|
-
activejob (= 5.2.4.
|
109
|
-
activemodel (= 5.2.4.
|
110
|
-
activerecord (= 5.2.4.
|
111
|
-
activestorage (= 5.2.4.
|
112
|
-
activesupport (= 5.2.4.
|
105
|
+
rails (5.2.4.5)
|
106
|
+
actioncable (= 5.2.4.5)
|
107
|
+
actionmailer (= 5.2.4.5)
|
108
|
+
actionpack (= 5.2.4.5)
|
109
|
+
actionview (= 5.2.4.5)
|
110
|
+
activejob (= 5.2.4.5)
|
111
|
+
activemodel (= 5.2.4.5)
|
112
|
+
activerecord (= 5.2.4.5)
|
113
|
+
activestorage (= 5.2.4.5)
|
114
|
+
activesupport (= 5.2.4.5)
|
113
115
|
bundler (>= 1.3.0)
|
114
|
-
railties (= 5.2.4.
|
116
|
+
railties (= 5.2.4.5)
|
115
117
|
sprockets-rails (>= 2.0.0)
|
116
118
|
rails-dom-testing (2.0.3)
|
117
119
|
activesupport (>= 4.2.0)
|
118
120
|
nokogiri (>= 1.6)
|
119
121
|
rails-html-sanitizer (1.3.0)
|
120
122
|
loofah (~> 2.3)
|
121
|
-
railties (5.2.4.
|
122
|
-
actionpack (= 5.2.4.
|
123
|
-
activesupport (= 5.2.4.
|
123
|
+
railties (5.2.4.5)
|
124
|
+
actionpack (= 5.2.4.5)
|
125
|
+
activesupport (= 5.2.4.5)
|
124
126
|
method_source
|
125
127
|
rake (>= 0.8.7)
|
126
128
|
thor (>= 0.19.0, < 2.0)
|
127
129
|
rainbow (3.0.0)
|
128
|
-
rake (13.0.
|
130
|
+
rake (13.0.3)
|
129
131
|
rb-fsevent (0.10.4)
|
130
132
|
rb-inotify (0.10.1)
|
131
133
|
ffi (~> 1.0)
|
@@ -166,15 +168,16 @@ GEM
|
|
166
168
|
actionpack (>= 4.0)
|
167
169
|
activesupport (>= 4.0)
|
168
170
|
sprockets (>= 3.0.0)
|
169
|
-
|
171
|
+
sqlite3 (1.4.2)
|
172
|
+
thor (1.1.0)
|
170
173
|
thread_safe (0.3.6)
|
171
|
-
tzinfo (1.2.
|
174
|
+
tzinfo (1.2.9)
|
172
175
|
thread_safe (~> 0.1)
|
173
176
|
unicode-display_width (1.7.0)
|
174
177
|
websocket-driver (0.7.3)
|
175
178
|
websocket-extensions (>= 0.1.0)
|
176
179
|
websocket-extensions (0.1.5)
|
177
|
-
yard (0.9.
|
180
|
+
yard (0.9.26)
|
178
181
|
|
179
182
|
PLATFORMS
|
180
183
|
ruby
|
@@ -192,6 +195,7 @@ DEPENDENCIES
|
|
192
195
|
responders
|
193
196
|
rspec
|
194
197
|
rubocop
|
198
|
+
sqlite3 (~> 1.4)
|
195
199
|
yard
|
196
200
|
|
197
201
|
BUNDLED WITH
|
@@ -28,13 +28,12 @@ module DeclareSchema
|
|
28
28
|
field(:lock_version, :integer, default: 1, null: false)
|
29
29
|
end
|
30
30
|
|
31
|
-
def field(name, type, *args)
|
32
|
-
|
33
|
-
@model.declare_field(name, type, *(args + [@options.merge(options)]))
|
31
|
+
def field(name, type, *args, **options)
|
32
|
+
@model.declare_field(name, type, *[*args, @options.merge(options)])
|
34
33
|
end
|
35
34
|
|
36
35
|
def method_missing(name, *args)
|
37
|
-
field(name,
|
36
|
+
field(name, *args)
|
38
37
|
end
|
39
38
|
end
|
40
39
|
end
|
data/lib/declare_schema/model.rb
CHANGED
@@ -81,8 +81,7 @@ module DeclareSchema
|
|
81
81
|
# arguments. The arguments are forwarded to the #field_added
|
82
82
|
# callback, allowing custom metadata to be added to field
|
83
83
|
# declarations.
|
84
|
-
def declare_field(name, type, *args)
|
85
|
-
options = args.extract_options!
|
84
|
+
def declare_field(name, type, *args, **options)
|
86
85
|
try(:field_added, name, type, args, options)
|
87
86
|
add_serialize_for_field(name, type, options)
|
88
87
|
add_formatting_for_field(name, type)
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DeclareSchema
|
4
|
+
class UnknownSqlTypeError < RuntimeError; end
|
5
|
+
|
6
|
+
module Model
|
7
|
+
# This class is a wrapper for the ActiveRecord::...::Column class
|
8
|
+
class Column
|
9
|
+
class << self
|
10
|
+
def native_type?(type)
|
11
|
+
type != :primary_key && native_types.has_key?(type)
|
12
|
+
end
|
13
|
+
|
14
|
+
# MySQL example:
|
15
|
+
# { primary_key: "bigint auto_increment PRIMARY KEY",
|
16
|
+
# string: { name: "varchar", limit: 255 },
|
17
|
+
# text: { name: "text", limit: 65535},
|
18
|
+
# integer: {name: "int", limit: 4 },
|
19
|
+
# float: {name: "float", limit: 24 },
|
20
|
+
# decimal: { name: "decimal" },
|
21
|
+
# datetime: { name: "datetime" },
|
22
|
+
# timestamp: { name: "timestamp" },
|
23
|
+
# time: { name: "time" },
|
24
|
+
# date: { name: "date" },
|
25
|
+
# binary: { name>: "blob", limit: 65535 },
|
26
|
+
# boolean: { name: "tinyint", limit: 1 },
|
27
|
+
# json: { name: "json" } }
|
28
|
+
#
|
29
|
+
# SQLite example:
|
30
|
+
# { primary_key: "integer PRIMARY KEY AUTOINCREMENT NOT NULL",
|
31
|
+
# string: { name: "varchar" },
|
32
|
+
# text: { name: "text"},
|
33
|
+
# integer: { name: "integer" },
|
34
|
+
# float: { name: "float" },
|
35
|
+
# decimal: { name: "decimal" },
|
36
|
+
# datetime: { name: "datetime" },
|
37
|
+
# time: { name: "time" },
|
38
|
+
# date: { name: "date" },
|
39
|
+
# binary: { name: "blob" },
|
40
|
+
# boolean: { name: "boolean" },
|
41
|
+
# json: { name: "json" } }
|
42
|
+
def native_types
|
43
|
+
@native_types ||= ActiveRecord::Base.connection.native_database_types.tap do |types|
|
44
|
+
if ActiveRecord::Base.connection.class.name.match?(/mysql/i)
|
45
|
+
types[:text][:limit] ||= 0xffff
|
46
|
+
types[:binary][:limit] ||= 0xffff
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def sql_type(type)
|
52
|
+
if native_type?(type)
|
53
|
+
type
|
54
|
+
else
|
55
|
+
if (field_class = DeclareSchema.to_class(type))
|
56
|
+
field_class::COLUMN_TYPE
|
57
|
+
end or raise UnknownSqlTypeError, "#{type.inspect} for type #{type.inspect}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def deserialize_default_value(column, sql_type, default_value)
|
62
|
+
sql_type or raise ArgumentError, "must pass sql_type; got #{sql_type.inspect}"
|
63
|
+
|
64
|
+
case Rails::VERSION::MAJOR
|
65
|
+
when 4
|
66
|
+
# TODO: Delete this Rails 4 support ASAP! This could be wrong, since it's using the type of the old column...which
|
67
|
+
# might be getting migrated to a new type. We should be using just sql_type as below. -Colin
|
68
|
+
column.type_cast_from_database(default_value)
|
69
|
+
else
|
70
|
+
cast_type = ActiveRecord::Base.connection.send(:lookup_cast_type, sql_type) or
|
71
|
+
raise "cast_type not found for #{sql_type}"
|
72
|
+
cast_type.deserialize(default_value)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Normalizes schema attributes for the given database adapter name.
|
77
|
+
# Note that the un-normalized attributes are still useful for generating migrations because those
|
78
|
+
# may be run with a different adapter.
|
79
|
+
# This method never mutates its argument.
|
80
|
+
def normalize_schema_attributes(schema_attributes, db_adapter_name)
|
81
|
+
case schema_attributes[:type]
|
82
|
+
when :boolean
|
83
|
+
schema_attributes.reverse_merge(limit: 1)
|
84
|
+
when :integer
|
85
|
+
schema_attributes.reverse_merge(limit: 8) if db_adapter_name.match?(/sqlite/i)
|
86
|
+
when :float
|
87
|
+
schema_attributes.except(:limit)
|
88
|
+
when :text
|
89
|
+
schema_attributes.except(:limit) if db_adapter_name.match?(/sqlite/i)
|
90
|
+
when :datetime
|
91
|
+
schema_attributes.reverse_merge(precision: 0)
|
92
|
+
when NilClass
|
93
|
+
raise ArgumentError, ":type key not found; keys: #{schema_attributes.keys.inspect}"
|
94
|
+
end || schema_attributes
|
95
|
+
end
|
96
|
+
|
97
|
+
def equivalent_schema_attributes?(schema_attributes_lhs, schema_attributes_rhs)
|
98
|
+
db_adapter_name = ActiveRecord::Base.connection.class.name
|
99
|
+
normalized_lhs = normalize_schema_attributes(schema_attributes_lhs, db_adapter_name)
|
100
|
+
normalized_rhs = normalize_schema_attributes(schema_attributes_rhs, db_adapter_name)
|
101
|
+
|
102
|
+
normalized_lhs == normalized_rhs
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
attr_reader :sql_type
|
107
|
+
|
108
|
+
def initialize(model, current_table_name, column)
|
109
|
+
@model = model or raise ArgumentError, "must pass model"
|
110
|
+
@current_table_name = current_table_name or raise ArgumentError, "must pass current_table_name"
|
111
|
+
@column = column or raise ArgumentError, "must pass column"
|
112
|
+
@sql_type = self.class.sql_type(@column.type)
|
113
|
+
end
|
114
|
+
|
115
|
+
SCHEMA_KEYS = [:type, :limit, :precision, :scale, :null, :default].freeze
|
116
|
+
|
117
|
+
# omits keys with nil values
|
118
|
+
def schema_attributes
|
119
|
+
SCHEMA_KEYS.each_with_object({}) do |key, result|
|
120
|
+
value =
|
121
|
+
case key
|
122
|
+
when :default
|
123
|
+
self.class.deserialize_default_value(@column, @sql_type, @column.default)
|
124
|
+
else
|
125
|
+
col_value = @column.send(key)
|
126
|
+
if col_value.nil? && (native_type = self.class.native_types[@column.type])
|
127
|
+
native_type[key]
|
128
|
+
else
|
129
|
+
col_value
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
result[key] = value unless value.nil?
|
134
|
+
end.tap do |result|
|
135
|
+
if ActiveRecord::Base.connection.class.name.match?(/mysql/i) && @column.type.in?([:string, :text])
|
136
|
+
result.merge!(collation_and_charset_for_column(@current_table_name, @column.name))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def collation_and_charset_for_column(current_table_name, column_name)
|
144
|
+
connection = ActiveRecord::Base.connection
|
145
|
+
connection.class.name.match?(/mysql/i) or raise ArgumentError, "only supported for MySQL"
|
146
|
+
|
147
|
+
database_name = connection.current_database
|
148
|
+
|
149
|
+
defaults = connection.select_one(<<~EOS)
|
150
|
+
SELECT C.character_set_name, C.collation_name
|
151
|
+
FROM information_schema.`COLUMNS` C
|
152
|
+
WHERE C.table_schema = '#{connection.quote_string(database_name)}' AND
|
153
|
+
C.table_name = '#{connection.quote_string(current_table_name)}' AND
|
154
|
+
C.column_name = '#{connection.quote_string(column_name)}';
|
155
|
+
EOS
|
156
|
+
|
157
|
+
defaults && defaults["character_set_name"] or raise "character_set_name missing from #{defaults.inspect} from #{database_name}.#{current_table_name}.#{column_name}"
|
158
|
+
defaults && defaults["collation_name"] or raise "collation_name missing from #{defaults.inspect}"
|
159
|
+
|
160
|
+
{
|
161
|
+
charset: defaults["character_set_name"],
|
162
|
+
collation: defaults["collation_name"]
|
163
|
+
}
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|