dynamic_migrations 3.6.9 → 3.6.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/lib/dynamic_migrations/postgres/generator/column.rb +10 -2
- data/lib/dynamic_migrations/postgres/generator/enum.rb +11 -2
- data/lib/dynamic_migrations/postgres/generator/extension.rb +6 -2
- data/lib/dynamic_migrations/postgres/generator/fragment.rb +18 -1
- data/lib/dynamic_migrations/postgres/generator/function.rb +9 -1
- data/lib/dynamic_migrations/postgres/generator/migration.rb +2 -2
- data/lib/dynamic_migrations/postgres/generator/trigger.rb +19 -3
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations.rb +1 -1
- data/lib/dynamic_migrations/postgres/server/database/schema/enum.rb +12 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/function.rb +1 -1
- data/lib/dynamic_migrations/postgres/server/database/schema/table/column.rb +3 -0
- data/lib/dynamic_migrations/version.rb +1 -1
- data/sig/dynamic_migrations/postgres/generator/fragment.rbs +3 -0
- data/sig/dynamic_migrations/postgres/generator/validation_template_base.rbs +1 -1
- data/sig/dynamic_migrations/postgres/server/database/schema/enum.rbs +2 -0
- 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: f31ee44c0dced52756c6f563ea8b321b0cbce5d6cd53f7ef7fb796efb5f7e58a
|
4
|
+
data.tar.gz: f3151d84b1574d421d9c122310ce3394f98d4920aa571dc168de2858c91cdc7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c090b0758ed52dd8b21a5327e83f6d41f23afc5ad3c53bf265166a85245738c37c5188b15dfed27bb890b36db62896590c7dea3fc8d80e130120d43bd548e560
|
7
|
+
data.tar.gz: 74eb4c9ad0d25987f588ccdc0239e460bbc7169a82cec5fc7c837077e822570ac11d61ae7a136a27f49a5c7093c2e91100d22dd3247729bbbb63fd9c316e19f2
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [3.6.11](https://github.com/craigulliott/dynamic_migrations/compare/v3.6.10...v3.6.11) (2023-09-13)
|
4
|
+
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
* injecting dependent_function into templated triggers ([9e770a3](https://github.com/craigulliott/dynamic_migrations/commit/9e770a352b176c7b10471e9185ac01feca538c0c))
|
9
|
+
* writing enums to the migration files as arrays of strings for more compatibility with special characters ([1910e0f](https://github.com/craigulliott/dynamic_migrations/commit/1910e0f709e5bd560696c2e2b3bd729c7a61e319))
|
10
|
+
|
11
|
+
## [3.6.10](https://github.com/craigulliott/dynamic_migrations/compare/v3.6.9...v3.6.10) (2023-09-13)
|
12
|
+
|
13
|
+
|
14
|
+
### Bug Fixes
|
15
|
+
|
16
|
+
* only concerned about function and enum dependencies if they are in other schemas or have multiple objects which reference them ([ee42670](https://github.com/craigulliott/dynamic_migrations/commit/ee426704d56329cd4ae450d93308097a4419ee63))
|
17
|
+
* some extensions have hyphens in their names, coercing them to underscores so that this does not break the migration class name ([0b2396b](https://github.com/craigulliott/dynamic_migrations/commit/0b2396b171f6d1eeb8dc4567658937576357ba2a))
|
18
|
+
|
3
19
|
## [3.6.9](https://github.com/craigulliott/dynamic_migrations/compare/v3.6.8...v3.6.9) (2023-09-13)
|
4
20
|
|
5
21
|
|
@@ -45,11 +45,19 @@ module DynamicMigrations
|
|
45
45
|
"\"#{data_type}\""
|
46
46
|
end
|
47
47
|
|
48
|
+
# we only provide a dependent enum if the enum has more than one column
|
49
|
+
# or is in a different schema, otherwise it is added to the same migration as this
|
50
|
+
# column and we don't need to worry about dependencies
|
51
|
+
dependent_enum = nil
|
52
|
+
# column.enum will be nil if the column is not an enum
|
53
|
+
if column.enum && (column.enum.columns.count > 1 || column.table.schema != column.enum.schema)
|
54
|
+
dependent_enum = column.enum
|
55
|
+
end
|
56
|
+
|
48
57
|
add_fragment schema: column.table.schema,
|
49
58
|
table: column.table,
|
50
59
|
migration_method: :add_column,
|
51
|
-
|
52
|
-
dependent_enum: column.enum,
|
60
|
+
dependent_enum: dependent_enum,
|
53
61
|
object: column,
|
54
62
|
code_comment: code_comment,
|
55
63
|
migration: <<~RUBY
|
@@ -6,13 +6,22 @@ module DynamicMigrations
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def create_enum enum, code_comment = nil
|
9
|
+
# we only provide a table if the enum has a single column and they
|
10
|
+
# are in the same schema, otherwise we can't reliable handle dependencies
|
11
|
+
# so the enum will be created in the schema's migration
|
12
|
+
enum_table = nil
|
13
|
+
if enum.columns.count == 1 && enum.schema == enum.columns.first&.table&.schema
|
14
|
+
enum_table = enum.columns.first&.table
|
15
|
+
end
|
16
|
+
|
9
17
|
add_fragment schema: enum.schema,
|
18
|
+
table: enum_table,
|
10
19
|
migration_method: :create_enum,
|
11
20
|
object: enum,
|
12
21
|
code_comment: code_comment,
|
13
22
|
migration: <<~RUBY
|
14
23
|
create_enum :#{enum.name}, [
|
15
|
-
|
24
|
+
"#{enum.values.join("\",\n \"")}"
|
16
25
|
]
|
17
26
|
RUBY
|
18
27
|
end
|
@@ -31,7 +40,7 @@ module DynamicMigrations
|
|
31
40
|
code_comment: code_comment,
|
32
41
|
migration: <<~RUBY
|
33
42
|
add_enum_values :#{updated_enum.name}, [
|
34
|
-
|
43
|
+
"#{added_values.join("\",\n \"")}"
|
35
44
|
]
|
36
45
|
RUBY
|
37
46
|
end
|
@@ -5,7 +5,9 @@ module DynamicMigrations
|
|
5
5
|
def enable_extension extension_name, code_comment = nil
|
6
6
|
# no table or schema name for this fragment (it is executed at the database level)
|
7
7
|
add_fragment migration_method: :enable_extension,
|
8
|
-
|
8
|
+
# some extensions have hyphens in them, so coerce the name to underscores
|
9
|
+
# because the object name is used in the migration class name
|
10
|
+
object: extension_name.to_s.tr("-", "_").to_sym,
|
9
11
|
code_comment: code_comment,
|
10
12
|
migration: <<~RUBY
|
11
13
|
enable_extension "#{extension_name}"
|
@@ -15,7 +17,9 @@ module DynamicMigrations
|
|
15
17
|
def disable_extension extension_name, code_comment = nil
|
16
18
|
# no table or schema name for this fragment (it is executed at the database level)
|
17
19
|
add_fragment migration_method: :disable_extension,
|
18
|
-
|
20
|
+
# some extensions have hyphens in them, so coerce the name to underscores
|
21
|
+
# because the object name is used in the migration class name
|
22
|
+
object: extension_name.to_s.tr("-", "_").to_sym,
|
19
23
|
code_comment: code_comment,
|
20
24
|
migration: <<~RUBY
|
21
25
|
disable_extension "#{extension_name}"
|
@@ -2,6 +2,9 @@ module DynamicMigrations
|
|
2
2
|
module Postgres
|
3
3
|
class Generator
|
4
4
|
class Fragment
|
5
|
+
class InvalidNameError < StandardError
|
6
|
+
end
|
7
|
+
|
5
8
|
attr_reader :schema_name
|
6
9
|
attr_reader :table_name
|
7
10
|
attr_reader :migration_method
|
@@ -12,10 +15,24 @@ module DynamicMigrations
|
|
12
15
|
attr_reader :dependency_enum_name
|
13
16
|
|
14
17
|
def initialize schema_name, table_name, migration_method, object_name, code_comment, content
|
18
|
+
valid_name_regex = /\A[a-z][a-z0-9]+(_[a-z0-9]+)*\z/
|
19
|
+
|
20
|
+
unless schema_name.nil? || (schema_name.to_s.match valid_name_regex)
|
21
|
+
raise InvalidNameError, "Invalid schema name `#{schema_name}`, must only be lowercase letters, numbers and underscores"
|
22
|
+
end
|
15
23
|
@schema_name = schema_name
|
24
|
+
|
25
|
+
unless table_name.nil? || (table_name.to_s.match valid_name_regex)
|
26
|
+
raise InvalidNameError, "Invalid table name `#{table_name}`, must only be lowercase letters, numbers and underscores"
|
27
|
+
end
|
16
28
|
@table_name = table_name
|
17
|
-
|
29
|
+
|
30
|
+
unless object_name.to_s.match valid_name_regex
|
31
|
+
raise InvalidNameError, "Invalid object name `#{object_name}`, must only be lowercase letters, numbers and underscores"
|
32
|
+
end
|
18
33
|
@object_name = object_name
|
34
|
+
|
35
|
+
@migration_method = migration_method
|
19
36
|
@code_comment = code_comment
|
20
37
|
@content = content
|
21
38
|
end
|
@@ -21,8 +21,16 @@ module DynamicMigrations
|
|
21
21
|
|
22
22
|
fn_sql = function.definition.strip
|
23
23
|
|
24
|
+
# we only provide a table if the function has a single trigger and they
|
25
|
+
# are in the same schema, otherwise we can't reliable handle dependencies
|
26
|
+
# so the function will be created in the schema's migration
|
27
|
+
function_table = nil
|
28
|
+
if function.triggers.count == 1 && function.schema == function.triggers.first&.table&.schema
|
29
|
+
function_table = function.triggers.first&.table
|
30
|
+
end
|
31
|
+
|
24
32
|
add_fragment schema: function.schema,
|
25
|
-
table:
|
33
|
+
table: function_table,
|
26
34
|
migration_method: :create_function,
|
27
35
|
object: function,
|
28
36
|
code_comment: code_comment,
|
@@ -181,10 +181,10 @@ module DynamicMigrations
|
|
181
181
|
:enums
|
182
182
|
|
183
183
|
elsif all_fragments_for_method? [:enable_extension]
|
184
|
-
(@fragments.count > 1) ? :enable_extensions : :"
|
184
|
+
(@fragments.count > 1) ? :enable_extensions : :"enable_#{fragments.first&.object_name}_extension"
|
185
185
|
|
186
186
|
elsif all_fragments_for_method? [:disable_extension]
|
187
|
-
(@fragments.count > 1) ? :disable_extensions : :"
|
187
|
+
(@fragments.count > 1) ? :disable_extensions : :"disable_#{fragments.first&.object_name}_extension"
|
188
188
|
|
189
189
|
elsif @fragments.first&.table_name
|
190
190
|
:"changes_for_#{@fragments.first&.table_name}"
|
@@ -32,7 +32,15 @@ module DynamicMigrations
|
|
32
32
|
end
|
33
33
|
|
34
34
|
arguments = template_class.new(trigger, code_comment).fragment_arguments
|
35
|
-
|
35
|
+
|
36
|
+
# we only provide a dependent function if the function has more than one trigger
|
37
|
+
# or is in a different schema, otherwise it is added to the same migration as this
|
38
|
+
# trigger and we don't need to worry about dependencies
|
39
|
+
if trigger.function && (trigger.function.triggers.count > 1 || trigger.table.schema != trigger.function.schema)
|
40
|
+
add_fragment(dependent_function: trigger.function, **arguments)
|
41
|
+
else
|
42
|
+
add_fragment(**arguments)
|
43
|
+
end
|
36
44
|
|
37
45
|
# no template, process this as a default trigger (takes all options)
|
38
46
|
else
|
@@ -83,13 +91,21 @@ module DynamicMigrations
|
|
83
91
|
|
84
92
|
options_syntax = options.map { |k, v| "#{k}: #{v}" }.join(", ")
|
85
93
|
|
94
|
+
# we only provide a dependent function if the function has more than one trigger
|
95
|
+
# or is in a different schema, otherwise it is added to the same migration as this
|
96
|
+
# trigger and we don't need to worry about dependencies
|
97
|
+
dependent_function = nil
|
98
|
+
# trigger.function will be nil if the trigger is not an function
|
99
|
+
if trigger.function && (trigger.function.triggers.count > 1 || trigger.table.schema != trigger.function.schema)
|
100
|
+
dependent_function = trigger.function
|
101
|
+
end
|
102
|
+
|
86
103
|
add_fragment schema: trigger.table.schema,
|
87
104
|
table: trigger.table,
|
88
105
|
migration_method: :add_trigger,
|
89
106
|
object: trigger,
|
90
107
|
code_comment: code_comment,
|
91
|
-
dependent_function:
|
92
|
-
# also need dependent_enum
|
108
|
+
dependent_function: dependent_function,
|
93
109
|
migration: <<~RUBY
|
94
110
|
#{method_name} :#{trigger.table.name}, #{options_syntax}
|
95
111
|
RUBY
|
@@ -50,7 +50,7 @@ module DynamicMigrations
|
|
50
50
|
process_schema schema_name, differences[:configuration][:schemas][schema_name], differences[:database][:schemas][schema_name]
|
51
51
|
end
|
52
52
|
|
53
|
-
# return the migrations
|
53
|
+
# return the migrations (they are sorted via a dependency algorithm)
|
54
54
|
@generator.migrations
|
55
55
|
end
|
56
56
|
|
@@ -17,11 +17,14 @@ module DynamicMigrations
|
|
17
17
|
attr_reader :name
|
18
18
|
attr_reader :values
|
19
19
|
attr_reader :description
|
20
|
+
attr_reader :columns
|
20
21
|
|
21
22
|
# initialize a new object to represent a postgres enum
|
22
23
|
def initialize source, schema, name, values, description: nil
|
23
24
|
super source
|
24
25
|
|
26
|
+
@columns = []
|
27
|
+
|
25
28
|
@values = []
|
26
29
|
|
27
30
|
raise ExpectedSchemaError, schema unless schema.is_a? Schema
|
@@ -47,6 +50,15 @@ module DynamicMigrations
|
|
47
50
|
!@description.nil?
|
48
51
|
end
|
49
52
|
|
53
|
+
# for tracking all the columns which are associated with this enum
|
54
|
+
def add_column column
|
55
|
+
# this should never happen, but adding it just in case
|
56
|
+
unless column.source == source
|
57
|
+
raise "Internal error - column source `#{column.source}` does not match enum source `#{source}`"
|
58
|
+
end
|
59
|
+
@columns << column
|
60
|
+
end
|
61
|
+
|
50
62
|
def differences_descriptions other_enum
|
51
63
|
method_differences_descriptions other_enum, [
|
52
64
|
:values
|
@@ -48,7 +48,7 @@ module DynamicMigrations
|
|
48
48
|
!@description.nil?
|
49
49
|
end
|
50
50
|
|
51
|
-
#
|
51
|
+
# for tracking all the triggers which are associated with this function
|
52
52
|
def add_trigger trigger
|
53
53
|
# this should never happen, but adding it just in case
|
54
54
|
unless trigger.source == source
|
@@ -54,6 +54,9 @@ module DynamicMigrations
|
|
54
54
|
raise UnexpectedEnumError, "enum `#{enum.full_name}` does not match this column's data type `#{@data_type}`"
|
55
55
|
end
|
56
56
|
@enum = enum
|
57
|
+
# associate this column with the enum (so they are aware of each other)
|
58
|
+
enum.add_column self
|
59
|
+
|
57
60
|
end
|
58
61
|
end
|
59
62
|
|
@@ -12,7 +12,7 @@ module DynamicMigrations
|
|
12
12
|
def initialize: (untyped validation, untyped code_comment) -> void
|
13
13
|
|
14
14
|
# abstract method (should actually be added to child classes)
|
15
|
-
def fragment_arguments: -> {schema: Postgres::Server::Database::Schema, table: Postgres::Server::Database::Schema::Table, migration_method:
|
15
|
+
def fragment_arguments: -> {schema: Postgres::Server::Database::Schema, table: Postgres::Server::Database::Schema::Table, migration_method: Symbol, object: untyped, code_comment: String?, migration: String, dependent_function: Postgres::Server::Database::Schema::Function?}
|
16
16
|
|
17
17
|
private
|
18
18
|
def assert_not_deferred!: -> nil
|
@@ -11,9 +11,11 @@ module DynamicMigrations
|
|
11
11
|
attr_reader name: Symbol
|
12
12
|
attr_reader values: Array[Symbol]
|
13
13
|
attr_reader description: String?
|
14
|
+
attr_reader columns: Array[Table::Column]
|
14
15
|
def initialize: (database_or_configuration source, Schema schema, Symbol name, Array[Symbol] values, ?description: String?) -> void
|
15
16
|
def full_name: -> Symbol
|
16
17
|
def has_description?: -> bool
|
18
|
+
def add_column: (Schema::Table::Column column) -> void
|
17
19
|
def differences_descriptions: (Enum other_enum) -> Array[String]
|
18
20
|
|
19
21
|
class ExpectedSchemaError < StandardError
|