dynamic_migrations 3.6.15 → 3.7.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 +37 -0
- data/lib/dynamic_migrations/active_record/migrators/primary_key.rb +21 -0
- data/lib/dynamic_migrations/active_record/migrators.rb +1 -0
- data/lib/dynamic_migrations/postgres/generator/primary_key.rb +32 -0
- data/lib/dynamic_migrations/postgres/generator/table.rb +20 -4
- data/lib/dynamic_migrations/postgres/generator/table_migration.rb +1 -1
- data/lib/dynamic_migrations/postgres/generator/validation.rb +0 -4
- data/lib/dynamic_migrations/postgres/generator/validation_template_base.rb +5 -3
- data/lib/dynamic_migrations/postgres/generator.rb +4 -5
- data/lib/dynamic_migrations/postgres/server/database/connection.rb +3 -1
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/functions.rb +1 -1
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/foreign_key_constraints.rb +2 -2
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/indexes.rb +2 -2
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/triggers.rb +2 -2
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/unique_constraints.rb +2 -2
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/validations.rb +2 -2
- data/lib/dynamic_migrations/postgres/server/database/differences.rb +3 -3
- data/lib/dynamic_migrations/postgres/server/database/enums_loader.rb +1 -1
- data/lib/dynamic_migrations/postgres/server/database/keys_and_unique_constraints_loader.rb +8 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/function.rb +51 -2
- data/lib/dynamic_migrations/postgres/server/database/schema/table/column.rb +29 -2
- data/lib/dynamic_migrations/postgres/server/database/schema/table/foreign_key_constraint.rb +4 -7
- data/lib/dynamic_migrations/postgres/server/database/schema/table/foreign_key_constraints.rb +5 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/table/trigger.rb +72 -6
- data/lib/dynamic_migrations/postgres/server/database/schema/table/validation.rb +95 -12
- data/lib/dynamic_migrations/postgres/server/database/schema/table/validations.rb +1 -1
- data/lib/dynamic_migrations/postgres/server/database/schema/table.rb +2 -0
- data/lib/dynamic_migrations/postgres/server/database/structure_loader.rb +9 -1
- data/lib/dynamic_migrations/postgres/server/database/triggers_and_functions_loader.rb +4 -3
- data/lib/dynamic_migrations/postgres/server/database/validations_loader.rb +42 -29
- data/lib/dynamic_migrations/postgres/server/database.rb +6 -0
- data/lib/dynamic_migrations/version.rb +1 -1
- data/lib/dynamic_migrations.rb +1 -0
- data/sig/dynamic_migrations/active_record/migrators/primary_key.rbs +18 -0
- data/sig/dynamic_migrations/postgres/generator/primary_key.rbs +2 -0
- data/sig/dynamic_migrations/postgres/generator/table.rbs +2 -0
- data/sig/dynamic_migrations/postgres/generator/validation_template_base.rbs +7 -7
- data/sig/dynamic_migrations/postgres/generator.rbs +1 -1
- data/sig/dynamic_migrations/postgres/server/database/connection.rbs +1 -1
- data/sig/dynamic_migrations/postgres/server/database/keys_and_unique_constraints_loader.rbs +1 -0
- data/sig/dynamic_migrations/postgres/server/database/schema/enum.rbs +2 -2
- data/sig/dynamic_migrations/postgres/server/database/schema/enums.rbs +1 -1
- data/sig/dynamic_migrations/postgres/server/database/schema/function.rbs +9 -0
- data/sig/dynamic_migrations/postgres/server/database/schema/table/column.rbs +4 -0
- data/sig/dynamic_migrations/postgres/server/database/schema/table/foreign_key_constraint.rbs +0 -3
- data/sig/dynamic_migrations/postgres/server/database/schema/table/foreign_key_constraints.rbs +1 -0
- data/sig/dynamic_migrations/postgres/server/database/schema/table/trigger.rbs +9 -0
- data/sig/dynamic_migrations/postgres/server/database/schema/table/validation.rbs +9 -1
- data/sig/dynamic_migrations/postgres/server/database/schema/table/validations.rbs +1 -1
- data/sig/dynamic_migrations/postgres/server/database/schema/table.rbs +1 -0
- data/sig/dynamic_migrations/postgres/server/database/structure_loader.rbs +1 -0
- data/sig/dynamic_migrations/postgres/server/database/validations_loader.rbs +1 -0
- data/sig/dynamic_migrations/postgres/server/database.rbs +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22fd29f59924e820da26858d1cf6caf04b03985ecc2fafd5f49205f5a0c2b34e
|
4
|
+
data.tar.gz: a8164cec22385ede8954df04e86c866bdb9d1ae4d420ba9107353f96e1a525e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec4eb2339d1ce110393eae8747c9e2aabee426d58a4e3caca8e01b7dd48ddfe99291ab903c9c7ba2e474a8b509a7185850132c1934f512c8ebe710e763243ba9
|
7
|
+
data.tar.gz: 50076bbed1405f301476ac49f0886207f9fde401c47af062fafa4095139cd3287699b8054cac4583b97422180f8fb3be935d94ac87b1ccd071a293972811eec7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,42 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [3.7.0](https://github.com/craigulliott/dynamic_migrations/compare/v3.6.16...v3.7.0) (2023-09-27)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* providing access to foreign key constraints from both sides of the association ([48dcf1c](https://github.com/craigulliott/dynamic_migrations/commit/48dcf1cd4cdb23bc37da3e47b00f8007b8bc0f8a))
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* allowing foreign keys to the same table because they are valid and sometimes useful ([0566384](https://github.com/craigulliott/dynamic_migrations/commit/0566384a4cfeade757d9806059035477f7c41ee2))
|
14
|
+
* lazy loading column names for validations when they were configured with a nil value for columns ([439200e](https://github.com/craigulliott/dynamic_migrations/commit/439200efdedf74dddc852bf9bd35e81c1f6b4336))
|
15
|
+
* providing convenience method to retrieve columns base data type from array columns ([cd3d9bf](https://github.com/craigulliott/dynamic_migrations/commit/cd3d9bf06682335a890d9b11133d397d7bcd50af))
|
16
|
+
* semi colon at the end of function definitions is now optional ([ca9b3aa](https://github.com/craigulliott/dynamic_migrations/commit/ca9b3aa04da23605ff61b2ec14baed927145d2c3))
|
17
|
+
* structure loader was not identifying enums properly ([95276d3](https://github.com/craigulliott/dynamic_migrations/commit/95276d33f98f41eca9a9467bb6abeb458a37f16b))
|
18
|
+
|
19
|
+
## [3.6.16](https://github.com/craigulliott/dynamic_migrations/compare/v3.6.15...v3.6.16) (2023-09-16)
|
20
|
+
|
21
|
+
|
22
|
+
### Bug Fixes
|
23
|
+
|
24
|
+
* adding convenience method to call all three cache rebuild methods at once ([287a73d](https://github.com/craigulliott/dynamic_migrations/commit/287a73d96c4bfa303150e3c1f65cb514569c03b6))
|
25
|
+
* allowing functions and triggers to be in different schemas ([6df3377](https://github.com/craigulliott/dynamic_migrations/commit/6df337780a9a6b6815776a1f65afd3c8325a00fd))
|
26
|
+
* always sorting column names on validations so that they match the structure loader ([3e7e646](https://github.com/craigulliott/dynamic_migrations/commit/3e7e646e834140bcce74e357e6e84c3996b9525e))
|
27
|
+
* corrected bug where we passed nil as trigger for updating trigger comment ([c7a3677](https://github.com/craigulliott/dynamic_migrations/commit/c7a3677694130125d581f8f68e56865644d5c442))
|
28
|
+
* enum values should be strings not symbols ([080e5da](https://github.com/craigulliott/dynamic_migrations/commit/080e5daaeefa1504912e2cd4f3482af82890ee08))
|
29
|
+
* fixed bug where constraint was duplicated due to pg check_constraints table allowing duplicates ([471b6f8](https://github.com/craigulliott/dynamic_migrations/commit/471b6f82fc01770e63f657a12d01d18011c69f07))
|
30
|
+
* fixing whitespace with create table migrator syntax ([5bf1a7f](https://github.com/craigulliott/dynamic_migrations/commit/5bf1a7f9f337883ca677b1a2015dd0c41a27442c))
|
31
|
+
* generating materialized views automatically when refreshing them but they don't yet exist ([471b6f8](https://github.com/craigulliott/dynamic_migrations/commit/471b6f82fc01770e63f657a12d01d18011c69f07))
|
32
|
+
* handling default comments via templates ([3e7e646](https://github.com/craigulliott/dynamic_migrations/commit/3e7e646e834140bcce74e357e6e84c3996b9525e))
|
33
|
+
* methods to refresh caches because this needs to be performed before and after migrations are generated and run ([ab72670](https://github.com/craigulliott/dynamic_migrations/commit/ab72670e5fc7d379aed86cf72be956cdc39ed620))
|
34
|
+
* more strictly validating column types data types which use enums ([3e7e646](https://github.com/craigulliott/dynamic_migrations/commit/3e7e646e834140bcce74e357e6e84c3996b9525e))
|
35
|
+
* removed code which was stripping empty lines from migrations, but inadvertently removing empty lines from within SQL statements ([3e7e646](https://github.com/craigulliott/dynamic_migrations/commit/3e7e646e834140bcce74e357e6e84c3996b9525e))
|
36
|
+
* updating action order so that its sequential based on the event manipulation type (update, insert etc.) ([3e7e646](https://github.com/craigulliott/dynamic_migrations/commit/3e7e646e834140bcce74e357e6e84c3996b9525e))
|
37
|
+
* validations should not end with a semicolon ([9e2cc8e](https://github.com/craigulliott/dynamic_migrations/commit/9e2cc8ebf1c6da8c4741c5257c6567fc9f3668a7))
|
38
|
+
* various fixes after running a variety of real migrations from platformer ([301db01](https://github.com/craigulliott/dynamic_migrations/commit/301db01397f1cb16c6c0e08e9e8c69e1f3ec799e))
|
39
|
+
|
3
40
|
## [3.6.15](https://github.com/craigulliott/dynamic_migrations/compare/v3.6.14...v3.6.15) (2023-09-14)
|
4
41
|
|
5
42
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DynamicMigrations
|
2
|
+
module ActiveRecord
|
3
|
+
module Migrators
|
4
|
+
module PrimaryKey
|
5
|
+
# add a comment to the primary_key
|
6
|
+
def set_primary_key_comment table_name, primary_key_name, comment
|
7
|
+
execute <<~SQL
|
8
|
+
COMMENT ON CONSTRAINT #{primary_key_name} ON #{schema_name}.#{table_name} IS #{quote comment};
|
9
|
+
SQL
|
10
|
+
end
|
11
|
+
|
12
|
+
# remove a primary_key comment
|
13
|
+
def remove_primary_key_comment table_name, primary_key_name
|
14
|
+
execute <<~SQL
|
15
|
+
COMMENT ON CONSTRAINT #{primary_key_name} ON #{schema_name}.#{table_name} IS NULL;
|
16
|
+
SQL
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -59,6 +59,38 @@ module DynamicMigrations
|
|
59
59
|
# return the new fragments (the main reason to return them here is for the specs)
|
60
60
|
[removal_fragment, recreation_fragment]
|
61
61
|
end
|
62
|
+
|
63
|
+
# add a comment to a primary_key
|
64
|
+
def set_primary_key_comment primary_key, code_comment = nil
|
65
|
+
description = primary_key.description
|
66
|
+
|
67
|
+
if description.nil?
|
68
|
+
raise MissingDescriptionError, "Missing required description for primary_key `#{primary_key.name}` in table `#{primary_key.table.schema.name}.#{primary_key.table.name}`"
|
69
|
+
end
|
70
|
+
|
71
|
+
add_fragment schema: primary_key.table.schema,
|
72
|
+
table: primary_key.table,
|
73
|
+
migration_method: :set_primary_key_comment,
|
74
|
+
object: primary_key,
|
75
|
+
code_comment: code_comment,
|
76
|
+
migration: <<~RUBY
|
77
|
+
set_primary_key_comment :#{primary_key.table.name}, :#{primary_key.name}, <<~COMMENT
|
78
|
+
#{indent description}
|
79
|
+
COMMENT
|
80
|
+
RUBY
|
81
|
+
end
|
82
|
+
|
83
|
+
# remove the comment from a primary_key
|
84
|
+
def remove_primary_key_comment primary_key, code_comment = nil
|
85
|
+
add_fragment schema: primary_key.table.schema,
|
86
|
+
table: primary_key.table,
|
87
|
+
migration_method: :remove_primary_key_comment,
|
88
|
+
object: primary_key,
|
89
|
+
code_comment: code_comment,
|
90
|
+
migration: <<~RUBY
|
91
|
+
remove_primary_key_comment :#{primary_key.table.name}, :#{primary_key.name}
|
92
|
+
RUBY
|
93
|
+
end
|
62
94
|
end
|
63
95
|
end
|
64
96
|
end
|
@@ -93,10 +93,20 @@ module DynamicMigrations
|
|
93
93
|
lines = []
|
94
94
|
timestamps = []
|
95
95
|
columns.each do |column|
|
96
|
-
# skip the :id
|
97
|
-
|
98
|
-
|
96
|
+
# skip creating the :id column as it is handled by the table_options
|
97
|
+
# method, but add the comment if there is one
|
98
|
+
if column.name == :id
|
99
|
+
unless column.description.nil?
|
100
|
+
set_column_comment column
|
101
|
+
end
|
102
|
+
next
|
103
|
+
end
|
104
|
+
# skip creating the :created_at and :updated_at column as it is handled
|
105
|
+
# by the table_options method, but add the comments
|
99
106
|
if column.name == :created_at || column.name == :updated_at
|
107
|
+
unless column.description.nil?
|
108
|
+
set_column_comment column
|
109
|
+
end
|
100
110
|
timestamps << column.name
|
101
111
|
next
|
102
112
|
end
|
@@ -115,7 +125,7 @@ module DynamicMigrations
|
|
115
125
|
if column.description.nil?
|
116
126
|
raise NoTableColumnCommentError, "Refusing to generate create_table migration, no description was provided for `#{column.table.schema.name}`.`#{column.table.name}` column `#{column.name}`"
|
117
127
|
end
|
118
|
-
options[:comment] = <<~RUBY
|
128
|
+
options[:comment] = <<~RUBY.strip
|
119
129
|
<<~COMMENT
|
120
130
|
#{indent column.description}
|
121
131
|
COMMENT
|
@@ -163,6 +173,12 @@ module DynamicMigrations
|
|
163
173
|
elsif pk_column_names.count > 1
|
164
174
|
options << "primary_key: [:#{pk_column_names.join(", :")}]"
|
165
175
|
end
|
176
|
+
|
177
|
+
# if the primary key has a description, then add it seperately
|
178
|
+
if table.primary_key.description
|
179
|
+
set_primary_key_comment table.primary_key
|
180
|
+
end
|
181
|
+
|
166
182
|
end
|
167
183
|
|
168
184
|
options << "comment: table_comment"
|
@@ -17,7 +17,7 @@ module DynamicMigrations
|
|
17
17
|
add_structure_template [:remove_table_comment, :set_table_comment], "Tables"
|
18
18
|
add_structure_template [:add_column], "Additional Columns"
|
19
19
|
add_structure_template [:change_column, :remove_column_comment, :set_column_comment], "Update Columns"
|
20
|
-
add_structure_template [:add_primary_key], "Primary Key"
|
20
|
+
add_structure_template [:add_primary_key, :set_primary_key_comment, :remove_primary_key_comment], "Primary Key"
|
21
21
|
add_structure_template [:add_index, :set_index_comment], "Indexes"
|
22
22
|
add_structure_template [:add_foreign_key, :set_foreign_key_constraint_comment, :remove_foreign_key_constraint_comment], "Foreign Keys"
|
23
23
|
add_structure_template [:add_validation, :add_unique_constraint, :set_validation_comment, :remove_validation_comment, :set_unique_constraint_comment, :remove_unique_constraint_comment], "Validations"
|
@@ -57,10 +57,6 @@ module DynamicMigrations
|
|
57
57
|
options_syntax = options.map { |k, v| "#{k}: #{v}" }.join(", ")
|
58
58
|
|
59
59
|
validation_sql = validation.check_clause.strip
|
60
|
-
# ensure that the validation ends with a semicolon
|
61
|
-
unless validation_sql.end_with? ";"
|
62
|
-
validation_sql << ";"
|
63
|
-
end
|
64
60
|
|
65
61
|
add_fragment schema: validation.table.schema,
|
66
62
|
table: validation.table,
|
@@ -46,14 +46,16 @@ module DynamicMigrations
|
|
46
46
|
matches[:value]
|
47
47
|
end
|
48
48
|
|
49
|
-
def name_and_description_options_string default_name
|
49
|
+
def name_and_description_options_string default_name, default_comment = nil
|
50
50
|
options = {}
|
51
51
|
# we only need to provide a name if it is different than the default
|
52
52
|
unless @validation.name == default_name
|
53
53
|
options[:name] = @validation.name
|
54
54
|
end
|
55
|
-
# only provide a comment if it is not nil
|
56
|
-
|
55
|
+
# only provide a comment if it is not nil and not equal to the provided
|
56
|
+
# default_comment, if it is the same as the default then we wont want to show
|
57
|
+
# it in the migration files
|
58
|
+
unless @validation.description.nil? || @validation.description == default_comment
|
57
59
|
options[:comment] = <<~RUBY
|
58
60
|
<<~COMMENT
|
59
61
|
#{indent @validation.description || ""}
|
@@ -243,9 +243,8 @@ module DynamicMigrations
|
|
243
243
|
# This method is called from within the various modules which are included to this class.
|
244
244
|
# It locally stores all the fragments which will later be organized into different migrations.
|
245
245
|
def add_fragment migration_method:, object:, migration:, schema: nil, table: nil, code_comment: nil, dependent_table: nil, dependent_function: nil, dependent_enum: nil
|
246
|
-
# Remove any empty lines and whitespace from the beginning or the end of the migration
|
247
|
-
|
248
|
-
final_migration = strip_empty_lines(migration).strip
|
246
|
+
# Remove any empty lines and whitespace from the beginning or the end of the migration
|
247
|
+
final_migration = trim_lines migration
|
249
248
|
fragment = Fragment.new(schema&.name, table&.name, migration_method, object.name, code_comment, final_migration)
|
250
249
|
|
251
250
|
if dependent_table
|
@@ -272,8 +271,8 @@ module DynamicMigrations
|
|
272
271
|
multi_line_string.gsub("\n", "\n#{spaces}")
|
273
272
|
end
|
274
273
|
|
275
|
-
def
|
276
|
-
|
274
|
+
def trim_lines string
|
275
|
+
string.split("\n").map(&:rstrip).join("\n")
|
277
276
|
end
|
278
277
|
end
|
279
278
|
end
|
@@ -42,10 +42,12 @@ module DynamicMigrations
|
|
42
42
|
# perform work with the connection
|
43
43
|
# todo: `yield connection` would have been preferred, but rbs/steep doesnt understand that syntax
|
44
44
|
if block.is_a? Proc
|
45
|
-
block.call connection
|
45
|
+
result = block.call connection
|
46
46
|
end
|
47
47
|
# close the connection
|
48
48
|
disconnect
|
49
|
+
# return whever was returned from within the block
|
50
|
+
result
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/functions.rb
CHANGED
@@ -33,7 +33,7 @@ module DynamicMigrations
|
|
33
33
|
|
34
34
|
# If the function exists in both the configuration and database representations
|
35
35
|
# but the definition is different then we need to update the definition.
|
36
|
-
elsif configuration_function[:
|
36
|
+
elsif configuration_function[:normalized_definition][:matches] == false
|
37
37
|
function = @database.configured_schema(schema_name).function(function_name)
|
38
38
|
@generator.update_function function
|
39
39
|
# does the description also need to be updated
|
@@ -44,9 +44,9 @@ module DynamicMigrations
|
|
44
44
|
if configuration_foreign_key_constraint[:description][:matches] == false
|
45
45
|
# if the description was removed
|
46
46
|
if configuration_foreign_key_constraint[:description].nil?
|
47
|
-
@generator.remove_foreign_key_constraint_comment
|
47
|
+
@generator.remove_foreign_key_constraint_comment updated_foreign_key_constraint
|
48
48
|
else
|
49
|
-
@generator.set_foreign_key_constraint_comment
|
49
|
+
@generator.set_foreign_key_constraint_comment updated_foreign_key_constraint
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -44,9 +44,9 @@ module DynamicMigrations
|
|
44
44
|
if configuration_index[:description][:matches] == false
|
45
45
|
# if the description was removed
|
46
46
|
if configuration_index[:description].nil?
|
47
|
-
@generator.remove_index_comment
|
47
|
+
@generator.remove_index_comment updated_index
|
48
48
|
else
|
49
|
-
@generator.set_index_comment
|
49
|
+
@generator.set_index_comment updated_index
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -44,9 +44,9 @@ module DynamicMigrations
|
|
44
44
|
if configuration_trigger[:description][:matches] == false
|
45
45
|
# if the description was removed
|
46
46
|
if configuration_trigger[:description].nil?
|
47
|
-
@generator.remove_trigger_comment
|
47
|
+
@generator.remove_trigger_comment updated_trigger
|
48
48
|
else
|
49
|
-
@generator.set_trigger_comment
|
49
|
+
@generator.set_trigger_comment updated_trigger
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -44,9 +44,9 @@ module DynamicMigrations
|
|
44
44
|
if configuration_unique_constraint[:description][:matches] == false
|
45
45
|
# if the description was removed
|
46
46
|
if configuration_unique_constraint[:description].nil?
|
47
|
-
@generator.remove_unique_constraint_comment
|
47
|
+
@generator.remove_unique_constraint_comment updated_unique_constraint
|
48
48
|
else
|
49
|
-
@generator.set_unique_constraint_comment
|
49
|
+
@generator.set_unique_constraint_comment updated_unique_constraint
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -44,9 +44,9 @@ module DynamicMigrations
|
|
44
44
|
if configuration_validation[:description][:matches] == false
|
45
45
|
# if the description was removed
|
46
46
|
if configuration_validation[:description].nil?
|
47
|
-
@generator.remove_validation_comment
|
47
|
+
@generator.remove_validation_comment updated_validation
|
48
48
|
else
|
49
|
-
@generator.set_validation_comment
|
49
|
+
@generator.set_validation_comment updated_validation
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -172,7 +172,7 @@ module DynamicMigrations
|
|
172
172
|
# the base functions
|
173
173
|
functions.each do |function_name, function|
|
174
174
|
result[function_name] = compare_record function, comparison_functions[function_name], [
|
175
|
-
:
|
175
|
+
:normalized_definition,
|
176
176
|
:description
|
177
177
|
]
|
178
178
|
end
|
@@ -249,7 +249,7 @@ module DynamicMigrations
|
|
249
249
|
:action_timing,
|
250
250
|
:event_manipulation,
|
251
251
|
:action_order,
|
252
|
-
:
|
252
|
+
:normalized_action_condition,
|
253
253
|
:parameters,
|
254
254
|
:action_orientation,
|
255
255
|
:action_reference_old_table,
|
@@ -332,7 +332,7 @@ module DynamicMigrations
|
|
332
332
|
validations.each do |name, validation|
|
333
333
|
# compare this validation to the equivilent in the comparison list
|
334
334
|
result[name] = compare_record validation, comparison_validations[name], [
|
335
|
-
:
|
335
|
+
:normalized_check_clause,
|
336
336
|
:column_names,
|
337
337
|
:description,
|
338
338
|
:deferrable,
|
@@ -22,7 +22,7 @@ module DynamicMigrations
|
|
22
22
|
rows.each do |row|
|
23
23
|
schema_name = row["schema_name"].to_sym
|
24
24
|
enum_name = row["enum_name"].to_sym
|
25
|
-
enum_value = row["enum_value"]
|
25
|
+
enum_value = row["enum_value"]
|
26
26
|
|
27
27
|
schema = schemas[schema_name] ||= {}
|
28
28
|
enum = schema[enum_name] ||= {
|
@@ -99,6 +99,14 @@ module DynamicMigrations
|
|
99
99
|
SQL
|
100
100
|
end
|
101
101
|
|
102
|
+
def refresh_database_keys_and_unique_constraints_cache
|
103
|
+
connection.exec(<<~SQL)
|
104
|
+
REFRESH MATERIALIZED VIEW public.dynamic_migrations_keys_and_unique_constraints_cache
|
105
|
+
SQL
|
106
|
+
rescue PG::UndefinedTable
|
107
|
+
create_database_keys_and_unique_constraints_cache
|
108
|
+
end
|
109
|
+
|
102
110
|
# fetch all required data from the database and build and return a
|
103
111
|
# useful hash representing the keys and indexes of your database
|
104
112
|
def fetch_keys_and_unique_constraints
|
@@ -13,6 +13,9 @@ module DynamicMigrations
|
|
13
13
|
class ExpectedDefinitionError < StandardError
|
14
14
|
end
|
15
15
|
|
16
|
+
class UnnormalizableDefinitionError < StandardError
|
17
|
+
end
|
18
|
+
|
16
19
|
attr_reader :schema
|
17
20
|
attr_reader :name
|
18
21
|
attr_reader :definition
|
@@ -31,7 +34,7 @@ module DynamicMigrations
|
|
31
34
|
raise ExpectedSymbolError, name unless name.is_a? Symbol
|
32
35
|
@name = name
|
33
36
|
|
34
|
-
unless definition.is_a?(String) && definition.strip != "" && definition.strip.end_with?("END;")
|
37
|
+
unless definition.is_a?(String) && definition.strip != "" && definition.strip.end_with?("END;", "END")
|
35
38
|
raise ExpectedDefinitionError, "Definition must be a string, and end with `END;`. Definition provided:\n#{definition}"
|
36
39
|
end
|
37
40
|
@definition = definition.strip
|
@@ -59,9 +62,55 @@ module DynamicMigrations
|
|
59
62
|
|
60
63
|
def differences_descriptions other_function
|
61
64
|
method_differences_descriptions other_function, [
|
62
|
-
:
|
65
|
+
:normalized_definition
|
63
66
|
]
|
64
67
|
end
|
68
|
+
|
69
|
+
# temporarily create a function in postgres and fetch the actual
|
70
|
+
# normalized definition directly from the database
|
71
|
+
def normalized_definition
|
72
|
+
# no need to normalize definitions which originated from the database
|
73
|
+
if from_database?
|
74
|
+
definition
|
75
|
+
else
|
76
|
+
@normalized_definition ||= fetch_normalized_definition
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def fetch_normalized_definition
|
83
|
+
fn_def = schema.database.with_connection do |connection|
|
84
|
+
# wrapped in a transaction just in case something here fails, because
|
85
|
+
# we don't want the function to be persisted
|
86
|
+
connection.exec("BEGIN")
|
87
|
+
|
88
|
+
# create a temporary function, from which we will fetch the normalized definition
|
89
|
+
connection.exec(<<~SQL)
|
90
|
+
CREATE OR REPLACE FUNCTION normalized_definition_temp_fn() returns trigger language plpgsql AS
|
91
|
+
$$#{definition}$$;
|
92
|
+
SQL
|
93
|
+
|
94
|
+
# get the normalzed version of the definition
|
95
|
+
rows = connection.exec(<<~SQL)
|
96
|
+
SELECT prosrc AS function_definition
|
97
|
+
FROM pg_proc
|
98
|
+
WHERE proname = 'normalized_definition_temp_fn';
|
99
|
+
SQL
|
100
|
+
|
101
|
+
# delete the temp table and close the transaction
|
102
|
+
connection.exec("ROLLBACK")
|
103
|
+
|
104
|
+
# return the normalized function definition
|
105
|
+
rows.first["function_definition"]
|
106
|
+
end
|
107
|
+
|
108
|
+
if fn_def.nil?
|
109
|
+
raise UnnormalizableDefinitionError, "Failed to nomalize action condition `#{definition}`"
|
110
|
+
end
|
111
|
+
|
112
|
+
fn_def
|
113
|
+
end
|
65
114
|
end
|
66
115
|
end
|
67
116
|
end
|
@@ -36,7 +36,11 @@ module DynamicMigrations
|
|
36
36
|
@data_type = data_type
|
37
37
|
|
38
38
|
@null = null
|
39
|
-
|
39
|
+
|
40
|
+
unless default.nil?
|
41
|
+
raise ExpectedStringError, default unless default.is_a? String
|
42
|
+
@default = default
|
43
|
+
end
|
40
44
|
|
41
45
|
unless description.nil?
|
42
46
|
raise ExpectedStringError, description unless description.is_a? String
|
@@ -50,7 +54,7 @@ module DynamicMigrations
|
|
50
54
|
unless enum.is_a? Enum
|
51
55
|
raise UnexpectedEnumError, "#{enum} is not a valid enum"
|
52
56
|
end
|
53
|
-
|
57
|
+
if (array? && @data_type != :"#{enum.full_name}[]") || (!array? && @data_type != enum.full_name)
|
54
58
|
raise UnexpectedEnumError, "enum `#{enum.full_name}` does not match this column's data type `#{@data_type}`"
|
55
59
|
end
|
56
60
|
@enum = enum
|
@@ -68,6 +72,29 @@ module DynamicMigrations
|
|
68
72
|
def array?
|
69
73
|
@data_type.end_with? "[]"
|
70
74
|
end
|
75
|
+
|
76
|
+
def enum?
|
77
|
+
!@enum.nil?
|
78
|
+
end
|
79
|
+
|
80
|
+
# for arrays returns the column type without the array brackets, for non arrays
|
81
|
+
# jsut returnms the column type
|
82
|
+
def base_data_type
|
83
|
+
array? ? @data_type[0..-3]&.to_sym : @data_type
|
84
|
+
end
|
85
|
+
|
86
|
+
# sometimes this system makes temporary tables in order to fetch the normalized
|
87
|
+
# version of constraint check clauses, function definitions or trigger action conditions
|
88
|
+
# because certain data types might not yet exist, we need to use alternative types
|
89
|
+
def temp_table_data_type
|
90
|
+
if enum
|
91
|
+
:text
|
92
|
+
elsif @data_type == :citext || @data_type == :"citext[]"
|
93
|
+
:text
|
94
|
+
else
|
95
|
+
@data_type
|
96
|
+
end
|
97
|
+
end
|
71
98
|
end
|
72
99
|
end
|
73
100
|
end
|
@@ -14,9 +14,6 @@ module DynamicMigrations
|
|
14
14
|
class ExpectedArrayOfColumnsError < StandardError
|
15
15
|
end
|
16
16
|
|
17
|
-
class ExpectedDifferentTablesError < StandardError
|
18
|
-
end
|
19
|
-
|
20
17
|
class DuplicateColumnError < StandardError
|
21
18
|
end
|
22
19
|
|
@@ -49,14 +46,14 @@ module DynamicMigrations
|
|
49
46
|
raise ExpectedArrayOfColumnsError
|
50
47
|
end
|
51
48
|
|
52
|
-
if table.name == foreign_table.name && table.schema.name == foreign_table.schema.name
|
53
|
-
raise ExpectedDifferentTablesError
|
54
|
-
end
|
55
|
-
|
56
49
|
# tables must be set before the columns are added
|
57
50
|
@table = table
|
58
51
|
@foreign_table = foreign_table
|
59
52
|
|
53
|
+
# add this foreign_key_constraint to the remote table (so we can always find
|
54
|
+
# these from both sides of the association)
|
55
|
+
@foreign_table.add_remote_foreign_key_constraint self
|
56
|
+
|
60
57
|
@columns = {}
|
61
58
|
columns.each do |column|
|
62
59
|
add_column column
|
data/lib/dynamic_migrations/postgres/server/database/schema/table/foreign_key_constraints.rb
CHANGED
@@ -61,6 +61,11 @@ module DynamicMigrations
|
|
61
61
|
# return the new foreign_key_constraint
|
62
62
|
new_foreign_key_constraint
|
63
63
|
end
|
64
|
+
|
65
|
+
# called automatically from the other side of the foreign key constraint to keep track of the foreign key from both sides
|
66
|
+
def add_remote_foreign_key_constraint foreign_key_constraint
|
67
|
+
@remote_foreign_key_constraints << foreign_key_constraint
|
68
|
+
end
|
64
69
|
end
|
65
70
|
end
|
66
71
|
end
|