dynamic_migrations 3.3.1 → 3.4.0

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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/lib/dynamic_migrations/active_record/migrators/enum.rb +44 -0
  4. data/lib/dynamic_migrations/active_record/migrators.rb +1 -0
  5. data/lib/dynamic_migrations/postgres/generator/database_migration.rb +14 -0
  6. data/lib/dynamic_migrations/postgres/generator/enum.rb +75 -0
  7. data/lib/dynamic_migrations/postgres/generator/extension.rb +27 -0
  8. data/lib/dynamic_migrations/postgres/generator/migration.rb +50 -19
  9. data/lib/dynamic_migrations/postgres/generator/schema_migration.rb +8 -0
  10. data/lib/dynamic_migrations/postgres/generator/table_migration.rb +1 -16
  11. data/lib/dynamic_migrations/postgres/generator.rb +25 -5
  12. data/lib/dynamic_migrations/postgres/server/database/configured_extensions.rb +40 -0
  13. data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/extensions.rb +30 -0
  14. data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/enums.rb +73 -0
  15. data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas.rb +3 -0
  16. data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations.rb +10 -2
  17. data/lib/dynamic_migrations/postgres/server/database/differences.rb +55 -3
  18. data/lib/dynamic_migrations/postgres/server/database/enums_loader.rb +40 -0
  19. data/lib/dynamic_migrations/postgres/server/database/extensions_loader.rb +26 -0
  20. data/lib/dynamic_migrations/postgres/server/database/loaded_extensions.rb +40 -0
  21. data/lib/dynamic_migrations/postgres/server/database/loaded_schemas_builder.rb +13 -1
  22. data/lib/dynamic_migrations/postgres/server/database/schema/enum.rb +60 -0
  23. data/lib/dynamic_migrations/postgres/server/database/schema/enums.rb +63 -0
  24. data/lib/dynamic_migrations/postgres/server/database/schema/function.rb +1 -1
  25. data/lib/dynamic_migrations/postgres/server/database/schema.rb +2 -0
  26. data/lib/dynamic_migrations/postgres/server/database/structure_loader.rb +1 -1
  27. data/lib/dynamic_migrations/postgres/server/database.rb +6 -0
  28. data/lib/dynamic_migrations/version.rb +1 -1
  29. data/lib/dynamic_migrations.rb +12 -0
  30. metadata +14 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3917e377fb83c0bf7d8d836521935e6fecb298d1fea691bef33b212577f78801
4
- data.tar.gz: 54c2c5ebc5c685029806cc2ecc99aea2871bf3a480fe245041594fe616362de8
3
+ metadata.gz: 4175e35ddf2a941304c9efec0400c7ed6d933bf982d3744eb45f2891d6806ec6
4
+ data.tar.gz: c78c493bf1660d8b2eb36fe355a07869b8ef2fdbc4a05527da51e27b56dcfa2e
5
5
  SHA512:
6
- metadata.gz: 18028c2423770216cb7b2121e626d361b4c9bd8943b17b28903221e0a05e63cb2b9ade9d59b23b4168a995d8e2d35b3ca9476a6f94f6b13980ef2931c7aa8885
7
- data.tar.gz: d2591dc1c9cf267efc8cf038dcef0a80ecd19eb0981dde81ae5fc68c853125ba805d7a2716123794843452fdc1eafe9dc7a9a1c34a09f71739e3aebd1b4579ff
6
+ metadata.gz: f4e13bc988a286385fa6e39b4cbf5d001674cec8482ee9cb4680d34fe9b3a82fc869dccbef8c31527f3f23a4230796cc07b4559bd90c35373b3865877328878c
7
+ data.tar.gz: 73a51e5ae774cd41863e67c2f5cf7f541beaeddbf6b027d81637a6926542d267fb0ca34e790b86b206786668cf2fc3466242a6347871ed552f739aa2a7a8baf8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.4.0](https://github.com/craigulliott/dynamic_migrations/compare/v3.3.1...v3.4.0) (2023-08-23)
4
+
5
+
6
+ ### Features
7
+
8
+ * adding support for enums and extensions ([6e00d5f](https://github.com/craigulliott/dynamic_migrations/commit/6e00d5fc726e2a1bbeb282477c8bca92b94462cf))
9
+
3
10
  ## [3.3.1](https://github.com/craigulliott/dynamic_migrations/compare/v3.3.0...v3.3.1) (2023-08-18)
4
11
 
5
12
 
@@ -0,0 +1,44 @@
1
+ module DynamicMigrations
2
+ module ActiveRecord
3
+ module Migrators
4
+ module Enum
5
+ # create a postgres enum
6
+ def create_enum enum_name, values
7
+ # schema_name was not provided to this method, it comes from the migration class
8
+ execute <<~SQL
9
+ CREATE TYPE #{schema_name}.#{enum_name} as ENUM ('#{values.join("','")}');
10
+ SQL
11
+ end
12
+
13
+ # add vaues to a given enum
14
+ def add_enum_values enum_name, values
15
+ sqls = values.map do |value|
16
+ "ALTER TYPE #{schema_name}.#{enum_name} ADD ATTRIBUTE '#{value}';"
17
+ end
18
+ execute sqls.join("\n")
19
+ end
20
+
21
+ # remove a enum from the schema
22
+ def drop_enum enum_name
23
+ execute <<~SQL
24
+ DROP TYPE #{schema_name}.#{enum_name};
25
+ SQL
26
+ end
27
+
28
+ # add a comment to a enum
29
+ def set_enum_comment enum_name, comment
30
+ execute <<~SQL
31
+ COMMENT ON TYPE #{schema_name}.#{enum_name} IS '#{quote comment}';
32
+ SQL
33
+ end
34
+
35
+ # remove the comment from a enum
36
+ def remove_enum_comment enum_name
37
+ execute <<~SQL
38
+ COMMENT ON TYPE #{schema_name}.#{enum_name} IS null;
39
+ SQL
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -30,6 +30,7 @@ module DynamicMigrations
30
30
  include Function
31
31
  include UniqueConstraint
32
32
  include Trigger
33
+ include Enum
33
34
 
34
35
  # The schema name should be set before the migrations for
35
36
  # each schema's migrations are run. This is done by:
@@ -0,0 +1,14 @@
1
+ module DynamicMigrations
2
+ module Postgres
3
+ class Generator
4
+ class DatabaseMigration < Migration
5
+ # these sections are in order for which they will appear in a migration,
6
+ # note that removals come before additions, and that the order here optomizes
7
+ # for dependencies (i.e. columns have to be created before indexes are added and
8
+ # triggers are removed before functions are dropped)
9
+ add_structure_template [:create_extension], "Create Extension"
10
+ add_structure_template [:drop_extension], "Drop Extension"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,75 @@
1
+ module DynamicMigrations
2
+ module Postgres
3
+ class Generator
4
+ module Enum
5
+ class UnremovableEnumValuesError < StandardError
6
+ end
7
+
8
+ def create_enum enum, code_comment = nil
9
+ add_fragment schema: enum.schema,
10
+ migration_method: :create_enum,
11
+ object: enum,
12
+ code_comment: code_comment,
13
+ migration: <<~RUBY
14
+ create_enum :#{enum.name}, [
15
+ :#{enum.values.join(",\n :")}
16
+ ]
17
+ RUBY
18
+ end
19
+
20
+ def update_enum original_enum, updated_enum, code_comment = nil
21
+ added_values = updated_enum.values - original_enum.values
22
+ removed_values = original_enum.values - updated_enum.values
23
+
24
+ if removed_values.any?
25
+ raise UnremovableEnumValuesError, "You can not remove enum values from postgres. Tring to remove '#{removed_values.join("', ")}'"
26
+ end
27
+
28
+ add_fragment schema: updated_enum.schema,
29
+ migration_method: :add_enum_values,
30
+ object: updated_enum,
31
+ code_comment: code_comment,
32
+ migration: <<~RUBY
33
+ add_enum_values :#{updated_enum.name}, [
34
+ :#{added_values.join(",\n :")}
35
+ ]
36
+ RUBY
37
+ end
38
+
39
+ def drop_enum enum, code_comment = nil
40
+ add_fragment schema: enum.schema,
41
+ migration_method: :drop_enum,
42
+ object: enum,
43
+ code_comment: code_comment,
44
+ migration: <<~RUBY
45
+ drop_enum :#{enum.name}
46
+ RUBY
47
+ end
48
+
49
+ # add a comment to a enum
50
+ def set_enum_comment enum, code_comment = nil
51
+ add_fragment schema: enum.schema,
52
+ migration_method: :set_enum_comment,
53
+ object: enum,
54
+ code_comment: code_comment,
55
+ migration: <<~RUBY
56
+ set_enum_comment :#{enum.name}, <<~COMMENT
57
+ #{indent enum.description || ""}
58
+ COMMENT
59
+ RUBY
60
+ end
61
+
62
+ # remove the comment from a enum
63
+ def remove_enum_comment enum, code_comment = nil
64
+ add_fragment schema: enum.schema,
65
+ migration_method: :remove_enum_comment,
66
+ object: enum,
67
+ code_comment: code_comment,
68
+ migration: <<~RUBY
69
+ remove_enum_comment :#{enum.name}
70
+ RUBY
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,27 @@
1
+ module DynamicMigrations
2
+ module Postgres
3
+ class Generator
4
+ module Extension
5
+ def create_extension extension_name, code_comment = nil
6
+ # no table or schema name for this fragment (it is executed at the database level)
7
+ add_fragment migration_method: :create_extension,
8
+ object: extension_name,
9
+ code_comment: code_comment,
10
+ migration: <<~RUBY
11
+ create_extension :#{extension_name}
12
+ RUBY
13
+ end
14
+
15
+ def drop_extension extension_name, code_comment = nil
16
+ # no table or schema name for this fragment (it is executed at the database level)
17
+ add_fragment migration_method: :drop_extension,
18
+ object: extension_name,
19
+ code_comment: code_comment,
20
+ migration: <<~RUBY
21
+ drop_extension :#{extension_name}
22
+ RUBY
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -2,9 +2,6 @@ module DynamicMigrations
2
2
  module Postgres
3
3
  class Generator
4
4
  class Migration
5
- class UnexpectedSchemaError < StandardError
6
- end
7
-
8
5
  class SectionNotFoundError < StandardError
9
6
  end
10
7
 
@@ -17,6 +14,29 @@ module DynamicMigrations
17
14
  class NoFragmentsError < StandardError
18
15
  end
19
16
 
17
+ class MissingRequiredTableName < StandardError
18
+ end
19
+
20
+ class MissingRequiredSchemaName < StandardError
21
+ end
22
+
23
+ class UnexpectedTableError < StandardError
24
+ end
25
+
26
+ class UnexpectedSchemaError < StandardError
27
+ end
28
+
29
+ attr_reader :table_name
30
+ attr_reader :schema_name
31
+ attr_reader :fragments
32
+
33
+ # schema_name and table_name can be nil
34
+ def initialize schema_name = nil, table_name = nil
35
+ @schema_name = schema_name
36
+ @table_name = table_name
37
+ @fragments = []
38
+ end
39
+
20
40
  # Defines a new section in the migration file, this is used to group
21
41
  # migration fragments of the provided method names together under the
22
42
  # provided header
@@ -47,25 +67,27 @@ module DynamicMigrations
47
67
  @structure_templates = []
48
68
  end
49
69
 
50
- attr_reader :schema_name
51
- attr_reader :fragments
52
-
53
- def initialize schema_name
54
- @schema_name = schema_name
55
- @fragments = []
56
- end
57
-
58
70
  # Add a migration fragment to this migration, if the migration is not
59
71
  # configured (via a structure template) to handle the method_name of the
60
72
  # fragment, then am error is raised. An error will also be raised if the
61
73
  # migration belongs to a different schema than the provided fragment.
62
74
  def add_fragment fragment
63
- raise UnexpectedSchemaError unless @schema_name == fragment.schema_name
64
-
65
75
  unless supported_migration_method? fragment.migration_method
66
76
  raise UnexpectedMigrationMethodNameError, "Expected method to be a valid migrator method, got `#{fragment.migration_method}`"
67
77
  end
68
78
 
79
+ # confirm the fragment is for this schema (even if both
80
+ # these values are nil/there is no schema)
81
+ unless @schema_name == fragment.schema_name
82
+ raise UnexpectedSchemaError, "Fragment is for schema `#{fragment.schema_name || "nil"}` but migration is for schema `#{@schema_name || "nil"}`"
83
+ end
84
+
85
+ # confirm this fragment is for this table, this works for database and schame
86
+ # migrations to, as all values should be nil
87
+ unless @table_name == fragment.table_name
88
+ raise UnexpectedTableError, "Fragment is for table `#{fragment.table_name || "nil"}` but migration is for table `#{@table_name || "nil"}`"
89
+ end
90
+
69
91
  @fragments << fragment
70
92
 
71
93
  fragment
@@ -122,25 +144,34 @@ module DynamicMigrations
122
144
  raise NoFragmentsError if fragments.empty?
123
145
 
124
146
  if fragments_for_method? :create_schema
125
- "create_#{first_fragment_using_migration_method(:create_schema).schema_name}_schema".to_sym
147
+ :"create_#{first_fragment_using_migration_method(:create_schema).schema_name}_schema"
126
148
 
127
149
  elsif fragments_for_method? :drop_schema
128
- "drop_#{first_fragment_using_migration_method(:drop_schema).schema_name}_schema".to_sym
150
+ :"drop_#{first_fragment_using_migration_method(:drop_schema).schema_name}_schema"
129
151
 
130
152
  elsif fragments_for_method? :create_table
131
- "create_#{first_fragment_using_migration_method(:create_table).table_name}".to_sym
153
+ :"create_#{first_fragment_using_migration_method(:create_table).table_name}"
132
154
 
133
155
  elsif fragments_for_method? :drop_table
134
- "drop_#{first_fragment_using_migration_method(:drop_table).table_name}".to_sym
156
+ :"drop_#{first_fragment_using_migration_method(:drop_table).table_name}"
135
157
 
136
158
  elsif all_fragments_for_method? [:create_function]
137
- "create_function_#{@fragments.find { |s| s.migration_method == :create_function }&.object_name}".to_sym
159
+ :"create_function_#{@fragments.find { |s| s.migration_method == :create_function }&.object_name}"
138
160
 
139
161
  elsif all_fragments_for_method? [:create_function, :update_function, :drop_function, :set_function_comment, :remove_function_comment]
140
162
  :schema_functions
141
163
 
164
+ elsif all_fragments_for_method? [:create_enum, :add_enum_values, :drop_enum, :set_enum_comment, :remove_enum_comment]
165
+ :enums
166
+
167
+ elsif all_fragments_for_method? [:create_extension]
168
+ (@fragments.count > 1) ? :":create_extensions" : :"create_#{fragments.first&.object_name}_extension"
169
+
170
+ elsif all_fragments_for_method? [:drop_extension]
171
+ (@fragments.count > 1) ? :":drop_extensions" : :"drop_#{fragments.first&.object_name}_extension"
172
+
142
173
  elsif @fragments.first&.table_name
143
- "changes_for_#{@fragments.first&.table_name}".to_sym
174
+ :"changes_for_#{@fragments.first&.table_name}"
144
175
 
145
176
  else
146
177
  :changes
@@ -7,10 +7,18 @@ module DynamicMigrations
7
7
  # for dependencies (i.e. columns have to be created before indexes are added and
8
8
  # triggers are removed before functions are dropped)
9
9
  add_structure_template [:remove_function_comment, :drop_function], "Remove Functions"
10
+ add_structure_template [:remove_enum_comment, :drop_enum], "Drop Enums"
10
11
  add_structure_template [:drop_schema], "Drop this schema"
12
+ add_structure_template [:create_enum, :add_enum_values, :set_enum_comment], "Enums"
11
13
  add_structure_template [:create_schema], "Create this schema"
12
14
  add_structure_template [:create_function], "Functions"
13
15
  add_structure_template [:update_function, :set_function_comment], "Update Functions"
16
+ add_structure_template [:create_extension, :drop_extension], "Extensions"
17
+
18
+ def initialize schema_name
19
+ raise MissingRequiredSchemaName unless schema_name
20
+ super
21
+ end
14
22
  end
15
23
  end
16
24
  end
@@ -2,12 +2,6 @@ module DynamicMigrations
2
2
  module Postgres
3
3
  class Generator
4
4
  class TableMigration < Migration
5
- class UnexpectedTableError < StandardError
6
- end
7
-
8
- class MissingRequiredTableName < StandardError
9
- end
10
-
11
5
  # these sections are in order for which they will appear in a migration,
12
6
  # note that removals come before additions, and that the order here optomizes
13
7
  # for dependencies (i.e. columns have to be created before indexes are added and
@@ -31,18 +25,9 @@ module DynamicMigrations
31
25
  add_structure_template [:add_trigger, :set_trigger_comment], "Triggers"
32
26
  add_structure_template [:update_function, :set_function_comment], "Update Functions"
33
27
 
34
- attr_accessor :table_name
35
-
36
28
  def initialize schema_name, table_name
29
+ raise MissingRequiredSchemaName unless schema_name
37
30
  raise MissingRequiredTableName unless table_name
38
- super schema_name
39
- @table_name = table_name
40
- end
41
-
42
- def add_fragment fragment
43
- unless @table_name == fragment.table_name
44
- raise UnexpectedTableError, "Frgment is for table `#{fragment.table_name}` but migration is for table `#{@table_name}`"
45
- end
46
31
  super
47
32
  end
48
33
  end
@@ -16,6 +16,9 @@ module DynamicMigrations
16
16
  class TableMigrationNotFound < StandardError
17
17
  end
18
18
 
19
+ class UnprocessableFragmentError < StandardError
20
+ end
21
+
19
22
  include Schema
20
23
  include Table
21
24
  include Column
@@ -26,6 +29,8 @@ module DynamicMigrations
26
29
  include Validation
27
30
  include Function
28
31
  include Trigger
32
+ include Enum
33
+ include Extension
29
34
 
30
35
  def initialize
31
36
  @fragments = []
@@ -36,6 +41,9 @@ module DynamicMigrations
36
41
  # a hash to hold the generated migrations orgnized by their schema and table
37
42
  # this makes it easier and faster to work with them within this method
38
43
  database_migrations = {}
44
+ # the database_specific_migration is for migrations which dont belong
45
+ # within a specific schema
46
+ database_specific_migration = DatabaseMigration.new
39
47
 
40
48
  # Process each fragment, and organize them into migrations. We create a shared
41
49
  # Migration for each table, and a single shared migration for any schema migrations
@@ -54,15 +62,22 @@ module DynamicMigrations
54
62
  table_name = fragment.table_name
55
63
  # If we have a table name, then add the migration fragment to a
56
64
  # TableMigration which holds all of the migrations for this table
57
- if table_name
65
+ if table_name && schema_name
58
66
  table_migration = schema_migrations[:table_migrations][table_name] ||= TableMigration.new(schema_name, table_name)
59
67
  table_migration.add_fragment fragment
60
68
 
61
- # migration fragments which do not belong to a specific table are added
69
+ # migration fragments which do have a schema, but do not belong to a specific table are added
62
70
  # to a dedicated SchemaMigration object
63
- else
71
+ elsif schema_name && table_name.nil?
64
72
  schema_migration = schema_migrations[:schema_migration] ||= SchemaMigration.new(schema_name)
65
73
  schema_migration.add_fragment fragment
74
+
75
+ # migrations with no schema or table, are added to a database
76
+ # migration (these re really just creating/dropping extensions)
77
+ elsif schema_name.nil? && table_name.nil?
78
+ database_specific_migration.add_fragment fragment
79
+ else
80
+ raise UnprocessableFragmentError
66
81
  end
67
82
  end
68
83
 
@@ -158,6 +173,11 @@ module DynamicMigrations
158
173
  # the order is determined by their dependencies
159
174
  final_migrations = dependency_sorter.tsort
160
175
 
176
+ # if any database only migrations exist, then add them to the from of the array here
177
+ if database_specific_migration.fragments.any?
178
+ final_migrations.unshift database_specific_migration
179
+ end
180
+
161
181
  # return the final migrations in the expected format
162
182
  final_migrations.map do |migration|
163
183
  {
@@ -200,11 +220,11 @@ module DynamicMigrations
200
220
  @dep[node].each(&block)
201
221
  end
202
222
 
203
- def add_fragment schema:, migration_method:, object:, migration:, table: nil, code_comment: nil, dependent_table: nil
223
+ def add_fragment migration_method:, object:, migration:, schema: nil, table: nil, code_comment: nil, dependent_table: nil
204
224
  # Remove any empty lines and whitespace from the beginning or the end of the migration and then
205
225
  # strip any empty lines witin the migration (remove the whitespace from them, not delete them).
206
226
  final_migration = strip_empty_lines(migration).strip
207
- fragment = Fragment.new(schema.name, table&.name, migration_method, object.name, code_comment, final_migration)
227
+ fragment = Fragment.new(schema&.name, table&.name, migration_method, object.name, code_comment, final_migration)
208
228
  if dependent_table
209
229
  fragment.set_dependent_table dependent_table.schema.name, dependent_table.name
210
230
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicMigrations
4
+ module Postgres
5
+ class Server
6
+ class Database
7
+ module ConfiguredExtensions
8
+ class ConfiguredExtensionAlreadyExistsError < StandardError
9
+ end
10
+
11
+ # adds a new configured extension for this database
12
+ def add_configured_extension extension_name
13
+ raise ExpectedSymbolError, extension_name unless extension_name.is_a? Symbol
14
+ if has_configured_extension? extension_name
15
+ raise(ConfiguredExtensionAlreadyExistsError, "Configured extension #{extension_name} already exists")
16
+ end
17
+ # sort the hash so that the extensions are in alphabetical order by name
18
+ @configured_extensions[extension_name] = true
19
+ sorted_extensions = {}
20
+ @configured_extensions.keys.sort.each do |extension_name|
21
+ sorted_extensions[extension_name] = true
22
+ end
23
+ @configured_extensions = sorted_extensions
24
+ end
25
+
26
+ # returns true if this table has a configured extension with the provided name, otherwise false
27
+ def has_configured_extension? extension_name
28
+ raise ExpectedSymbolError, extension_name unless extension_name.is_a? Symbol
29
+ @configured_extensions.key? extension_name
30
+ end
31
+
32
+ # returns an array of this tables configured extensions
33
+ def configured_extensions
34
+ @configured_extensions.keys
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicMigrations
4
+ module Postgres
5
+ class Server
6
+ class Database
7
+ class Differences
8
+ class ToMigrations
9
+ module Extensions
10
+ def process_extension extension_name, configuration_extension, database_extension
11
+ # if the extension exists in the configuration but not in the database
12
+ # then we have to create it
13
+ if configuration_extension[:exists] == true && database_extension[:exists] == false
14
+ # a migration to create the extension
15
+ @generator.create_extension extension_name
16
+
17
+ # if the extension exists in the database but not in the configuration
18
+ # then we need to delete it
19
+ elsif configuration_extension[:exists] == false && database_extension[:exists] == true
20
+ # a migration to drop the extension
21
+ @generator.drop_extension extension_name
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicMigrations
4
+ module Postgres
5
+ class Server
6
+ class Database
7
+ class Differences
8
+ class ToMigrations
9
+ module Schemas
10
+ module Enums
11
+ def process_enums schema_name, configuration_enums, database_enums
12
+ # process all the enums
13
+ enum_names = (configuration_enums.keys + database_enums.keys).uniq
14
+ enum_names.each do |enum_name|
15
+ process_enum schema_name, enum_name, configuration_enums[enum_name] || {}, database_enums[enum_name] || {}
16
+ end
17
+ end
18
+
19
+ def process_enum schema_name, enum_name, configuration_enum, database_enum
20
+ # If the enum exists in the configuration but not in the database
21
+ # then we have to create it.
22
+ if configuration_enum[:exists] == true && database_enum[:exists] == false
23
+ # a migration to create the enum
24
+ enum = @database.configured_schema(schema_name).enum(enum_name)
25
+ @generator.create_enum enum
26
+ # optionally add the description
27
+ if enum.has_description?
28
+ @generator.set_enum_comment enum
29
+ end
30
+
31
+ # If the schema exists in the database but not in the configuration
32
+ # then we need to delete it.
33
+ elsif configuration_enum[:exists] == false && database_enum[:exists] == true
34
+ # a migration to create the enum
35
+ enum = @database.loaded_schema(schema_name).enum(enum_name)
36
+ @generator.drop_enum enum
37
+
38
+ # If the enum exists in both the configuration and database representations
39
+ # but the values is different then we need to update the values.
40
+ elsif configuration_enum[:values][:matches] == false
41
+ original_enum = @database.loaded_schema(schema_name).enum(enum_name)
42
+ updated_enum = @database.configured_schema(schema_name).enum(enum_name)
43
+ @generator.update_enum original_enum, updated_enum
44
+ # does the description also need to be updated
45
+ if configuration_enum[:description][:matches] == false
46
+ # if the description was removed
47
+ if configuration_enum[:description].nil?
48
+ @generator.remove_enum_comment updated_enum
49
+ else
50
+ @generator.set_enum_comment updated_enum
51
+ end
52
+ end
53
+
54
+ # If the enum exists in both the configuration and database representations
55
+ # but the description is different then we need to update the description.
56
+ elsif configuration_enum[:description][:matches] == false
57
+ enum = @database.configured_schema(schema_name).enum(enum_name)
58
+ # if the description was removed
59
+ if configuration_enum[:description].nil?
60
+ @generator.remove_enum_comment enum
61
+ else
62
+ @generator.set_enum_comment enum
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -18,6 +18,7 @@ module DynamicMigrations
18
18
  # we process the tables and functions after we create the schema
19
19
  # otherwise the schemas objects will not be able to be created
20
20
  process_functions schema_name, configuration_schema[:functions], {}
21
+ process_enums schema_name, configuration_schema[:enums], {}
21
22
  process_tables schema_name, configuration_schema[:tables], {}
22
23
 
23
24
  # if the schema exists in the database but not in the configuration
@@ -26,6 +27,7 @@ module DynamicMigrations
26
27
  # we process the tables and functions before we drop the schema
27
28
  # as this will drop any dependencies on the schema
28
29
  process_functions schema_name, {}, database_schema[:functions]
30
+ process_enums schema_name, {}, database_schema[:enums]
29
31
  process_tables schema_name, {}, database_schema[:tables]
30
32
 
31
33
  # a migration to drop the schema
@@ -36,6 +38,7 @@ module DynamicMigrations
36
38
  # then we just need to process the tables and functions
37
39
  else
38
40
  process_functions schema_name, configuration_schema[:functions], database_schema[:functions]
41
+ process_enums schema_name, configuration_schema[:enums], database_schema[:enums]
39
42
  process_tables schema_name, configuration_schema[:tables], database_schema[:tables]
40
43
  end
41
44
  end
@@ -12,8 +12,10 @@ module DynamicMigrations
12
12
  class UnexpectedDifferencesObjectError < StandardError
13
13
  end
14
14
 
15
+ include Extensions
15
16
  include Schemas
16
17
  include Schemas::Functions
18
+ include Schemas::Enums
17
19
  include Schemas::Tables
18
20
  include Schemas::Tables::Columns
19
21
  include Schemas::Tables::ForeignKeyConstraints
@@ -35,11 +37,17 @@ module DynamicMigrations
35
37
  end
36
38
 
37
39
  def migrations
40
+ # process all the extensions
41
+ extension_names = differences[:configuration][:extensions].keys
42
+ extension_names.each do |extension_name|
43
+ process_extension extension_name, differences[:configuration][:extensions][extension_name], differences[:database][:extensions][extension_name]
44
+ end
45
+
38
46
  # process all the schemas (we can fetch the schema names from either the
39
47
  # configuration or the database object)
40
- schema_names = differences[:configuration].keys
48
+ schema_names = differences[:configuration][:schemas].keys
41
49
  schema_names.each do |schema_name|
42
- process_schema schema_name, differences[:configuration][schema_name], differences[:database][schema_name]
50
+ process_schema schema_name, differences[:configuration][:schemas][schema_name], differences[:database][:schemas][schema_name]
43
51
  end
44
52
 
45
53
  # return the migrations organized by schema
@@ -32,11 +32,38 @@ module DynamicMigrations
32
32
  # versions of the current database
33
33
  def to_h
34
34
  {
35
- configuration: self.class.compare_schemas(@database.configured_schemas_hash, @database.loaded_schemas_hash),
36
- database: self.class.compare_schemas(@database.loaded_schemas_hash, @database.configured_schemas_hash)
35
+ configuration: {
36
+ schemas: self.class.compare_schemas(@database.configured_schemas_hash, @database.loaded_schemas_hash),
37
+ extensions: self.class.compare_extensions(@database.configured_extensions, @database.loaded_extensions)
38
+ },
39
+ database: {
40
+ schemas: self.class.compare_schemas(@database.loaded_schemas_hash, @database.configured_schemas_hash),
41
+ extensions: self.class.compare_extensions(@database.loaded_extensions, @database.configured_extensions)
42
+ }
37
43
  }
38
44
  end
39
45
 
46
+ def self.compare_extensions extensions, comparison_extensions
47
+ result = {}
48
+ # the extensions
49
+ extensions.each do |extension_name|
50
+ # compare this extension to the equivilent in the comparison list
51
+ # note that the comparison may be nil
52
+ result[extension_name] = {
53
+ exists: true
54
+ }
55
+ end
56
+ # look for any in the comparison list which were not in the base list
57
+ comparison_extensions.each do |extension_name|
58
+ unless result.key? extension_name
59
+ result[extension_name] = {
60
+ exists: false
61
+ }
62
+ end
63
+ end
64
+ result
65
+ end
66
+
40
67
  def self.compare_schemas schemas, comparison_schemas
41
68
  result = {}
42
69
  # the base schemas
@@ -63,10 +90,12 @@ module DynamicMigrations
63
90
 
64
91
  comparison_tables = comparison_schema.nil? ? {} : comparison_schema.tables_hash
65
92
  comparison_functions = comparison_schema.nil? ? {} : comparison_schema.functions_hash
93
+ comparison_enums = comparison_schema.nil? ? {} : comparison_schema.enums_hash
66
94
  {
67
95
  exists: true,
68
96
  tables: compare_tables(schema.tables_hash, comparison_tables),
69
- functions: compare_functions(schema.functions_hash, comparison_functions)
97
+ functions: compare_functions(schema.functions_hash, comparison_functions),
98
+ enums: compare_enums(schema.enums_hash, comparison_enums)
70
99
  }
71
100
  end
72
101
 
@@ -158,6 +187,29 @@ module DynamicMigrations
158
187
  result
159
188
  end
160
189
 
190
+ # compare two hash representations of a set of enums and return
191
+ # an object which represents the provided `enums` and any differences
192
+ # between it and the `comparison_enums`
193
+ def self.compare_enums enums, comparison_enums
194
+ result = {}
195
+ # the base enums
196
+ enums.each do |enum_name, enum|
197
+ result[enum_name] = compare_record enum, comparison_enums[enum_name], [
198
+ :values,
199
+ :description
200
+ ]
201
+ end
202
+ # look for any in the comparison list which were not in the base list
203
+ comparison_enums.each do |enum_name, enum|
204
+ unless result.key? enum_name
205
+ result[enum_name] = {
206
+ exists: false
207
+ }
208
+ end
209
+ end
210
+ result
211
+ end
212
+
161
213
  # compare two hash representations of a set of columns and return
162
214
  # an object which represents the provided `columns` and any differences
163
215
  # between it and the `comparison_columns`
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicMigrations
4
+ module Postgres
5
+ class Server
6
+ class Database
7
+ module EnumsLoader
8
+ def fetch_enums
9
+ rows = connection.exec(<<~SQL)
10
+ SELECT
11
+ n.nspname AS schema_name,
12
+ t.typname AS enum_name,
13
+ e.enumlabel AS enum_value,
14
+ obj_description(e.enumtypid, 'pg_type') as enum_description
15
+ FROM pg_type t
16
+ JOIN pg_enum e ON t.oid = e.enumtypid
17
+ JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
18
+ ORDER BY enumsortorder
19
+ SQL
20
+
21
+ schemas = {}
22
+ rows.each do |row|
23
+ schema_name = row["schema_name"].to_sym
24
+ enum_name = row["enum_name"].to_sym
25
+ enum_value = row["enum_value"].to_sym
26
+
27
+ schema = schemas[schema_name] ||= {}
28
+ enum = schema[enum_name] ||= {
29
+ values: [],
30
+ description: row["enum_description"]
31
+ }
32
+ enum[:values] << enum_value
33
+ end
34
+ schemas
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicMigrations
4
+ module Postgres
5
+ class Server
6
+ class Database
7
+ module ExtensionsLoader
8
+ # return an array of the extensions active in this database
9
+ def fetch_extensions
10
+ rows = connection.exec(<<~SQL)
11
+ SELECT
12
+ extname AS name
13
+ FROM pg_extension;
14
+ SQL
15
+
16
+ extensions = []
17
+ rows.each do |row|
18
+ extensions << row["name"].to_sym
19
+ end
20
+ extensions
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicMigrations
4
+ module Postgres
5
+ class Server
6
+ class Database
7
+ module LoadedExtensions
8
+ class LoadedExtensionAlreadyExistsError < StandardError
9
+ end
10
+
11
+ # adds a new loaded extension for this database
12
+ def add_loaded_extension extension_name
13
+ raise ExpectedSymbolError, extension_name unless extension_name.is_a? Symbol
14
+ if has_loaded_extension? extension_name
15
+ raise(LoadedExtensionAlreadyExistsError, "Loaded extension #{extension_name} already exists")
16
+ end
17
+ # sort the hash so that the extensions are in alphabetical order by name
18
+ @loaded_extensions[extension_name] = true
19
+ sorted_extensions = {}
20
+ @loaded_extensions.keys.sort.each do |extension_name|
21
+ sorted_extensions[extension_name] = true
22
+ end
23
+ @loaded_extensions = sorted_extensions
24
+ end
25
+
26
+ # returns true if this table has a loaded extension with the provided name, otherwise false
27
+ def has_loaded_extension? extension_name
28
+ raise ExpectedSymbolError, extension_name unless extension_name.is_a? Symbol
29
+ @loaded_extensions.key? extension_name
30
+ end
31
+
32
+ # returns an array of this tables loaded extensions
33
+ def loaded_extensions
34
+ @loaded_extensions.keys
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -13,7 +13,7 @@ module DynamicMigrations
13
13
 
14
14
  # recursively process the database and build all the schemas,
15
15
  # tables and columns
16
- def recursively_build_schemas_from_database
16
+ def recursively_load_database_structure
17
17
  validations = fetch_validations
18
18
  fetch_structure.each do |schema_name, schema_definition|
19
19
  schema = add_loaded_schema schema_name
@@ -39,6 +39,18 @@ module DynamicMigrations
39
39
  end
40
40
  end
41
41
 
42
+ # add any active extensions to the database
43
+ fetch_extensions.each do |extension_name|
44
+ add_loaded_extension extension_name
45
+ end
46
+
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
+
42
54
  # now that the structure has been loaded, we can add keys (foreign
43
55
  # keys need to be added last, because they can depend on tables from
44
56
  # different schemas)
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicMigrations
4
+ module Postgres
5
+ class Server
6
+ class Database
7
+ class Schema
8
+ # This class represents a postgres enum.
9
+ class Enum < Source
10
+ class ExpectedSchemaError < StandardError
11
+ end
12
+
13
+ class ExpectedValuesError < StandardError
14
+ end
15
+
16
+ attr_reader :schema
17
+ attr_reader :name
18
+ attr_reader :values
19
+ attr_reader :description
20
+
21
+ # initialize a new object to represent a postgres enum
22
+ def initialize source, schema, name, values, description: nil
23
+ super source
24
+
25
+ @values = []
26
+
27
+ raise ExpectedSchemaError, schema unless schema.is_a? Schema
28
+ @schema = schema
29
+
30
+ raise ExpectedSymbolError, name unless name.is_a? Symbol
31
+ @name = name
32
+
33
+ unless values.is_a?(Array) && values.count > 0
34
+ raise ExpectedValuesError, "Values are required for enums"
35
+ end
36
+ @values = values
37
+
38
+ unless description.nil?
39
+ raise ExpectedStringError, description unless description.is_a? String
40
+ @description = description.strip
41
+ @description = nil if description == ""
42
+ end
43
+ end
44
+
45
+ # returns true if this enum has a description, otehrwise false
46
+ def has_description?
47
+ !@description.nil?
48
+ end
49
+
50
+ def differences_descriptions other_enum
51
+ method_differences_descriptions other_enum, [
52
+ :values
53
+ ]
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicMigrations
4
+ module Postgres
5
+ class Server
6
+ class Database
7
+ class Schema < Source
8
+ module Enums
9
+ class EnumAlreadyExistsError < StandardError
10
+ end
11
+
12
+ class EnumDoesNotExistError < StandardError
13
+ end
14
+
15
+ # create and add a new enum
16
+ def add_enum enum_name, values, description: nil
17
+ raise ExpectedSymbolError, enum_name unless enum_name.is_a? Symbol
18
+ if has_enum? enum_name
19
+ raise(EnumAlreadyExistsError, "Enum #{enum_name} already exists")
20
+ end
21
+ included_target = self
22
+ if included_target.is_a? Schema
23
+ new_enum = @enums[enum_name] = Enum.new source, included_target, enum_name, values, description: description
24
+ else
25
+ raise ModuleIncludedIntoUnexpectedTargetError, included_target
26
+ end
27
+ # sort the hash so that the enums are in alphabetical order by name
28
+ sorted_enums = {}
29
+ @enums.keys.sort.each do |enum_name|
30
+ sorted_enums[enum_name] = @enums[enum_name]
31
+ end
32
+ @enums = sorted_enums
33
+ # return the new enum
34
+ new_enum
35
+ end
36
+
37
+ # return a enum by its name, raises an error if the enum does not exist
38
+ def enum enum_name
39
+ raise ExpectedSymbolError, enum_name unless enum_name.is_a? Symbol
40
+ raise EnumDoesNotExistError unless has_enum? enum_name
41
+ @enums[enum_name]
42
+ end
43
+
44
+ # returns true/false representing if a enum with the provided name exists
45
+ def has_enum? enum_name
46
+ raise ExpectedSymbolError, enum_name unless enum_name.is_a? Symbol
47
+ @enums.key? enum_name
48
+ end
49
+
50
+ # returns an array of all enums in the schema
51
+ def enums
52
+ @enums.values
53
+ end
54
+
55
+ def enums_hash
56
+ @enums
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -23,7 +23,7 @@ module DynamicMigrations
23
23
  def initialize source, schema, name, definition, description: nil
24
24
  super source
25
25
 
26
- @triggers ||= []
26
+ @triggers = []
27
27
 
28
28
  raise ExpectedSchemaError, schema unless schema.is_a? Schema
29
29
  @schema = schema
@@ -13,6 +13,7 @@ module DynamicMigrations
13
13
 
14
14
  include Tables
15
15
  include Functions
16
+ include Enums
16
17
 
17
18
  attr_reader :database
18
19
  attr_reader :name
@@ -26,6 +27,7 @@ module DynamicMigrations
26
27
  @name = name
27
28
  @tables = {}
28
29
  @functions = {}
30
+ @enums = {}
29
31
  end
30
32
  end
31
33
  end
@@ -104,7 +104,7 @@ module DynamicMigrations
104
104
 
105
105
  # recursively process the database and build all the schemas,
106
106
  # tables and columns
107
- def recursively_build_schemas_from_database
107
+ def recursively_load_database_structure
108
108
  fetch_structure.each do |schema_name, schema_definition|
109
109
  schema = add_loaded_schema schema_name
110
110
 
@@ -17,6 +17,10 @@ module DynamicMigrations
17
17
  include LoadedSchemas
18
18
  include ConfiguredSchemas
19
19
  include LoadedSchemasBuilder
20
+ include ConfiguredExtensions
21
+ include LoadedExtensions
22
+ include EnumsLoader
23
+ include ExtensionsLoader
20
24
 
21
25
  attr_reader :server
22
26
  attr_reader :name
@@ -29,6 +33,8 @@ module DynamicMigrations
29
33
  @name = name
30
34
  @configured_schemas = {}
31
35
  @loaded_schemas = {}
36
+ @configured_extensions = {}
37
+ @loaded_extensions = {}
32
38
  end
33
39
 
34
40
  # if `source` is :configuration then returns the configured schema with
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DynamicMigrations
4
- VERSION = "3.3.1"
4
+ VERSION = "3.4.0"
5
5
  end
@@ -15,11 +15,16 @@ require "dynamic_migrations/postgres/server/database/structure_loader"
15
15
  require "dynamic_migrations/postgres/server/database/validations_loader"
16
16
  require "dynamic_migrations/postgres/server/database/keys_and_unique_constraints_loader"
17
17
  require "dynamic_migrations/postgres/server/database/triggers_and_functions_loader"
18
+ require "dynamic_migrations/postgres/server/database/extensions_loader"
19
+ require "dynamic_migrations/postgres/server/database/enums_loader"
18
20
  require "dynamic_migrations/postgres/server/database/loaded_schemas_builder"
19
21
  require "dynamic_migrations/postgres/server/database/loaded_schemas"
20
22
  require "dynamic_migrations/postgres/server/database/configured_schemas"
23
+ require "dynamic_migrations/postgres/server/database/loaded_extensions"
24
+ require "dynamic_migrations/postgres/server/database/configured_extensions"
21
25
 
22
26
  require "dynamic_migrations/postgres/server/database/differences"
27
+ require "dynamic_migrations/postgres/server/database/differences/to_migrations/extensions"
23
28
  require "dynamic_migrations/postgres/server/database/differences/to_migrations/schemas"
24
29
  require "dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables"
25
30
  require "dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/columns"
@@ -30,6 +35,7 @@ require "dynamic_migrations/postgres/server/database/differences/to_migrations/s
30
35
  require "dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/unique_constraints"
31
36
  require "dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/validations"
32
37
  require "dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/functions"
38
+ require "dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/enums"
33
39
  require "dynamic_migrations/postgres/server/database/differences/to_migrations"
34
40
 
35
41
  require "dynamic_migrations/postgres/server/database"
@@ -37,8 +43,10 @@ require "dynamic_migrations/postgres/server/database/source"
37
43
 
38
44
  require "dynamic_migrations/postgres/server/database/schema/tables"
39
45
  require "dynamic_migrations/postgres/server/database/schema/functions"
46
+ require "dynamic_migrations/postgres/server/database/schema/enums"
40
47
  require "dynamic_migrations/postgres/server/database/schema"
41
48
  require "dynamic_migrations/postgres/server/database/schema/function"
49
+ require "dynamic_migrations/postgres/server/database/schema/enum"
42
50
  require "dynamic_migrations/postgres/server/database/schema/table/validations"
43
51
  require "dynamic_migrations/postgres/server/database/schema/table/indexes"
44
52
  require "dynamic_migrations/postgres/server/database/schema/table/foreign_key_constraints"
@@ -58,8 +66,10 @@ require "dynamic_migrations/postgres/server"
58
66
  require "dynamic_migrations/postgres/connections"
59
67
 
60
68
  require "dynamic_migrations/postgres/generator/schema"
69
+ require "dynamic_migrations/postgres/generator/extension"
61
70
  require "dynamic_migrations/postgres/generator/table"
62
71
  require "dynamic_migrations/postgres/generator/column"
72
+ require "dynamic_migrations/postgres/generator/enum"
63
73
  require "dynamic_migrations/postgres/generator/foreign_key_constraint"
64
74
  require "dynamic_migrations/postgres/generator/function"
65
75
  require "dynamic_migrations/postgres/generator/index"
@@ -70,6 +80,7 @@ require "dynamic_migrations/postgres/generator/validation"
70
80
  require "dynamic_migrations/postgres/generator"
71
81
  require "dynamic_migrations/postgres/generator/fragment"
72
82
  require "dynamic_migrations/postgres/generator/migration"
83
+ require "dynamic_migrations/postgres/generator/database_migration"
73
84
  require "dynamic_migrations/postgres/generator/schema_migration"
74
85
  require "dynamic_migrations/postgres/generator/table_migration"
75
86
  require "dynamic_migrations/postgres/generator/migration_dependency_sorter"
@@ -82,6 +93,7 @@ require "dynamic_migrations/active_record/migrators/function"
82
93
  require "dynamic_migrations/active_record/migrators/trigger"
83
94
  require "dynamic_migrations/active_record/migrators/table"
84
95
  require "dynamic_migrations/active_record/migrators/index"
96
+ require "dynamic_migrations/active_record/migrators/enum"
85
97
  require "dynamic_migrations/active_record/migrators/column"
86
98
  require "dynamic_migrations/active_record/migrators"
87
99
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamic_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.1
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Craig Ulliott
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-18 00:00:00.000000000 Z
11
+ date: 2023-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -67,6 +67,7 @@ files:
67
67
  - lib/dynamic_migrations.rb
68
68
  - lib/dynamic_migrations/active_record/migrators.rb
69
69
  - lib/dynamic_migrations/active_record/migrators/column.rb
70
+ - lib/dynamic_migrations/active_record/migrators/enum.rb
70
71
  - lib/dynamic_migrations/active_record/migrators/foreign_key_constraint.rb
71
72
  - lib/dynamic_migrations/active_record/migrators/function.rb
72
73
  - lib/dynamic_migrations/active_record/migrators/index.rb
@@ -86,6 +87,9 @@ files:
86
87
  - lib/dynamic_migrations/postgres/connections.rb
87
88
  - lib/dynamic_migrations/postgres/generator.rb
88
89
  - lib/dynamic_migrations/postgres/generator/column.rb
90
+ - lib/dynamic_migrations/postgres/generator/database_migration.rb
91
+ - lib/dynamic_migrations/postgres/generator/enum.rb
92
+ - lib/dynamic_migrations/postgres/generator/extension.rb
89
93
  - lib/dynamic_migrations/postgres/generator/foreign_key_constraint.rb
90
94
  - lib/dynamic_migrations/postgres/generator/fragment.rb
91
95
  - lib/dynamic_migrations/postgres/generator/function.rb
@@ -102,11 +106,14 @@ files:
102
106
  - lib/dynamic_migrations/postgres/generator/validation.rb
103
107
  - lib/dynamic_migrations/postgres/server.rb
104
108
  - lib/dynamic_migrations/postgres/server/database.rb
109
+ - lib/dynamic_migrations/postgres/server/database/configured_extensions.rb
105
110
  - lib/dynamic_migrations/postgres/server/database/configured_schemas.rb
106
111
  - lib/dynamic_migrations/postgres/server/database/connection.rb
107
112
  - lib/dynamic_migrations/postgres/server/database/differences.rb
108
113
  - lib/dynamic_migrations/postgres/server/database/differences/to_migrations.rb
114
+ - lib/dynamic_migrations/postgres/server/database/differences/to_migrations/extensions.rb
109
115
  - lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas.rb
116
+ - lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/enums.rb
110
117
  - lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/functions.rb
111
118
  - lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables.rb
112
119
  - lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/columns.rb
@@ -116,10 +123,15 @@ files:
116
123
  - lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/triggers.rb
117
124
  - lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/unique_constraints.rb
118
125
  - lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/validations.rb
126
+ - lib/dynamic_migrations/postgres/server/database/enums_loader.rb
127
+ - lib/dynamic_migrations/postgres/server/database/extensions_loader.rb
119
128
  - lib/dynamic_migrations/postgres/server/database/keys_and_unique_constraints_loader.rb
129
+ - lib/dynamic_migrations/postgres/server/database/loaded_extensions.rb
120
130
  - lib/dynamic_migrations/postgres/server/database/loaded_schemas.rb
121
131
  - lib/dynamic_migrations/postgres/server/database/loaded_schemas_builder.rb
122
132
  - lib/dynamic_migrations/postgres/server/database/schema.rb
133
+ - lib/dynamic_migrations/postgres/server/database/schema/enum.rb
134
+ - lib/dynamic_migrations/postgres/server/database/schema/enums.rb
123
135
  - lib/dynamic_migrations/postgres/server/database/schema/function.rb
124
136
  - lib/dynamic_migrations/postgres/server/database/schema/functions.rb
125
137
  - lib/dynamic_migrations/postgres/server/database/schema/table.rb