dynamic_migrations 3.6.9 → 3.6.10

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: 93b2822411008957140dcf9902d9e769cfaf10ea99e9ac424f5c57effdaff8f4
4
+ data.tar.gz: 38e53d341c2f9fd15231f1eea9c670ed1f724d7ce4a6618b587645faafec7356
5
5
  SHA512:
6
- metadata.gz: 85bb27898ab75f4815f7d08b6c7cdd27174f7bbb850fb55d21dad082627077e175d26b87fa64aa3651d98a914e1719a81d0d72955b7b763ecb5fe2ee5e93c9a1
7
- data.tar.gz: a2bb9765ad753949c7f8db6640ca41046f7d1e946d0ed05211cce922d1f0c8b63dc4111183d1ab556c8f4b01278f3f83b2a39fd45c49dd50f718e32e8e617bbb
6
+ metadata.gz: 1f383da41e391a24896b2ae6264710c891f9ab6a46382f70953cf424ccffcee1644e42123ccbe6cb29391d494bb9058c12c93c81a7cba9f20f20755e8eb43d10
7
+ data.tar.gz: b77823cc86a9f235be6ad33d6eb48b382c671ab8a60465435f060de14ad981acdc29767645af87e2128c817d9a0cdd24bc7aca1a9352a6be44289ac2d13688d5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.6.10](https://github.com/craigulliott/dynamic_migrations/compare/v3.6.9...v3.6.10) (2023-09-13)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * 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))
9
+ * 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))
10
+
3
11
  ## [3.6.9](https://github.com/craigulliott/dynamic_migrations/compare/v3.6.8...v3.6.9) (2023-09-13)
4
12
 
5
13
 
@@ -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,7 +6,16 @@ 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,
@@ -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}"
@@ -83,13 +83,21 @@ module DynamicMigrations
83
83
 
84
84
  options_syntax = options.map { |k, v| "#{k}: #{v}" }.join(", ")
85
85
 
86
+ # we only provide a dependent function if the function has more than one trigger
87
+ # or is in a different schema, otherwise it is added to the same migration as this
88
+ # trigger and we don't need to worry about dependencies
89
+ dependent_function = nil
90
+ # trigger.function will be nil if the trigger is not an function
91
+ if trigger.function && (trigger.function.triggers.count > 1 || trigger.table.schema != trigger.function.schema)
92
+ dependent_function = trigger.function
93
+ end
94
+
86
95
  add_fragment schema: trigger.table.schema,
87
96
  table: trigger.table,
88
97
  migration_method: :add_trigger,
89
98
  object: trigger,
90
99
  code_comment: code_comment,
91
- dependent_function: trigger.function,
92
- # also need dependent_enum
100
+ dependent_function: dependent_function,
93
101
  migration: <<~RUBY
94
102
  #{method_name} :#{trigger.table.name}, #{options_syntax}
95
103
  RUBY
@@ -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.10"
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
@@ -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.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Craig Ulliott