dynamic_migrations 3.6.9 → 3.6.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eda59bc82b8accf553a95dabc66fdb1d59ea68750cb4318b2ee970d62d5b679f
4
- data.tar.gz: faaf288de33ee1a6d419be2148a4cc7ec5f76bcd05260d5419b82af7fd256f51
3
+ metadata.gz: f31ee44c0dced52756c6f563ea8b321b0cbce5d6cd53f7ef7fb796efb5f7e58a
4
+ data.tar.gz: f3151d84b1574d421d9c122310ce3394f98d4920aa571dc168de2858c91cdc7a
5
5
  SHA512:
6
- metadata.gz: 85bb27898ab75f4815f7d08b6c7cdd27174f7bbb850fb55d21dad082627077e175d26b87fa64aa3651d98a914e1719a81d0d72955b7b763ecb5fe2ee5e93c9a1
7
- data.tar.gz: a2bb9765ad753949c7f8db6640ca41046f7d1e946d0ed05211cce922d1f0c8b63dc4111183d1ab556c8f4b01278f3f83b2a39fd45c49dd50f718e32e8e617bbb
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
- # this will be nil if the column is not an enum
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
- :#{enum.values.join(",\n :")}
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
- :#{added_values.join(",\n :")}
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
- object: extension_name,
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
- object: extension_name,
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
- @migration_method = migration_method
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: function.triggers.first&.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 : :"create_#{fragments.first&.object_name}_extension"
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 : :"drop_#{fragments.first&.object_name}_extension"
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
- add_fragment(**arguments)
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: trigger.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 organized by schema
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
- # returns all the triggers which are associated with this function
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DynamicMigrations
4
- VERSION = "3.6.9"
4
+ VERSION = "3.6.11"
5
5
  end
@@ -37,6 +37,9 @@ module DynamicMigrations
37
37
  def set_dependent_enum: (Symbol schema_name, Symbol enum_name) -> void
38
38
 
39
39
  def dependency_type: -> (nil | :function | :table | :enum)
40
+
41
+ class InvalidNameError < StandardError
42
+ end
40
43
  end
41
44
  end
42
45
  end
@@ -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: :add_validation, object: Postgres::Server::Database::Schema::Table::Validation, code_comment: String?, migration: String}
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamic_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.9
4
+ version: 3.6.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Craig Ulliott