ridgepole 0.7.3.beta → 0.7.3.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +38 -0
- data/Appraisals +2 -2
- data/README.md +3 -9
- data/Rakefile +7 -1
- data/bin/ridgepole +97 -108
- data/gemfiles/activerecord_5.2.gemfile +1 -1
- data/lib/ridgepole/cli/config.rb +43 -43
- data/lib/ridgepole/client.rb +65 -63
- data/lib/ridgepole/default_limit.rb +26 -24
- data/lib/ridgepole/delta.rb +367 -369
- data/lib/ridgepole/diff.rb +366 -377
- data/lib/ridgepole/dsl_parser.rb +22 -20
- data/lib/ridgepole/dsl_parser/context.rb +95 -93
- data/lib/ridgepole/dsl_parser/table_definition.rb +125 -123
- data/lib/ridgepole/dumper.rb +73 -71
- data/lib/ridgepole/execute_expander.rb +55 -55
- data/lib/ridgepole/ext/abstract_mysql_adapter/dump_auto_increment.rb +3 -3
- data/lib/ridgepole/ext/abstract_mysql_adapter/use_alter_index.rb +1 -1
- data/lib/ridgepole/ext/pp_sort_hash.rb +14 -14
- data/lib/ridgepole/ext/schema_dumper.rb +1 -1
- data/lib/ridgepole/external_sql_executer.rb +20 -20
- data/lib/ridgepole/logger.rb +17 -15
- data/lib/ridgepole/migration_ext.rb +6 -8
- data/lib/ridgepole/schema_statements_ext.rb +3 -3
- data/lib/ridgepole/version.rb +1 -1
- data/ridgepole.gemspec +11 -10
- data/spec/cli_helper.rb +2 -2
- data/spec/erb_helper.rb +6 -2
- data/spec/hide_pending_formatter.rb +5 -4
- data/spec/mysql/_migrate/migrate_change_table_option_spec.rb +8 -8
- data/spec/mysql/bigint_pk/bigint_pk_spec.rb +8 -8
- data/spec/mysql/bigint_pk/int_pk_spec.rb +13 -13
- data/spec/mysql/cli/config_spec.rb +52 -53
- data/spec/mysql/cli/ridgepole_spec.rb +111 -111
- data/spec/mysql/collation/collation_spec.rb +39 -39
- data/spec/mysql/comment/comment_spec.rb +36 -36
- data/spec/mysql/default_lambda/default_lambda_spec.rb +30 -30
- data/spec/mysql/diff/diff2_spec.rb +18 -18
- data/spec/mysql/diff/diff_spec.rb +11 -11
- data/spec/mysql/dump/dump_class_method_spec.rb +2 -2
- data/spec/mysql/dump/dump_some_tables_spec.rb +14 -14
- data/spec/mysql/dump/dump_spec.rb +2 -2
- data/spec/mysql/dump/dump_unknown_column_type_spec.rb +3 -3
- data/spec/mysql/dump/dump_without_table_options_spec.rb +8 -8
- data/spec/mysql/fk/migrate_change_fk_spec.rb +40 -40
- data/spec/mysql/fk/migrate_create_fk_spec.rb +40 -40
- data/spec/mysql/fk/migrate_drop_fk_spec.rb +60 -60
- data/spec/mysql/migrate/check_orphan_index_spec.rb +6 -6
- data/spec/mysql/migrate/migrate_add_column2_spec.rb +43 -43
- data/spec/mysql/migrate/migrate_add_column_order_spec.rb +50 -50
- data/spec/mysql/migrate/migrate_add_column_spec.rb +11 -11
- data/spec/mysql/migrate/migrate_add_column_with_alter_extra_spec.rb +8 -8
- data/spec/mysql/migrate/migrate_add_column_with_script_spec.rb +11 -11
- data/spec/mysql/migrate/migrate_change_column2_spec.rb +20 -20
- data/spec/mysql/migrate/migrate_change_column3_spec.rb +60 -60
- data/spec/mysql/migrate/migrate_change_column4_spec.rb +16 -16
- data/spec/mysql/migrate/migrate_change_column5_spec.rb +24 -24
- data/spec/mysql/migrate/migrate_change_column6_spec.rb +40 -40
- data/spec/mysql/migrate/migrate_change_column7_spec.rb +4 -4
- data/spec/mysql/migrate/migrate_change_column8_spec.rb +9 -9
- data/spec/mysql/migrate/migrate_change_column_default_spec.rb +48 -48
- data/spec/mysql/migrate/migrate_change_column_float_spec.rb +16 -16
- data/spec/mysql/migrate/migrate_change_column_spec.rb +11 -11
- data/spec/mysql/migrate/migrate_change_index2_spec.rb +20 -20
- data/spec/mysql/migrate/migrate_change_index3_spec.rb +43 -43
- data/spec/mysql/migrate/migrate_change_index4_spec.rb +24 -24
- data/spec/mysql/migrate/migrate_change_index5_spec.rb +16 -16
- data/spec/mysql/migrate/migrate_change_index6_spec.rb +12 -12
- data/spec/mysql/migrate/migrate_change_index7_spec.rb +20 -20
- data/spec/mysql/migrate/migrate_change_index8_spec.rb +20 -20
- data/spec/mysql/migrate/migrate_change_index_spec.rb +17 -17
- data/spec/mysql/migrate/migrate_change_table_comment_spec.rb +10 -10
- data/spec/mysql/migrate/migrate_change_table_option_spec.rb +18 -18
- data/spec/mysql/migrate/migrate_check_relation_column_type_spec.rb +37 -37
- data/spec/mysql/migrate/migrate_create_index2_spec.rb +12 -12
- data/spec/mysql/migrate/migrate_create_index_spec.rb +11 -11
- data/spec/mysql/migrate/migrate_create_table_spec.rb +8 -8
- data/spec/mysql/migrate/migrate_create_table_with_index_spec.rb +6 -6
- data/spec/mysql/migrate/migrate_create_table_with_options_spec.rb +12 -12
- data/spec/mysql/migrate/migrate_create_table_with_script_spec.rb +11 -11
- data/spec/mysql/migrate/migrate_drop_column_and_index2_spec.rb +9 -9
- data/spec/mysql/migrate/migrate_drop_column_and_index_spec.rb +12 -12
- data/spec/mysql/migrate/migrate_drop_column_and_unique_index_spec.rb +10 -10
- data/spec/mysql/migrate/migrate_drop_column_spec.rb +11 -11
- data/spec/mysql/migrate/migrate_drop_index_spec.rb +11 -11
- data/spec/mysql/migrate/migrate_drop_table_spec.rb +8 -8
- data/spec/mysql/migrate/migrate_duplicate_index_spec.rb +6 -6
- data/spec/mysql/migrate/migrate_duplicate_table_spec.rb +6 -6
- data/spec/mysql/migrate/migrate_empty_spec.rb +4 -4
- data/spec/mysql/migrate/migrate_execute_spec.rb +55 -55
- data/spec/mysql/migrate/migrate_log_file_spec.rb +9 -9
- data/spec/mysql/migrate/migrate_merge_mode_spec.rb +9 -9
- data/spec/mysql/migrate/migrate_noop_spec.rb +19 -19
- data/spec/mysql/migrate/migrate_primary_key_spec.rb +18 -18
- data/spec/mysql/migrate/migrate_rename_column_spec.rb +17 -17
- data/spec/mysql/migrate/migrate_rename_table_spec.rb +26 -26
- data/spec/mysql/migrate/migrate_same_default_null_spec.rb +16 -16
- data/spec/mysql/migrate/migrate_same_spec.rb +4 -4
- data/spec/mysql/migrate/migrate_script_error_spec.rb +8 -8
- data/spec/mysql/migrate/migrate_skip_column_comment_change_spec.rb +8 -8
- data/spec/mysql/migrate/migrate_skip_drop_table_spec.rb +9 -9
- data/spec/mysql/migrate/migrate_skip_rename_column_spec.rb +8 -8
- data/spec/mysql/migrate/migrate_skip_rename_table_spec.rb +9 -9
- data/spec/mysql/migrate/migrate_with_ignore_tables_spec.rb +64 -64
- data/spec/mysql/migrate/migrate_with_pre_post_query_spec.rb +12 -12
- data/spec/mysql/migrate/migrate_with_tables_spec.rb +29 -29
- data/spec/mysql/migrate/migrate_with_verbose_log_spec.rb +18 -18
- data/spec/mysql/migrate_/migrate_create_index_with_alter_spec.rb +8 -8
- data/spec/mysql/migrate_/migrate_drop_index_with_alter_spec.rb +8 -8
- data/spec/mysql/text_blob_types/text_blob_types_spec.rb +8 -8
- data/spec/mysql/~default_name_fk/migrate_change_fk_spec.rb +12 -12
- data/spec/mysql/~default_name_fk/migrate_create_fk_spec.rb +30 -30
- data/spec/mysql/~default_name_fk/migrate_drop_fk_spec.rb +22 -22
- data/spec/mysql/~dump_auto_increment/migrate_create_table_with_index_spec.rb +7 -7
- data/spec/mysql57/json/add_json_column_spec.rb +8 -8
- data/spec/mysql57/json/change_json_column_spec.rb +24 -24
- data/spec/mysql57/json/drop_json_column_spec.rb +8 -8
- data/spec/mysql57/virtual/add_virtual_column_spec.rb +9 -9
- data/spec/mysql57/virtual/change_virtual_column_spec.rb +9 -9
- data/spec/mysql57/virtual/drop_virtual_column_spec.rb +9 -9
- data/spec/postgresql/diff/diff_spec.rb +18 -18
- data/spec/postgresql/dump/dump_spec.rb +2 -2
- data/spec/postgresql/fk/migrate_change_fk_spec.rb +24 -24
- data/spec/postgresql/fk/migrate_create_fk_spec.rb +40 -40
- data/spec/postgresql/fk/migrate_drop_fk_spec.rb +44 -44
- data/spec/postgresql/migrate/migrate_add_column_spec.rb +21 -21
- data/spec/postgresql/migrate/migrate_add_expression_index_spec.rb +2 -2
- data/spec/postgresql/migrate/migrate_bigint_spec.rb +12 -12
- data/spec/postgresql/migrate/migrate_change_column_default_spec.rb +8 -8
- data/spec/postgresql/migrate/migrate_change_column_spec.rb +19 -19
- data/spec/postgresql/migrate/migrate_change_index_spec.rb +13 -13
- data/spec/postgresql/migrate/migrate_check_relation_column_type_spec.rb +19 -19
- data/spec/postgresql/migrate/migrate_create_table_spec.rb +8 -8
- data/spec/postgresql/migrate/migrate_create_table_with_default_proc_spec.rb +18 -18
- data/spec/postgresql/migrate/migrate_drop_column_spec.rb +11 -11
- data/spec/postgresql/migrate/migrate_drop_column_with_index_spec.rb +12 -12
- data/spec/postgresql/migrate/migrate_drop_expression_index_spec.rb +8 -8
- data/spec/postgresql/migrate/migrate_drop_index_spec.rb +11 -11
- data/spec/postgresql/migrate/migrate_drop_table_spec.rb +8 -8
- data/spec/postgresql/migrate/migrate_ext_cols_spec.rb +8 -8
- data/spec/postgresql/migrate/migrate_primary_key_spec.rb +97 -0
- data/spec/postgresql/migrate/migrate_references_spec.rb +24 -24
- data/spec/postgresql/migrate/migrate_rename_column_spec.rb +11 -11
- data/spec/postgresql/migrate/migrate_rename_table_spec.rb +16 -16
- data/spec/postgresql/migrate/migrate_same_spec.rb +4 -4
- data/spec/postgresql/~default_name_fk/migrate_change_fk_spec.rb +12 -12
- data/spec/postgresql/~default_name_fk/migrate_create_fk_spec.rb +30 -30
- data/spec/postgresql/~default_name_fk/migrate_drop_fk_spec.rb +22 -22
- data/spec/processing_for_travis.rb +1 -1
- data/spec/spec_condition.rb +2 -2
- data/spec/spec_const.rb +9 -9
- data/spec/spec_helper.rb +21 -23
- metadata +54 -37
data/lib/ridgepole/diff.rb
CHANGED
@@ -1,64 +1,65 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Ridgepole
|
2
|
+
class Diff
|
3
|
+
PRIMARY_KEY_OPTIONS = %i[id limit default null precision scale collation unsigned].freeze
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
def initialize(options = {})
|
6
|
+
@options = options
|
7
|
+
@logger = Ridgepole::Logger.instance
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
def diff(from, to, options = {})
|
11
|
+
from = (from || {}).deep_dup
|
12
|
+
to = (to || {}).deep_dup
|
12
13
|
|
13
|
-
|
14
|
+
check_table_existence(to)
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
delta = {}
|
17
|
+
relation_info = {}
|
17
18
|
|
18
|
-
|
19
|
+
scan_table_rename(from, to, delta)
|
19
20
|
|
20
|
-
|
21
|
-
|
21
|
+
to.each do |table_name, to_attrs|
|
22
|
+
collect_relation_info!(table_name, to_attrs, relation_info)
|
22
23
|
|
23
|
-
|
24
|
+
next unless target?(table_name)
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
if (from_attrs = from.delete(table_name))
|
27
|
+
@logger.verbose_info("# #{table_name}")
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
unless (attrs_delta = diff_inspect(from_attrs, to_attrs)).empty?
|
30
|
+
@logger.verbose_info(attrs_delta)
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
scan_change(table_name, from_attrs, to_attrs, delta)
|
34
|
+
else
|
35
|
+
delta[:add] ||= {}
|
36
|
+
delta[:add][table_name] = to_attrs
|
37
|
+
end
|
36
38
|
end
|
37
|
-
end
|
38
39
|
|
39
|
-
|
40
|
+
scan_relation_info(relation_info)
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
unless @options[:merge] || @options[:skip_drop_table]
|
43
|
+
from.each do |table_name, from_attrs|
|
44
|
+
next unless target?(table_name)
|
44
45
|
|
45
|
-
|
46
|
-
|
46
|
+
delta[:delete] ||= {}
|
47
|
+
delta[:delete][table_name] = from_attrs
|
48
|
+
end
|
47
49
|
end
|
48
|
-
end
|
49
50
|
|
50
|
-
|
51
|
+
delta[:execute] = options[:execute]
|
51
52
|
|
52
|
-
|
53
|
-
|
53
|
+
Ridgepole::Delta.new(delta, @options)
|
54
|
+
end
|
54
55
|
|
55
|
-
|
56
|
+
private
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
58
|
+
def scan_table_rename(from, to, delta, _options = {})
|
59
|
+
to.dup.each do |table_name, to_attrs|
|
60
|
+
next unless target?(table_name)
|
60
61
|
|
61
|
-
|
62
|
+
next unless (from_table_name = (to_attrs[:options] || {}).delete(:renamed_from))
|
62
63
|
from_table_name = from_table_name.to_s if from_table_name
|
63
64
|
|
64
65
|
# Already renamed
|
@@ -79,174 +80,174 @@ class Ridgepole::Diff
|
|
79
80
|
to.delete(table_name)
|
80
81
|
end
|
81
82
|
end
|
82
|
-
end
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
84
|
+
def scan_change(table_name, from, to, delta)
|
85
|
+
from = (from || {}).dup
|
86
|
+
to = (to || {}).dup
|
87
|
+
table_delta = {}
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
89
|
+
scan_options_change(table_name, from[:options], to[:options], table_delta)
|
90
|
+
scan_definition_change(from[:definition], to[:definition], from[:indices], table_name, from[:options], table_delta)
|
91
|
+
scan_indices_change(from[:indices], to[:indices], to[:definition], table_delta, from[:options], to[:options])
|
92
|
+
scan_foreign_keys_change(from[:foreign_keys], to[:foreign_keys], table_delta, @options)
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
unless table_delta.empty?
|
95
|
+
delta[:change] ||= {}
|
96
|
+
delta[:change][table_name] = table_delta
|
97
|
+
end
|
97
98
|
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def scan_options_change(table_name, from, to, table_delta)
|
101
|
-
from = (from || {}).dup
|
102
|
-
to = (to || {}).dup
|
103
99
|
|
104
|
-
|
100
|
+
def scan_options_change(table_name, from, to, table_delta)
|
101
|
+
from = (from || {}).dup
|
102
|
+
to = (to || {}).dup
|
105
103
|
|
106
|
-
|
107
|
-
to_options = to[:options] || {}
|
104
|
+
normalize_default_proc_options!(from, to)
|
108
105
|
|
109
|
-
|
110
|
-
|
111
|
-
to.delete(:comment)
|
112
|
-
end
|
106
|
+
from_options = from[:options] || {}
|
107
|
+
to_options = to[:options] || {}
|
113
108
|
|
114
|
-
|
115
|
-
|
116
|
-
|
109
|
+
if @options[:ignore_table_comment]
|
110
|
+
from.delete(:comment)
|
111
|
+
to.delete(:comment)
|
117
112
|
end
|
118
|
-
end
|
119
113
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
table_delta[:table_options] = to_options
|
114
|
+
[from, to].each do |table_attrs|
|
115
|
+
if table_attrs.key?(:default) && table_attrs[:default].nil?
|
116
|
+
table_attrs.delete(:default)
|
117
|
+
end
|
125
118
|
end
|
126
119
|
|
127
|
-
if
|
128
|
-
|
129
|
-
|
130
|
-
|
120
|
+
if Ridgepole::ConnectionAdapters.mysql?
|
121
|
+
if @options[:mysql_change_table_options] && (from_options != to_options)
|
122
|
+
from.delete(:options)
|
123
|
+
to.delete(:options)
|
124
|
+
table_delta[:table_options] = to_options
|
125
|
+
end
|
126
|
+
|
127
|
+
if @options[:mysql_change_table_comment] && (from[:comment] != to[:comment])
|
128
|
+
from.delete(:comment)
|
129
|
+
to_comment = to.delete(:comment)
|
130
|
+
table_delta[:table_comment] = to_comment
|
131
|
+
end
|
131
132
|
end
|
132
|
-
end
|
133
133
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
134
|
+
if @options[:dump_without_table_options]
|
135
|
+
from.delete(:options)
|
136
|
+
to.delete(:options)
|
137
|
+
end
|
138
138
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
139
|
+
pk_attrs = build_primary_key_attrs_if_changed(from, to, table_name)
|
140
|
+
if pk_attrs
|
141
|
+
if @options[:allow_pk_change]
|
142
|
+
delta_type = pk_attrs[:options][:id] == false ? :delete : :change
|
143
|
+
table_delta[:primary_key_definition] = { delta_type => { id: pk_attrs } }
|
144
|
+
else
|
145
|
+
@logger.warn(<<-MSG)
|
145
146
|
[WARNING] Primary key definition of `#{table_name}` differ but `allow_pk_change` option is false
|
146
147
|
from: #{from.slice(*PRIMARY_KEY_OPTIONS)}
|
147
148
|
to: #{to.slice(*PRIMARY_KEY_OPTIONS)}
|
148
|
-
|
149
|
+
MSG
|
150
|
+
end
|
149
151
|
end
|
150
|
-
|
151
|
-
|
152
|
-
to = to.except(*PRIMARY_KEY_OPTIONS)
|
152
|
+
from = from.except(*PRIMARY_KEY_OPTIONS)
|
153
|
+
to = to.except(*PRIMARY_KEY_OPTIONS)
|
153
154
|
|
154
|
-
|
155
|
-
|
155
|
+
unless from == to
|
156
|
+
@logger.warn(<<-MSG)
|
156
157
|
[WARNING] No difference of schema configuration for table `#{table_name}` but table options differ.
|
157
158
|
from: #{from}
|
158
159
|
to: #{to}
|
159
|
-
|
160
|
+
MSG
|
161
|
+
end
|
160
162
|
end
|
161
|
-
end
|
162
163
|
|
163
|
-
|
164
|
-
|
164
|
+
def convert_to_primary_key_attrs(column_options)
|
165
|
+
options = column_options.dup
|
165
166
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
167
|
+
type = if options[:id]
|
168
|
+
options.delete(:id)
|
169
|
+
else
|
170
|
+
Ridgepole::DSLParser::TableDefinition::DEFAULT_PRIMARY_KEY_TYPE
|
171
|
+
end
|
171
172
|
|
172
|
-
|
173
|
-
|
173
|
+
if %i[integer bigint].include?(type) && !options.key?(:default)
|
174
|
+
options[:auto_increment] = true
|
175
|
+
end
|
176
|
+
|
177
|
+
{ type: type, options: options }
|
174
178
|
end
|
175
179
|
|
176
|
-
|
177
|
-
|
180
|
+
def build_attrs_if_changed(to_attrs, from_attrs, table_name, primary_key: false)
|
181
|
+
normalize_column_options!(from_attrs, primary_key)
|
182
|
+
normalize_column_options!(to_attrs, primary_key)
|
178
183
|
|
179
|
-
|
180
|
-
|
181
|
-
|
184
|
+
unless compare_column_attrs(from_attrs, to_attrs)
|
185
|
+
new_to_attrs = fix_change_column_options(table_name, from_attrs, to_attrs)
|
186
|
+
end
|
187
|
+
new_to_attrs
|
188
|
+
end
|
182
189
|
|
183
|
-
|
184
|
-
|
190
|
+
def build_primary_key_attrs_if_changed(from, to, table_name)
|
191
|
+
from_column_attrs = convert_to_primary_key_attrs(from.slice(*PRIMARY_KEY_OPTIONS))
|
192
|
+
to_column_attrs = convert_to_primary_key_attrs(to.slice(*PRIMARY_KEY_OPTIONS))
|
193
|
+
return if from_column_attrs == to_column_attrs
|
194
|
+
build_attrs_if_changed(to_column_attrs, from_column_attrs, table_name, primary_key: true)
|
185
195
|
end
|
186
|
-
new_to_attrs
|
187
|
-
end
|
188
196
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
build_attrs_if_changed(to_column_attrs, from_column_attrs, table_name, primary_key: true)
|
194
|
-
end
|
197
|
+
def scan_definition_change(from, to, from_indices, table_name, table_options, table_delta)
|
198
|
+
from = (from || {}).dup
|
199
|
+
to = (to || {}).dup
|
200
|
+
definition_delta = {}
|
195
201
|
|
196
|
-
|
197
|
-
from = (from || {}).dup
|
198
|
-
to = (to || {}).dup
|
199
|
-
definition_delta = {}
|
202
|
+
scan_column_rename(from, to, definition_delta)
|
200
203
|
|
201
|
-
|
204
|
+
priv_column_name = if (table_options[:id] == false) || table_options[:primary_key].is_a?(Array)
|
205
|
+
nil
|
206
|
+
else
|
207
|
+
table_options[:primary_key] || 'id'
|
208
|
+
end
|
202
209
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
210
|
+
to.each do |column_name, to_attrs|
|
211
|
+
if (from_attrs = from.delete(column_name))
|
212
|
+
to_attrs = build_attrs_if_changed(to_attrs, from_attrs, table_name)
|
213
|
+
if to_attrs
|
214
|
+
definition_delta[:change] ||= {}
|
215
|
+
definition_delta[:change][column_name] = to_attrs
|
216
|
+
end
|
217
|
+
else
|
218
|
+
definition_delta[:add] ||= {}
|
219
|
+
to_attrs[:options] ||= {}
|
208
220
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
definition_delta[:change][column_name] = to_attrs
|
215
|
-
end
|
216
|
-
else
|
217
|
-
definition_delta[:add] ||= {}
|
218
|
-
to_attrs[:options] ||= {}
|
221
|
+
if priv_column_name
|
222
|
+
to_attrs[:options][:after] = priv_column_name
|
223
|
+
else
|
224
|
+
to_attrs[:options][:first] = true
|
225
|
+
end
|
219
226
|
|
220
|
-
|
221
|
-
to_attrs[:options][:after] = priv_column_name
|
222
|
-
else
|
223
|
-
to_attrs[:options][:first] = true
|
227
|
+
definition_delta[:add][column_name] = to_attrs
|
224
228
|
end
|
225
229
|
|
226
|
-
|
230
|
+
priv_column_name = column_name
|
227
231
|
end
|
228
232
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
@logger.warn("[WARNING] PostgreSQL doesn't support adding a new column except for the last position. #{table_name}.#{column_name} will be added to the last.")
|
233
|
+
if Ridgepole::ConnectionAdapters.postgresql?
|
234
|
+
added_size = 0
|
235
|
+
to.reverse_each.with_index do |(column_name, to_attrs), i|
|
236
|
+
if to_attrs[:options].delete(:after)
|
237
|
+
if added_size != i
|
238
|
+
@logger.warn("[WARNING] PostgreSQL doesn't support adding a new column except for the last position. #{table_name}.#{column_name} will be added to the last.")
|
239
|
+
end
|
240
|
+
added_size += 1
|
238
241
|
end
|
239
|
-
added_size += 1
|
240
242
|
end
|
241
243
|
end
|
242
|
-
end
|
243
244
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
245
|
+
unless @options[:merge]
|
246
|
+
from.each do |column_name, from_attrs|
|
247
|
+
definition_delta[:delete] ||= {}
|
248
|
+
definition_delta[:delete][column_name] = from_attrs
|
248
249
|
|
249
|
-
|
250
|
+
next unless from_indices
|
250
251
|
modified_indices = []
|
251
252
|
|
252
253
|
from_indices.each do |name, attrs|
|
@@ -257,32 +258,29 @@ class Ridgepole::Diff
|
|
257
258
|
|
258
259
|
# In PostgreSQL, the index is deleted when the column is deleted
|
259
260
|
if @options[:index_removed_drop_column]
|
260
|
-
from_indices.reject! do |name,
|
261
|
+
from_indices.reject! do |name, _attrs|
|
261
262
|
modified_indices.include?(name)
|
262
263
|
end
|
263
264
|
end
|
264
265
|
|
265
|
-
from_indices.reject! do |
|
266
|
+
from_indices.reject! do |_name, attrs|
|
266
267
|
attrs[:column_name].is_a?(Array) && attrs[:column_name].empty?
|
267
268
|
end
|
268
269
|
end
|
269
270
|
end
|
270
|
-
end
|
271
271
|
|
272
|
-
|
273
|
-
table_delta[:definition] = definition_delta
|
272
|
+
table_delta[:definition] = definition_delta unless definition_delta.empty?
|
274
273
|
end
|
275
|
-
end
|
276
274
|
|
277
|
-
|
278
|
-
|
279
|
-
|
275
|
+
def scan_column_rename(from, to, definition_delta)
|
276
|
+
to.dup.each do |column_name, to_attrs|
|
277
|
+
next unless (from_column_name = (to_attrs[:options] || {}).delete(:renamed_from))
|
280
278
|
from_column_name = from_column_name.to_s if from_column_name
|
281
279
|
|
282
280
|
# Already renamed
|
283
281
|
next if from[column_name]
|
284
282
|
|
285
|
-
unless from.
|
283
|
+
unless from.key?(from_column_name)
|
286
284
|
raise "Column `#{from_column_name}` not found"
|
287
285
|
end
|
288
286
|
|
@@ -293,292 +291,283 @@ class Ridgepole::Diff
|
|
293
291
|
to.delete(column_name)
|
294
292
|
end
|
295
293
|
end
|
296
|
-
end
|
297
294
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
295
|
+
def scan_indices_change(from, to, to_columns, table_delta, _from_table_options, to_table_options)
|
296
|
+
from = (from || {}).dup
|
297
|
+
to = (to || {}).dup
|
298
|
+
indices_delta = {}
|
302
299
|
|
303
|
-
|
304
|
-
|
305
|
-
|
300
|
+
to.each do |index_name, to_attrs|
|
301
|
+
if index_name.is_a?(Array)
|
302
|
+
from_index_name, from_attrs = from.find { |_name, attrs| attrs[:column_name] == index_name }
|
306
303
|
|
307
|
-
|
308
|
-
|
309
|
-
|
304
|
+
if from_attrs
|
305
|
+
from.delete(from_index_name)
|
306
|
+
from_attrs[:options].delete(:name)
|
307
|
+
end
|
308
|
+
else
|
309
|
+
from_attrs = from.delete(index_name)
|
310
310
|
end
|
311
|
-
else
|
312
|
-
from_attrs = from.delete(index_name)
|
313
|
-
end
|
314
|
-
|
315
|
-
if from_attrs
|
316
|
-
normalize_index_options!(from_attrs[:options])
|
317
|
-
normalize_index_options!(to_attrs[:options])
|
318
311
|
|
319
|
-
if from_attrs
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
312
|
+
if from_attrs
|
313
|
+
normalize_index_options!(from_attrs[:options])
|
314
|
+
normalize_index_options!(to_attrs[:options])
|
315
|
+
|
316
|
+
if from_attrs != to_attrs
|
317
|
+
indices_delta[:add] ||= {}
|
318
|
+
indices_delta[:add][index_name] = to_attrs
|
319
|
+
|
320
|
+
unless @options[:merge]
|
321
|
+
if columns_all_include?(from_attrs[:column_name], to_columns.keys, to_table_options)
|
322
|
+
indices_delta[:delete] ||= {}
|
323
|
+
indices_delta[:delete][index_name] = from_attrs
|
324
|
+
end
|
327
325
|
end
|
328
326
|
end
|
327
|
+
else
|
328
|
+
indices_delta[:add] ||= {}
|
329
|
+
indices_delta[:add][index_name] = to_attrs
|
329
330
|
end
|
330
|
-
else
|
331
|
-
indices_delta[:add] ||= {}
|
332
|
-
indices_delta[:add][index_name] = to_attrs
|
333
331
|
end
|
334
|
-
end
|
335
332
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
333
|
+
unless @options[:merge]
|
334
|
+
from.each do |index_name, from_attrs|
|
335
|
+
if columns_all_include?(from_attrs[:column_name], to_columns.keys, to_table_options)
|
336
|
+
indices_delta[:delete] ||= {}
|
337
|
+
indices_delta[:delete][index_name] = from_attrs
|
338
|
+
end
|
341
339
|
end
|
342
340
|
end
|
343
|
-
end
|
344
341
|
|
345
|
-
|
346
|
-
table_delta[:indices] = indices_delta
|
342
|
+
table_delta[:indices] = indices_delta unless indices_delta.empty?
|
347
343
|
end
|
348
|
-
end
|
349
344
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
345
|
+
def target?(table_name)
|
346
|
+
if @options[:tables] && @options[:tables].include?(table_name)
|
347
|
+
true
|
348
|
+
elsif @options[:ignore_tables] && @options[:ignore_tables].any? { |i| i =~ table_name }
|
349
|
+
false
|
350
|
+
elsif @options[:tables]
|
351
|
+
false
|
352
|
+
else
|
353
|
+
true
|
354
|
+
end
|
359
355
|
end
|
360
|
-
end
|
361
356
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
357
|
+
def normalize_column_options!(attrs, primary_key = false)
|
358
|
+
opts = attrs[:options]
|
359
|
+
opts[:null] = true if !opts.key?(:null) && !primary_key
|
360
|
+
default_limit = Ridgepole::DefaultsLimit.default_limit(attrs[:type], @options)
|
361
|
+
opts.delete(:limit) if opts[:limit] == default_limit
|
367
362
|
|
368
|
-
|
369
|
-
|
370
|
-
opts[:default] = nil
|
371
|
-
end
|
363
|
+
# XXX: MySQL only?
|
364
|
+
opts[:default] = nil if !opts.key?(:default) && !primary_key
|
372
365
|
|
373
|
-
|
374
|
-
|
366
|
+
if Ridgepole::ConnectionAdapters.mysql?
|
367
|
+
opts[:unsigned] = false unless opts.key?(:unsigned)
|
375
368
|
|
376
|
-
|
377
|
-
|
378
|
-
|
369
|
+
if (attrs[:type] == :integer) && (opts[:limit] == Ridgepole::DefaultsLimit.default_limit(:bigint, @options))
|
370
|
+
attrs[:type] = :bigint
|
371
|
+
opts.delete(:limit)
|
372
|
+
end
|
379
373
|
end
|
380
374
|
end
|
381
|
-
end
|
382
|
-
|
383
|
-
def normalize_index_options!(opts)
|
384
|
-
# XXX: MySQL only?
|
385
|
-
opts[:using] = :btree unless opts.has_key?(:using)
|
386
|
-
opts[:unique] = false unless opts.has_key?(:unique)
|
387
|
-
end
|
388
375
|
|
389
|
-
|
390
|
-
|
391
|
-
|
376
|
+
def normalize_index_options!(opts)
|
377
|
+
# XXX: MySQL only?
|
378
|
+
opts[:using] = :btree unless opts.key?(:using)
|
379
|
+
opts[:unique] = false unless opts.key?(:unique)
|
392
380
|
end
|
393
381
|
|
394
|
-
|
395
|
-
|
382
|
+
def columns_all_include?(expected_columns, actual_columns, table_options)
|
383
|
+
return true unless expected_columns.is_a?(Array)
|
384
|
+
|
385
|
+
if (table_options[:id] != false) && !table_options[:primary_key].is_a?(Array)
|
386
|
+
actual_columns += [(table_options[:primary_key] || 'id').to_s]
|
387
|
+
end
|
388
|
+
|
389
|
+
expected_columns.all? { |i| actual_columns.include?(i) }
|
396
390
|
end
|
397
391
|
|
398
|
-
|
399
|
-
|
392
|
+
def scan_foreign_keys_change(from, to, table_delta, options)
|
393
|
+
from = (from || {}).dup
|
394
|
+
to = (to || {}).dup
|
395
|
+
foreign_keys_delta = {}
|
400
396
|
|
401
|
-
|
402
|
-
|
403
|
-
to = (to || {}).dup
|
404
|
-
foreign_keys_delta = {}
|
397
|
+
to.each do |foreign_key_name_or_tables, to_attrs|
|
398
|
+
from_attrs = from.delete(foreign_key_name_or_tables)
|
405
399
|
|
406
|
-
|
407
|
-
|
400
|
+
if from_attrs
|
401
|
+
if from_attrs != to_attrs
|
402
|
+
foreign_keys_delta[:add] ||= {}
|
403
|
+
foreign_keys_delta[:add][foreign_key_name_or_tables] = to_attrs
|
408
404
|
|
409
|
-
|
410
|
-
|
405
|
+
unless options[:merge]
|
406
|
+
foreign_keys_delta[:delete] ||= {}
|
407
|
+
foreign_keys_delta[:delete][foreign_key_name_or_tables] = from_attrs
|
408
|
+
end
|
409
|
+
end
|
410
|
+
else
|
411
411
|
foreign_keys_delta[:add] ||= {}
|
412
412
|
foreign_keys_delta[:add][foreign_key_name_or_tables] = to_attrs
|
413
|
-
|
414
|
-
unless options[:merge]
|
415
|
-
foreign_keys_delta[:delete] ||= {}
|
416
|
-
foreign_keys_delta[:delete][foreign_key_name_or_tables] = from_attrs
|
417
|
-
end
|
418
413
|
end
|
419
|
-
else
|
420
|
-
foreign_keys_delta[:add] ||= {}
|
421
|
-
foreign_keys_delta[:add][foreign_key_name_or_tables] = to_attrs
|
422
414
|
end
|
423
|
-
end
|
424
415
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
416
|
+
unless options[:merge]
|
417
|
+
from.each do |foreign_key_name_or_tables, from_attrs|
|
418
|
+
foreign_keys_delta[:delete] ||= {}
|
419
|
+
foreign_keys_delta[:delete][foreign_key_name_or_tables] = from_attrs
|
420
|
+
end
|
429
421
|
end
|
430
|
-
end
|
431
422
|
|
432
|
-
|
433
|
-
|
423
|
+
unless foreign_keys_delta.empty?
|
424
|
+
table_delta[:foreign_keys] = foreign_keys_delta
|
425
|
+
end
|
434
426
|
end
|
435
|
-
end
|
436
427
|
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
428
|
+
# XXX: MySQL only?
|
429
|
+
# https://github.com/rails/rails/blob/v4.2.1/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb#L760
|
430
|
+
# https://github.com/rails/rails/blob/v4.2.1/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb#L102
|
431
|
+
def fix_change_column_options(table_name, from_attrs, to_attrs)
|
432
|
+
# default: 0, null: false -> default: nil, null: false | default: nil
|
433
|
+
# default: 0, null: false -> null: false | default: nil
|
434
|
+
# default: 0, null: false -> default: nil, null: true | default: nil, null: true
|
435
|
+
# default: 0, null: false -> null: true | default: nil, null: true
|
436
|
+
# default: 0, null: true -> default: nil, null: true | default: nil
|
437
|
+
# default: 0, null: true -> null: true | default: nil
|
438
|
+
# default: 0, null: true -> default: nil, null: false | default: nil, null: false (`default: nil` is ignored)
|
439
|
+
# default: 0, null: true -> null: false | default: nil, null: false (`default: nil` is ignored)
|
440
|
+
|
441
|
+
if (from_attrs[:options][:default] != to_attrs[:options][:default]) && (from_attrs[:options][:null] == to_attrs[:options][:null])
|
442
|
+
to_attrs = to_attrs.deep_dup
|
443
|
+
to_attrs[:options].delete(:null)
|
444
|
+
end
|
454
445
|
|
455
|
-
|
456
|
-
|
457
|
-
|
446
|
+
if Ridgepole::ConnectionAdapters.mysql? && ActiveRecord::VERSION::STRING.start_with?('5.0.')
|
447
|
+
if to_attrs[:options][:default].nil? && (to_attrs[:options][:null] == false)
|
448
|
+
Ridgepole::Logger.instance.warn("[WARNING] Table `#{table_name}`: `default: nil` is ignored when `null: false`. Please apply twice")
|
449
|
+
end
|
458
450
|
end
|
451
|
+
|
452
|
+
to_attrs
|
459
453
|
end
|
460
454
|
|
461
|
-
|
462
|
-
|
455
|
+
def compare_column_attrs(attrs1, attrs2)
|
456
|
+
attrs1 = attrs1.merge(options: attrs1.fetch(:options, {}).dup)
|
457
|
+
attrs2 = attrs2.merge(options: attrs2.fetch(:options, {}).dup)
|
458
|
+
normalize_default_proc_options!(attrs1[:options], attrs2[:options])
|
463
459
|
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
460
|
+
if @options[:skip_column_comment_change]
|
461
|
+
attrs1.fetch(:options).delete(:comment)
|
462
|
+
attrs2.fetch(:options).delete(:comment)
|
463
|
+
end
|
468
464
|
|
469
|
-
|
470
|
-
attrs1.fetch(:options).delete(:comment)
|
471
|
-
attrs2.fetch(:options).delete(:comment)
|
465
|
+
attrs1 == attrs2
|
472
466
|
end
|
473
467
|
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
opts1[:default] = opts1[:default].call
|
480
|
-
opts2[:default] = opts2[:default].call
|
468
|
+
def normalize_default_proc_options!(opts1, opts2)
|
469
|
+
if opts1[:default].is_a?(Proc) && opts2[:default].is_a?(Proc)
|
470
|
+
opts1[:default] = opts1[:default].call
|
471
|
+
opts2[:default] = opts2[:default].call
|
472
|
+
end
|
481
473
|
end
|
482
|
-
end
|
483
474
|
|
484
|
-
|
485
|
-
|
486
|
-
|
475
|
+
def diff_inspect(obj1, obj2, _options = {})
|
476
|
+
obj1 = Ridgepole::Ext::PpSortHash.extend_if_hash(obj1)
|
477
|
+
obj2 = Ridgepole::Ext::PpSortHash.extend_if_hash(obj2)
|
487
478
|
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
479
|
+
diffy = Diffy::Diff.new(
|
480
|
+
obj1.pretty_inspect,
|
481
|
+
obj2.pretty_inspect,
|
482
|
+
diff: '-u'
|
483
|
+
)
|
493
484
|
|
494
|
-
|
495
|
-
|
485
|
+
diffy.to_s(@options[:color] ? :color : :text).gsub(/\s+\z/m, '')
|
486
|
+
end
|
496
487
|
|
497
|
-
|
498
|
-
|
488
|
+
def collect_relation_info!(table_name, table_attr, relation_info)
|
489
|
+
return unless @options[:check_relation_type]
|
499
490
|
|
500
|
-
|
501
|
-
|
491
|
+
attrs_by_column = {}
|
492
|
+
definition = table_attr[:definition] || {}
|
502
493
|
|
503
|
-
|
504
|
-
|
505
|
-
|
494
|
+
definition.each do |column_name, column_attrs|
|
495
|
+
if column_name =~ /\w+_id\z/
|
496
|
+
attrs_by_column[column_name] = column_attrs.dup
|
497
|
+
end
|
506
498
|
end
|
507
|
-
end
|
508
499
|
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
500
|
+
relation_info[table_name] = {
|
501
|
+
options: table_attr[:options] || {},
|
502
|
+
columns: attrs_by_column
|
503
|
+
}
|
504
|
+
end
|
514
505
|
|
515
|
-
|
516
|
-
|
506
|
+
def scan_relation_info(relation_info)
|
507
|
+
return unless @options[:check_relation_type]
|
517
508
|
|
518
|
-
|
519
|
-
|
509
|
+
relation_info.each do |child_table, table_info|
|
510
|
+
next unless target?(child_table)
|
520
511
|
|
521
|
-
|
522
|
-
|
512
|
+
attrs_by_column = table_info.fetch(:columns)
|
513
|
+
parent_table_info = nil
|
523
514
|
|
524
|
-
|
525
|
-
|
515
|
+
attrs_by_column.each do |column_name, column_attrs|
|
516
|
+
parent_table = column_name.sub(/_id\z/, '')
|
526
517
|
|
527
|
-
|
528
|
-
|
518
|
+
[parent_table.pluralize, parent_table.singularize].each do |table_name|
|
519
|
+
parent_table_info = relation_info[table_name]
|
529
520
|
|
530
|
-
|
531
|
-
|
532
|
-
|
521
|
+
if parent_table_info
|
522
|
+
parent_table = table_name
|
523
|
+
break
|
524
|
+
end
|
533
525
|
end
|
534
|
-
end
|
535
526
|
|
536
|
-
|
527
|
+
next unless parent_table_info
|
537
528
|
|
538
|
-
|
539
|
-
|
529
|
+
table_options = parent_table_info.fetch(:options)
|
530
|
+
next if table_options[:id] == false
|
540
531
|
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
532
|
+
parent_column_info = {
|
533
|
+
type: table_options[:id] || @options[:check_relation_type].to_sym,
|
534
|
+
unsigned: table_options[:unsigned]
|
535
|
+
}
|
545
536
|
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
537
|
+
child_column_info = {
|
538
|
+
type: column_attrs[:type],
|
539
|
+
unsigned: column_attrs.fetch(:options, {})[:unsigned]
|
540
|
+
}
|
550
541
|
|
551
|
-
|
552
|
-
|
553
|
-
column_info.delete(:unsigned)
|
554
|
-
end
|
542
|
+
[parent_column_info, child_column_info].each do |column_info|
|
543
|
+
column_info.delete(:unsigned) unless column_info[:unsigned]
|
555
544
|
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
545
|
+
# for PostgreSQL
|
546
|
+
column_info[:type] = {
|
547
|
+
serial: :integer,
|
548
|
+
bigserial: :bigint
|
549
|
+
}.fetch(column_info[:type], column_info[:type])
|
550
|
+
end
|
562
551
|
|
563
|
-
|
552
|
+
next unless parent_column_info != child_column_info
|
564
553
|
parent_label = "#{parent_table}.id"
|
565
554
|
child_label = "#{child_table}.#{column_name}"
|
566
555
|
label_len = [parent_label.length, child_label.length].max
|
567
556
|
|
568
|
-
@logger.warn(<<-
|
557
|
+
@logger.warn(format(<<-MSG, label_len, parent_label, label_len, child_label))
|
569
558
|
[WARNING] Relation column type is different.
|
570
559
|
%*s: #{parent_column_info}
|
571
560
|
%*s: #{child_column_info}
|
572
|
-
|
561
|
+
MSG
|
573
562
|
end
|
574
563
|
end
|
575
564
|
end
|
576
|
-
end
|
577
565
|
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
566
|
+
def check_table_existence(definition)
|
567
|
+
return unless @options[:tables]
|
568
|
+
@options[:tables].each do |table_name|
|
569
|
+
@logger.warn "[WARNING] '#{table_name}' definition is not found" unless definition.key?(table_name)
|
570
|
+
end
|
582
571
|
end
|
583
572
|
end
|
584
573
|
end
|