dynamic_migrations 2.1.0 → 3.0.0
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 +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
|