dynamic_migrations 2.1.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/lib/dynamic_migrations/active_record/migrators/column.rb +21 -0
- data/lib/dynamic_migrations/active_record/migrators/foreign_key_constraint.rb +112 -0
- data/lib/dynamic_migrations/active_record/migrators/function.rb +108 -0
- data/lib/dynamic_migrations/active_record/migrators/index.rb +27 -0
- data/lib/dynamic_migrations/active_record/migrators/schema.rb +21 -0
- data/lib/dynamic_migrations/active_record/migrators/table.rb +21 -0
- data/lib/dynamic_migrations/active_record/migrators/trigger.rb +109 -0
- data/lib/dynamic_migrations/active_record/migrators/unique_constraint.rb +63 -0
- data/lib/dynamic_migrations/active_record/migrators/validation.rb +67 -0
- data/lib/dynamic_migrations/active_record/migrators.rb +64 -0
- data/lib/dynamic_migrations/name_helper.rb +13 -0
- data/lib/dynamic_migrations/postgres/generator/column.rb +92 -0
- data/lib/dynamic_migrations/postgres/generator/foreign_key_constraint.rb +84 -0
- data/lib/dynamic_migrations/postgres/generator/fragment.rb +30 -0
- data/lib/dynamic_migrations/postgres/generator/function.rb +77 -0
- data/lib/dynamic_migrations/postgres/generator/index.rb +101 -0
- data/lib/dynamic_migrations/postgres/generator/primary_key.rb +55 -0
- data/lib/dynamic_migrations/postgres/generator/schema.rb +19 -0
- data/lib/dynamic_migrations/postgres/generator/schema_migrations/section.rb +37 -0
- data/lib/dynamic_migrations/postgres/generator/schema_migrations.rb +92 -0
- data/lib/dynamic_migrations/postgres/generator/table.rb +122 -0
- data/lib/dynamic_migrations/postgres/generator/trigger.rb +101 -0
- data/lib/dynamic_migrations/postgres/generator/unique_constraint.rb +79 -0
- data/lib/dynamic_migrations/postgres/generator/validation.rb +87 -0
- data/lib/dynamic_migrations/postgres/generator.rb +359 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/functions.rb +68 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/columns.rb +72 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/foreign_key_constraints.rb +73 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/indexes.rb +73 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/primary_key.rb +49 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/triggers.rb +73 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/unique_constraints.rb +73 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/validations.rb +73 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables.rb +80 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas.rb +48 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations.rb +59 -0
- data/lib/dynamic_migrations/postgres/server/database/differences.rb +76 -16
- data/lib/dynamic_migrations/postgres/server/database/keys_and_unique_constraints_loader.rb +35 -9
- data/lib/dynamic_migrations/postgres/server/database/loaded_schemas_builder.rb +50 -26
- data/lib/dynamic_migrations/postgres/server/database/schema/function.rb +69 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/functions.rb +63 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/table/column.rb +6 -44
- data/lib/dynamic_migrations/postgres/server/database/schema/table/columns.rb +1 -1
- data/lib/dynamic_migrations/postgres/server/database/schema/table/foreign_key_constraint.rb +40 -5
- data/lib/dynamic_migrations/postgres/server/database/schema/table/index.rb +23 -9
- data/lib/dynamic_migrations/postgres/server/database/schema/table/primary_key.rb +21 -6
- data/lib/dynamic_migrations/postgres/server/database/schema/table/trigger.rb +151 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/table/triggers.rb +66 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/table/unique_constraint.rb +19 -9
- data/lib/dynamic_migrations/postgres/server/database/schema/table/validation.rb +20 -1
- data/lib/dynamic_migrations/postgres/server/database/schema/table.rb +15 -5
- data/lib/dynamic_migrations/postgres/server/database/schema/tables.rb +63 -0
- data/lib/dynamic_migrations/postgres/server/database/schema.rb +3 -49
- data/lib/dynamic_migrations/postgres/server/database/source.rb +21 -0
- data/lib/dynamic_migrations/postgres/server/database/structure_loader.rb +22 -112
- data/lib/dynamic_migrations/postgres/server/database/triggers_and_functions_loader.rb +131 -0
- data/lib/dynamic_migrations/postgres/server/database/validations_loader.rb +10 -4
- data/lib/dynamic_migrations/postgres/server/database.rb +2 -1
- data/lib/dynamic_migrations/postgres/server.rb +6 -0
- data/lib/dynamic_migrations/postgres.rb +1 -1
- data/lib/dynamic_migrations/version.rb +1 -1
- data/lib/dynamic_migrations.rb +47 -4
- metadata +44 -3
- data/lib/dynamic_migrations/postgres/data_types.rb +0 -320
@@ -0,0 +1,359 @@
|
|
1
|
+
module DynamicMigrations
|
2
|
+
module Postgres
|
3
|
+
class Generator
|
4
|
+
class ExpectedSymbolError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class DeferrableOptionsError < StandardError
|
8
|
+
end
|
9
|
+
|
10
|
+
class UnexpectedMigrationMethodNameError < StandardError
|
11
|
+
end
|
12
|
+
|
13
|
+
class MissingDescriptionError < StandardError
|
14
|
+
end
|
15
|
+
|
16
|
+
class NoDifferenceError < StandardError
|
17
|
+
end
|
18
|
+
|
19
|
+
# these sections are in order for which they will appear in a migration,
|
20
|
+
# note that removals come before additions, and that the order here optomizes
|
21
|
+
# for dependencies (i.e. columns have to be created before indexes are added and
|
22
|
+
# triggers are removed before functions are dropped)
|
23
|
+
STRUCTURE = [
|
24
|
+
{
|
25
|
+
header_comment: <<~COMMENT,
|
26
|
+
#
|
27
|
+
# Remove Functions
|
28
|
+
#
|
29
|
+
COMMENT
|
30
|
+
methods: [
|
31
|
+
:remove_function_comment,
|
32
|
+
:drop_function
|
33
|
+
]
|
34
|
+
},
|
35
|
+
{
|
36
|
+
header_comment: <<~COMMENT,
|
37
|
+
#
|
38
|
+
# Remove Triggers
|
39
|
+
#
|
40
|
+
COMMENT
|
41
|
+
methods: [
|
42
|
+
:remove_trigger_comment,
|
43
|
+
:remove_trigger
|
44
|
+
]
|
45
|
+
},
|
46
|
+
{
|
47
|
+
header_comment: <<~COMMENT,
|
48
|
+
#
|
49
|
+
# Remove Validations
|
50
|
+
#
|
51
|
+
COMMENT
|
52
|
+
methods: [
|
53
|
+
:remove_validation,
|
54
|
+
:remove_unique_constraint
|
55
|
+
]
|
56
|
+
},
|
57
|
+
{
|
58
|
+
header_comment: <<~COMMENT,
|
59
|
+
#
|
60
|
+
# Remove Foreign Keys
|
61
|
+
#
|
62
|
+
COMMENT
|
63
|
+
methods: [
|
64
|
+
:remove_foreign_key
|
65
|
+
]
|
66
|
+
},
|
67
|
+
{
|
68
|
+
header_comment: <<~COMMENT,
|
69
|
+
#
|
70
|
+
# Remove Primary Keys
|
71
|
+
#
|
72
|
+
COMMENT
|
73
|
+
methods: [
|
74
|
+
:remove_primary_key
|
75
|
+
]
|
76
|
+
},
|
77
|
+
{
|
78
|
+
header_comment: <<~COMMENT,
|
79
|
+
#
|
80
|
+
# Remove Indexes
|
81
|
+
#
|
82
|
+
COMMENT
|
83
|
+
methods: [
|
84
|
+
:remove_index,
|
85
|
+
:remove_index_comment
|
86
|
+
]
|
87
|
+
},
|
88
|
+
{
|
89
|
+
header_comment: <<~COMMENT,
|
90
|
+
#
|
91
|
+
# Remove Columns
|
92
|
+
#
|
93
|
+
COMMENT
|
94
|
+
methods: [
|
95
|
+
:remove_column
|
96
|
+
]
|
97
|
+
},
|
98
|
+
{
|
99
|
+
header_comment: <<~COMMENT,
|
100
|
+
#
|
101
|
+
# Remove Tables
|
102
|
+
#
|
103
|
+
COMMENT
|
104
|
+
break_after: true,
|
105
|
+
methods: [
|
106
|
+
:drop_table
|
107
|
+
]
|
108
|
+
},
|
109
|
+
{
|
110
|
+
# this is important enough to get it's own migration
|
111
|
+
break_before: true,
|
112
|
+
break_after: true,
|
113
|
+
header_comment: <<~COMMENT,
|
114
|
+
#
|
115
|
+
# Drop this schema
|
116
|
+
#
|
117
|
+
COMMENT
|
118
|
+
methods: [
|
119
|
+
:drop_schema
|
120
|
+
]
|
121
|
+
},
|
122
|
+
{
|
123
|
+
# this is important enough to get it's own migration
|
124
|
+
break_before: true,
|
125
|
+
break_after: true,
|
126
|
+
header_comment: <<~COMMENT,
|
127
|
+
#
|
128
|
+
# Create this schema
|
129
|
+
#
|
130
|
+
COMMENT
|
131
|
+
methods: [
|
132
|
+
:create_schema
|
133
|
+
]
|
134
|
+
},
|
135
|
+
{
|
136
|
+
header_comment: <<~COMMENT,
|
137
|
+
#
|
138
|
+
# Create Table
|
139
|
+
#
|
140
|
+
COMMENT
|
141
|
+
methods: [
|
142
|
+
:create_table
|
143
|
+
]
|
144
|
+
},
|
145
|
+
{
|
146
|
+
header_comment: <<~COMMENT,
|
147
|
+
#
|
148
|
+
# Tables
|
149
|
+
#
|
150
|
+
COMMENT
|
151
|
+
methods: [
|
152
|
+
:remove_table_comment,
|
153
|
+
:set_table_comment
|
154
|
+
]
|
155
|
+
},
|
156
|
+
{
|
157
|
+
header_comment: <<~COMMENT,
|
158
|
+
#
|
159
|
+
# Additional Columns
|
160
|
+
#
|
161
|
+
COMMENT
|
162
|
+
methods: [
|
163
|
+
:add_column
|
164
|
+
]
|
165
|
+
},
|
166
|
+
{
|
167
|
+
header_comment: <<~COMMENT,
|
168
|
+
#
|
169
|
+
# Update Columns
|
170
|
+
#
|
171
|
+
COMMENT
|
172
|
+
methods: [
|
173
|
+
:change_column,
|
174
|
+
:remove_column_comment,
|
175
|
+
:set_column_comment
|
176
|
+
]
|
177
|
+
},
|
178
|
+
{
|
179
|
+
header_comment: <<~COMMENT,
|
180
|
+
#
|
181
|
+
# Primary Key
|
182
|
+
#
|
183
|
+
COMMENT
|
184
|
+
methods: [
|
185
|
+
:add_primary_key
|
186
|
+
]
|
187
|
+
},
|
188
|
+
{
|
189
|
+
header_comment: <<~COMMENT,
|
190
|
+
#
|
191
|
+
# Indexes
|
192
|
+
#
|
193
|
+
COMMENT
|
194
|
+
methods: [
|
195
|
+
:add_index,
|
196
|
+
:set_index_comment
|
197
|
+
]
|
198
|
+
},
|
199
|
+
{
|
200
|
+
header_comment: <<~COMMENT,
|
201
|
+
#
|
202
|
+
# Foreign Keys
|
203
|
+
#
|
204
|
+
COMMENT
|
205
|
+
methods: [
|
206
|
+
:add_foreign_key,
|
207
|
+
:set_foreign_key_constraint_comment,
|
208
|
+
:remove_foreign_key_constraint_comment
|
209
|
+
]
|
210
|
+
},
|
211
|
+
{
|
212
|
+
header_comment: <<~COMMENT,
|
213
|
+
#
|
214
|
+
# Validations
|
215
|
+
#
|
216
|
+
COMMENT
|
217
|
+
methods: [
|
218
|
+
:add_validation,
|
219
|
+
:add_unique_constraint,
|
220
|
+
:set_validation_comment,
|
221
|
+
:remove_validation_comment,
|
222
|
+
:set_unique_constraint_comment,
|
223
|
+
:remove_unique_constraint_comment
|
224
|
+
]
|
225
|
+
},
|
226
|
+
{
|
227
|
+
header_comment: <<~COMMENT,
|
228
|
+
#
|
229
|
+
# Functions
|
230
|
+
#
|
231
|
+
COMMENT
|
232
|
+
methods: [
|
233
|
+
:create_function
|
234
|
+
]
|
235
|
+
},
|
236
|
+
{
|
237
|
+
header_comment: <<~COMMENT,
|
238
|
+
#
|
239
|
+
# Triggers
|
240
|
+
#
|
241
|
+
COMMENT
|
242
|
+
methods: [
|
243
|
+
:add_trigger,
|
244
|
+
:set_trigger_comment
|
245
|
+
]
|
246
|
+
},
|
247
|
+
{
|
248
|
+
header_comment: <<~COMMENT,
|
249
|
+
#
|
250
|
+
# Update Functions
|
251
|
+
#
|
252
|
+
COMMENT
|
253
|
+
methods: [
|
254
|
+
:update_function,
|
255
|
+
:set_function_comment
|
256
|
+
]
|
257
|
+
}
|
258
|
+
]
|
259
|
+
|
260
|
+
include Schema
|
261
|
+
include Table
|
262
|
+
include Column
|
263
|
+
include ForeignKeyConstraint
|
264
|
+
include Index
|
265
|
+
include PrimaryKey
|
266
|
+
include UniqueConstraint
|
267
|
+
include Validation
|
268
|
+
include Function
|
269
|
+
include Trigger
|
270
|
+
|
271
|
+
def initialize
|
272
|
+
@migrations = {}
|
273
|
+
end
|
274
|
+
|
275
|
+
# builds an array of migrations that can be used to create the provided schema
|
276
|
+
def migrations
|
277
|
+
final_migrations = {}
|
278
|
+
# an array of table names which have migrations, we group migrations for the same table together
|
279
|
+
@migrations.map do |schema_name, table_migrations|
|
280
|
+
schema_migrations = SchemaMigrations.new
|
281
|
+
# iterate through the tables which have migrations
|
282
|
+
table_migrations.map do |table_name, fragments|
|
283
|
+
# iterate through the structure object in order, and create the final migrations
|
284
|
+
STRUCTURE.each do |section|
|
285
|
+
# if this section requires a new migration, then end any current one
|
286
|
+
if section[:break_before]
|
287
|
+
schema_migrations.finalize
|
288
|
+
end
|
289
|
+
|
290
|
+
# add the header comment if we have a migration which matches one of the
|
291
|
+
# methods in this section
|
292
|
+
if (section[:methods] & fragments.keys).any?
|
293
|
+
header_fragment = Fragment.new nil, nil, section[:header_comment]
|
294
|
+
schema_migrations.add_fragment schema_name, table_name, :comment, header_fragment
|
295
|
+
end
|
296
|
+
|
297
|
+
# iterate through this sections methods in order and look
|
298
|
+
# for any that match the migrations we have
|
299
|
+
section[:methods].each do |method_name|
|
300
|
+
# if we have any migration fragments for this method then add them
|
301
|
+
fragments[method_name]&.each do |fragment|
|
302
|
+
schema_migrations.add_fragment schema_name, table_name, method_name, fragment
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
# if this section causes a new migration then end any current one
|
307
|
+
if section[:break_after]
|
308
|
+
schema_migrations.finalize
|
309
|
+
end
|
310
|
+
end
|
311
|
+
schema_migrations.finalize
|
312
|
+
end
|
313
|
+
final_migrations[schema_name] = schema_migrations.to_a
|
314
|
+
end
|
315
|
+
final_migrations
|
316
|
+
end
|
317
|
+
|
318
|
+
private
|
319
|
+
|
320
|
+
def supported_migration_method_names
|
321
|
+
@supported_migration_method_names ||= STRUCTURE.map { |s| s[:methods] }.flatten
|
322
|
+
end
|
323
|
+
|
324
|
+
def supported_migration_method? method_name
|
325
|
+
supported_migration_method_names.include? method_name
|
326
|
+
end
|
327
|
+
|
328
|
+
def add_migration schema_name, table_name, migration_method, object_name, code_comment, migration
|
329
|
+
raise ExpectedSymbolError, "Expected schema_name to be a symbol, got #{schema_name}" unless schema_name.is_a?(Symbol)
|
330
|
+
raise ExpectedSymbolError, "Expected table_name to be a symbol, got #{table_name}" unless schema_name.is_a?(Symbol)
|
331
|
+
|
332
|
+
unless supported_migration_method? migration_method
|
333
|
+
raise UnexpectedMigrationMethodNameError, "Expected migration_method to be a valid migrator method, got `#{migration_method}`"
|
334
|
+
end
|
335
|
+
|
336
|
+
final_migration = strip_empty_lines(migration).strip
|
337
|
+
fragment = Fragment.new(object_name, code_comment, final_migration)
|
338
|
+
|
339
|
+
# note, table_name can be nil, which is OK because nil is a valid
|
340
|
+
# key and we do want to group them all together
|
341
|
+
@migrations[schema_name] ||= {}
|
342
|
+
@migrations[schema_name][table_name] ||= {}
|
343
|
+
@migrations[schema_name][table_name][migration_method] ||= []
|
344
|
+
@migrations[schema_name][table_name][migration_method] << fragment
|
345
|
+
|
346
|
+
# return the newly created migration fragment
|
347
|
+
fragment
|
348
|
+
end
|
349
|
+
|
350
|
+
def indent multi_line_string
|
351
|
+
multi_line_string.gsub("\n", "\n ")
|
352
|
+
end
|
353
|
+
|
354
|
+
def strip_empty_lines multi_line_string
|
355
|
+
multi_line_string.gsub(/^\s*\n/, "")
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/functions.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DynamicMigrations
|
4
|
+
module Postgres
|
5
|
+
class Server
|
6
|
+
class Database
|
7
|
+
class Differences
|
8
|
+
class ToMigrations
|
9
|
+
module Schemas
|
10
|
+
module Functions
|
11
|
+
def process_functions schema_name, configuration_functions, database_functions
|
12
|
+
# process all the functions
|
13
|
+
function_names = (configuration_functions.keys + database_functions.keys).uniq
|
14
|
+
function_names.each do |function_name|
|
15
|
+
process_function schema_name, function_name, configuration_functions[function_name] || {}, database_functions[function_name] || {}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def process_function schema_name, function_name, configuration_function, database_function
|
20
|
+
# If the function exists in the configuration but not in the database
|
21
|
+
# then we have to create it.
|
22
|
+
if configuration_function[:exists] == true && database_function[:exists] == false
|
23
|
+
# a migration to create the function
|
24
|
+
function = @database.configured_schema(schema_name).function(function_name)
|
25
|
+
@generator.create_function function
|
26
|
+
|
27
|
+
# If the schema exists in the database but not in the configuration
|
28
|
+
# then we need to delete it.
|
29
|
+
elsif configuration_function[:exists] == false && database_function[:exists] == true
|
30
|
+
# a migration to create the function
|
31
|
+
function = @database.loaded_schema(schema_name).function(function_name)
|
32
|
+
@generator.drop_function function
|
33
|
+
|
34
|
+
# If the function exists in both the configuration and database representations
|
35
|
+
# but the definition is different then we need to update the definition.
|
36
|
+
elsif configuration_function[:definition][:matches] == false
|
37
|
+
function = @database.configured_schema(schema_name).function(function_name)
|
38
|
+
@generator.update_function function
|
39
|
+
# does the description also need to be updated
|
40
|
+
if configuration_function[:description][:matches] == false
|
41
|
+
# if the description was removed
|
42
|
+
if configuration_function[:description].nil?
|
43
|
+
@generator.remove_function_comment function
|
44
|
+
else
|
45
|
+
@generator.set_function_comment function
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# If the function exists in both the configuration and database representations
|
50
|
+
# but the description is different then we need to update the description.
|
51
|
+
elsif configuration_function[:description][:matches] == false
|
52
|
+
function = @database.configured_schema(schema_name).function(function_name)
|
53
|
+
# if the description was removed
|
54
|
+
if configuration_function[:description].nil?
|
55
|
+
@generator.remove_function_comment function
|
56
|
+
else
|
57
|
+
@generator.set_function_comment function
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DynamicMigrations
|
4
|
+
module Postgres
|
5
|
+
class Server
|
6
|
+
class Database
|
7
|
+
class Differences
|
8
|
+
class ToMigrations
|
9
|
+
module Schemas
|
10
|
+
module Tables
|
11
|
+
module Columns
|
12
|
+
def process_columns schema_name, table_name, configuration_columns, database_columns
|
13
|
+
# process all the columns
|
14
|
+
column_names = (configuration_columns.keys + database_columns.keys).uniq
|
15
|
+
column_names.each do |column_name|
|
16
|
+
process_column schema_name, table_name, column_name, configuration_columns[column_name] || {}, database_columns[column_name] || {}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_column schema_name, table_name, column_name, configuration_column, database_column
|
21
|
+
# If the column exists in the configuration but not in the database
|
22
|
+
# then we have to create it.
|
23
|
+
if configuration_column[:exists] == true && database_column[:exists] == false
|
24
|
+
# a migration to create the column
|
25
|
+
column = @database.configured_schema(schema_name).table(table_name).column(column_name)
|
26
|
+
@generator.add_column column
|
27
|
+
|
28
|
+
# If the schema exists in the database but not in the configuration
|
29
|
+
# then we need to delete it.
|
30
|
+
elsif configuration_column[:exists] == false && database_column[:exists] == true
|
31
|
+
# a migration to create the column
|
32
|
+
column = @database.loaded_schema(schema_name).table(table_name).column(column_name)
|
33
|
+
@generator.remove_column column
|
34
|
+
|
35
|
+
# If the column exists in both the configuration and database representations
|
36
|
+
# but the definition (except description, which is handled seeprately below) is different
|
37
|
+
# then we need to update the definition.
|
38
|
+
elsif configuration_column.except(:exists, :description).filter { |name, attributes| attributes[:matches] == false }.any?
|
39
|
+
# update the column
|
40
|
+
column = @database.configured_schema(schema_name).table(table_name).column(column_name)
|
41
|
+
@generator.change_column column
|
42
|
+
# does the description also need to be updated
|
43
|
+
if configuration_column[:description][:matches] == false
|
44
|
+
# if the description was removed
|
45
|
+
if configuration_column[:description].nil?
|
46
|
+
@generator.remove_column_comment column
|
47
|
+
else
|
48
|
+
@generator.set_column_comment column
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# If the column exists in both the configuration and database representations
|
53
|
+
# but the description is different then we need to update the description.
|
54
|
+
elsif configuration_column[:description][:matches] == false
|
55
|
+
column = @database.configured_schema(schema_name).table(table_name).column(column_name)
|
56
|
+
# if the description was removed
|
57
|
+
if configuration_column[:description].nil?
|
58
|
+
@generator.remove_column_comment column
|
59
|
+
else
|
60
|
+
@generator.set_column_comment column
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DynamicMigrations
|
4
|
+
module Postgres
|
5
|
+
class Server
|
6
|
+
class Database
|
7
|
+
class Differences
|
8
|
+
class ToMigrations
|
9
|
+
module Schemas
|
10
|
+
module Tables
|
11
|
+
module ForeignKeyConstraints
|
12
|
+
def process_foreign_key_constraints schema_name, table_name, configuration_foreign_key_constraints, database_foreign_key_constraints
|
13
|
+
# process all the foreign_key_constraints
|
14
|
+
foreign_key_constraint_names = (configuration_foreign_key_constraints.keys + database_foreign_key_constraints.keys).uniq
|
15
|
+
foreign_key_constraint_names.each do |foreign_key_constraint_name|
|
16
|
+
process_foreign_key_constraint schema_name, table_name, foreign_key_constraint_name, configuration_foreign_key_constraints[foreign_key_constraint_name] || {}, database_foreign_key_constraints[foreign_key_constraint_name] || {}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_foreign_key_constraint schema_name, table_name, foreign_key_constraint_name, configuration_foreign_key_constraint, database_foreign_key_constraint
|
21
|
+
# If the foreign_key_constraint exists in the configuration but not in the database
|
22
|
+
# then we have to create it.
|
23
|
+
if configuration_foreign_key_constraint[:exists] == true && database_foreign_key_constraint[:exists] == false
|
24
|
+
# a migration to create the foreign_key_constraint
|
25
|
+
foreign_key_constraint = @database.configured_schema(schema_name).table(table_name).foreign_key_constraint(foreign_key_constraint_name)
|
26
|
+
@generator.add_foreign_key_constraint foreign_key_constraint
|
27
|
+
|
28
|
+
# If the schema exists in the database but not in the configuration
|
29
|
+
# then we need to delete it.
|
30
|
+
elsif configuration_foreign_key_constraint[:exists] == false && database_foreign_key_constraint[:exists] == true
|
31
|
+
# a migration to create the foreign_key_constraint
|
32
|
+
foreign_key_constraint = @database.loaded_schema(schema_name).table(table_name).foreign_key_constraint(foreign_key_constraint_name)
|
33
|
+
@generator.remove_foreign_key_constraint foreign_key_constraint
|
34
|
+
|
35
|
+
# If the foreign_key_constraint exists in both the configuration and database representations
|
36
|
+
# but the definition (except description, which is handled seeprately below) is different
|
37
|
+
# then we need to update the definition.
|
38
|
+
elsif configuration_foreign_key_constraint.except(:exists, :description).filter { |name, attributes| attributes[:matches] == false }.any?
|
39
|
+
# recreate the foreign_key_constraint
|
40
|
+
original_foreign_key_constraint = @database.loaded_schema(schema_name).table(table_name).foreign_key_constraint(foreign_key_constraint_name)
|
41
|
+
updated_foreign_key_constraint = @database.configured_schema(schema_name).table(table_name).foreign_key_constraint(foreign_key_constraint_name)
|
42
|
+
@generator.recreate_foreign_key_constraint original_foreign_key_constraint, updated_foreign_key_constraint
|
43
|
+
# does the description also need to be updated
|
44
|
+
if configuration_foreign_key_constraint[:description][:matches] == false
|
45
|
+
# if the description was removed
|
46
|
+
if configuration_foreign_key_constraint[:description].nil?
|
47
|
+
@generator.remove_foreign_key_constraint_comment foreign_key_constraint
|
48
|
+
else
|
49
|
+
@generator.set_foreign_key_constraint_comment foreign_key_constraint
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# If the foreign_key_constraint exists in both the configuration and database representations
|
54
|
+
# but the description is different then we need to update the description.
|
55
|
+
elsif configuration_foreign_key_constraint[:description][:matches] == false
|
56
|
+
foreign_key_constraint = @database.configured_schema(schema_name).table(table_name).foreign_key_constraint(foreign_key_constraint_name)
|
57
|
+
# if the description was removed
|
58
|
+
if configuration_foreign_key_constraint[:description].nil?
|
59
|
+
@generator.remove_foreign_key_constraint_comment foreign_key_constraint
|
60
|
+
else
|
61
|
+
@generator.set_foreign_key_constraint_comment foreign_key_constraint
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DynamicMigrations
|
4
|
+
module Postgres
|
5
|
+
class Server
|
6
|
+
class Database
|
7
|
+
class Differences
|
8
|
+
class ToMigrations
|
9
|
+
module Schemas
|
10
|
+
module Tables
|
11
|
+
module Indexes
|
12
|
+
def process_indexes schema_name, table_name, configuration_indexes, database_indexes
|
13
|
+
# process all the indexes
|
14
|
+
index_names = (configuration_indexes.keys + database_indexes.keys).uniq
|
15
|
+
index_names.each do |index_name|
|
16
|
+
process_index schema_name, table_name, index_name, configuration_indexes[index_name] || {}, database_indexes[index_name] || {}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_index schema_name, table_name, index_name, configuration_index, database_index
|
21
|
+
# If the index exists in the configuration but not in the database
|
22
|
+
# then we have to create it.
|
23
|
+
if configuration_index[:exists] == true && database_index[:exists] == false
|
24
|
+
# a migration to create the index
|
25
|
+
index = @database.configured_schema(schema_name).table(table_name).index(index_name)
|
26
|
+
@generator.add_index index
|
27
|
+
|
28
|
+
# If the schema exists in the database but not in the configuration
|
29
|
+
# then we need to delete it.
|
30
|
+
elsif configuration_index[:exists] == false && database_index[:exists] == true
|
31
|
+
# a migration to create the index
|
32
|
+
index = @database.loaded_schema(schema_name).table(table_name).index(index_name)
|
33
|
+
@generator.remove_index index
|
34
|
+
|
35
|
+
# If the index exists in both the configuration and database representations
|
36
|
+
# but the definition (except description, which is handled seeprately below) is different
|
37
|
+
# then we need to update the definition.
|
38
|
+
elsif configuration_index.except(:exists, :description).filter { |name, attributes| attributes[:matches] == false }.any?
|
39
|
+
# rebild the index
|
40
|
+
original_index = @database.loaded_schema(schema_name).table(table_name).index(index_name)
|
41
|
+
updated_index = @database.configured_schema(schema_name).table(table_name).index(index_name)
|
42
|
+
@generator.recreate_index original_index, updated_index
|
43
|
+
# does the description also need to be updated
|
44
|
+
if configuration_index[:description][:matches] == false
|
45
|
+
# if the description was removed
|
46
|
+
if configuration_index[:description].nil?
|
47
|
+
@generator.remove_index_comment index
|
48
|
+
else
|
49
|
+
@generator.set_index_comment index
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# If the index exists in both the configuration and database representations
|
54
|
+
# but the description is different then we need to update the description.
|
55
|
+
elsif configuration_index[:description][:matches] == false
|
56
|
+
index = @database.configured_schema(schema_name).table(table_name).index(index_name)
|
57
|
+
# if the description was removed
|
58
|
+
if configuration_index[:description].nil?
|
59
|
+
@generator.remove_index_comment index
|
60
|
+
else
|
61
|
+
@generator.set_index_comment index
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|