dynamic_migrations 3.6.7 → 3.6.8
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 +9 -0
- data/lib/dynamic_migrations/active_record/migrators/trigger.rb +10 -8
- data/lib/dynamic_migrations/postgres/generator/column.rb +4 -0
- data/lib/dynamic_migrations/postgres/generator/fragment.rb +64 -3
- data/lib/dynamic_migrations/postgres/generator/migration.rb +20 -4
- data/lib/dynamic_migrations/postgres/generator/table.rb +19 -3
- data/lib/dynamic_migrations/postgres/generator/trigger.rb +4 -2
- data/lib/dynamic_migrations/postgres/generator.rb +46 -16
- data/lib/dynamic_migrations/postgres/server/database/loaded_schemas_builder.rb +27 -10
- data/lib/dynamic_migrations/postgres/server/database/schema/table/column.rb +15 -2
- data/lib/dynamic_migrations/postgres/server/database/schema/table/trigger.rb +8 -8
- data/lib/dynamic_migrations/postgres/server/database/structure_loader.rb +8 -20
- data/lib/dynamic_migrations/postgres/server/database/triggers_and_functions_loader.rb +6 -2
- data/lib/dynamic_migrations/version.rb +1 -1
- data/sig/dynamic_migrations/active_record/migrators/trigger.rbs +7 -7
- data/sig/dynamic_migrations/postgres/generator/column.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator/enum.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator/extension.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator/foreign_key_constraint.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator/fragment.rbs +13 -2
- data/sig/dynamic_migrations/postgres/generator/function.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator/index.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator/migration.rbs +6 -2
- data/sig/dynamic_migrations/postgres/generator/primary_key.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator/schema.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator/table.rbs +3 -2
- data/sig/dynamic_migrations/postgres/generator/trigger.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator/unique_constraint.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator/validation.rbs +1 -1
- data/sig/dynamic_migrations/postgres/generator.rbs +1 -1
- data/sig/dynamic_migrations/postgres/server/database/schema/table/column.rbs +6 -1
- data/sig/dynamic_migrations/postgres/server/database/schema/table/trigger.rbs +2 -2
- data/sig/dynamic_migrations/postgres/server/database/schema/table/triggers.rbs +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d876905704f02b0e0f4fa5ba3842e7b7b8083ab7ba957f7e30b2ea314f62578d
|
4
|
+
data.tar.gz: 06e02f49a1d162cff9062d4c785ae76f67e03547402411566152a2facc91812e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 311b0e7c617dd0484212b84d4c929853f12c21fe9bd0ea78209d38a995c2ae20f4f2bc8a6674b6fb6ddba896130814bf6fbccfb6880828bcbecc3066c9986940
|
7
|
+
data.tar.gz: adafdf79065b117c281cf12aaf23abef54948bc6e93d78956157cc0b7d56f2e78bec05ba9e7c008138772477c9855107dafd41b39dc1d4f462c7a071ee00cb82
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [3.6.8](https://github.com/craigulliott/dynamic_migrations/compare/v3.6.7...v3.6.8) (2023-09-13)
|
4
|
+
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
* dependency resolution is now aware of functions, enums and works across schemas. ([460de82](https://github.com/craigulliott/dynamic_migrations/commit/460de828be1826930bc1b185cf2a4c4e354d7dad))
|
9
|
+
* enum columns now accept an enum object ([460de82](https://github.com/craigulliott/dynamic_migrations/commit/460de828be1826930bc1b185cf2a4c4e354d7dad))
|
10
|
+
* trigger parameters is now an array of strings ([460de82](https://github.com/craigulliott/dynamic_migrations/commit/460de828be1826930bc1b185cf2a4c4e354d7dad))
|
11
|
+
|
3
12
|
## [3.6.7](https://github.com/craigulliott/dynamic_migrations/compare/v3.6.6...v3.6.7) (2023-09-13)
|
4
13
|
|
5
14
|
|
@@ -16,7 +16,7 @@ module DynamicMigrations
|
|
16
16
|
end
|
17
17
|
|
18
18
|
# create a postgres trigger
|
19
|
-
def add_trigger table_name, name:, action_timing:, event_manipulation:, action_orientation:, function_schema_name:, function_name:, parameters:
|
19
|
+
def add_trigger table_name, name:, action_timing:, event_manipulation:, action_orientation:, function_schema_name:, function_name:, parameters: [], action_condition: nil, action_reference_old_table: nil, action_reference_new_table: nil, comment: nil
|
20
20
|
unless [:insert, :delete, :update].include? event_manipulation
|
21
21
|
raise UnexpectedEventManipulationError, event_manipulation
|
22
22
|
end
|
@@ -47,13 +47,15 @@ module DynamicMigrations
|
|
47
47
|
end
|
48
48
|
temp_tables_sql = temp_tables.any? ? "REFERENCING #{temp_tables.join(" ")}" : ""
|
49
49
|
|
50
|
+
parameters_str = parameters.map { |p| quote(p) }.join(", ")
|
51
|
+
|
50
52
|
# schema_name was not provided to this method, it comes from the migration class
|
51
53
|
execute <<~SQL
|
52
54
|
CREATE TRIGGER #{name}
|
53
55
|
#{timing_sql} ON #{schema_name}.#{table_name} #{temp_tables_sql}
|
54
56
|
FOR EACH #{action_orientation}
|
55
57
|
#{condition_sql}
|
56
|
-
EXECUTE FUNCTION #{function_schema_name}.#{function_name}(#{
|
58
|
+
EXECUTE FUNCTION #{function_schema_name}.#{function_name}(#{parameters_str});
|
57
59
|
SQL
|
58
60
|
|
59
61
|
if comment.is_a? String
|
@@ -62,27 +64,27 @@ module DynamicMigrations
|
|
62
64
|
end
|
63
65
|
|
64
66
|
# wrappers for add_trigger which provide more friendly syntax
|
65
|
-
def before_insert table_name, name:, function_schema_name:, function_name:, parameters:
|
67
|
+
def before_insert table_name, name:, function_schema_name:, function_name:, parameters: [], action_condition: nil, action_reference_old_table: nil, action_reference_new_table: nil, comment: nil
|
66
68
|
add_trigger table_name, name: name, action_timing: :before, event_manipulation: :insert, action_orientation: :row, function_schema_name: function_schema_name, function_name: function_name, parameters: parameters, action_condition: action_condition, action_reference_old_table: action_reference_old_table, action_reference_new_table: action_reference_new_table, comment: comment
|
67
69
|
end
|
68
70
|
|
69
|
-
def before_update table_name, name:, function_schema_name:, function_name:, parameters:
|
71
|
+
def before_update table_name, name:, function_schema_name:, function_name:, parameters: [], action_condition: nil, action_reference_old_table: nil, action_reference_new_table: nil, comment: nil
|
70
72
|
add_trigger table_name, name: name, action_timing: :before, event_manipulation: :update, action_orientation: :row, function_schema_name: function_schema_name, function_name: function_name, parameters: parameters, action_condition: action_condition, action_reference_old_table: action_reference_old_table, action_reference_new_table: action_reference_new_table, comment: comment
|
71
73
|
end
|
72
74
|
|
73
|
-
def before_delete table_name, name:, function_schema_name:, function_name:, parameters:
|
75
|
+
def before_delete table_name, name:, function_schema_name:, function_name:, parameters: [], action_condition: nil, action_reference_old_table: nil, action_reference_new_table: nil, comment: nil
|
74
76
|
add_trigger table_name, name: name, action_timing: :before, event_manipulation: :delete, action_orientation: :row, function_schema_name: function_schema_name, function_name: function_name, parameters: parameters, action_condition: action_condition, action_reference_old_table: action_reference_old_table, action_reference_new_table: action_reference_new_table, comment: comment
|
75
77
|
end
|
76
78
|
|
77
|
-
def after_insert table_name, name:, function_schema_name:, function_name:, parameters:
|
79
|
+
def after_insert table_name, name:, function_schema_name:, function_name:, parameters: [], action_condition: nil, action_reference_old_table: nil, action_reference_new_table: nil, comment: nil
|
78
80
|
add_trigger table_name, name: name, action_timing: :after, event_manipulation: :insert, action_orientation: :row, function_schema_name: function_schema_name, function_name: function_name, parameters: parameters, action_condition: action_condition, action_reference_old_table: action_reference_old_table, action_reference_new_table: action_reference_new_table, comment: comment
|
79
81
|
end
|
80
82
|
|
81
|
-
def after_update table_name, name:, function_schema_name:, function_name:, parameters:
|
83
|
+
def after_update table_name, name:, function_schema_name:, function_name:, parameters: [], action_condition: nil, action_reference_old_table: nil, action_reference_new_table: nil, comment: nil
|
82
84
|
add_trigger table_name, name: name, action_timing: :after, event_manipulation: :update, action_orientation: :row, function_schema_name: function_schema_name, function_name: function_name, parameters: parameters, action_condition: action_condition, action_reference_old_table: action_reference_old_table, action_reference_new_table: action_reference_new_table, comment: comment
|
83
85
|
end
|
84
86
|
|
85
|
-
def after_delete table_name, name:, function_schema_name:, function_name:, parameters:
|
87
|
+
def after_delete table_name, name:, function_schema_name:, function_name:, parameters: [], action_condition: nil, action_reference_old_table: nil, action_reference_new_table: nil, comment: nil
|
86
88
|
add_trigger table_name, name: name, action_timing: :after, event_manipulation: :delete, action_orientation: :row, function_schema_name: function_schema_name, function_name: function_name, parameters: parameters, action_condition: action_condition, action_reference_old_table: action_reference_old_table, action_reference_new_table: action_reference_new_table, comment: comment
|
87
89
|
end
|
88
90
|
|
@@ -48,6 +48,8 @@ module DynamicMigrations
|
|
48
48
|
add_fragment schema: column.table.schema,
|
49
49
|
table: column.table,
|
50
50
|
migration_method: :add_column,
|
51
|
+
# this will be nil if the column is not an enum
|
52
|
+
dependent_enum: column.enum,
|
51
53
|
object: column,
|
52
54
|
code_comment: code_comment,
|
53
55
|
migration: <<~RUBY
|
@@ -77,6 +79,8 @@ module DynamicMigrations
|
|
77
79
|
add_fragment schema: column.table.schema,
|
78
80
|
table: column.table,
|
79
81
|
migration_method: :change_column,
|
82
|
+
# this will be nil if the column is not an enum
|
83
|
+
dependent_enum: column.enum,
|
80
84
|
object: column,
|
81
85
|
code_comment: code_comment,
|
82
86
|
migration: <<~RUBY
|
@@ -8,6 +8,8 @@ module DynamicMigrations
|
|
8
8
|
attr_reader :object_name
|
9
9
|
attr_reader :dependency_schema_name
|
10
10
|
attr_reader :dependency_table_name
|
11
|
+
attr_reader :dependency_function_name
|
12
|
+
attr_reader :dependency_enum_name
|
11
13
|
|
12
14
|
def initialize schema_name, table_name, migration_method, object_name, code_comment, content
|
13
15
|
@schema_name = schema_name
|
@@ -38,7 +40,7 @@ module DynamicMigrations
|
|
38
40
|
|
39
41
|
# If a table dependency has been set, then returns a hash with the schema_name
|
40
42
|
# and table_name, otherwise returns nil.
|
41
|
-
def
|
43
|
+
def table_dependency
|
42
44
|
if dependency_schema_name && dependency_table_name
|
43
45
|
{
|
44
46
|
schema_name: dependency_schema_name,
|
@@ -47,18 +49,77 @@ module DynamicMigrations
|
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
52
|
+
# If a function dependency has been set, then returns a hash with the schema_name
|
53
|
+
# and function_name, otherwise returns nil.
|
54
|
+
def function_dependency
|
55
|
+
if dependency_schema_name && dependency_function_name
|
56
|
+
{
|
57
|
+
schema_name: dependency_schema_name,
|
58
|
+
function_name: dependency_function_name
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# If an enum dependency has been set, then returns a hash with the schema_name
|
64
|
+
# and enum_name, otherwise returns nil.
|
65
|
+
def enum_dependency
|
66
|
+
if dependency_schema_name && dependency_enum_name
|
67
|
+
{
|
68
|
+
schema_name: dependency_schema_name,
|
69
|
+
enum_name: dependency_enum_name
|
70
|
+
}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
50
74
|
# returns true if the fragment has a table dependency, and the dependency matches
|
51
75
|
# the provided schema_name and table_name, otherwise returns false.
|
52
|
-
def
|
76
|
+
def is_dependent_on_table? schema_name, table_name
|
53
77
|
dependency_schema_name && schema_name == dependency_schema_name && table_name == dependency_table_name || false
|
54
78
|
end
|
55
79
|
|
56
|
-
# Set
|
80
|
+
# Set a table dependency for this fragment. Takes a schema name and
|
57
81
|
# table name
|
58
82
|
def set_dependent_table schema_name, table_name
|
83
|
+
if @dependency_schema_name
|
84
|
+
raise "Cannot set a table dependency for a fragment that already has a #{dependency_type} dependency"
|
85
|
+
end
|
59
86
|
@dependency_schema_name = schema_name
|
60
87
|
@dependency_table_name = table_name
|
61
88
|
end
|
89
|
+
|
90
|
+
# Set a function dependency for this fragment. Takes a schema name and
|
91
|
+
# function name
|
92
|
+
def set_dependent_function schema_name, function_name
|
93
|
+
if @dependency_schema_name
|
94
|
+
raise "Cannot set a table dependency for a fragment that already has a #{dependency_type} dependency"
|
95
|
+
end
|
96
|
+
@dependency_schema_name = schema_name
|
97
|
+
@dependency_function_name = function_name
|
98
|
+
end
|
99
|
+
|
100
|
+
# Set an enum dependency for this fragment. Takes a schema name and
|
101
|
+
# enum name
|
102
|
+
def set_dependent_enum schema_name, enum_name
|
103
|
+
if @dependency_schema_name
|
104
|
+
raise "Cannot set a table dependency for a fragment that already has a #{dependency_type} dependency"
|
105
|
+
end
|
106
|
+
@dependency_schema_name = schema_name
|
107
|
+
@dependency_enum_name = enum_name
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
# returns a symbol representing the type of dependency this fragment has,
|
113
|
+
# or nil if there is no dependency
|
114
|
+
def dependency_type
|
115
|
+
if dependency_function_name
|
116
|
+
:function
|
117
|
+
elsif dependency_enum_name
|
118
|
+
:enum
|
119
|
+
elsif dependency_table_name
|
120
|
+
:table
|
121
|
+
end
|
122
|
+
end
|
62
123
|
end
|
63
124
|
end
|
64
125
|
end
|
@@ -96,18 +96,34 @@ module DynamicMigrations
|
|
96
96
|
# Return an array of table dependencies for this migration, this array comes from
|
97
97
|
# combining any table dependencies from each fragment.
|
98
98
|
# Will raise an error if no fragments have been provided.
|
99
|
-
def
|
99
|
+
def table_dependencies
|
100
100
|
raise NoFragmentsError if fragments.empty?
|
101
|
-
@fragments.map(&:
|
101
|
+
@fragments.map(&:table_dependency).compact
|
102
|
+
end
|
103
|
+
|
104
|
+
# Return an array of function dependencies for this migration, this array comes from
|
105
|
+
# combining any function dependencies from each fragment.
|
106
|
+
# Will raise an error if no fragments have been provided.
|
107
|
+
def function_dependencies
|
108
|
+
raise NoFragmentsError if fragments.empty?
|
109
|
+
@fragments.map(&:function_dependency).compact
|
110
|
+
end
|
111
|
+
|
112
|
+
# Return an array of enum dependencies for this migration, this array comes from
|
113
|
+
# combining any enum dependencies from each fragment.
|
114
|
+
# Will raise an error if no fragments have been provided.
|
115
|
+
def enum_dependencies
|
116
|
+
raise NoFragmentsError if fragments.empty?
|
117
|
+
@fragments.map(&:enum_dependency).compact
|
102
118
|
end
|
103
119
|
|
104
120
|
# removes and returns any fragments which have a dependency on the table with the
|
105
121
|
# provided schema_name and table_name, this is used for extracting fragments which
|
106
122
|
# cause circular dependencies so they can be placed into their own migrations
|
107
123
|
def extract_fragments_with_dependency schema_name, table_name
|
108
|
-
results = @fragments.filter { |f| f.
|
124
|
+
results = @fragments.filter { |f| f.is_dependent_on_table? schema_name, table_name }
|
109
125
|
# remove any of these from the internal array of fragments
|
110
|
-
@fragments.filter! { |f| !f.
|
126
|
+
@fragments.filter! { |f| !f.is_dependent_on_table?(schema_name, table_name) }
|
111
127
|
# return the results
|
112
128
|
results
|
113
129
|
end
|
@@ -13,19 +13,35 @@ module DynamicMigrations
|
|
13
13
|
raise NoTableCommentError, "Refusing to generate create_table migration, no description was provided for `#{table.schema.name}`.`#{table.name}`"
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
# We only add the columns that are not enums from within the add_table block, this
|
17
|
+
# is because columns that are enums require those enums to be created first and we
|
18
|
+
# want to create those as seperate fragments which have the correct dependency metadata
|
19
|
+
columns_without_enums = table.columns.reject(&:enum)
|
20
|
+
columns_with_enums = table.columns.select(&:enum)
|
21
|
+
|
22
|
+
fragments = []
|
23
|
+
fragments << add_fragment(schema: table.schema,
|
17
24
|
table: table,
|
18
25
|
migration_method: :create_table,
|
19
26
|
object: table,
|
20
27
|
code_comment: code_comment,
|
21
28
|
migration: <<~RUBY
|
22
29
|
table_comment = <<~COMMENT
|
23
|
-
#{indent table.description}
|
30
|
+
#{indent table.description || ""}
|
24
31
|
COMMENT
|
25
32
|
create_table :#{table.name}, #{table_options table} do |t|
|
26
|
-
#{indent table_columns(
|
33
|
+
#{indent table_columns(columns_without_enums)}
|
27
34
|
end
|
28
35
|
RUBY
|
36
|
+
)
|
37
|
+
|
38
|
+
# seperately add the columns that are enums (so dependency managment works correctly)
|
39
|
+
fragments += columns_with_enums.map do |column|
|
40
|
+
add_column column
|
41
|
+
end
|
42
|
+
|
43
|
+
# return all the fragments (we do this with all generators so e can more easily test the methods)
|
44
|
+
fragments
|
29
45
|
end
|
30
46
|
|
31
47
|
def drop_table table, code_comment = nil
|
@@ -61,8 +61,8 @@ module DynamicMigrations
|
|
61
61
|
options[:action_condition] = "\"#{trigger.action_condition}\""
|
62
62
|
end
|
63
63
|
|
64
|
-
unless trigger.parameters.
|
65
|
-
options[:parameters] = "\"#{trigger.parameters}\""
|
64
|
+
unless trigger.parameters.empty?
|
65
|
+
options[:parameters] = "[\"#{trigger.parameters.join('", "')}\"]"
|
66
66
|
end
|
67
67
|
|
68
68
|
unless trigger.action_reference_old_table.nil?
|
@@ -88,6 +88,8 @@ module DynamicMigrations
|
|
88
88
|
migration_method: :add_trigger,
|
89
89
|
object: trigger,
|
90
90
|
code_comment: code_comment,
|
91
|
+
dependent_function: trigger.function,
|
92
|
+
# also need dependent_enum
|
91
93
|
migration: <<~RUBY
|
92
94
|
#{method_name} :#{trigger.table.name}, #{options_syntax}
|
93
95
|
RUBY
|
@@ -41,9 +41,10 @@ module DynamicMigrations
|
|
41
41
|
# a hash to hold the generated migrations orgnized by their schema and table
|
42
42
|
# this makes it easier and faster to work with them within this method
|
43
43
|
database_migrations = {}
|
44
|
-
# the
|
45
|
-
# within a specific schema
|
46
|
-
|
44
|
+
# the database_specific_migrations are for migrations which dont belong
|
45
|
+
# within a specific schema, they are important enough that we have a
|
46
|
+
# dedicated migration for each one
|
47
|
+
database_specific_migrations = []
|
47
48
|
|
48
49
|
# Process each fragment, and organize them into migrations. We create a shared
|
49
50
|
# Migration for each table, and a single shared migration for any schema migrations
|
@@ -75,7 +76,9 @@ module DynamicMigrations
|
|
75
76
|
# migrations with no schema or table, are added to a database
|
76
77
|
# migration (these are really just creating/dropping schemas and extensions)
|
77
78
|
elsif schema_name.nil? && table_name.nil?
|
78
|
-
database_specific_migration.
|
79
|
+
database_specific_migration = DatabaseMigration.new
|
80
|
+
database_specific_migration.add_fragment(fragment)
|
81
|
+
database_specific_migrations << database_specific_migration
|
79
82
|
|
80
83
|
else
|
81
84
|
raise UnprocessableFragmentError
|
@@ -94,7 +97,7 @@ module DynamicMigrations
|
|
94
97
|
# never have dependencies
|
95
98
|
schema_migrations[:table_migrations].values.each do |table_migration|
|
96
99
|
# recursively test each table migration for circular dependencies
|
97
|
-
table_migration.
|
100
|
+
table_migration.table_dependencies.each do |dependency|
|
98
101
|
if circular_dependency? table_migration.schema_name, table_migration.table_name, dependency, all_table_migrations
|
99
102
|
# remove the fragment which is causing the circular dependency
|
100
103
|
removed_fragments = table_migration.extract_fragments_with_dependency dependency[:schema_name], dependency[:table_name]
|
@@ -132,10 +135,10 @@ module DynamicMigrations
|
|
132
135
|
# if there is a schema migration, then it should always come first
|
133
136
|
# so make the table migration depend on it
|
134
137
|
deps << schema_migrations[:schema_migration] if schema_migrations[:schema_migration]
|
135
|
-
# if the table migration has any dependencies, then add them
|
136
|
-
table_migration.
|
138
|
+
# if the table migration has any dependencies on other tables, then add them
|
139
|
+
table_migration.table_dependencies.each do |dependency|
|
137
140
|
# find the migration which matches the dependency
|
138
|
-
dependent_migration =
|
141
|
+
dependent_migration = database_migrations[dependency[:schema_name]] && database_migrations[dependency[:schema_name]][:table_migrations][dependency[:table_name]]
|
139
142
|
# if the table migration is not found, then it's safe to assume the table was created
|
140
143
|
# by an earlier set of migrations
|
141
144
|
unless dependent_migration.nil?
|
@@ -143,6 +146,14 @@ module DynamicMigrations
|
|
143
146
|
deps << dependent_migration
|
144
147
|
end
|
145
148
|
end
|
149
|
+
# if the table migration has any dependencies on functions or enums, then add them
|
150
|
+
(table_migration.function_dependencies + table_migration.enum_dependencies).each do |dependency|
|
151
|
+
# functions are always added to a schema specific migration, if it does not exist then
|
152
|
+
# we can assume the function was added in a previous set of migrations
|
153
|
+
if (dependencies_schema_migration = database_migrations[dependency[:schema_name]] && database_migrations[dependency[:schema_name]][:schema_migration])
|
154
|
+
deps << dependencies_schema_migration
|
155
|
+
end
|
156
|
+
end
|
146
157
|
end
|
147
158
|
# add each additional migration, and its dependencies
|
148
159
|
schema_migrations[:additional_migrations].each do |additional_migration|
|
@@ -157,16 +168,24 @@ module DynamicMigrations
|
|
157
168
|
unless table_migration.nil?
|
158
169
|
deps << table_migration
|
159
170
|
end
|
160
|
-
# if the additional_migration has any dependencies, then add them too
|
161
|
-
additional_migration.
|
171
|
+
# if the additional_migration has any dependencies on other tables, then add them too
|
172
|
+
additional_migration.table_dependencies.each do |dependency|
|
162
173
|
# find the table migration which matches the dependency
|
163
|
-
dependent_migration =
|
174
|
+
dependent_migration = database_migrations[dependency[:schema_name]] && database_migrations[dependency[:schema_name]][:table_migrations][dependency[:table_name]]
|
164
175
|
# if the table migration is not found, then it's safe to assume the table was created
|
165
176
|
# by an earlier set of migrations
|
166
177
|
unless dependent_migration.nil?
|
167
178
|
deps << dependent_migration
|
168
179
|
end
|
169
180
|
end
|
181
|
+
# if the table migration has any dependencies on functions or enums, then add them
|
182
|
+
(table_migration.function_dependencies + table_migration.enum_dependencies).each do |dependency|
|
183
|
+
# functions are always added to a schema specific migration, if it does not exist then
|
184
|
+
# we can assume the function was added in a previous set of migrations
|
185
|
+
if (dependencies_schema_migration = database_migrations[dependency[:schema_name]] && database_migrations[dependency[:schema_name]][:schema_migration])
|
186
|
+
deps << dependencies_schema_migration
|
187
|
+
end
|
188
|
+
end
|
170
189
|
end
|
171
190
|
end
|
172
191
|
|
@@ -174,9 +193,9 @@ module DynamicMigrations
|
|
174
193
|
# the order is determined by their dependencies
|
175
194
|
final_migrations = dependency_sorter.tsort
|
176
195
|
|
177
|
-
# if any database only migrations exist, then add them to the
|
178
|
-
if
|
179
|
-
final_migrations
|
196
|
+
# if any database only migrations exist, then add them to the front of the array here
|
197
|
+
if database_specific_migrations.any?
|
198
|
+
final_migrations = database_specific_migrations + final_migrations
|
180
199
|
end
|
181
200
|
|
182
201
|
# return the final migrations in the expected format
|
@@ -200,7 +219,7 @@ module DynamicMigrations
|
|
200
219
|
dependent_migrations = all_table_migrations.filter { |m| m.schema_name == dependency[:schema_name] && m.table_name == dependency[:table_name] }
|
201
220
|
# recursively call this method for all the dependencies for these migrations
|
202
221
|
dependent_migrations.each do |dependent_migration|
|
203
|
-
dependent_migration.
|
222
|
+
dependent_migration.table_dependencies.each do |next_dependency|
|
204
223
|
# if we find a dependency which matches the original schema and table name then we have a circular dependency
|
205
224
|
if circular_dependency?(schema_name, table_name, next_dependency, all_table_migrations)
|
206
225
|
return true
|
@@ -221,15 +240,26 @@ module DynamicMigrations
|
|
221
240
|
@dep[node].each(&block)
|
222
241
|
end
|
223
242
|
|
224
|
-
|
243
|
+
# This method is called from within the various modules which are included to this class.
|
244
|
+
# It locally stores all the fragments which will later be organized into different migrations.
|
245
|
+
def add_fragment migration_method:, object:, migration:, schema: nil, table: nil, code_comment: nil, dependent_table: nil, dependent_function: nil, dependent_enum: nil
|
225
246
|
# Remove any empty lines and whitespace from the beginning or the end of the migration and then
|
226
247
|
# strip any empty lines witin the migration (remove the whitespace from them, not delete them).
|
227
248
|
final_migration = strip_empty_lines(migration).strip
|
228
249
|
fragment = Fragment.new(schema&.name, table&.name, migration_method, object.name, code_comment, final_migration)
|
250
|
+
|
229
251
|
if dependent_table
|
230
252
|
fragment.set_dependent_table dependent_table.schema.name, dependent_table.name
|
231
253
|
end
|
232
254
|
|
255
|
+
if dependent_function
|
256
|
+
fragment.set_dependent_function dependent_function.schema.name, dependent_function.name
|
257
|
+
end
|
258
|
+
|
259
|
+
if dependent_enum
|
260
|
+
fragment.set_dependent_enum dependent_enum.schema.name, dependent_enum.name
|
261
|
+
end
|
262
|
+
|
233
263
|
# add this fragment to the list
|
234
264
|
@fragments << fragment
|
235
265
|
|
@@ -15,8 +15,24 @@ module DynamicMigrations
|
|
15
15
|
# tables and columns
|
16
16
|
def recursively_load_database_structure
|
17
17
|
validations = fetch_validations
|
18
|
-
|
19
|
-
|
18
|
+
|
19
|
+
structure = fetch_structure
|
20
|
+
|
21
|
+
# add any schemas
|
22
|
+
structure.each do |schema_name, schema_definition|
|
23
|
+
add_loaded_schema schema_name
|
24
|
+
end
|
25
|
+
|
26
|
+
# add any enums (required for adding columns below)
|
27
|
+
fetch_enums.each do |schema_name, schema_definition|
|
28
|
+
schema_definition.each do |enum_name, enum_definition|
|
29
|
+
loaded_schema(schema_name).add_enum enum_name, enum_definition[:values], description: enum_definition[:description]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
structure.each do |schema_name, schema_definition|
|
34
|
+
# the schema was already added above
|
35
|
+
schema = loaded_schema schema_name
|
20
36
|
schema_validations = validations[schema_name]
|
21
37
|
|
22
38
|
schema_definition[:tables].each do |table_name, table_definition|
|
@@ -25,11 +41,19 @@ module DynamicMigrations
|
|
25
41
|
|
26
42
|
# add each table column
|
27
43
|
table_definition[:columns].each do |column_name, column_definition|
|
44
|
+
if column_definition[:is_enum]
|
45
|
+
enum_schema, enum_name = column_definition[:data_type].to_s.split(".")
|
46
|
+
enum = table.schema.database.loaded_schema(enum_schema.to_sym).enum(enum_name.to_sym)
|
47
|
+
else
|
48
|
+
enum = nil
|
49
|
+
end
|
50
|
+
|
28
51
|
table.add_column column_name, column_definition[:data_type],
|
29
52
|
null: column_definition[:null],
|
30
53
|
default: column_definition[:default],
|
31
54
|
description: column_definition[:description],
|
32
|
-
interval_type: column_definition[:interval_type]
|
55
|
+
interval_type: column_definition[:interval_type],
|
56
|
+
enum: enum
|
33
57
|
end
|
34
58
|
|
35
59
|
# add any validations
|
@@ -44,13 +68,6 @@ module DynamicMigrations
|
|
44
68
|
add_loaded_extension extension_name
|
45
69
|
end
|
46
70
|
|
47
|
-
# add any enums
|
48
|
-
fetch_enums.each do |schema_name, schema_definition|
|
49
|
-
schema_definition.each do |enum_name, enum_definition|
|
50
|
-
loaded_schema(schema_name).add_enum enum_name, enum_definition[:values], description: enum_definition[:description]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
71
|
# now that the structure has been loaded, we can add keys (foreign
|
55
72
|
# keys need to be added last, because they can depend on tables from
|
56
73
|
# different schemas)
|
@@ -11,6 +11,9 @@ module DynamicMigrations
|
|
11
11
|
class ExpectedTableError < StandardError
|
12
12
|
end
|
13
13
|
|
14
|
+
class UnexpectedEnumError < StandardError
|
15
|
+
end
|
16
|
+
|
14
17
|
attr_reader :table
|
15
18
|
attr_reader :name
|
16
19
|
attr_reader :data_type
|
@@ -18,9 +21,10 @@ module DynamicMigrations
|
|
18
21
|
attr_reader :null
|
19
22
|
attr_reader :default
|
20
23
|
attr_reader :interval_type
|
24
|
+
attr_reader :enum
|
21
25
|
|
22
26
|
# initialize a new object to represent a column in a postgres table
|
23
|
-
def initialize source, table, name, data_type, null: true, default: nil, description: nil, interval_type: nil
|
27
|
+
def initialize source, table, name, data_type, null: true, default: nil, description: nil, interval_type: nil, enum: nil
|
24
28
|
super source
|
25
29
|
raise ExpectedTableError, table unless table.is_a? Table
|
26
30
|
@table = table
|
@@ -28,7 +32,6 @@ module DynamicMigrations
|
|
28
32
|
raise ExpectedSymbolError, name unless name.is_a? Symbol
|
29
33
|
@name = name
|
30
34
|
|
31
|
-
@data_type = data_type
|
32
35
|
raise ExpectedSymbolError, data_type unless data_type.is_a? Symbol
|
33
36
|
@data_type = data_type
|
34
37
|
|
@@ -42,6 +45,16 @@ module DynamicMigrations
|
|
42
45
|
end
|
43
46
|
|
44
47
|
@interval_type = interval_type
|
48
|
+
|
49
|
+
if enum
|
50
|
+
unless enum.is_a? Enum
|
51
|
+
raise UnexpectedEnumError, "#{enum} is not a valid enum"
|
52
|
+
end
|
53
|
+
unless @data_type == enum.name || @data_type == "#{enum.name}[]"
|
54
|
+
raise UnexpectedEnumError, "enum `#{enum.name}` does not match this column's data type `#{@data_type}`"
|
55
|
+
end
|
56
|
+
@enum = enum
|
57
|
+
end
|
45
58
|
end
|
46
59
|
|
47
60
|
# return true if this column has a description, otherwise false
|
@@ -92,11 +92,10 @@ module DynamicMigrations
|
|
92
92
|
end
|
93
93
|
@action_condition = action_condition&.strip
|
94
94
|
|
95
|
-
|
96
|
-
|
97
|
-
raise UnexpectedParametersError, "unexpected parameters `#{parameters}`, currently only a comma seeparated list of strings is supported"
|
95
|
+
unless parameters.is_a?(Array) && parameters.all? { |p| p.is_a? String }
|
96
|
+
raise UnexpectedParametersError, "unexpected parameters `#{parameters}`, currently only an array of strings is supported"
|
98
97
|
end
|
99
|
-
@parameters = parameters
|
98
|
+
@parameters = parameters
|
100
99
|
|
101
100
|
unless [:row, :statement].include? action_orientation
|
102
101
|
raise UnexpectedActionOrientationError, action_orientation
|
@@ -167,11 +166,12 @@ module DynamicMigrations
|
|
167
166
|
@action_condition = new_action_condition&.strip
|
168
167
|
end
|
169
168
|
|
170
|
-
def
|
171
|
-
unless
|
172
|
-
raise
|
169
|
+
def add_parameter new_parameter
|
170
|
+
unless new_parameter.is_a? String
|
171
|
+
raise UnexpectedParametersError, "unexpected parameter `#{new_parameter}`, can only add strings to the list of parameters"
|
173
172
|
end
|
174
|
-
|
173
|
+
|
174
|
+
@parameters << new_parameter
|
175
175
|
end
|
176
176
|
|
177
177
|
# return true if this has a description, otherwise false
|
@@ -33,6 +33,13 @@ module DynamicMigrations
|
|
33
33
|
AND attnum = columns.ordinal_position
|
34
34
|
)
|
35
35
|
END AS data_type,
|
36
|
+
-- is this an emum
|
37
|
+
EXISTS (
|
38
|
+
SELECT 1
|
39
|
+
FROM pg_type typ
|
40
|
+
INNER JOIN pg_enum enu ON typ.oid = enu.enumtypid
|
41
|
+
WHERE typ.typname = columns.udt_name
|
42
|
+
) AS is_enum,
|
36
43
|
-- If data_type identifies an interval type, this column contains
|
37
44
|
-- the specification which fields the intervals include for this
|
38
45
|
-- column, e.g., YEAR TO MONTH, DAY TO SECOND, etc. If no field
|
@@ -93,6 +100,7 @@ module DynamicMigrations
|
|
93
100
|
|
94
101
|
column[:data_type] = row["data_type"].to_sym
|
95
102
|
column[:null] = row["is_nullable"] == "YES"
|
103
|
+
column[:is_enum] = row["is_enum"] == "TRUE"
|
96
104
|
column[:default] = row["column_default"]
|
97
105
|
column[:description] = row["column_description"]
|
98
106
|
column[:interval_type] = row["interval_type"].nil? ? nil : row["interval_type"].to_sym
|
@@ -102,26 +110,6 @@ module DynamicMigrations
|
|
102
110
|
schemas
|
103
111
|
end
|
104
112
|
|
105
|
-
# recursively process the database and build all the schemas,
|
106
|
-
# tables and columns
|
107
|
-
def recursively_load_database_structure
|
108
|
-
fetch_structure.each do |schema_name, schema_definition|
|
109
|
-
schema = add_loaded_schema schema_name
|
110
|
-
|
111
|
-
schema_definition[:tables].each do |table_name, table_definition|
|
112
|
-
table = schema.add_table table_name, table_definition[:description]
|
113
|
-
|
114
|
-
table_definition[:columns].each do |column_name, column_definition|
|
115
|
-
table.add_column column_name, column_definition[:data_type],
|
116
|
-
null: column_definition[:null],
|
117
|
-
default: column_definition[:default],
|
118
|
-
description: column_definition[:description],
|
119
|
-
interval_type: column_definition[:interval_type]
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
113
|
# returns a list of the schema names in this database
|
126
114
|
def fetch_schema_names
|
127
115
|
rows = connection.exec(<<~SQL)
|
@@ -38,7 +38,7 @@ module DynamicMigrations
|
|
38
38
|
SUBSTRING(
|
39
39
|
pg_get_triggerdef(t.oid)
|
40
40
|
FROM
|
41
|
-
'\\(([
|
41
|
+
'\\(([^(]+)\\)$'
|
42
42
|
) AS parameters,
|
43
43
|
p_n.nspname AS function_schema,
|
44
44
|
p.proname AS function_name,
|
@@ -96,6 +96,10 @@ module DynamicMigrations
|
|
96
96
|
raise EventTriggerProcedureSchemaMismatchError, "Expected trigger, procedure and event_object to be in the same schema for trigger '#{trigger_name}'"
|
97
97
|
end
|
98
98
|
|
99
|
+
# turn the parameters into an array of strings
|
100
|
+
# the format looks a little like this: "'hi', 'there', 'hmmm'"
|
101
|
+
parameters = row["parameters"]&.delete("'")&.split(",")&.map(&:strip) || []
|
102
|
+
|
99
103
|
table[trigger_name] = {
|
100
104
|
trigger_schema: row["trigger_schema"].to_sym,
|
101
105
|
event_manipulation: row["event_manipulation"].to_sym,
|
@@ -104,7 +108,7 @@ module DynamicMigrations
|
|
104
108
|
function_schema: row["function_schema"].to_sym,
|
105
109
|
function_name: row["function_name"].to_sym,
|
106
110
|
function_definition: row["function_definition"],
|
107
|
-
parameters:
|
111
|
+
parameters: parameters,
|
108
112
|
action_orientation: row["action_orientation"].to_sym,
|
109
113
|
action_timing: row["action_timing"].to_sym,
|
110
114
|
# `action_reference_old_table` and `action_reference_new_table` can be null
|
@@ -3,17 +3,17 @@ module DynamicMigrations
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Migrators
|
5
5
|
module Trigger
|
6
|
-
def add_trigger: (Symbol table_name, name: Symbol, action_timing: Symbol, event_manipulation: Symbol, action_orientation: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: String
|
6
|
+
def add_trigger: (Symbol table_name, name: Symbol, action_timing: Symbol, event_manipulation: Symbol, action_orientation: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: Array[String], ?action_condition: String?, ?action_reference_old_table: Symbol?, ?action_reference_new_table: Symbol?, ?comment: String?) -> void
|
7
7
|
def remove_trigger: (Symbol table_name, Symbol trigger_name) -> void
|
8
8
|
def set_trigger_comment: (Symbol table_name, Symbol trigger_name, String comment) -> void
|
9
9
|
def remove_trigger_comment: (Symbol table_name, Symbol trigger_name) -> void
|
10
10
|
|
11
|
-
def before_insert: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: String
|
12
|
-
def before_update: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: String
|
13
|
-
def before_delete: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: String
|
14
|
-
def after_insert: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: String
|
15
|
-
def after_update: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: String
|
16
|
-
def after_delete: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: String
|
11
|
+
def before_insert: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: Array[String], ?action_condition: String?, ?action_reference_old_table: Symbol?, ?action_reference_new_table: Symbol?, ?comment: String?) -> void
|
12
|
+
def before_update: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: Array[String], ?action_condition: String?, ?action_reference_old_table: Symbol?, ?action_reference_new_table: Symbol?, ?comment: String?) -> void
|
13
|
+
def before_delete: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: Array[String], ?action_condition: String?, ?action_reference_old_table: Symbol?, ?action_reference_new_table: Symbol?, ?comment: String?) -> void
|
14
|
+
def after_insert: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: Array[String], ?action_condition: String?, ?action_reference_old_table: Symbol?, ?action_reference_new_table: Symbol?, ?comment: String?) -> void
|
15
|
+
def after_update: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: Array[String], ?action_condition: String?, ?action_reference_old_table: Symbol?, ?action_reference_new_table: Symbol?, ?comment: String?) -> void
|
16
|
+
def after_delete: (Symbol table_name, name: Symbol, function_schema_name: Symbol, function_name: Symbol, ?parameters: Array[String], ?action_condition: String?, ?action_reference_old_table: Symbol?, ?action_reference_new_table: Symbol?, ?comment: String?) -> void
|
17
17
|
|
18
18
|
# stubbing these out, as they are available on the module which includes this module
|
19
19
|
def execute: (String sql) -> void
|
@@ -12,7 +12,7 @@ module DynamicMigrations
|
|
12
12
|
def remove_column_comment: (Postgres::Server::Database::Schema::Table::Column column, ?String? code_comment) -> Fragment
|
13
13
|
|
14
14
|
# these come from the generator object (which this module is included into)
|
15
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
15
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
16
16
|
|
17
17
|
def indent: (String migration, ?Integer levels) -> String
|
18
18
|
|
@@ -11,7 +11,7 @@ module DynamicMigrations
|
|
11
11
|
def set_enum_comment: (Server::Database::Schema::Enum enum, ?String? code_comment) -> Fragment
|
12
12
|
def remove_enum_comment: (Server::Database::Schema::Enum enum, ?String? code_comment) -> Fragment
|
13
13
|
# these come from the generator object (which this module is included into)
|
14
|
-
def add_fragment: (
|
14
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
15
15
|
def indent: (String migration, ?Integer levels) -> String
|
16
16
|
|
17
17
|
class UnremovableEnumValuesError < StandardError
|
@@ -9,7 +9,7 @@ module DynamicMigrations
|
|
9
9
|
def disable_extension: (Symbol extension_name, ?String? code_comment) -> Fragment
|
10
10
|
|
11
11
|
# these come from the generator object (which this module is included into)
|
12
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
12
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -12,7 +12,7 @@ module DynamicMigrations
|
|
12
12
|
def remove_foreign_key_constraint_comment: (Postgres::Server::Database::Schema::Table::ForeignKeyConstraint foreign_key_constraint, ?String? code_comment) -> Fragment
|
13
13
|
|
14
14
|
# these come from the generator object (which this module is included into)
|
15
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
15
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
16
16
|
|
17
17
|
def indent: (String migration, ?Integer levels) -> String
|
18
18
|
end
|
@@ -19,13 +19,24 @@ module DynamicMigrations
|
|
19
19
|
# dependecy on a table is optional
|
20
20
|
attr_reader dependency_schema_name: Symbol?
|
21
21
|
attr_reader dependency_table_name: Symbol?
|
22
|
+
attr_reader dependency_function_name: Symbol?
|
23
|
+
attr_reader dependency_enum_name: Symbol?
|
22
24
|
|
23
25
|
def initialize: (Symbol? schema_name, Symbol? table_name, Symbol migration_method, Symbol object_name, String? code_comment, String content) -> void
|
24
26
|
def to_s: -> String
|
25
27
|
def has_code_comment?: -> bool
|
26
|
-
|
27
|
-
def
|
28
|
+
|
29
|
+
def table_dependency: -> ({schema_name: Symbol, table_name: Symbol} | nil)
|
30
|
+
def function_dependency: -> ({schema_name: Symbol, function_name: Symbol} | nil)
|
31
|
+
def enum_dependency: -> ({schema_name: Symbol, enum_name: Symbol} | nil)
|
32
|
+
|
33
|
+
def is_dependent_on_table?: (Symbol schema_name, Symbol table_name) -> bool
|
34
|
+
|
28
35
|
def set_dependent_table: (Symbol schema_name, Symbol table_name) -> void
|
36
|
+
def set_dependent_function: (Symbol schema_name, Symbol function_name) -> void
|
37
|
+
def set_dependent_enum: (Symbol schema_name, Symbol enum_name) -> void
|
38
|
+
|
39
|
+
def dependency_type: -> (nil | :function | :table | :enum)
|
29
40
|
end
|
30
41
|
end
|
31
42
|
end
|
@@ -12,7 +12,7 @@ module DynamicMigrations
|
|
12
12
|
def remove_function_comment: (Postgres::Server::Database::Schema::Function function, ?String? code_comment) -> Fragment
|
13
13
|
|
14
14
|
# these come from the generator object (which this module is included into)
|
15
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
15
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
16
16
|
|
17
17
|
def indent: (String migration, ?Integer levels) -> String
|
18
18
|
end
|
@@ -12,7 +12,7 @@ module DynamicMigrations
|
|
12
12
|
def remove_index_comment: (Postgres::Server::Database::Schema::Table::Index index, ?String? code_comment) -> Fragment
|
13
13
|
|
14
14
|
# these come from the generator object (which this module is included into)
|
15
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
15
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
16
16
|
|
17
17
|
def indent: (String migration, ?Integer levels) -> String
|
18
18
|
end
|
@@ -18,8 +18,12 @@ module DynamicMigrations
|
|
18
18
|
attr_reader fragments: Array[Fragment]
|
19
19
|
def initialize: (?Symbol? schema_name, ?Symbol? table_name) -> void
|
20
20
|
def add_fragment: (Fragment fragment) -> void
|
21
|
-
def
|
22
|
-
def
|
21
|
+
def table_dependencies: -> Array[{schema_name: Symbol, table_name: Symbol}]
|
22
|
+
def enum_dependencies: -> Array[{schema_name: Symbol, enum_name: Symbol}]
|
23
|
+
def function_dependencies: -> Array[{schema_name: Symbol, function_name: Symbol}]
|
24
|
+
|
25
|
+
def extract_fragments_with_table_dependency: (Symbol schema_name, Symbol table_name) -> Array[Fragment]
|
26
|
+
|
23
27
|
def content: -> String
|
24
28
|
def name: -> (:changes | :schema_functions | Symbol)
|
25
29
|
|
@@ -10,7 +10,7 @@ module DynamicMigrations
|
|
10
10
|
def recreate_primary_key: (Postgres::Server::Database::Schema::Table::PrimaryKey original_primary_key, Postgres::Server::Database::Schema::Table::PrimaryKey updated_primary_key) -> Array[Fragment]
|
11
11
|
|
12
12
|
# these come from the generator object (which this module is included into)
|
13
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
13
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
14
14
|
|
15
15
|
def indent: (String migration, ?Integer levels) -> String
|
16
16
|
|
@@ -9,7 +9,7 @@ module DynamicMigrations
|
|
9
9
|
def drop_schema: (Postgres::Server::Database::Schema schema, ?String? code_comment) -> Fragment
|
10
10
|
|
11
11
|
# these come from the generator object (which this module is included into)
|
12
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
12
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
13
13
|
|
14
14
|
end
|
15
15
|
end
|
@@ -5,13 +5,14 @@ module DynamicMigrations
|
|
5
5
|
module Postgres
|
6
6
|
class Generator
|
7
7
|
module Table
|
8
|
-
def create_table: (Postgres::Server::Database::Schema::Table table, ?String? code_comment) -> Fragment
|
8
|
+
def create_table: (Postgres::Server::Database::Schema::Table table, ?String? code_comment) -> Array[Fragment]
|
9
9
|
def drop_table: (Postgres::Server::Database::Schema::Table table, ?String? code_comment) -> Fragment
|
10
10
|
def set_table_comment: (Postgres::Server::Database::Schema::Table table, ?String? code_comment) -> Fragment
|
11
11
|
def remove_table_comment: (Postgres::Server::Database::Schema::Table table, ?String? code_comment) -> Fragment
|
12
12
|
|
13
13
|
# these come from the generator object (which this module is included into)
|
14
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
14
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
15
|
+
def add_column: (Postgres::Server::Database::Schema::Table::Column column, ?String? code_comment) -> Fragment
|
15
16
|
|
16
17
|
def indent: (String migration, ?Integer levels) -> String
|
17
18
|
|
@@ -16,7 +16,7 @@ module DynamicMigrations
|
|
16
16
|
def remove_trigger_comment: (Postgres::Server::Database::Schema::Table::Trigger trigger, ?String? code_comment) -> Fragment
|
17
17
|
|
18
18
|
# these come from the generator object (which this module is included into)
|
19
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
19
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
20
20
|
|
21
21
|
def indent: (String migration, ?Integer levels) -> String
|
22
22
|
|
@@ -12,7 +12,7 @@ module DynamicMigrations
|
|
12
12
|
def remove_unique_constraint_comment: (Postgres::Server::Database::Schema::Table::UniqueConstraint unique_constraint, ?String? code_comment) -> Fragment
|
13
13
|
|
14
14
|
# these come from the generator object (which this module is included into)
|
15
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
15
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
16
16
|
|
17
17
|
def indent: (String migration, ?Integer levels) -> String
|
18
18
|
end
|
@@ -18,7 +18,7 @@ module DynamicMigrations
|
|
18
18
|
def remove_validation_comment: (Postgres::Server::Database::Schema::Table::Validation validation, ?String? code_comment) -> Fragment
|
19
19
|
|
20
20
|
# these come from the generator object (which this module is included into)
|
21
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?) ->
|
21
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
22
22
|
|
23
23
|
def indent: (String migration, ?Integer levels) -> String
|
24
24
|
|
@@ -29,7 +29,7 @@ module DynamicMigrations
|
|
29
29
|
private
|
30
30
|
def circular_dependency?: (Symbol schema_name, Symbol table_name, {schema_name: Symbol, table_name: Symbol} dependency, Array[TableMigration] all_table_migrations) -> bool
|
31
31
|
def supported_migration_method?: (Symbol migration_method) -> bool
|
32
|
-
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table:
|
32
|
+
def add_fragment: (migration_method: Symbol, object: untyped, migration: String, ?schema: Server::Database::Schema?, ?table: Server::Database::Schema::Table?, ?code_comment: String?, ?dependent_table: Server::Database::Schema::Table?, ?dependent_function: Server::Database::Schema::Function?, ?dependent_enum: Server::Database::Schema::Enum?) -> Fragment
|
33
33
|
def indent: (String migration, ?Integer levels) -> String
|
34
34
|
def strip_empty_lines: (String migration) -> String
|
35
35
|
def tsort_each_node: -> Enumerator[untyped, untyped]
|
@@ -13,12 +13,17 @@ module DynamicMigrations
|
|
13
13
|
attr_reader data_type: Symbol
|
14
14
|
attr_reader array: bool
|
15
15
|
attr_reader interval_type: Symbol?
|
16
|
-
|
16
|
+
attr_reader enum: Enum?
|
17
|
+
|
18
|
+
def initialize: (database_or_configuration source, Table table, Symbol name, Symbol data_type, ?null: bool, ?default: untyped, ?description: String?, ?interval_type: Symbol?, ?enum: Enum?) -> void
|
17
19
|
def has_description?: -> bool
|
18
20
|
def array?: -> bool
|
19
21
|
|
20
22
|
class ExpectedTableError < StandardError
|
21
23
|
end
|
24
|
+
|
25
|
+
class UnexpectedEnumError < StandardError
|
26
|
+
end
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
@@ -14,7 +14,7 @@ module DynamicMigrations
|
|
14
14
|
attr_reader event_manipulation: Symbol
|
15
15
|
attr_reader action_timing: Symbol
|
16
16
|
attr_reader action_condition: String?
|
17
|
-
attr_reader parameters: String
|
17
|
+
attr_reader parameters: Array[String]
|
18
18
|
attr_reader action_orientation: Symbol
|
19
19
|
attr_reader function: Function
|
20
20
|
attr_reader action_reference_old_table: Symbol?
|
@@ -22,7 +22,7 @@ module DynamicMigrations
|
|
22
22
|
attr_reader description: String?
|
23
23
|
attr_reader template: Symbol?
|
24
24
|
|
25
|
-
def initialize: (database_or_configuration source, Table table, Symbol name, action_timing: Symbol, event_manipulation: Symbol, parameters: String
|
25
|
+
def initialize: (database_or_configuration source, Table table, Symbol name, action_timing: Symbol, event_manipulation: Symbol, parameters: Array[String], action_orientation: Symbol, function: Function, ?action_order: Integer?, ?action_condition: String?, ?action_reference_old_table: Symbol?, ?action_reference_new_table: Symbol?, ?description: String?, ?template: Symbol?) -> void
|
26
26
|
def action_order: -> Integer
|
27
27
|
def has_description?: -> false
|
28
28
|
def differences_descriptions: (Trigger other_trigger) -> Array[String]
|
@@ -14,7 +14,7 @@ module DynamicMigrations
|
|
14
14
|
def has_trigger?: (untyped name) -> bool
|
15
15
|
def triggers: -> Array[Trigger]
|
16
16
|
def triggers_hash: -> Hash[Symbol, Trigger]
|
17
|
-
def add_trigger: (Symbol name, action_timing: Symbol, event_manipulation: Symbol, parameters: String, action_orientation: Symbol, function: Function, ?action_order: Integer?, ?action_condition: String?, ?action_reference_old_table: Symbol?, ?action_reference_new_table: Symbol?, ?description: String?, ?template: Symbol?) -> Trigger
|
17
|
+
def add_trigger: (Symbol name, action_timing: Symbol, event_manipulation: Symbol, parameters: Array[String], action_orientation: Symbol, function: Function, ?action_order: Integer?, ?action_condition: String?, ?action_reference_old_table: Symbol?, ?action_reference_new_table: Symbol?, ?description: String?, ?template: Symbol?) -> Trigger
|
18
18
|
|
19
19
|
# these come from the table object (which this module is included into)
|
20
20
|
def source: -> database_or_configuration
|