activerecord 6.0.6.1 → 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 +782 -928
 - data/MIT-LICENSE +1 -1
 - data/README.rdoc +3 -3
 - data/lib/active_record/aggregations.rb +1 -1
 - data/lib/active_record/association_relation.rb +22 -14
 - data/lib/active_record/associations/alias_tracker.rb +19 -15
 - data/lib/active_record/associations/association.rb +43 -26
 - data/lib/active_record/associations/association_scope.rb +11 -15
 - data/lib/active_record/associations/belongs_to_association.rb +15 -5
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
 - data/lib/active_record/associations/builder/association.rb +9 -3
 - data/lib/active_record/associations/builder/belongs_to.rb +10 -7
 - data/lib/active_record/associations/builder/collection_association.rb +5 -4
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
 - data/lib/active_record/associations/builder/has_many.rb +6 -2
 - data/lib/active_record/associations/builder/has_one.rb +11 -14
 - data/lib/active_record/associations/builder/singular_association.rb +1 -1
 - data/lib/active_record/associations/collection_association.rb +19 -13
 - data/lib/active_record/associations/collection_proxy.rb +12 -5
 - data/lib/active_record/associations/foreign_association.rb +13 -0
 - data/lib/active_record/associations/has_many_association.rb +24 -2
 - data/lib/active_record/associations/has_many_through_association.rb +10 -4
 - data/lib/active_record/associations/has_one_association.rb +15 -1
 - data/lib/active_record/associations/join_dependency/join_association.rb +29 -14
 - data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
 - data/lib/active_record/associations/join_dependency.rb +63 -49
 - data/lib/active_record/associations/preloader/association.rb +13 -5
 - data/lib/active_record/associations/preloader/through_association.rb +1 -1
 - data/lib/active_record/associations/preloader.rb +5 -3
 - data/lib/active_record/associations/singular_association.rb +1 -1
 - data/lib/active_record/associations.rb +114 -11
 - data/lib/active_record/attribute_assignment.rb +10 -8
 - data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
 - data/lib/active_record/attribute_methods/dirty.rb +1 -11
 - data/lib/active_record/attribute_methods/primary_key.rb +6 -2
 - data/lib/active_record/attribute_methods/query.rb +3 -6
 - data/lib/active_record/attribute_methods/read.rb +8 -11
 - data/lib/active_record/attribute_methods/serialization.rb +11 -5
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
 - data/lib/active_record/attribute_methods/write.rb +12 -20
 - data/lib/active_record/attribute_methods.rb +64 -54
 - data/lib/active_record/attributes.rb +32 -7
 - data/lib/active_record/autosave_association.rb +47 -30
 - data/lib/active_record/base.rb +2 -14
 - data/lib/active_record/callbacks.rb +152 -22
 - data/lib/active_record/coders/yaml_column.rb +2 -24
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +185 -134
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +65 -22
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -7
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +35 -44
 - data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +110 -30
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +224 -85
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +80 -32
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +49 -72
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +123 -87
 - data/lib/active_record/connection_adapters/column.rb +15 -1
 - 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/database_statements.rb +22 -24
 - data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -6
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
 - data/lib/active_record/connection_adapters/mysql/schema_statements.rb +3 -3
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
 - 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 +24 -1
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +12 -53
 - 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 +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
 - 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/point.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +72 -55
 - data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
 - data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +30 -5
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
 - data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
 - data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +36 -3
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
 - data/lib/active_record/connection_adapters.rb +50 -0
 - data/lib/active_record/connection_handling.rb +210 -71
 - data/lib/active_record/core.rb +223 -66
 - data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
 - data/lib/active_record/database_configurations/database_config.rb +52 -9
 - data/lib/active_record/database_configurations/hash_config.rb +54 -8
 - data/lib/active_record/database_configurations/url_config.rb +15 -40
 - data/lib/active_record/database_configurations.rb +124 -85
 - data/lib/active_record/delegated_type.rb +209 -0
 - data/lib/active_record/destroy_association_async_job.rb +36 -0
 - data/lib/active_record/enum.rb +27 -10
 - data/lib/active_record/errors.rb +47 -12
 - data/lib/active_record/explain.rb +9 -4
 - 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 +1 -2
 - data/lib/active_record/fixture_set/render_context.rb +1 -1
 - data/lib/active_record/fixture_set/table_row.rb +2 -2
 - data/lib/active_record/fixtures.rb +54 -8
 - data/lib/active_record/gem_version.rb +3 -3
 - data/lib/active_record/inheritance.rb +40 -18
 - data/lib/active_record/insert_all.rb +34 -5
 - data/lib/active_record/integration.rb +3 -5
 - data/lib/active_record/internal_metadata.rb +16 -7
 - data/lib/active_record/legacy_yaml_adapter.rb +7 -3
 - data/lib/active_record/locking/optimistic.rb +13 -16
 - data/lib/active_record/locking/pessimistic.rb +6 -2
 - data/lib/active_record/log_subscriber.rb +26 -8
 - data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
 - data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
 - data/lib/active_record/middleware/database_selector.rb +4 -1
 - data/lib/active_record/migration/command_recorder.rb +47 -27
 - data/lib/active_record/migration/compatibility.rb +67 -17
 - data/lib/active_record/migration.rb +113 -83
 - data/lib/active_record/model_schema.rb +88 -13
 - data/lib/active_record/nested_attributes.rb +2 -3
 - data/lib/active_record/no_touching.rb +1 -1
 - data/lib/active_record/persistence.rb +50 -45
 - data/lib/active_record/query_cache.rb +15 -5
 - data/lib/active_record/querying.rb +11 -6
 - data/lib/active_record/railtie.rb +64 -44
 - data/lib/active_record/railties/databases.rake +266 -95
 - data/lib/active_record/readonly_attributes.rb +4 -0
 - data/lib/active_record/reflection.rb +60 -44
 - data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
 - data/lib/active_record/relation/batches.rb +38 -31
 - data/lib/active_record/relation/calculations.rb +100 -43
 - data/lib/active_record/relation/finder_methods.rb +44 -14
 - data/lib/active_record/relation/from_clause.rb +1 -1
 - data/lib/active_record/relation/merger.rb +20 -23
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
 - data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
 - data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
 - data/lib/active_record/relation/predicate_builder.rb +57 -33
 - data/lib/active_record/relation/query_methods.rb +318 -197
 - data/lib/active_record/relation/record_fetch_warning.rb +3 -3
 - data/lib/active_record/relation/spawn_methods.rb +8 -7
 - data/lib/active_record/relation/where_clause.rb +104 -57
 - data/lib/active_record/relation.rb +90 -64
 - data/lib/active_record/result.rb +41 -33
 - data/lib/active_record/runtime_registry.rb +2 -2
 - data/lib/active_record/sanitization.rb +6 -17
 - data/lib/active_record/schema_dumper.rb +34 -4
 - data/lib/active_record/schema_migration.rb +2 -8
 - data/lib/active_record/scoping/named.rb +1 -17
 - 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 +20 -4
 - data/lib/active_record/store.rb +2 -2
 - data/lib/active_record/suppressor.rb +2 -2
 - data/lib/active_record/table_metadata.rb +39 -51
 - data/lib/active_record/tasks/database_tasks.rb +139 -113
 - data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
 - data/lib/active_record/test_databases.rb +5 -4
 - data/lib/active_record/test_fixtures.rb +36 -33
 - data/lib/active_record/timestamp.rb +4 -6
 - data/lib/active_record/touch_later.rb +21 -21
 - data/lib/active_record/transactions.rb +15 -64
 - data/lib/active_record/type/serialized.rb +6 -2
 - data/lib/active_record/type.rb +8 -1
 - data/lib/active_record/type_caster/connection.rb +0 -1
 - data/lib/active_record/type_caster/map.rb +8 -5
 - data/lib/active_record/validations/associated.rb +1 -1
 - data/lib/active_record/validations/numericality.rb +35 -0
 - data/lib/active_record/validations/uniqueness.rb +24 -4
 - data/lib/active_record/validations.rb +1 -0
 - data/lib/active_record.rb +7 -14
 - data/lib/arel/attributes/attribute.rb +4 -0
 - data/lib/arel/collectors/bind.rb +5 -0
 - data/lib/arel/collectors/composite.rb +8 -0
 - data/lib/arel/collectors/sql_string.rb +7 -0
 - data/lib/arel/collectors/substitute_binds.rb +7 -0
 - data/lib/arel/nodes/binary.rb +82 -8
 - data/lib/arel/nodes/bind_param.rb +8 -0
 - data/lib/arel/nodes/casted.rb +21 -9
 - data/lib/arel/nodes/equality.rb +6 -9
 - data/lib/arel/nodes/grouping.rb +3 -0
 - data/lib/arel/nodes/homogeneous_in.rb +72 -0
 - data/lib/arel/nodes/in.rb +8 -1
 - data/lib/arel/nodes/infix_operation.rb +13 -1
 - data/lib/arel/nodes/join_source.rb +1 -1
 - data/lib/arel/nodes/node.rb +7 -6
 - data/lib/arel/nodes/ordering.rb +27 -0
 - data/lib/arel/nodes/sql_literal.rb +3 -0
 - data/lib/arel/nodes/table_alias.rb +7 -3
 - data/lib/arel/nodes/unary.rb +0 -1
 - data/lib/arel/nodes.rb +3 -1
 - data/lib/arel/predications.rb +12 -18
 - data/lib/arel/select_manager.rb +1 -2
 - data/lib/arel/table.rb +13 -5
 - data/lib/arel/visitors/dot.rb +14 -2
 - data/lib/arel/visitors/mysql.rb +11 -1
 - data/lib/arel/visitors/postgresql.rb +15 -4
 - data/lib/arel/visitors/to_sql.rb +89 -78
 - data/lib/arel/visitors.rb +0 -7
 - data/lib/arel.rb +5 -13
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
 - data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
 - data/lib/rails/generators/active_record/migration.rb +6 -1
 - 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
 - metadata +28 -30
 - data/lib/active_record/advisory_lock_base.rb +0 -18
 - data/lib/active_record/attribute_decorators.rb +0 -88
 - data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
 - data/lib/active_record/define_callbacks.rb +0 -22
 - data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
 - data/lib/active_record/relation/where_clause_factory.rb +0 -33
 - data/lib/arel/attributes.rb +0 -22
 - data/lib/arel/visitors/depth_first.rb +0 -203
 - data/lib/arel/visitors/ibm_db.rb +0 -34
 - data/lib/arel/visitors/informix.rb +0 -62
 - data/lib/arel/visitors/mssql.rb +0 -156
 - data/lib/arel/visitors/oracle.rb +0 -158
 - data/lib/arel/visitors/oracle12.rb +0 -65
 - data/lib/arel/visitors/where_sql.rb +0 -22
 
| 
         @@ -12,12 +12,12 @@ module ActiveRecord 
     | 
|
| 
       12 
12 
     | 
    
         
             
                # Becomes:
         
     | 
| 
       13 
13 
     | 
    
         
             
                #
         
     | 
| 
       14 
14 
     | 
    
         
             
                #   #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
         
     | 
| 
       15 
     | 
    
         
            -
                #     @env_name="development", @ 
     | 
| 
      
 15 
     | 
    
         
            +
                #     @env_name="development", @name="primary", @config={database: "db_name"}>
         
     | 
| 
       16 
16 
     | 
    
         
             
                #
         
     | 
| 
       17 
17 
     | 
    
         
             
                # ==== Options
         
     | 
| 
       18 
18 
     | 
    
         
             
                #
         
     | 
| 
       19 
19 
     | 
    
         
             
                # * <tt>:env_name</tt> - The Rails environment, i.e. "development".
         
     | 
| 
       20 
     | 
    
         
            -
                # * <tt>: 
     | 
| 
      
 20 
     | 
    
         
            +
                # * <tt>:name</tt> - The db config name. In a standard two-tier
         
     | 
| 
       21 
21 
     | 
    
         
             
                #   database configuration this will default to "primary". In a multiple
         
     | 
| 
       22 
22 
     | 
    
         
             
                #   database three-tier database configuration this corresponds to the name
         
     | 
| 
       23 
23 
     | 
    
         
             
                #   used in the second tier, for example "primary_readonly".
         
     | 
| 
         @@ -25,25 +25,71 @@ module ActiveRecord 
     | 
|
| 
       25 
25 
     | 
    
         
             
                #   database adapter, name, and other important information for database
         
     | 
| 
       26 
26 
     | 
    
         
             
                #   connections.
         
     | 
| 
       27 
27 
     | 
    
         
             
                class HashConfig < DatabaseConfig
         
     | 
| 
       28 
     | 
    
         
            -
                  attr_reader : 
     | 
| 
      
 28 
     | 
    
         
            +
                  attr_reader :configuration_hash
         
     | 
| 
      
 29 
     | 
    
         
            +
                  def initialize(env_name, name, configuration_hash)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    super(env_name, name)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    @configuration_hash = configuration_hash.symbolize_keys.freeze
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
       29 
33 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                  def  
     | 
| 
       31 
     | 
    
         
            -
                     
     | 
| 
       32 
     | 
    
         
            -
                     
     | 
| 
      
 34 
     | 
    
         
            +
                  def config
         
     | 
| 
      
 35 
     | 
    
         
            +
                    ActiveSupport::Deprecation.warn("DatabaseConfig#config will be removed in 6.2.0 in favor of DatabaseConfigurations#configuration_hash which returns a hash with symbol keys")
         
     | 
| 
      
 36 
     | 
    
         
            +
                    configuration_hash.stringify_keys
         
     | 
| 
       33 
37 
     | 
    
         
             
                  end
         
     | 
| 
       34 
38 
     | 
    
         | 
| 
       35 
39 
     | 
    
         
             
                  # Determines whether a database configuration is for a replica / readonly
         
     | 
| 
       36 
40 
     | 
    
         
             
                  # connection. If the +replica+ key is present in the config, +replica?+ will
         
     | 
| 
       37 
41 
     | 
    
         
             
                  # return +true+.
         
     | 
| 
       38 
42 
     | 
    
         
             
                  def replica?
         
     | 
| 
       39 
     | 
    
         
            -
                     
     | 
| 
      
 43 
     | 
    
         
            +
                    configuration_hash[:replica]
         
     | 
| 
       40 
44 
     | 
    
         
             
                  end
         
     | 
| 
       41 
45 
     | 
    
         | 
| 
       42 
46 
     | 
    
         
             
                  # The migrations paths for a database configuration. If the
         
     | 
| 
       43 
47 
     | 
    
         
             
                  # +migrations_paths+ key is present in the config, +migrations_paths+
         
     | 
| 
       44 
48 
     | 
    
         
             
                  # will return its value.
         
     | 
| 
       45 
49 
     | 
    
         
             
                  def migrations_paths
         
     | 
| 
       46 
     | 
    
         
            -
                     
     | 
| 
      
 50 
     | 
    
         
            +
                    configuration_hash[:migrations_paths]
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  def host
         
     | 
| 
      
 54 
     | 
    
         
            +
                    configuration_hash[:host]
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  def database
         
     | 
| 
      
 58 
     | 
    
         
            +
                    configuration_hash[:database]
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  def _database=(database) # :nodoc:
         
     | 
| 
      
 62 
     | 
    
         
            +
                    @configuration_hash = configuration_hash.merge(database: database).freeze
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def pool
         
     | 
| 
      
 66 
     | 
    
         
            +
                    (configuration_hash[:pool] || 5).to_i
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  def checkout_timeout
         
     | 
| 
      
 70 
     | 
    
         
            +
                    (configuration_hash[:checkout_timeout] || 5).to_f
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  # +reaping_frequency+ is configurable mostly for historical reasons, but it could
         
     | 
| 
      
 74 
     | 
    
         
            +
                  # also be useful if someone wants a very low +idle_timeout+.
         
     | 
| 
      
 75 
     | 
    
         
            +
                  def reaping_frequency
         
     | 
| 
      
 76 
     | 
    
         
            +
                    configuration_hash.fetch(:reaping_frequency, 60)&.to_f
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  def idle_timeout
         
     | 
| 
      
 80 
     | 
    
         
            +
                    timeout = configuration_hash.fetch(:idle_timeout, 300).to_f
         
     | 
| 
      
 81 
     | 
    
         
            +
                    timeout if timeout > 0
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  def adapter
         
     | 
| 
      
 85 
     | 
    
         
            +
                    configuration_hash[:adapter]
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  # The path to the schema cache dump file for a database.
         
     | 
| 
      
 89 
     | 
    
         
            +
                  # If omitted, the filename will be read from ENV or a
         
     | 
| 
      
 90 
     | 
    
         
            +
                  # default will be derived.
         
     | 
| 
      
 91 
     | 
    
         
            +
                  def schema_cache_path
         
     | 
| 
      
 92 
     | 
    
         
            +
                    configuration_hash[:schema_cache_path]
         
     | 
| 
       47 
93 
     | 
    
         
             
                  end
         
     | 
| 
       48 
94 
     | 
    
         
             
                end
         
     | 
| 
       49 
95 
     | 
    
         
             
              end
         
     | 
| 
         @@ -13,14 +13,14 @@ module ActiveRecord 
     | 
|
| 
       13 
13 
     | 
    
         
             
                # Becomes:
         
     | 
| 
       14 
14 
     | 
    
         
             
                #
         
     | 
| 
       15 
15 
     | 
    
         
             
                #   #<ActiveRecord::DatabaseConfigurations::UrlConfig:0x00007fdc3238f340
         
     | 
| 
       16 
     | 
    
         
            -
                #     @env_name="default_env", @ 
     | 
| 
       17 
     | 
    
         
            -
                #     @config={ 
     | 
| 
      
 16 
     | 
    
         
            +
                #     @env_name="default_env", @name="primary",
         
     | 
| 
      
 17 
     | 
    
         
            +
                #     @config={adapter: "postgresql", database: "foo", host: "localhost"},
         
     | 
| 
       18 
18 
     | 
    
         
             
                #     @url="postgres://localhost/foo">
         
     | 
| 
       19 
19 
     | 
    
         
             
                #
         
     | 
| 
       20 
20 
     | 
    
         
             
                # ==== Options
         
     | 
| 
       21 
21 
     | 
    
         
             
                #
         
     | 
| 
       22 
22 
     | 
    
         
             
                # * <tt>:env_name</tt> - The Rails environment, ie "development".
         
     | 
| 
       23 
     | 
    
         
            -
                # * <tt>: 
     | 
| 
      
 23 
     | 
    
         
            +
                # * <tt>:name</tt> - The db config name. In a standard two-tier
         
     | 
| 
       24 
24 
     | 
    
         
             
                #   database configuration this will default to "primary". In a multiple
         
     | 
| 
       25 
25 
     | 
    
         
             
                #   database three-tier database configuration this corresponds to the name
         
     | 
| 
       26 
26 
     | 
    
         
             
                #   used in the second tier, for example "primary_readonly".
         
     | 
| 
         @@ -28,49 +28,24 @@ module ActiveRecord 
     | 
|
| 
       28 
28 
     | 
    
         
             
                # * <tt>:config</tt> - The config hash. This is the hash that contains the
         
     | 
| 
       29 
29 
     | 
    
         
             
                #   database adapter, name, and other important information for database
         
     | 
| 
       30 
30 
     | 
    
         
             
                #   connections.
         
     | 
| 
       31 
     | 
    
         
            -
                class UrlConfig <  
     | 
| 
       32 
     | 
    
         
            -
                  attr_reader :url 
     | 
| 
      
 31 
     | 
    
         
            +
                class UrlConfig < HashConfig
         
     | 
| 
      
 32 
     | 
    
         
            +
                  attr_reader :url
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                  def initialize(env_name,  
     | 
| 
       35 
     | 
    
         
            -
                    super(env_name,  
     | 
| 
       36 
     | 
    
         
            -
                    @config = build_config(config, url)
         
     | 
| 
       37 
     | 
    
         
            -
                    @url = url
         
     | 
| 
       38 
     | 
    
         
            -
                  end
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                  def url_config? # :nodoc:
         
     | 
| 
       41 
     | 
    
         
            -
                    true
         
     | 
| 
       42 
     | 
    
         
            -
                  end
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                  # Determines whether a database configuration is for a replica / readonly
         
     | 
| 
       45 
     | 
    
         
            -
                  # connection. If the +replica+ key is present in the config, +replica?+ will
         
     | 
| 
       46 
     | 
    
         
            -
                  # return +true+.
         
     | 
| 
       47 
     | 
    
         
            -
                  def replica?
         
     | 
| 
       48 
     | 
    
         
            -
                    config["replica"]
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  def initialize(env_name, name, url, configuration_hash = {})
         
     | 
| 
      
 35 
     | 
    
         
            +
                    super(env_name, name, configuration_hash)
         
     | 
| 
       50 
36 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                  # will return its value.
         
     | 
| 
       54 
     | 
    
         
            -
                  def migrations_paths
         
     | 
| 
       55 
     | 
    
         
            -
                    config["migrations_paths"]
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @url = url
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @configuration_hash = @configuration_hash.merge(build_url_hash).freeze
         
     | 
| 
       56 
39 
     | 
    
         
             
                  end
         
     | 
| 
       57 
40 
     | 
    
         | 
| 
       58 
41 
     | 
    
         
             
                  private
         
     | 
| 
       59 
     | 
    
         
            -
                     
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                       
     | 
| 
       63 
     | 
    
         
            -
                         
     | 
| 
       64 
     | 
    
         
            -
                      end
         
     | 
| 
       65 
     | 
    
         
            -
                    end
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                    def build_config(original_config, url)
         
     | 
| 
       68 
     | 
    
         
            -
                      hash = build_url_hash(url)
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                      if original_config[env_name]
         
     | 
| 
       71 
     | 
    
         
            -
                        original_config[env_name].merge(hash)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    # Return a Hash that can be merged into the main config that represents
         
     | 
| 
      
 43 
     | 
    
         
            +
                    # the passed in url
         
     | 
| 
      
 44 
     | 
    
         
            +
                    def build_url_hash
         
     | 
| 
      
 45 
     | 
    
         
            +
                      if url.nil? || url.start_with?("jdbc:")
         
     | 
| 
      
 46 
     | 
    
         
            +
                        { url: url }
         
     | 
| 
       72 
47 
     | 
    
         
             
                      else
         
     | 
| 
       73 
     | 
    
         
            -
                         
     | 
| 
      
 48 
     | 
    
         
            +
                        ConnectionUrlResolver.new(url).to_hash
         
     | 
| 
       74 
49 
     | 
    
         
             
                      end
         
     | 
| 
       75 
50 
     | 
    
         
             
                    end
         
     | 
| 
       76 
51 
     | 
    
         
             
                end
         
     | 
| 
         @@ -3,6 +3,7 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            require "active_record/database_configurations/database_config"
         
     | 
| 
       4 
4 
     | 
    
         
             
            require "active_record/database_configurations/hash_config"
         
     | 
| 
       5 
5 
     | 
    
         
             
            require "active_record/database_configurations/url_config"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "active_record/database_configurations/connection_url_resolver"
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
       7 
8 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       8 
9 
     | 
    
         
             
              # ActiveRecord::DatabaseConfigurations returns an array of DatabaseConfig
         
     | 
| 
         @@ -21,7 +22,7 @@ module ActiveRecord 
     | 
|
| 
       21 
22 
     | 
    
         
             
                # Collects the configs for the environment and optionally the specification
         
     | 
| 
       22 
23 
     | 
    
         
             
                # name passed in. To include replica configurations pass <tt>include_replicas: true</tt>.
         
     | 
| 
       23 
24 
     | 
    
         
             
                #
         
     | 
| 
       24 
     | 
    
         
            -
                # If a  
     | 
| 
      
 25 
     | 
    
         
            +
                # If a name is provided a single DatabaseConfig object will be
         
     | 
| 
       25 
26 
     | 
    
         
             
                # returned, otherwise an array of DatabaseConfig objects will be
         
     | 
| 
       26 
27 
     | 
    
         
             
                # returned that corresponds with the environment and type requested.
         
     | 
| 
       27 
28 
     | 
    
         
             
                #
         
     | 
| 
         @@ -29,13 +30,20 @@ module ActiveRecord 
     | 
|
| 
       29 
30 
     | 
    
         
             
                #
         
     | 
| 
       30 
31 
     | 
    
         
             
                # * <tt>env_name:</tt> The environment name. Defaults to +nil+ which will collect
         
     | 
| 
       31 
32 
     | 
    
         
             
                #   configs for all environments.
         
     | 
| 
       32 
     | 
    
         
            -
                # * <tt> 
     | 
| 
       33 
     | 
    
         
            -
                #   to +nil+.
         
     | 
| 
      
 33 
     | 
    
         
            +
                # * <tt>name:</tt> The db config name (i.e. primary, animals, etc.). Defaults
         
     | 
| 
      
 34 
     | 
    
         
            +
                #   to +nil+. If no +env_name+ is specified the config for the default env and the
         
     | 
| 
      
 35 
     | 
    
         
            +
                #   passed +name+ will be returned.
         
     | 
| 
       34 
36 
     | 
    
         
             
                # * <tt>include_replicas:</tt> Determines whether to include replicas in
         
     | 
| 
       35 
37 
     | 
    
         
             
                #   the returned list. Most of the time we're only iterating over the write
         
     | 
| 
       36 
38 
     | 
    
         
             
                #   connection (i.e. migrations don't need to run for the write and read connection).
         
     | 
| 
       37 
39 
     | 
    
         
             
                #   Defaults to +false+.
         
     | 
| 
       38 
     | 
    
         
            -
                def configs_for(env_name: nil, spec_name: nil, include_replicas: false)
         
     | 
| 
      
 40 
     | 
    
         
            +
                def configs_for(env_name: nil, spec_name: nil, name: nil, include_replicas: false)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  if spec_name
         
     | 
| 
      
 42 
     | 
    
         
            +
                    name = spec_name
         
     | 
| 
      
 43 
     | 
    
         
            +
                    ActiveSupport::Deprecation.warn("The kwarg `spec_name` is deprecated in favor of `name`. `spec_name` will be removed in Rails 6.2")
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  env_name ||= default_env if name
         
     | 
| 
       39 
47 
     | 
    
         
             
                  configs = env_with_configs(env_name)
         
     | 
| 
       40 
48 
     | 
    
         | 
| 
       41 
49 
     | 
    
         
             
                  unless include_replicas
         
     | 
| 
         @@ -44,9 +52,9 @@ module ActiveRecord 
     | 
|
| 
       44 
52 
     | 
    
         
             
                    end
         
     | 
| 
       45 
53 
     | 
    
         
             
                  end
         
     | 
| 
       46 
54 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
                  if  
     | 
| 
      
 55 
     | 
    
         
            +
                  if name
         
     | 
| 
       48 
56 
     | 
    
         
             
                    configs.find do |db_config|
         
     | 
| 
       49 
     | 
    
         
            -
                      db_config. 
     | 
| 
      
 57 
     | 
    
         
            +
                      db_config.name == name
         
     | 
| 
       50 
58 
     | 
    
         
             
                    end
         
     | 
| 
       51 
59 
     | 
    
         
             
                  else
         
     | 
| 
       52 
60 
     | 
    
         
             
                    configs
         
     | 
| 
         @@ -59,31 +67,46 @@ module ActiveRecord 
     | 
|
| 
       59 
67 
     | 
    
         
             
                # return the first config hash for the environment.
         
     | 
| 
       60 
68 
     | 
    
         
             
                #
         
     | 
| 
       61 
69 
     | 
    
         
             
                #   { database: "my_db", adapter: "mysql2" }
         
     | 
| 
       62 
     | 
    
         
            -
                def default_hash(env =  
     | 
| 
      
 70 
     | 
    
         
            +
                def default_hash(env = default_env)
         
     | 
| 
       63 
71 
     | 
    
         
             
                  default = find_db_config(env)
         
     | 
| 
       64 
     | 
    
         
            -
                  default. 
     | 
| 
      
 72 
     | 
    
         
            +
                  default.configuration_hash if default
         
     | 
| 
       65 
73 
     | 
    
         
             
                end
         
     | 
| 
       66 
74 
     | 
    
         
             
                alias :[] :default_hash
         
     | 
| 
      
 75 
     | 
    
         
            +
                deprecate "[]": "Use configs_for", default_hash: "Use configs_for"
         
     | 
| 
       67 
76 
     | 
    
         | 
| 
       68 
77 
     | 
    
         
             
                # Returns a single DatabaseConfig object based on the requested environment.
         
     | 
| 
       69 
78 
     | 
    
         
             
                #
         
     | 
| 
       70 
79 
     | 
    
         
             
                # If the application has multiple databases +find_db_config+ will return
         
     | 
| 
       71 
80 
     | 
    
         
             
                # the first DatabaseConfig for the environment.
         
     | 
| 
       72 
81 
     | 
    
         
             
                def find_db_config(env)
         
     | 
| 
       73 
     | 
    
         
            -
                  configurations 
     | 
| 
       74 
     | 
    
         
            -
                     
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
      
 82 
     | 
    
         
            +
                  configurations
         
     | 
| 
      
 83 
     | 
    
         
            +
                    .sort_by.with_index { |db_config, i| db_config.for_current_env? ? [0, i] : [1, i] }
         
     | 
| 
      
 84 
     | 
    
         
            +
                    .find do |db_config|
         
     | 
| 
      
 85 
     | 
    
         
            +
                      db_config.env_name == env.to_s ||
         
     | 
| 
      
 86 
     | 
    
         
            +
                        (db_config.for_current_env? && db_config.name == env.to_s)
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                # A primary configuration is one that is named primary or if there is
         
     | 
| 
      
 91 
     | 
    
         
            +
                # no primary, the first configuration for an environment will be treated
         
     | 
| 
      
 92 
     | 
    
         
            +
                # as primary. This is used as the "default" configuration and is used
         
     | 
| 
      
 93 
     | 
    
         
            +
                # when the application needs to treat one configuration differently. For
         
     | 
| 
      
 94 
     | 
    
         
            +
                # example, when Rails dumps the schema, the primary configuration's schema
         
     | 
| 
      
 95 
     | 
    
         
            +
                # file will be named `schema.rb` instead of `primary_schema.rb`.
         
     | 
| 
      
 96 
     | 
    
         
            +
                def primary?(name) # :nodoc:
         
     | 
| 
      
 97 
     | 
    
         
            +
                  return true if name == "primary"
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  first_config = find_db_config(default_env)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  first_config && name == first_config.name
         
     | 
| 
       77 
101 
     | 
    
         
             
                end
         
     | 
| 
       78 
102 
     | 
    
         | 
| 
       79 
103 
     | 
    
         
             
                # Returns the DatabaseConfigurations object as a Hash.
         
     | 
| 
       80 
104 
     | 
    
         
             
                def to_h
         
     | 
| 
       81 
     | 
    
         
            -
                   
     | 
| 
       82 
     | 
    
         
            -
                    memo.merge(db_config. 
     | 
| 
      
 105 
     | 
    
         
            +
                  configurations.inject({}) do |memo, db_config|
         
     | 
| 
      
 106 
     | 
    
         
            +
                    memo.merge(db_config.env_name => db_config.configuration_hash.stringify_keys)
         
     | 
| 
       83 
107 
     | 
    
         
             
                  end
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                  Hash[configs.to_a.reverse]
         
     | 
| 
       86 
108 
     | 
    
         
             
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
                deprecate to_h: "You can use `ActiveRecord::Base.configurations.configs_for(env_name: 'env', name: 'primary').configuration_hash` to get the configuration hashes."
         
     | 
| 
       87 
110 
     | 
    
         | 
| 
       88 
111 
     | 
    
         
             
                # Checks if the application's configurations are empty.
         
     | 
| 
       89 
112 
     | 
    
         
             
                #
         
     | 
| 
         @@ -93,20 +116,43 @@ module ActiveRecord 
     | 
|
| 
       93 
116 
     | 
    
         
             
                end
         
     | 
| 
       94 
117 
     | 
    
         
             
                alias :blank? :empty?
         
     | 
| 
       95 
118 
     | 
    
         | 
| 
       96 
     | 
    
         
            -
                 
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
                 
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
                 
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
      
 119 
     | 
    
         
            +
                # Returns fully resolved connection, accepts hash, string or symbol.
         
     | 
| 
      
 120 
     | 
    
         
            +
                # Always returns a DatabaseConfiguration::DatabaseConfig
         
     | 
| 
      
 121 
     | 
    
         
            +
                #
         
     | 
| 
      
 122 
     | 
    
         
            +
                # == Examples
         
     | 
| 
      
 123 
     | 
    
         
            +
                #
         
     | 
| 
      
 124 
     | 
    
         
            +
                # Symbol representing current environment.
         
     | 
| 
      
 125 
     | 
    
         
            +
                #
         
     | 
| 
      
 126 
     | 
    
         
            +
                #   DatabaseConfigurations.new("production" => {}).resolve(:production)
         
     | 
| 
      
 127 
     | 
    
         
            +
                #   # => DatabaseConfigurations::HashConfig.new(env_name: "production", config: {})
         
     | 
| 
      
 128 
     | 
    
         
            +
                #
         
     | 
| 
      
 129 
     | 
    
         
            +
                # One layer deep hash of connection values.
         
     | 
| 
      
 130 
     | 
    
         
            +
                #
         
     | 
| 
      
 131 
     | 
    
         
            +
                #   DatabaseConfigurations.new({}).resolve("adapter" => "sqlite3")
         
     | 
| 
      
 132 
     | 
    
         
            +
                #   # => DatabaseConfigurations::HashConfig.new(config: {"adapter" => "sqlite3"})
         
     | 
| 
      
 133 
     | 
    
         
            +
                #
         
     | 
| 
      
 134 
     | 
    
         
            +
                # Connection URL.
         
     | 
| 
      
 135 
     | 
    
         
            +
                #
         
     | 
| 
      
 136 
     | 
    
         
            +
                #   DatabaseConfigurations.new({}).resolve("postgresql://localhost/foo")
         
     | 
| 
      
 137 
     | 
    
         
            +
                #   # => DatabaseConfigurations::UrlConfig.new(config: {"adapter" => "postgresql", "host" => "localhost", "database" => "foo"})
         
     | 
| 
      
 138 
     | 
    
         
            +
                def resolve(config) # :nodoc:
         
     | 
| 
      
 139 
     | 
    
         
            +
                  return config if DatabaseConfigurations::DatabaseConfig === config
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                  case config
         
     | 
| 
      
 142 
     | 
    
         
            +
                  when Symbol
         
     | 
| 
      
 143 
     | 
    
         
            +
                    resolve_symbol_connection(config)
         
     | 
| 
      
 144 
     | 
    
         
            +
                  when Hash, String
         
     | 
| 
      
 145 
     | 
    
         
            +
                    build_db_config_from_raw_config(default_env, "primary", config)
         
     | 
| 
      
 146 
     | 
    
         
            +
                  else
         
     | 
| 
      
 147 
     | 
    
         
            +
                    raise TypeError, "Invalid type for configuration. Expected Symbol, String, or Hash. Got #{config.inspect}"
         
     | 
| 
      
 148 
     | 
    
         
            +
                  end
         
     | 
| 
       107 
149 
     | 
    
         
             
                end
         
     | 
| 
       108 
150 
     | 
    
         | 
| 
       109 
151 
     | 
    
         
             
                private
         
     | 
| 
      
 152 
     | 
    
         
            +
                  def default_env
         
     | 
| 
      
 153 
     | 
    
         
            +
                    ActiveRecord::ConnectionHandling::DEFAULT_ENV.call.to_s
         
     | 
| 
      
 154 
     | 
    
         
            +
                  end
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
       110 
156 
     | 
    
         
             
                  def env_with_configs(env = nil)
         
     | 
| 
       111 
157 
     | 
    
         
             
                    if env
         
     | 
| 
       112 
158 
     | 
    
         
             
                      configurations.select { |db_config| db_config.env_name == env }
         
     | 
| 
         @@ -127,107 +173,100 @@ module ActiveRecord 
     | 
|
| 
       127 
173 
     | 
    
         
             
                      end
         
     | 
| 
       128 
174 
     | 
    
         
             
                    end
         
     | 
| 
       129 
175 
     | 
    
         | 
| 
       130 
     | 
    
         
            -
                    current_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call.to_s
         
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
176 
     | 
    
         
             
                    unless db_configs.find(&:for_current_env?)
         
     | 
| 
       133 
     | 
    
         
            -
                      db_configs << environment_url_config( 
     | 
| 
      
 177 
     | 
    
         
            +
                      db_configs << environment_url_config(default_env, "primary", {})
         
     | 
| 
       134 
178 
     | 
    
         
             
                    end
         
     | 
| 
       135 
179 
     | 
    
         | 
| 
       136 
     | 
    
         
            -
                    merge_db_environment_variables( 
     | 
| 
      
 180 
     | 
    
         
            +
                    merge_db_environment_variables(default_env, db_configs.compact)
         
     | 
| 
       137 
181 
     | 
    
         
             
                  end
         
     | 
| 
       138 
182 
     | 
    
         | 
| 
       139 
183 
     | 
    
         
             
                  def walk_configs(env_name, config)
         
     | 
| 
       140 
     | 
    
         
            -
                    config.map do | 
     | 
| 
       141 
     | 
    
         
            -
                      build_db_config_from_raw_config(env_name,  
     | 
| 
      
 184 
     | 
    
         
            +
                    config.map do |name, sub_config|
         
     | 
| 
      
 185 
     | 
    
         
            +
                      build_db_config_from_raw_config(env_name, name.to_s, sub_config)
         
     | 
| 
       142 
186 
     | 
    
         
             
                    end
         
     | 
| 
       143 
187 
     | 
    
         
             
                  end
         
     | 
| 
       144 
188 
     | 
    
         | 
| 
       145 
     | 
    
         
            -
                  def  
     | 
| 
      
 189 
     | 
    
         
            +
                  def resolve_symbol_connection(name)
         
     | 
| 
      
 190 
     | 
    
         
            +
                    if db_config = find_db_config(name)
         
     | 
| 
      
 191 
     | 
    
         
            +
                      db_config
         
     | 
| 
      
 192 
     | 
    
         
            +
                    else
         
     | 
| 
      
 193 
     | 
    
         
            +
                      raise AdapterNotSpecified, <<~MSG
         
     | 
| 
      
 194 
     | 
    
         
            +
                        The `#{name}` database is not configured for the `#{default_env}` environment.
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                          Available databases configurations are:
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
                          #{build_configuration_sentence}
         
     | 
| 
      
 199 
     | 
    
         
            +
                      MSG
         
     | 
| 
      
 200 
     | 
    
         
            +
                    end
         
     | 
| 
      
 201 
     | 
    
         
            +
                  end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                  def build_configuration_sentence
         
     | 
| 
      
 204 
     | 
    
         
            +
                    configs = configs_for(include_replicas: true)
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
                    configs.group_by(&:env_name).map do |env, config|
         
     | 
| 
      
 207 
     | 
    
         
            +
                      names = config.map(&:name)
         
     | 
| 
      
 208 
     | 
    
         
            +
                      if names.size > 1
         
     | 
| 
      
 209 
     | 
    
         
            +
                        "#{env}: #{names.join(", ")}"
         
     | 
| 
      
 210 
     | 
    
         
            +
                      else
         
     | 
| 
      
 211 
     | 
    
         
            +
                        env
         
     | 
| 
      
 212 
     | 
    
         
            +
                      end
         
     | 
| 
      
 213 
     | 
    
         
            +
                    end.join("\n")
         
     | 
| 
      
 214 
     | 
    
         
            +
                  end
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                  def build_db_config_from_raw_config(env_name, name, config)
         
     | 
| 
       146 
217 
     | 
    
         
             
                    case config
         
     | 
| 
       147 
218 
     | 
    
         
             
                    when String
         
     | 
| 
       148 
     | 
    
         
            -
                      build_db_config_from_string(env_name,  
     | 
| 
      
 219 
     | 
    
         
            +
                      build_db_config_from_string(env_name, name, config)
         
     | 
| 
       149 
220 
     | 
    
         
             
                    when Hash
         
     | 
| 
       150 
     | 
    
         
            -
                      build_db_config_from_hash(env_name,  
     | 
| 
      
 221 
     | 
    
         
            +
                      build_db_config_from_hash(env_name, name, config.symbolize_keys)
         
     | 
| 
       151 
222 
     | 
    
         
             
                    else
         
     | 
| 
       152 
223 
     | 
    
         
             
                      raise InvalidConfigurationError, "'{ #{env_name} => #{config} }' is not a valid configuration. Expected '#{config}' to be a URL string or a Hash."
         
     | 
| 
       153 
224 
     | 
    
         
             
                    end
         
     | 
| 
       154 
225 
     | 
    
         
             
                  end
         
     | 
| 
       155 
226 
     | 
    
         | 
| 
       156 
     | 
    
         
            -
                  def build_db_config_from_string(env_name,  
     | 
| 
      
 227 
     | 
    
         
            +
                  def build_db_config_from_string(env_name, name, config)
         
     | 
| 
       157 
228 
     | 
    
         
             
                    url = config
         
     | 
| 
       158 
229 
     | 
    
         
             
                    uri = URI.parse(url)
         
     | 
| 
       159 
230 
     | 
    
         
             
                    if uri.scheme
         
     | 
| 
       160 
     | 
    
         
            -
                       
     | 
| 
      
 231 
     | 
    
         
            +
                      UrlConfig.new(env_name, name, url)
         
     | 
| 
       161 
232 
     | 
    
         
             
                    else
         
     | 
| 
       162 
233 
     | 
    
         
             
                      raise InvalidConfigurationError, "'{ #{env_name} => #{config} }' is not a valid configuration. Expected '#{config}' to be a URL string or a Hash."
         
     | 
| 
       163 
234 
     | 
    
         
             
                    end
         
     | 
| 
       164 
235 
     | 
    
         
             
                  end
         
     | 
| 
       165 
236 
     | 
    
         | 
| 
       166 
     | 
    
         
            -
                  def build_db_config_from_hash(env_name,  
     | 
| 
       167 
     | 
    
         
            -
                    if config.has_key?( 
     | 
| 
       168 
     | 
    
         
            -
                      url = config[ 
     | 
| 
      
 237 
     | 
    
         
            +
                  def build_db_config_from_hash(env_name, name, config)
         
     | 
| 
      
 238 
     | 
    
         
            +
                    if config.has_key?(:url)
         
     | 
| 
      
 239 
     | 
    
         
            +
                      url = config[:url]
         
     | 
| 
       169 
240 
     | 
    
         
             
                      config_without_url = config.dup
         
     | 
| 
       170 
     | 
    
         
            -
                      config_without_url.delete  
     | 
| 
      
 241 
     | 
    
         
            +
                      config_without_url.delete :url
         
     | 
| 
       171 
242 
     | 
    
         | 
| 
       172 
     | 
    
         
            -
                       
     | 
| 
      
 243 
     | 
    
         
            +
                      UrlConfig.new(env_name, name, url, config_without_url)
         
     | 
| 
       173 
244 
     | 
    
         
             
                    else
         
     | 
| 
       174 
     | 
    
         
            -
                       
     | 
| 
      
 245 
     | 
    
         
            +
                      HashConfig.new(env_name, name, config)
         
     | 
| 
       175 
246 
     | 
    
         
             
                    end
         
     | 
| 
       176 
247 
     | 
    
         
             
                  end
         
     | 
| 
       177 
248 
     | 
    
         | 
| 
       178 
249 
     | 
    
         
             
                  def merge_db_environment_variables(current_env, configs)
         
     | 
| 
       179 
250 
     | 
    
         
             
                    configs.map do |config|
         
     | 
| 
       180 
     | 
    
         
            -
                      next config if config. 
     | 
| 
      
 251 
     | 
    
         
            +
                      next config if config.is_a?(UrlConfig) || config.env_name != current_env
         
     | 
| 
       181 
252 
     | 
    
         | 
| 
       182 
     | 
    
         
            -
                      url_config = environment_url_config(current_env, config. 
     | 
| 
      
 253 
     | 
    
         
            +
                      url_config = environment_url_config(current_env, config.name, config.configuration_hash)
         
     | 
| 
       183 
254 
     | 
    
         
             
                      url_config || config
         
     | 
| 
       184 
255 
     | 
    
         
             
                    end
         
     | 
| 
       185 
256 
     | 
    
         
             
                  end
         
     | 
| 
       186 
257 
     | 
    
         | 
| 
       187 
     | 
    
         
            -
                  def environment_url_config(env,  
     | 
| 
       188 
     | 
    
         
            -
                    url = environment_value_for( 
     | 
| 
      
 258 
     | 
    
         
            +
                  def environment_url_config(env, name, config)
         
     | 
| 
      
 259 
     | 
    
         
            +
                    url = environment_value_for(name)
         
     | 
| 
       189 
260 
     | 
    
         
             
                    return unless url
         
     | 
| 
       190 
261 
     | 
    
         | 
| 
       191 
     | 
    
         
            -
                     
     | 
| 
      
 262 
     | 
    
         
            +
                    UrlConfig.new(env, name, url, config)
         
     | 
| 
       192 
263 
     | 
    
         
             
                  end
         
     | 
| 
       193 
264 
     | 
    
         | 
| 
       194 
     | 
    
         
            -
                  def environment_value_for( 
     | 
| 
       195 
     | 
    
         
            -
                     
     | 
| 
       196 
     | 
    
         
            -
                    url = ENV[ 
     | 
| 
       197 
     | 
    
         
            -
                    url ||= ENV["DATABASE_URL"] if  
     | 
| 
      
 265 
     | 
    
         
            +
                  def environment_value_for(name)
         
     | 
| 
      
 266 
     | 
    
         
            +
                    name_env_key = "#{name.upcase}_DATABASE_URL"
         
     | 
| 
      
 267 
     | 
    
         
            +
                    url = ENV[name_env_key]
         
     | 
| 
      
 268 
     | 
    
         
            +
                    url ||= ENV["DATABASE_URL"] if name == "primary"
         
     | 
| 
       198 
269 
     | 
    
         
             
                    url
         
     | 
| 
       199 
270 
     | 
    
         
             
                  end
         
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
                  def method_missing(method, *args, &blk)
         
     | 
| 
       202 
     | 
    
         
            -
                    case method
         
     | 
| 
       203 
     | 
    
         
            -
                    when :fetch
         
     | 
| 
       204 
     | 
    
         
            -
                      throw_getter_deprecation(method)
         
     | 
| 
       205 
     | 
    
         
            -
                      configs_for(env_name: args.first)
         
     | 
| 
       206 
     | 
    
         
            -
                    when :values
         
     | 
| 
       207 
     | 
    
         
            -
                      throw_getter_deprecation(method)
         
     | 
| 
       208 
     | 
    
         
            -
                      configurations.map(&:config)
         
     | 
| 
       209 
     | 
    
         
            -
                    when :[]=
         
     | 
| 
       210 
     | 
    
         
            -
                      throw_setter_deprecation(method)
         
     | 
| 
       211 
     | 
    
         
            -
             
     | 
| 
       212 
     | 
    
         
            -
                      env_name = args[0]
         
     | 
| 
       213 
     | 
    
         
            -
                      config = args[1]
         
     | 
| 
       214 
     | 
    
         
            -
             
     | 
| 
       215 
     | 
    
         
            -
                      remaining_configs = configurations.reject { |db_config| db_config.env_name == env_name }
         
     | 
| 
       216 
     | 
    
         
            -
                      new_config = build_configs(env_name => config)
         
     | 
| 
       217 
     | 
    
         
            -
                      new_configs = remaining_configs + new_config
         
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
                      ActiveRecord::Base.configurations = new_configs
         
     | 
| 
       220 
     | 
    
         
            -
                    else
         
     | 
| 
       221 
     | 
    
         
            -
                      raise NotImplementedError, "`ActiveRecord::Base.configurations` in Rails 6 now returns an object instead of a hash. The `#{method}` method is not supported. Please use `configs_for` or consult the documentation for supported methods."
         
     | 
| 
       222 
     | 
    
         
            -
                    end
         
     | 
| 
       223 
     | 
    
         
            -
                  end
         
     | 
| 
       224 
     | 
    
         
            -
             
     | 
| 
       225 
     | 
    
         
            -
                  def throw_setter_deprecation(method)
         
     | 
| 
       226 
     | 
    
         
            -
                    ActiveSupport::Deprecation.warn("Setting `ActiveRecord::Base.configurations` with `#{method}` is deprecated. Use `ActiveRecord::Base.configurations=` directly to set the configurations instead.")
         
     | 
| 
       227 
     | 
    
         
            -
                  end
         
     | 
| 
       228 
     | 
    
         
            -
             
     | 
| 
       229 
     | 
    
         
            -
                  def throw_getter_deprecation(method)
         
     | 
| 
       230 
     | 
    
         
            -
                    ActiveSupport::Deprecation.warn("`ActiveRecord::Base.configurations` no longer returns a hash. Methods that act on the hash like `#{method}` are deprecated and will be removed in Rails 6.1. Use the `configs_for` method to collect and iterate over the database configurations.")
         
     | 
| 
       231 
     | 
    
         
            -
                  end
         
     | 
| 
       232 
271 
     | 
    
         
             
              end
         
     | 
| 
       233 
272 
     | 
    
         
             
            end
         
     |