activerecord 5.2.3 → 6.1.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.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +898 -532
- data/MIT-LICENSE +3 -1
- data/README.rdoc +7 -5
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +5 -4
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +95 -42
- data/lib/active_record/associations/association_scope.rb +21 -21
- data/lib/active_record/associations/belongs_to_association.rb +50 -46
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -5
- data/lib/active_record/associations/builder/association.rb +23 -21
- data/lib/active_record/associations/builder/belongs_to.rb +29 -59
- data/lib/active_record/associations/builder/collection_association.rb +10 -19
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
- data/lib/active_record/associations/builder/has_many.rb +8 -2
- data/lib/active_record/associations/builder/has_one.rb +33 -2
- data/lib/active_record/associations/builder/singular_association.rb +3 -1
- data/lib/active_record/associations/collection_association.rb +31 -29
- data/lib/active_record/associations/collection_proxy.rb +25 -21
- data/lib/active_record/associations/foreign_association.rb +20 -0
- data/lib/active_record/associations/has_many_association.rb +26 -13
- data/lib/active_record/associations/has_many_through_association.rb +27 -28
- data/lib/active_record/associations/has_one_association.rb +43 -31
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +54 -12
- data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +91 -60
- data/lib/active_record/associations/preloader/association.rb +71 -43
- data/lib/active_record/associations/preloader/through_association.rb +49 -40
- data/lib/active_record/associations/preloader.rb +48 -35
- data/lib/active_record/associations/singular_association.rb +3 -17
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +133 -25
- data/lib/active_record/attribute_assignment.rb +17 -19
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
- data/lib/active_record/attribute_methods/dirty.rb +101 -40
- data/lib/active_record/attribute_methods/primary_key.rb +20 -25
- data/lib/active_record/attribute_methods/query.rb +4 -8
- data/lib/active_record/attribute_methods/read.rb +14 -56
- data/lib/active_record/attribute_methods/serialization.rb +12 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +18 -34
- data/lib/active_record/attribute_methods.rb +81 -143
- data/lib/active_record/attributes.rb +45 -8
- data/lib/active_record/autosave_association.rb +76 -47
- data/lib/active_record/base.rb +4 -17
- data/lib/active_record/callbacks.rb +158 -43
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +293 -132
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +21 -17
- data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +203 -90
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +381 -146
- data/lib/active_record/connection_adapters/abstract/transaction.rb +155 -68
- data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -98
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
- data/lib/active_record/connection_adapters/column.rb +30 -12
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +86 -32
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +38 -54
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +222 -112
- data/lib/active_record/connection_adapters/schema_cache.rb +127 -21
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +19 -6
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +175 -187
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_handling.rb +285 -33
- data/lib/active_record/core.rb +308 -100
- data/lib/active_record/counter_cache.rb +8 -30
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +80 -0
- data/lib/active_record/database_configurations/hash_config.rb +96 -0
- data/lib/active_record/database_configurations/url_config.rb +53 -0
- data/lib/active_record/database_configurations.rb +272 -0
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +3 -4
- data/lib/active_record/enum.rb +71 -17
- data/lib/active_record/errors.rb +62 -19
- data/lib/active_record/explain.rb +10 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +32 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +197 -481
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +53 -24
- data/lib/active_record/insert_all.rb +208 -0
- data/lib/active_record/integration.rb +67 -17
- data/lib/active_record/internal_metadata.rb +26 -9
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +26 -22
- data/lib/active_record/locking/pessimistic.rb +9 -5
- data/lib/active_record/log_subscriber.rb +34 -35
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/migration/command_recorder.rb +96 -44
- data/lib/active_record/migration/compatibility.rb +141 -64
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/migration.rb +205 -156
- data/lib/active_record/model_schema.rb +148 -22
- data/lib/active_record/nested_attributes.rb +4 -7
- data/lib/active_record/no_touching.rb +8 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +267 -59
- data/lib/active_record/query_cache.rb +21 -4
- data/lib/active_record/querying.rb +40 -23
- data/lib/active_record/railtie.rb +115 -58
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +402 -78
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +113 -101
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/batches.rb +44 -35
- data/lib/active_record/relation/calculations.rb +157 -93
- data/lib/active_record/relation/delegation.rb +35 -50
- data/lib/active_record/relation/finder_methods.rb +65 -40
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +32 -40
- data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -7
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +58 -40
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +487 -199
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +9 -9
- data/lib/active_record/relation/where_clause.rb +108 -58
- data/lib/active_record/relation.rb +375 -104
- data/lib/active_record/result.rb +64 -38
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +22 -41
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +54 -9
- data/lib/active_record/schema_migration.rb +7 -9
- data/lib/active_record/scoping/default.rb +6 -8
- data/lib/active_record/scoping/named.rb +17 -24
- data/lib/active_record/scoping.rb +8 -9
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +51 -8
- data/lib/active_record/store.rb +88 -9
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +39 -43
- data/lib/active_record/tasks/database_tasks.rb +276 -81
- data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
- data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
- data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +246 -0
- data/lib/active_record/timestamp.rb +43 -32
- data/lib/active_record/touch_later.rb +23 -22
- data/lib/active_record/transactions.rb +59 -117
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +6 -3
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type.rb +10 -5
- data/lib/active_record/type_caster/connection.rb +15 -15
- data/lib/active_record/type_caster/map.rb +8 -8
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +38 -30
- data/lib/active_record/validations.rb +4 -3
- data/lib/active_record.rb +13 -12
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +41 -0
- data/lib/arel/collectors/bind.rb +29 -0
- data/lib/arel/collectors/composite.rb +39 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +27 -0
- data/lib/arel/collectors/substitute_binds.rb +35 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +126 -0
- data/lib/arel/nodes/bind_param.rb +44 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +62 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +15 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +11 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +15 -0
- data/lib/arel/nodes/infix_operation.rb +92 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +51 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +19 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +31 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +70 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +250 -0
- data/lib/arel/select_manager.rb +270 -0
- data/lib/arel/table.rb +118 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/dot.rb +308 -0
- data/lib/arel/visitors/mysql.rb +93 -0
- data/lib/arel/visitors/postgresql.rb +120 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +899 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors.rb +13 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +54 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
- data/lib/rails/generators/active_record/migration.rb +19 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +117 -32
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/collection_cache_key.rb +0 -53
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
- data/lib/active_record/relation/where_clause_factory.rb +0 -34
| @@ -1,11 +1,15 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require "benchmark"
         | 
| 3 4 | 
             
            require "set"
         | 
| 4 5 | 
             
            require "zlib"
         | 
| 6 | 
            +
            require "active_support/core_ext/array/access"
         | 
| 7 | 
            +
            require "active_support/core_ext/enumerable"
         | 
| 5 8 | 
             
            require "active_support/core_ext/module/attribute_accessors"
         | 
| 9 | 
            +
            require "active_support/actionable_error"
         | 
| 6 10 |  | 
| 7 11 | 
             
            module ActiveRecord
         | 
| 8 | 
            -
              class MigrationError < ActiveRecordError#:nodoc:
         | 
| 12 | 
            +
              class MigrationError < ActiveRecordError #:nodoc:
         | 
| 9 13 | 
             
                def initialize(message = nil)
         | 
| 10 14 | 
             
                  message = "\n\n#{message}\n\n" if message
         | 
| 11 15 | 
             
                  super
         | 
| @@ -16,13 +20,13 @@ module ActiveRecord | |
| 16 20 | 
             
              # For example the following migration is not reversible.
         | 
| 17 21 | 
             
              # Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
         | 
| 18 22 | 
             
              #
         | 
| 19 | 
            -
              #   class IrreversibleMigrationExample < ActiveRecord::Migration[ | 
| 23 | 
            +
              #   class IrreversibleMigrationExample < ActiveRecord::Migration[6.0]
         | 
| 20 24 | 
             
              #     def change
         | 
| 21 25 | 
             
              #       create_table :distributors do |t|
         | 
| 22 26 | 
             
              #         t.string :zipcode
         | 
| 23 27 | 
             
              #       end
         | 
| 24 28 | 
             
              #
         | 
| 25 | 
            -
              #       execute  | 
| 29 | 
            +
              #       execute <<~SQL
         | 
| 26 30 | 
             
              #         ALTER TABLE distributors
         | 
| 27 31 | 
             
              #           ADD CONSTRAINT zipchk
         | 
| 28 32 | 
             
              #             CHECK (char_length(zipcode) = 5) NO INHERIT;
         | 
| @@ -34,13 +38,13 @@ module ActiveRecord | |
| 34 38 | 
             
              #
         | 
| 35 39 | 
             
              # 1. Define <tt>#up</tt> and <tt>#down</tt> methods instead of <tt>#change</tt>:
         | 
| 36 40 | 
             
              #
         | 
| 37 | 
            -
              #  class ReversibleMigrationExample < ActiveRecord::Migration[ | 
| 41 | 
            +
              #  class ReversibleMigrationExample < ActiveRecord::Migration[6.0]
         | 
| 38 42 | 
             
              #    def up
         | 
| 39 43 | 
             
              #      create_table :distributors do |t|
         | 
| 40 44 | 
             
              #        t.string :zipcode
         | 
| 41 45 | 
             
              #      end
         | 
| 42 46 | 
             
              #
         | 
| 43 | 
            -
              #      execute  | 
| 47 | 
            +
              #      execute <<~SQL
         | 
| 44 48 | 
             
              #        ALTER TABLE distributors
         | 
| 45 49 | 
             
              #          ADD CONSTRAINT zipchk
         | 
| 46 50 | 
             
              #            CHECK (char_length(zipcode) = 5) NO INHERIT;
         | 
| @@ -48,7 +52,7 @@ module ActiveRecord | |
| 48 52 | 
             
              #    end
         | 
| 49 53 | 
             
              #
         | 
| 50 54 | 
             
              #    def down
         | 
| 51 | 
            -
              #      execute  | 
| 55 | 
            +
              #      execute <<~SQL
         | 
| 52 56 | 
             
              #        ALTER TABLE distributors
         | 
| 53 57 | 
             
              #          DROP CONSTRAINT zipchk
         | 
| 54 58 | 
             
              #      SQL
         | 
| @@ -59,7 +63,7 @@ module ActiveRecord | |
| 59 63 | 
             
              #
         | 
| 60 64 | 
             
              # 2. Use the #reversible method in <tt>#change</tt> method:
         | 
| 61 65 | 
             
              #
         | 
| 62 | 
            -
              #   class ReversibleMigrationExample < ActiveRecord::Migration[ | 
| 66 | 
            +
              #   class ReversibleMigrationExample < ActiveRecord::Migration[6.0]
         | 
| 63 67 | 
             
              #     def change
         | 
| 64 68 | 
             
              #       create_table :distributors do |t|
         | 
| 65 69 | 
             
              #         t.string :zipcode
         | 
| @@ -67,7 +71,7 @@ module ActiveRecord | |
| 67 71 | 
             
              #
         | 
| 68 72 | 
             
              #       reversible do |dir|
         | 
| 69 73 | 
             
              #         dir.up do
         | 
| 70 | 
            -
              #           execute  | 
| 74 | 
            +
              #           execute <<~SQL
         | 
| 71 75 | 
             
              #             ALTER TABLE distributors
         | 
| 72 76 | 
             
              #               ADD CONSTRAINT zipchk
         | 
| 73 77 | 
             
              #                 CHECK (char_length(zipcode) = 5) NO INHERIT;
         | 
| @@ -75,7 +79,7 @@ module ActiveRecord | |
| 75 79 | 
             
              #         end
         | 
| 76 80 | 
             
              #
         | 
| 77 81 | 
             
              #         dir.down do
         | 
| 78 | 
            -
              #           execute  | 
| 82 | 
            +
              #           execute <<~SQL
         | 
| 79 83 | 
             
              #             ALTER TABLE distributors
         | 
| 80 84 | 
             
              #               DROP CONSTRAINT zipchk
         | 
| 81 85 | 
             
              #           SQL
         | 
| @@ -86,7 +90,7 @@ module ActiveRecord | |
| 86 90 | 
             
              class IrreversibleMigration < MigrationError
         | 
| 87 91 | 
             
              end
         | 
| 88 92 |  | 
| 89 | 
            -
              class DuplicateMigrationVersionError < MigrationError#:nodoc:
         | 
| 93 | 
            +
              class DuplicateMigrationVersionError < MigrationError #:nodoc:
         | 
| 90 94 | 
             
                def initialize(version = nil)
         | 
| 91 95 | 
             
                  if version
         | 
| 92 96 | 
             
                    super("Multiple migrations have the version number #{version}.")
         | 
| @@ -96,7 +100,7 @@ module ActiveRecord | |
| 96 100 | 
             
                end
         | 
| 97 101 | 
             
              end
         | 
| 98 102 |  | 
| 99 | 
            -
              class DuplicateMigrationNameError < MigrationError#:nodoc:
         | 
| 103 | 
            +
              class DuplicateMigrationNameError < MigrationError #:nodoc:
         | 
| 100 104 | 
             
                def initialize(name = nil)
         | 
| 101 105 | 
             
                  if name
         | 
| 102 106 | 
             
                    super("Multiple migrations have the name #{name}.")
         | 
| @@ -116,7 +120,7 @@ module ActiveRecord | |
| 116 120 | 
             
                end
         | 
| 117 121 | 
             
              end
         | 
| 118 122 |  | 
| 119 | 
            -
              class IllegalMigrationNameError < MigrationError#:nodoc:
         | 
| 123 | 
            +
              class IllegalMigrationNameError < MigrationError #:nodoc:
         | 
| 120 124 | 
             
                def initialize(name = nil)
         | 
| 121 125 | 
             
                  if name
         | 
| 122 126 | 
             
                    super("Illegal name for migration file: #{name}\n\t(only lower case letters, numbers, and '_' allowed).")
         | 
| @@ -126,21 +130,44 @@ module ActiveRecord | |
| 126 130 | 
             
                end
         | 
| 127 131 | 
             
              end
         | 
| 128 132 |  | 
| 129 | 
            -
              class PendingMigrationError < MigrationError#:nodoc:
         | 
| 130 | 
            -
                 | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
                   | 
| 134 | 
            -
             | 
| 135 | 
            -
                   | 
| 136 | 
            -
                     | 
| 133 | 
            +
              class PendingMigrationError < MigrationError #:nodoc:
         | 
| 134 | 
            +
                include ActiveSupport::ActionableError
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                action "Run pending migrations" do
         | 
| 137 | 
            +
                  ActiveRecord::Tasks::DatabaseTasks.migrate
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                  if ActiveRecord::Base.dump_schema_after_migration
         | 
| 140 | 
            +
                    ActiveRecord::Tasks::DatabaseTasks.dump_schema(
         | 
| 141 | 
            +
                      ActiveRecord::Base.connection_db_config
         | 
| 142 | 
            +
                    )
         | 
| 137 143 | 
             
                  end
         | 
| 138 144 | 
             
                end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                def initialize(message = nil)
         | 
| 147 | 
            +
                  super(message || detailed_migration_message)
         | 
| 148 | 
            +
                end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                private
         | 
| 151 | 
            +
                  def detailed_migration_message
         | 
| 152 | 
            +
                    message = "Migrations are pending. To resolve this issue, run:\n\n        bin/rails db:migrate"
         | 
| 153 | 
            +
                    message += " RAILS_ENV=#{::Rails.env}" if defined?(Rails.env)
         | 
| 154 | 
            +
                    message += "\n\n"
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                    pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                    message += "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}\n\n"
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                    pending_migrations.each do |pending_migration|
         | 
| 161 | 
            +
                      message += "#{pending_migration.basename}\n"
         | 
| 162 | 
            +
                    end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                    message
         | 
| 165 | 
            +
                  end
         | 
| 139 166 | 
             
              end
         | 
| 140 167 |  | 
| 141 168 | 
             
              class ConcurrentMigrationError < MigrationError #:nodoc:
         | 
| 142 | 
            -
                DEFAULT_MESSAGE = "Cannot run migrations because another migration process is currently running." | 
| 143 | 
            -
                RELEASE_LOCK_FAILED_MESSAGE = "Failed to release advisory lock" | 
| 169 | 
            +
                DEFAULT_MESSAGE = "Cannot run migrations because another migration process is currently running."
         | 
| 170 | 
            +
                RELEASE_LOCK_FAILED_MESSAGE = "Failed to release advisory lock"
         | 
| 144 171 |  | 
| 145 172 | 
             
                def initialize(message = DEFAULT_MESSAGE)
         | 
| 146 173 | 
             
                  super
         | 
| @@ -160,7 +187,7 @@ module ActiveRecord | |
| 160 187 |  | 
| 161 188 | 
             
              class ProtectedEnvironmentError < ActiveRecordError #:nodoc:
         | 
| 162 189 | 
             
                def initialize(env = "production")
         | 
| 163 | 
            -
                  msg = "You are attempting to run a destructive action against your '#{env}' database.\n" | 
| 190 | 
            +
                  msg = +"You are attempting to run a destructive action against your '#{env}' database.\n"
         | 
| 164 191 | 
             
                  msg << "If you are sure you want to continue, run the same command with the environment variable:\n"
         | 
| 165 192 | 
             
                  msg << "DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
         | 
| 166 193 | 
             
                  super(msg)
         | 
| @@ -169,7 +196,7 @@ module ActiveRecord | |
| 169 196 |  | 
| 170 197 | 
             
              class EnvironmentMismatchError < ActiveRecordError
         | 
| 171 198 | 
             
                def initialize(current: nil, stored: nil)
         | 
| 172 | 
            -
                  msg = | 
| 199 | 
            +
                  msg = +"You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
         | 
| 173 200 | 
             
                  msg << "You are running in `#{ current }` environment. "
         | 
| 174 201 | 
             
                  msg << "If you are sure you want to continue, first set the environment using:\n\n"
         | 
| 175 202 | 
             
                  msg << "        bin/rails db:environment:set"
         | 
| @@ -181,6 +208,14 @@ module ActiveRecord | |
| 181 208 | 
             
                end
         | 
| 182 209 | 
             
              end
         | 
| 183 210 |  | 
| 211 | 
            +
              class EnvironmentStorageError < ActiveRecordError # :nodoc:
         | 
| 212 | 
            +
                def initialize
         | 
| 213 | 
            +
                  msg = +"You are attempting to store the environment in a database where metadata is disabled.\n"
         | 
| 214 | 
            +
                  msg << "Check your database configuration to see if this is intended."
         | 
| 215 | 
            +
                  super(msg)
         | 
| 216 | 
            +
                end
         | 
| 217 | 
            +
              end
         | 
| 218 | 
            +
             | 
| 184 219 | 
             
              # = Active Record Migrations
         | 
| 185 220 | 
             
              #
         | 
| 186 221 | 
             
              # Migrations can manage the evolution of a schema used by several physical
         | 
| @@ -193,7 +228,7 @@ module ActiveRecord | |
| 193 228 | 
             
              #
         | 
| 194 229 | 
             
              # Example of a simple migration:
         | 
| 195 230 | 
             
              #
         | 
| 196 | 
            -
              #   class AddSsl < ActiveRecord::Migration[ | 
| 231 | 
            +
              #   class AddSsl < ActiveRecord::Migration[6.0]
         | 
| 197 232 | 
             
              #     def up
         | 
| 198 233 | 
             
              #       add_column :accounts, :ssl_enabled, :boolean, default: true
         | 
| 199 234 | 
             
              #     end
         | 
| @@ -213,7 +248,7 @@ module ActiveRecord | |
| 213 248 | 
             
              #
         | 
| 214 249 | 
             
              # Example of a more complex migration that also needs to initialize data:
         | 
| 215 250 | 
             
              #
         | 
| 216 | 
            -
              #   class AddSystemSettings < ActiveRecord::Migration[ | 
| 251 | 
            +
              #   class AddSystemSettings < ActiveRecord::Migration[6.0]
         | 
| 217 252 | 
             
              #     def up
         | 
| 218 253 | 
             
              #       create_table :system_settings do |t|
         | 
| 219 254 | 
             
              #         t.string  :name
         | 
| @@ -307,7 +342,7 @@ module ActiveRecord | |
| 307 342 | 
             
              #   named +column_name+ from the table called +table_name+.
         | 
| 308 343 | 
             
              # * <tt>remove_columns(table_name, *column_names)</tt>: Removes the given
         | 
| 309 344 | 
             
              #   columns from the table definition.
         | 
| 310 | 
            -
              # * <tt>remove_foreign_key(from_table,  | 
| 345 | 
            +
              # * <tt>remove_foreign_key(from_table, to_table = nil, **options)</tt>: Removes the
         | 
| 311 346 | 
             
              #   given foreign key from the table called +table_name+.
         | 
| 312 347 | 
             
              # * <tt>remove_index(table_name, column: column_names)</tt>: Removes the index
         | 
| 313 348 | 
             
              #   specified by +column_names+.
         | 
| @@ -329,7 +364,7 @@ module ActiveRecord | |
| 329 364 | 
             
              # The Rails package has several tools to help create and apply migrations.
         | 
| 330 365 | 
             
              #
         | 
| 331 366 | 
             
              # To generate a new migration, you can use
         | 
| 332 | 
            -
              #   rails generate migration MyNewMigration
         | 
| 367 | 
            +
              #   bin/rails generate migration MyNewMigration
         | 
| 333 368 | 
             
              #
         | 
| 334 369 | 
             
              # where MyNewMigration is the name of your migration. The generator will
         | 
| 335 370 | 
             
              # create an empty migration file <tt>timestamp_my_new_migration.rb</tt>
         | 
| @@ -338,41 +373,36 @@ module ActiveRecord | |
| 338 373 | 
             
              #
         | 
| 339 374 | 
             
              # There is a special syntactic shortcut to generate migrations that add fields to a table.
         | 
| 340 375 | 
             
              #
         | 
| 341 | 
            -
              #   rails generate migration add_fieldname_to_tablename fieldname:string
         | 
| 376 | 
            +
              #   bin/rails generate migration add_fieldname_to_tablename fieldname:string
         | 
| 342 377 | 
             
              #
         | 
| 343 378 | 
             
              # This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
         | 
| 344 | 
            -
              #   class AddFieldnameToTablename < ActiveRecord::Migration[ | 
| 379 | 
            +
              #   class AddFieldnameToTablename < ActiveRecord::Migration[6.0]
         | 
| 345 380 | 
             
              #     def change
         | 
| 346 381 | 
             
              #       add_column :tablenames, :fieldname, :string
         | 
| 347 382 | 
             
              #     end
         | 
| 348 383 | 
             
              #   end
         | 
| 349 384 | 
             
              #
         | 
| 350 385 | 
             
              # To run migrations against the currently configured database, use
         | 
| 351 | 
            -
              # <tt>rails db:migrate</tt>. This will update the database by running all of the
         | 
| 386 | 
            +
              # <tt>bin/rails db:migrate</tt>. This will update the database by running all of the
         | 
| 352 387 | 
             
              # pending migrations, creating the <tt>schema_migrations</tt> table
         | 
| 353 388 | 
             
              # (see "About the schema_migrations table" section below) if missing. It will also
         | 
| 354 | 
            -
              # invoke the db:schema:dump  | 
| 389 | 
            +
              # invoke the db:schema:dump command, which will update your db/schema.rb file
         | 
| 355 390 | 
             
              # to match the structure of your database.
         | 
| 356 391 | 
             
              #
         | 
| 357 392 | 
             
              # To roll the database back to a previous migration version, use
         | 
| 358 | 
            -
              # <tt>rails db:rollback VERSION=X</tt> where <tt>X</tt> is the version to which
         | 
| 393 | 
            +
              # <tt>bin/rails db:rollback VERSION=X</tt> where <tt>X</tt> is the version to which
         | 
| 359 394 | 
             
              # you wish to downgrade. Alternatively, you can also use the STEP option if you
         | 
| 360 | 
            -
              # wish to rollback last few migrations. <tt>rails db:rollback STEP=2</tt> will rollback
         | 
| 395 | 
            +
              # wish to rollback last few migrations. <tt>bin/rails db:rollback STEP=2</tt> will rollback
         | 
| 361 396 | 
             
              # the latest two migrations.
         | 
| 362 397 | 
             
              #
         | 
| 363 398 | 
             
              # If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
         | 
| 364 399 | 
             
              # that step will fail and you'll have some manual work to do.
         | 
| 365 400 | 
             
              #
         | 
| 366 | 
            -
              # == Database support
         | 
| 367 | 
            -
              #
         | 
| 368 | 
            -
              # Migrations are currently supported in MySQL, PostgreSQL, SQLite,
         | 
| 369 | 
            -
              # SQL Server, and Oracle (all supported databases except DB2).
         | 
| 370 | 
            -
              #
         | 
| 371 401 | 
             
              # == More examples
         | 
| 372 402 | 
             
              #
         | 
| 373 403 | 
             
              # Not all migrations change the schema. Some just fix the data:
         | 
| 374 404 | 
             
              #
         | 
| 375 | 
            -
              #   class RemoveEmptyTags < ActiveRecord::Migration[ | 
| 405 | 
            +
              #   class RemoveEmptyTags < ActiveRecord::Migration[6.0]
         | 
| 376 406 | 
             
              #     def up
         | 
| 377 407 | 
             
              #       Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
         | 
| 378 408 | 
             
              #     end
         | 
| @@ -385,7 +415,7 @@ module ActiveRecord | |
| 385 415 | 
             
              #
         | 
| 386 416 | 
             
              # Others remove columns when they migrate up instead of down:
         | 
| 387 417 | 
             
              #
         | 
| 388 | 
            -
              #   class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[ | 
| 418 | 
            +
              #   class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[6.0]
         | 
| 389 419 | 
             
              #     def up
         | 
| 390 420 | 
             
              #       remove_column :items, :incomplete_items_count
         | 
| 391 421 | 
             
              #       remove_column :items, :completed_items_count
         | 
| @@ -399,7 +429,7 @@ module ActiveRecord | |
| 399 429 | 
             
              #
         | 
| 400 430 | 
             
              # And sometimes you need to do something in SQL not abstracted directly by migrations:
         | 
| 401 431 | 
             
              #
         | 
| 402 | 
            -
              #   class MakeJoinUnique < ActiveRecord::Migration[ | 
| 432 | 
            +
              #   class MakeJoinUnique < ActiveRecord::Migration[6.0]
         | 
| 403 433 | 
             
              #     def up
         | 
| 404 434 | 
             
              #       execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
         | 
| 405 435 | 
             
              #     end
         | 
| @@ -416,7 +446,7 @@ module ActiveRecord | |
| 416 446 | 
             
              # <tt>Base#reset_column_information</tt> in order to ensure that the model has the
         | 
| 417 447 | 
             
              # latest column data from after the new column was added. Example:
         | 
| 418 448 | 
             
              #
         | 
| 419 | 
            -
              #   class AddPeopleSalary < ActiveRecord::Migration[ | 
| 449 | 
            +
              #   class AddPeopleSalary < ActiveRecord::Migration[6.0]
         | 
| 420 450 | 
             
              #     def up
         | 
| 421 451 | 
             
              #       add_column :people, :salary, :integer
         | 
| 422 452 | 
             
              #       Person.reset_column_information
         | 
| @@ -474,7 +504,7 @@ module ActiveRecord | |
| 474 504 | 
             
              # To define a reversible migration, define the +change+ method in your
         | 
| 475 505 | 
             
              # migration like this:
         | 
| 476 506 | 
             
              #
         | 
| 477 | 
            -
              #   class TenderloveMigration < ActiveRecord::Migration[ | 
| 507 | 
            +
              #   class TenderloveMigration < ActiveRecord::Migration[6.0]
         | 
| 478 508 | 
             
              #     def change
         | 
| 479 509 | 
             
              #       create_table(:horses) do |t|
         | 
| 480 510 | 
             
              #         t.column :content, :text
         | 
| @@ -486,9 +516,9 @@ module ActiveRecord | |
| 486 516 | 
             
              # This migration will create the horses table for you on the way up, and
         | 
| 487 517 | 
             
              # automatically figure out how to drop the table on the way down.
         | 
| 488 518 | 
             
              #
         | 
| 489 | 
            -
              # Some commands  | 
| 490 | 
            -
              #  | 
| 491 | 
            -
              #  | 
| 519 | 
            +
              # Some commands cannot be reversed. If you care to define how to move up
         | 
| 520 | 
            +
              # and down in these cases, you should define the +up+ and +down+ methods
         | 
| 521 | 
            +
              # as before.
         | 
| 492 522 | 
             
              #
         | 
| 493 523 | 
             
              # If a command cannot be reversed, an
         | 
| 494 524 | 
             
              # <tt>ActiveRecord::IrreversibleMigration</tt> exception will be raised when
         | 
| @@ -504,7 +534,7 @@ module ActiveRecord | |
| 504 534 | 
             
              # can't execute inside a transaction though, and for these situations
         | 
| 505 535 | 
             
              # you can turn the automatic transactions off.
         | 
| 506 536 | 
             
              #
         | 
| 507 | 
            -
              #   class ChangeEnum < ActiveRecord::Migration[ | 
| 537 | 
            +
              #   class ChangeEnum < ActiveRecord::Migration[6.0]
         | 
| 508 538 | 
             
              #     disable_ddl_transaction!
         | 
| 509 539 | 
             
              #
         | 
| 510 540 | 
             
              #     def up
         | 
| @@ -517,12 +547,13 @@ module ActiveRecord | |
| 517 547 | 
             
              class Migration
         | 
| 518 548 | 
             
                autoload :CommandRecorder, "active_record/migration/command_recorder"
         | 
| 519 549 | 
             
                autoload :Compatibility, "active_record/migration/compatibility"
         | 
| 550 | 
            +
                autoload :JoinTable, "active_record/migration/join_table"
         | 
| 520 551 |  | 
| 521 552 | 
             
                # This must be defined before the inherited hook, below
         | 
| 522 | 
            -
                class Current < Migration  | 
| 553 | 
            +
                class Current < Migration #:nodoc:
         | 
| 523 554 | 
             
                end
         | 
| 524 555 |  | 
| 525 | 
            -
                def self.inherited(subclass)  | 
| 556 | 
            +
                def self.inherited(subclass) #:nodoc:
         | 
| 526 557 | 
             
                  super
         | 
| 527 558 | 
             
                  if subclass.superclass == Migration
         | 
| 528 559 | 
             
                    raise StandardError, "Directly inheriting from ActiveRecord::Migration is not supported. " \
         | 
| @@ -540,26 +571,41 @@ module ActiveRecord | |
| 540 571 | 
             
                  ActiveRecord::VERSION::STRING.to_f
         | 
| 541 572 | 
             
                end
         | 
| 542 573 |  | 
| 543 | 
            -
                MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/  | 
| 574 | 
            +
                MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ #:nodoc:
         | 
| 544 575 |  | 
| 545 576 | 
             
                # This class is used to verify that all migrations have been run before
         | 
| 546 577 | 
             
                # loading a web page if <tt>config.active_record.migration_error</tt> is set to :page_load
         | 
| 547 578 | 
             
                class CheckPending
         | 
| 548 | 
            -
                  def initialize(app)
         | 
| 579 | 
            +
                  def initialize(app, file_watcher: ActiveSupport::FileUpdateChecker)
         | 
| 549 580 | 
             
                    @app = app
         | 
| 550 | 
            -
                    @ | 
| 581 | 
            +
                    @needs_check = true
         | 
| 582 | 
            +
                    @mutex = Mutex.new
         | 
| 583 | 
            +
                    @file_watcher = file_watcher
         | 
| 551 584 | 
             
                  end
         | 
| 552 585 |  | 
| 553 586 | 
             
                  def call(env)
         | 
| 554 | 
            -
                     | 
| 555 | 
            -
             | 
| 556 | 
            -
             | 
| 557 | 
            -
             | 
| 587 | 
            +
                    @mutex.synchronize do
         | 
| 588 | 
            +
                      @watcher ||= build_watcher do
         | 
| 589 | 
            +
                        @needs_check = true
         | 
| 590 | 
            +
                        ActiveRecord::Migration.check_pending!(connection)
         | 
| 591 | 
            +
                        @needs_check = false
         | 
| 592 | 
            +
                      end
         | 
| 593 | 
            +
             | 
| 594 | 
            +
                      if @needs_check
         | 
| 595 | 
            +
                        @watcher.execute
         | 
| 596 | 
            +
                      else
         | 
| 597 | 
            +
                        @watcher.execute_if_updated
         | 
| 598 | 
            +
                      end
         | 
| 558 599 | 
             
                    end
         | 
| 600 | 
            +
             | 
| 559 601 | 
             
                    @app.call(env)
         | 
| 560 602 | 
             
                  end
         | 
| 561 603 |  | 
| 562 604 | 
             
                  private
         | 
| 605 | 
            +
                    def build_watcher(&block)
         | 
| 606 | 
            +
                      paths = Array(connection.migration_context.migrations_paths)
         | 
| 607 | 
            +
                      @file_watcher.new([], paths.index_with(["rb"]), &block)
         | 
| 608 | 
            +
                    end
         | 
| 563 609 |  | 
| 564 610 | 
             
                    def connection
         | 
| 565 611 | 
             
                      ActiveRecord::Base.connection
         | 
| @@ -567,10 +613,10 @@ module ActiveRecord | |
| 567 613 | 
             
                end
         | 
| 568 614 |  | 
| 569 615 | 
             
                class << self
         | 
| 570 | 
            -
                  attr_accessor :delegate  | 
| 571 | 
            -
                  attr_accessor :disable_ddl_transaction  | 
| 616 | 
            +
                  attr_accessor :delegate #:nodoc:
         | 
| 617 | 
            +
                  attr_accessor :disable_ddl_transaction #:nodoc:
         | 
| 572 618 |  | 
| 573 | 
            -
                  def nearest_delegate  | 
| 619 | 
            +
                  def nearest_delegate #:nodoc:
         | 
| 574 620 | 
             
                    delegate || superclass.nearest_delegate
         | 
| 575 621 | 
             
                  end
         | 
| 576 622 |  | 
| @@ -580,29 +626,38 @@ module ActiveRecord | |
| 580 626 | 
             
                  end
         | 
| 581 627 |  | 
| 582 628 | 
             
                  def load_schema_if_pending!
         | 
| 583 | 
            -
                     | 
| 629 | 
            +
                    current_db_config = Base.connection_db_config
         | 
| 630 | 
            +
                    all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
         | 
| 631 | 
            +
             | 
| 632 | 
            +
                    needs_update = !all_configs.all? do |db_config|
         | 
| 633 | 
            +
                      Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord::Base.schema_format)
         | 
| 634 | 
            +
                    end
         | 
| 635 | 
            +
             | 
| 636 | 
            +
                    if needs_update
         | 
| 584 637 | 
             
                      # Roundtrip to Rake to allow plugins to hook into database initialization.
         | 
| 585 638 | 
             
                      root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
         | 
| 586 639 | 
             
                      FileUtils.cd(root) do
         | 
| 587 | 
            -
                        current_config = Base.connection_config
         | 
| 588 640 | 
             
                        Base.clear_all_connections!
         | 
| 589 641 | 
             
                        system("bin/rails db:test:prepare")
         | 
| 590 | 
            -
                        # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
         | 
| 591 | 
            -
                        Base.establish_connection(current_config)
         | 
| 592 642 | 
             
                      end
         | 
| 593 | 
            -
                      check_pending!
         | 
| 594 643 | 
             
                    end
         | 
| 644 | 
            +
             | 
| 645 | 
            +
                    # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
         | 
| 646 | 
            +
                    Base.establish_connection(current_db_config)
         | 
| 647 | 
            +
             | 
| 648 | 
            +
                    check_pending!
         | 
| 595 649 | 
             
                  end
         | 
| 596 650 |  | 
| 597 | 
            -
                  def maintain_test_schema!  | 
| 651 | 
            +
                  def maintain_test_schema! #:nodoc:
         | 
| 598 652 | 
             
                    if ActiveRecord::Base.maintain_test_schema
         | 
| 599 653 | 
             
                      suppress_messages { load_schema_if_pending! }
         | 
| 600 654 | 
             
                    end
         | 
| 601 655 | 
             
                  end
         | 
| 602 656 |  | 
| 603 | 
            -
                  def method_missing(name, *args, &block)  | 
| 657 | 
            +
                  def method_missing(name, *args, &block) #:nodoc:
         | 
| 604 658 | 
             
                    nearest_delegate.send(name, *args, &block)
         | 
| 605 659 | 
             
                  end
         | 
| 660 | 
            +
                  ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
         | 
| 606 661 |  | 
| 607 662 | 
             
                  def migrate(direction)
         | 
| 608 663 | 
             
                    new.migrate direction
         | 
| @@ -617,7 +672,7 @@ module ActiveRecord | |
| 617 672 | 
             
                  end
         | 
| 618 673 | 
             
                end
         | 
| 619 674 |  | 
| 620 | 
            -
                def disable_ddl_transaction  | 
| 675 | 
            +
                def disable_ddl_transaction #:nodoc:
         | 
| 621 676 | 
             
                  self.class.disable_ddl_transaction
         | 
| 622 677 | 
             
                end
         | 
| 623 678 |  | 
| @@ -641,7 +696,7 @@ module ActiveRecord | |
| 641 696 | 
             
                # and create the table 'apples' on the way up, and the reverse
         | 
| 642 697 | 
             
                # on the way down.
         | 
| 643 698 | 
             
                #
         | 
| 644 | 
            -
                #   class FixTLMigration < ActiveRecord::Migration[ | 
| 699 | 
            +
                #   class FixTLMigration < ActiveRecord::Migration[6.0]
         | 
| 645 700 | 
             
                #     def change
         | 
| 646 701 | 
             
                #       revert do
         | 
| 647 702 | 
             
                #         create_table(:horses) do |t|
         | 
| @@ -658,9 +713,9 @@ module ActiveRecord | |
| 658 713 | 
             
                # Or equivalently, if +TenderloveMigration+ is defined as in the
         | 
| 659 714 | 
             
                # documentation for Migration:
         | 
| 660 715 | 
             
                #
         | 
| 661 | 
            -
                #   require_relative  | 
| 716 | 
            +
                #   require_relative "20121212123456_tenderlove_migration"
         | 
| 662 717 | 
             
                #
         | 
| 663 | 
            -
                #   class FixupTLMigration < ActiveRecord::Migration[ | 
| 718 | 
            +
                #   class FixupTLMigration < ActiveRecord::Migration[6.0]
         | 
| 664 719 | 
             
                #     def change
         | 
| 665 720 | 
             
                #       revert TenderloveMigration
         | 
| 666 721 | 
             
                #
         | 
| @@ -677,15 +732,13 @@ module ActiveRecord | |
| 677 732 | 
             
                    if connection.respond_to? :revert
         | 
| 678 733 | 
             
                      connection.revert { yield }
         | 
| 679 734 | 
             
                    else
         | 
| 680 | 
            -
                      recorder =  | 
| 735 | 
            +
                      recorder = command_recorder
         | 
| 681 736 | 
             
                      @connection = recorder
         | 
| 682 737 | 
             
                      suppress_messages do
         | 
| 683 738 | 
             
                        connection.revert { yield }
         | 
| 684 739 | 
             
                      end
         | 
| 685 740 | 
             
                      @connection = recorder.delegate
         | 
| 686 | 
            -
                      recorder. | 
| 687 | 
            -
                        send(cmd, *args, &block)
         | 
| 688 | 
            -
                      end
         | 
| 741 | 
            +
                      recorder.replay(self)
         | 
| 689 742 | 
             
                    end
         | 
| 690 743 | 
             
                  end
         | 
| 691 744 | 
             
                end
         | 
| @@ -694,7 +747,7 @@ module ActiveRecord | |
| 694 747 | 
             
                  connection.respond_to?(:reverting) && connection.reverting
         | 
| 695 748 | 
             
                end
         | 
| 696 749 |  | 
| 697 | 
            -
                ReversibleBlockHelper = Struct.new(:reverting) do  | 
| 750 | 
            +
                ReversibleBlockHelper = Struct.new(:reverting) do #:nodoc:
         | 
| 698 751 | 
             
                  def up
         | 
| 699 752 | 
             
                    yield unless reverting
         | 
| 700 753 | 
             
                  end
         | 
| @@ -713,7 +766,7 @@ module ActiveRecord | |
| 713 766 | 
             
                # when the three columns 'first_name', 'last_name' and 'full_name' exist,
         | 
| 714 767 | 
             
                # even when migrating down:
         | 
| 715 768 | 
             
                #
         | 
| 716 | 
            -
                #    class SplitNameMigration < ActiveRecord::Migration[ | 
| 769 | 
            +
                #    class SplitNameMigration < ActiveRecord::Migration[6.0]
         | 
| 717 770 | 
             
                #      def change
         | 
| 718 771 | 
             
                #        add_column :users, :first_name, :string
         | 
| 719 772 | 
             
                #        add_column :users, :last_name, :string
         | 
| @@ -741,7 +794,7 @@ module ActiveRecord | |
| 741 794 | 
             
                # In the following example, the new column +published+ will be given
         | 
| 742 795 | 
             
                # the value +true+ for all existing records.
         | 
| 743 796 | 
             
                #
         | 
| 744 | 
            -
                #    class AddPublishedToPosts < ActiveRecord::Migration[ | 
| 797 | 
            +
                #    class AddPublishedToPosts < ActiveRecord::Migration[6.0]
         | 
| 745 798 | 
             
                #      def change
         | 
| 746 799 | 
             
                #        add_column :posts, :published, :boolean, default: false
         | 
| 747 800 | 
             
                #        up_only do
         | 
| @@ -814,7 +867,7 @@ module ActiveRecord | |
| 814 867 | 
             
                      change
         | 
| 815 868 | 
             
                    end
         | 
| 816 869 | 
             
                  else
         | 
| 817 | 
            -
                     | 
| 870 | 
            +
                    public_send(direction)
         | 
| 818 871 | 
             
                  end
         | 
| 819 872 | 
             
                ensure
         | 
| 820 873 | 
             
                  @connection = nil
         | 
| @@ -830,10 +883,14 @@ module ActiveRecord | |
| 830 883 | 
             
                  write "== %s %s" % [text, "=" * length]
         | 
| 831 884 | 
             
                end
         | 
| 832 885 |  | 
| 886 | 
            +
                # Takes a message argument and outputs it as is.
         | 
| 887 | 
            +
                # A second boolean argument can be passed to specify whether to indent or not.
         | 
| 833 888 | 
             
                def say(message, subitem = false)
         | 
| 834 889 | 
             
                  write "#{subitem ? "   ->" : "--"} #{message}"
         | 
| 835 890 | 
             
                end
         | 
| 836 891 |  | 
| 892 | 
            +
                # Outputs text along with how long it took to run its block.
         | 
| 893 | 
            +
                # If the block returns an integer it assumes it is the number of rows affected.
         | 
| 837 894 | 
             
                def say_with_time(message)
         | 
| 838 895 | 
             
                  say(message)
         | 
| 839 896 | 
             
                  result = nil
         | 
| @@ -843,6 +900,7 @@ module ActiveRecord | |
| 843 900 | 
             
                  result
         | 
| 844 901 | 
             
                end
         | 
| 845 902 |  | 
| 903 | 
            +
                # Takes a block as an argument and suppresses any output generated by the block.
         | 
| 846 904 | 
             
                def suppress_messages
         | 
| 847 905 | 
             
                  save, self.verbose = verbose, false
         | 
| 848 906 | 
             
                  yield
         | 
| @@ -871,21 +929,23 @@ module ActiveRecord | |
| 871 929 | 
             
                    connection.send(method, *arguments, &block)
         | 
| 872 930 | 
             
                  end
         | 
| 873 931 | 
             
                end
         | 
| 932 | 
            +
                ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
         | 
| 874 933 |  | 
| 875 934 | 
             
                def copy(destination, sources, options = {})
         | 
| 876 935 | 
             
                  copied = []
         | 
| 936 | 
            +
                  schema_migration = options[:schema_migration] || ActiveRecord::SchemaMigration
         | 
| 877 937 |  | 
| 878 938 | 
             
                  FileUtils.mkdir_p(destination) unless File.exist?(destination)
         | 
| 879 939 |  | 
| 880 | 
            -
                  destination_migrations = ActiveRecord::MigrationContext.new(destination).migrations
         | 
| 940 | 
            +
                  destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration).migrations
         | 
| 881 941 | 
             
                  last = destination_migrations.last
         | 
| 882 942 | 
             
                  sources.each do |scope, path|
         | 
| 883 | 
            -
                    source_migrations = ActiveRecord::MigrationContext.new(path).migrations
         | 
| 943 | 
            +
                    source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration).migrations
         | 
| 884 944 |  | 
| 885 945 | 
             
                    source_migrations.each do |migration|
         | 
| 886 946 | 
             
                      source = File.binread(migration.filename)
         | 
| 887 947 | 
             
                      inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
         | 
| 888 | 
            -
                      magic_comments = "" | 
| 948 | 
            +
                      magic_comments = +""
         | 
| 889 949 | 
             
                      loop do
         | 
| 890 950 | 
             
                        # If we have a magic comment in the original migration,
         | 
| 891 951 | 
             
                        # insert our comment after the first newline(end of the magic comment line)
         | 
| @@ -956,6 +1016,10 @@ module ActiveRecord | |
| 956 1016 | 
             
                      yield
         | 
| 957 1017 | 
             
                    end
         | 
| 958 1018 | 
             
                  end
         | 
| 1019 | 
            +
             | 
| 1020 | 
            +
                  def command_recorder
         | 
| 1021 | 
            +
                    CommandRecorder.new(connection)
         | 
| 1022 | 
            +
                  end
         | 
| 959 1023 | 
             
              end
         | 
| 960 1024 |  | 
| 961 1025 | 
             
              # MigrationProxy is used to defer loading of the actual migration classes
         | 
| @@ -970,14 +1034,9 @@ module ActiveRecord | |
| 970 1034 | 
             
                  File.basename(filename)
         | 
| 971 1035 | 
             
                end
         | 
| 972 1036 |  | 
| 973 | 
            -
                def mtime
         | 
| 974 | 
            -
                  File.mtime filename
         | 
| 975 | 
            -
                end
         | 
| 976 | 
            -
             | 
| 977 1037 | 
             
                delegate :migrate, :announce, :write, :disable_ddl_transaction, to: :migration
         | 
| 978 1038 |  | 
| 979 1039 | 
             
                private
         | 
| 980 | 
            -
             | 
| 981 1040 | 
             
                  def migration
         | 
| 982 1041 | 
             
                    @migration ||= load_migration
         | 
| 983 1042 | 
             
                  end
         | 
| @@ -988,21 +1047,12 @@ module ActiveRecord | |
| 988 1047 | 
             
                  end
         | 
| 989 1048 | 
             
              end
         | 
| 990 1049 |  | 
| 991 | 
            -
              class  | 
| 992 | 
            -
                 | 
| 993 | 
            -
                  super(nil, 0, nil, nil)
         | 
| 994 | 
            -
                end
         | 
| 1050 | 
            +
              class MigrationContext #:nodoc:
         | 
| 1051 | 
            +
                attr_reader :migrations_paths, :schema_migration
         | 
| 995 1052 |  | 
| 996 | 
            -
                def  | 
| 997 | 
            -
                  0
         | 
| 998 | 
            -
                end
         | 
| 999 | 
            -
              end
         | 
| 1000 | 
            -
             | 
| 1001 | 
            -
              class MigrationContext # :nodoc:
         | 
| 1002 | 
            -
                attr_reader :migrations_paths
         | 
| 1003 | 
            -
             | 
| 1004 | 
            -
                def initialize(migrations_paths)
         | 
| 1053 | 
            +
                def initialize(migrations_paths, schema_migration)
         | 
| 1005 1054 | 
             
                  @migrations_paths = migrations_paths
         | 
| 1055 | 
            +
                  @schema_migration = schema_migration
         | 
| 1006 1056 | 
             
                end
         | 
| 1007 1057 |  | 
| 1008 1058 | 
             
                def migrate(target_version = nil, &block)
         | 
| @@ -1033,7 +1083,7 @@ module ActiveRecord | |
| 1033 1083 | 
             
                    migrations
         | 
| 1034 1084 | 
             
                  end
         | 
| 1035 1085 |  | 
| 1036 | 
            -
                  Migrator.new(:up, selected_migrations, target_version).migrate
         | 
| 1086 | 
            +
                  Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
         | 
| 1037 1087 | 
             
                end
         | 
| 1038 1088 |  | 
| 1039 1089 | 
             
                def down(target_version = nil)
         | 
| @@ -1043,20 +1093,20 @@ module ActiveRecord | |
| 1043 1093 | 
             
                    migrations
         | 
| 1044 1094 | 
             
                  end
         | 
| 1045 1095 |  | 
| 1046 | 
            -
                  Migrator.new(:down, selected_migrations, target_version).migrate
         | 
| 1096 | 
            +
                  Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
         | 
| 1047 1097 | 
             
                end
         | 
| 1048 1098 |  | 
| 1049 1099 | 
             
                def run(direction, target_version)
         | 
| 1050 | 
            -
                  Migrator.new(direction, migrations, target_version).run
         | 
| 1100 | 
            +
                  Migrator.new(direction, migrations, schema_migration, target_version).run
         | 
| 1051 1101 | 
             
                end
         | 
| 1052 1102 |  | 
| 1053 1103 | 
             
                def open
         | 
| 1054 | 
            -
                  Migrator.new(:up, migrations,  | 
| 1104 | 
            +
                  Migrator.new(:up, migrations, schema_migration)
         | 
| 1055 1105 | 
             
                end
         | 
| 1056 1106 |  | 
| 1057 1107 | 
             
                def get_all_versions
         | 
| 1058 | 
            -
                  if  | 
| 1059 | 
            -
                     | 
| 1108 | 
            +
                  if schema_migration.table_exists?
         | 
| 1109 | 
            +
                    schema_migration.all_versions.map(&:to_i)
         | 
| 1060 1110 | 
             
                  else
         | 
| 1061 1111 | 
             
                    []
         | 
| 1062 1112 | 
             
                  end
         | 
| @@ -1075,14 +1125,6 @@ module ActiveRecord | |
| 1075 1125 | 
             
                  migrations.any?
         | 
| 1076 1126 | 
             
                end
         | 
| 1077 1127 |  | 
| 1078 | 
            -
                def last_migration #:nodoc:
         | 
| 1079 | 
            -
                  migrations.last || NullMigration.new
         | 
| 1080 | 
            -
                end
         | 
| 1081 | 
            -
             | 
| 1082 | 
            -
                def parse_migration_filename(filename) # :nodoc:
         | 
| 1083 | 
            -
                  File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
         | 
| 1084 | 
            -
                end
         | 
| 1085 | 
            -
             | 
| 1086 1128 | 
             
                def migrations
         | 
| 1087 1129 | 
             
                  migrations = migration_files.map do |file|
         | 
| 1088 1130 | 
             
                    version, name, scope = parse_migration_filename(file)
         | 
| @@ -1097,12 +1139,12 @@ module ActiveRecord | |
| 1097 1139 | 
             
                end
         | 
| 1098 1140 |  | 
| 1099 1141 | 
             
                def migrations_status
         | 
| 1100 | 
            -
                  db_list =  | 
| 1142 | 
            +
                  db_list = schema_migration.normalized_versions
         | 
| 1101 1143 |  | 
| 1102 1144 | 
             
                  file_list = migration_files.map do |file|
         | 
| 1103 1145 | 
             
                    version, name, scope = parse_migration_filename(file)
         | 
| 1104 1146 | 
             
                    raise IllegalMigrationNameError.new(file) unless version
         | 
| 1105 | 
            -
                    version =  | 
| 1147 | 
            +
                    version = schema_migration.normalize_migration_number(version)
         | 
| 1106 1148 | 
             
                    status = db_list.delete(version) ? "up" : "down"
         | 
| 1107 1149 | 
             
                    [status, version, (name + scope).humanize]
         | 
| 1108 1150 | 
             
                  end.compact
         | 
| @@ -1114,11 +1156,6 @@ module ActiveRecord | |
| 1114 1156 | 
             
                  (db_list + file_list).sort_by { |_, version, _| version }
         | 
| 1115 1157 | 
             
                end
         | 
| 1116 1158 |  | 
| 1117 | 
            -
                def migration_files
         | 
| 1118 | 
            -
                  paths = Array(migrations_paths)
         | 
| 1119 | 
            -
                  Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
         | 
| 1120 | 
            -
                end
         | 
| 1121 | 
            -
             | 
| 1122 1159 | 
             
                def current_environment
         | 
| 1123 1160 | 
             
                  ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
         | 
| 1124 1161 | 
             
                end
         | 
| @@ -1128,6 +1165,7 @@ module ActiveRecord | |
| 1128 1165 | 
             
                end
         | 
| 1129 1166 |  | 
| 1130 1167 | 
             
                def last_stored_environment
         | 
| 1168 | 
            +
                  return nil unless ActiveRecord::InternalMetadata.enabled?
         | 
| 1131 1169 | 
             
                  return nil if current_version == 0
         | 
| 1132 1170 | 
             
                  raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
         | 
| 1133 1171 |  | 
| @@ -1137,8 +1175,17 @@ module ActiveRecord | |
| 1137 1175 | 
             
                end
         | 
| 1138 1176 |  | 
| 1139 1177 | 
             
                private
         | 
| 1178 | 
            +
                  def migration_files
         | 
| 1179 | 
            +
                    paths = Array(migrations_paths)
         | 
| 1180 | 
            +
                    Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
         | 
| 1181 | 
            +
                  end
         | 
| 1182 | 
            +
             | 
| 1183 | 
            +
                  def parse_migration_filename(filename)
         | 
| 1184 | 
            +
                    File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
         | 
| 1185 | 
            +
                  end
         | 
| 1186 | 
            +
             | 
| 1140 1187 | 
             
                  def move(direction, steps)
         | 
| 1141 | 
            -
                    migrator = Migrator.new(direction, migrations)
         | 
| 1188 | 
            +
                    migrator = Migrator.new(direction, migrations, schema_migration)
         | 
| 1142 1189 |  | 
| 1143 1190 | 
             
                    if current_version != 0 && !migrator.current_migration
         | 
| 1144 1191 | 
             
                      raise UnknownMigrationVersionError.new(current_version)
         | 
| @@ -1153,7 +1200,7 @@ module ActiveRecord | |
| 1153 1200 |  | 
| 1154 1201 | 
             
                    finish = migrator.migrations[start_index + steps]
         | 
| 1155 1202 | 
             
                    version = finish ? finish.version : 0
         | 
| 1156 | 
            -
                     | 
| 1203 | 
            +
                    public_send(direction, version)
         | 
| 1157 1204 | 
             
                  end
         | 
| 1158 1205 | 
             
              end
         | 
| 1159 1206 |  | 
| @@ -1161,30 +1208,24 @@ module ActiveRecord | |
| 1161 1208 | 
             
                class << self
         | 
| 1162 1209 | 
             
                  attr_accessor :migrations_paths
         | 
| 1163 1210 |  | 
| 1164 | 
            -
                  def migrations_path=(path)
         | 
| 1165 | 
            -
                    ActiveSupport::Deprecation.warn \
         | 
| 1166 | 
            -
                      "`ActiveRecord::Migrator.migrations_path=` is now deprecated and will be removed in Rails 6.0. " \
         | 
| 1167 | 
            -
                      "You can set the `migrations_paths` on the `connection` instead through the `database.yml`."
         | 
| 1168 | 
            -
                    self.migrations_paths = [path]
         | 
| 1169 | 
            -
                  end
         | 
| 1170 | 
            -
             | 
| 1171 1211 | 
             
                  # For cases where a table doesn't exist like loading from schema cache
         | 
| 1172 1212 | 
             
                  def current_version
         | 
| 1173 | 
            -
                    MigrationContext.new(migrations_paths).current_version
         | 
| 1213 | 
            +
                    MigrationContext.new(migrations_paths, SchemaMigration).current_version
         | 
| 1174 1214 | 
             
                  end
         | 
| 1175 1215 | 
             
                end
         | 
| 1176 1216 |  | 
| 1177 1217 | 
             
                self.migrations_paths = ["db/migrate"]
         | 
| 1178 1218 |  | 
| 1179 | 
            -
                def initialize(direction, migrations, target_version = nil)
         | 
| 1219 | 
            +
                def initialize(direction, migrations, schema_migration, target_version = nil)
         | 
| 1180 1220 | 
             
                  @direction         = direction
         | 
| 1181 1221 | 
             
                  @target_version    = target_version
         | 
| 1182 1222 | 
             
                  @migrated_versions = nil
         | 
| 1183 1223 | 
             
                  @migrations        = migrations
         | 
| 1224 | 
            +
                  @schema_migration  = schema_migration
         | 
| 1184 1225 |  | 
| 1185 1226 | 
             
                  validate(@migrations)
         | 
| 1186 1227 |  | 
| 1187 | 
            -
                   | 
| 1228 | 
            +
                  @schema_migration.create_table
         | 
| 1188 1229 | 
             
                  ActiveRecord::InternalMetadata.create_table
         | 
| 1189 1230 | 
             
                end
         | 
| 1190 1231 |  | 
| @@ -1238,16 +1279,15 @@ module ActiveRecord | |
| 1238 1279 | 
             
                end
         | 
| 1239 1280 |  | 
| 1240 1281 | 
             
                def load_migrated
         | 
| 1241 | 
            -
                  @migrated_versions = Set.new( | 
| 1282 | 
            +
                  @migrated_versions = Set.new(@schema_migration.all_versions.map(&:to_i))
         | 
| 1242 1283 | 
             
                end
         | 
| 1243 1284 |  | 
| 1244 1285 | 
             
                private
         | 
| 1245 | 
            -
             | 
| 1246 1286 | 
             
                  # Used for running a specific migration.
         | 
| 1247 1287 | 
             
                  def run_without_lock
         | 
| 1248 1288 | 
             
                    migration = migrations.detect { |m| m.version == @target_version }
         | 
| 1249 1289 | 
             
                    raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
         | 
| 1250 | 
            -
                    result = execute_migration_in_transaction(migration | 
| 1290 | 
            +
                    result = execute_migration_in_transaction(migration)
         | 
| 1251 1291 |  | 
| 1252 1292 | 
             
                    record_environment
         | 
| 1253 1293 | 
             
                    result
         | 
| @@ -1259,10 +1299,7 @@ module ActiveRecord | |
| 1259 1299 | 
             
                      raise UnknownMigrationVersionError.new(@target_version)
         | 
| 1260 1300 | 
             
                    end
         | 
| 1261 1301 |  | 
| 1262 | 
            -
                    result = runnable.each | 
| 1263 | 
            -
                      execute_migration_in_transaction(migration, @direction)
         | 
| 1264 | 
            -
                    end
         | 
| 1265 | 
            -
             | 
| 1302 | 
            +
                    result = runnable.each(&method(:execute_migration_in_transaction))
         | 
| 1266 1303 | 
             
                    record_environment
         | 
| 1267 1304 | 
             
                    result
         | 
| 1268 1305 | 
             
                  end
         | 
| @@ -1282,18 +1319,18 @@ module ActiveRecord | |
| 1282 1319 | 
             
                    @target_version && @target_version != 0 && !target
         | 
| 1283 1320 | 
             
                  end
         | 
| 1284 1321 |  | 
| 1285 | 
            -
                  def execute_migration_in_transaction(migration | 
| 1322 | 
            +
                  def execute_migration_in_transaction(migration)
         | 
| 1286 1323 | 
             
                    return if down? && !migrated.include?(migration.version.to_i)
         | 
| 1287 1324 | 
             
                    return if up?   &&  migrated.include?(migration.version.to_i)
         | 
| 1288 1325 |  | 
| 1289 1326 | 
             
                    Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
         | 
| 1290 1327 |  | 
| 1291 1328 | 
             
                    ddl_transaction(migration) do
         | 
| 1292 | 
            -
                      migration.migrate(direction)
         | 
| 1329 | 
            +
                      migration.migrate(@direction)
         | 
| 1293 1330 | 
             
                      record_version_state_after_migrating(migration.version)
         | 
| 1294 1331 | 
             
                    end
         | 
| 1295 1332 | 
             
                  rescue => e
         | 
| 1296 | 
            -
                    msg = "An error has occurred, " | 
| 1333 | 
            +
                    msg = +"An error has occurred, "
         | 
| 1297 1334 | 
             
                    msg << "this and " if use_transaction?(migration)
         | 
| 1298 1335 | 
             
                    msg << "all later migrations canceled:\n\n#{e}"
         | 
| 1299 1336 | 
             
                    raise StandardError, msg, e.backtrace
         | 
| @@ -1322,10 +1359,10 @@ module ActiveRecord | |
| 1322 1359 | 
             
                  def record_version_state_after_migrating(version)
         | 
| 1323 1360 | 
             
                    if down?
         | 
| 1324 1361 | 
             
                      migrated.delete(version)
         | 
| 1325 | 
            -
                       | 
| 1362 | 
            +
                      @schema_migration.delete_by(version: version.to_s)
         | 
| 1326 1363 | 
             
                    else
         | 
| 1327 1364 | 
             
                      migrated << version
         | 
| 1328 | 
            -
                       | 
| 1365 | 
            +
                      @schema_migration.create!(version: version.to_s)
         | 
| 1329 1366 | 
             
                    end
         | 
| 1330 1367 | 
             
                  end
         | 
| 1331 1368 |  | 
| @@ -1351,24 +1388,36 @@ module ActiveRecord | |
| 1351 1388 | 
             
                  end
         | 
| 1352 1389 |  | 
| 1353 1390 | 
             
                  def use_advisory_lock?
         | 
| 1354 | 
            -
                    Base.connection. | 
| 1391 | 
            +
                    Base.connection.advisory_locks_enabled?
         | 
| 1355 1392 | 
             
                  end
         | 
| 1356 1393 |  | 
| 1357 1394 | 
             
                  def with_advisory_lock
         | 
| 1358 1395 | 
             
                    lock_id = generate_migrator_advisory_lock_id
         | 
| 1359 | 
            -
             | 
| 1360 | 
            -
                     | 
| 1361 | 
            -
             | 
| 1362 | 
            -
             | 
| 1363 | 
            -
             | 
| 1364 | 
            -
             | 
| 1365 | 
            -
                     | 
| 1366 | 
            -
                       | 
| 1367 | 
            -
                        ConcurrentMigrationError | 
| 1368 | 
            -
             | 
| 1396 | 
            +
             | 
| 1397 | 
            +
                    with_advisory_lock_connection do |connection|
         | 
| 1398 | 
            +
                      got_lock = connection.get_advisory_lock(lock_id)
         | 
| 1399 | 
            +
                      raise ConcurrentMigrationError unless got_lock
         | 
| 1400 | 
            +
                      load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
         | 
| 1401 | 
            +
                      yield
         | 
| 1402 | 
            +
                    ensure
         | 
| 1403 | 
            +
                      if got_lock && !connection.release_advisory_lock(lock_id)
         | 
| 1404 | 
            +
                        raise ConcurrentMigrationError.new(
         | 
| 1405 | 
            +
                          ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
         | 
| 1406 | 
            +
                        )
         | 
| 1407 | 
            +
                      end
         | 
| 1369 1408 | 
             
                    end
         | 
| 1370 1409 | 
             
                  end
         | 
| 1371 1410 |  | 
| 1411 | 
            +
                  def with_advisory_lock_connection
         | 
| 1412 | 
            +
                    pool = ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
         | 
| 1413 | 
            +
                      ActiveRecord::Base.connection_db_config
         | 
| 1414 | 
            +
                    )
         | 
| 1415 | 
            +
             | 
| 1416 | 
            +
                    pool.with_connection { |connection| yield(connection) }
         | 
| 1417 | 
            +
                  ensure
         | 
| 1418 | 
            +
                    pool&.disconnect!
         | 
| 1419 | 
            +
                  end
         | 
| 1420 | 
            +
             | 
| 1372 1421 | 
             
                  MIGRATOR_SALT = 2053462845
         | 
| 1373 1422 | 
             
                  def generate_migrator_advisory_lock_id
         | 
| 1374 1423 | 
             
                    db_name_hash = Zlib.crc32(Base.connection.current_database)
         |