1. 24 9月, 2019 2 次提交
    • J
      Make UrlConfig a subclass of HashConfig · 1d8537b1
      John Crepezzi 提交于
      A `UrlConfig` is a `HashConfig` that mixes in connection information
      based on a `url` passed from the constructor.
      
      Previously, for each new property we wanted to introduce an accessor
      for, we'd need to write an implementation for `HashConfig` _and_ for
      `UrlConfig`.
      
      Now we make `UrlConfig` descend from `HashConfig` so we can write a
      single implementation for both cases.
      
      Also while we're in here, take the `adapter` implementation into
      `HashConfig` so that `DatabaseConfig` isn't making any assumptions about
      the structure of its subclasses.
      Co-authored-by: Neileencodes <eileencodes@gmail.com>
      1d8537b1
    • J
      Remove UrlConfig#url_config? · c582253e
      John Crepezzi 提交于
      This private method is only used in one place, to check whether an
      object we have is an instance of `UrlConfig`.
      
      Instead we can just check that we have the right type of object
      c582253e
  2. 18 9月, 2019 1 次提交
    • E
      Deprecate `to_h` and `to_legacy_hash` · 4e01932d
      eileencodes 提交于
      These should have been deprecated when I added them but for some reason
      I didn't.
      
      As we move away from passing hashes around we no longer need these
      methods, and since we no longer use configuration hashes as database
      configuration we can deprecate this in favor of using the database
      configuration objects and access the connection hashes from there.
      Co-authored-by: NJohn Crepezzi <john.crepezzi@gmail.com>
      4e01932d
  3. 14 9月, 2019 2 次提交
    • E
      Reduce surface area of ConnectionSpecification · b8fc0150
      eileencodes 提交于
      Eventually we'd like to get rid of this class altogether but for now
      this PR reduces the surface area by removing methods from the class and
      moving classes out into their own files.
      
      * `adapter_method` was moved into database configurations
      * `initialize_dup` was removed because it was only used in tests
      * Resolver is now it's own class under connection adapters
      * ConnectionUrlResolver, only used by the configurations, is in a class
      under DatabaseConfigurations
      Co-authored-by: NJohn Crepezzi <john.crepezzi@gmail.com>
      b8fc0150
    • J
      Pass db_config object around instead of hashes · 20c7bbd4
      John Crepezzi 提交于
      This is part 1 of removing the need to pass hashes around inside
      connection management. This PR creates database config objects every
      time when passing a hash, string, or symbol and sends that object to
      connection specification. ConnectionSpecification reaches into the
      config hash on db_config when needed, but eventually we'll get rid of
      that and ConnectionSpecification since it's doing duplicate work with
      the DatabaseConfigurations.
      
      We also chose to change the keys to strings because that's what the
      database.yml would create and what apps currently expect. While symbols
      are nicer, we'd end up having to deprecate the string behavior first.
      Co-authored-by: Neileencodes <eileencodes@gmail.com>
      20c7bbd4
  4. 13 9月, 2019 1 次提交
    • E
      Use symbols everywhere for database configurations · ce9b197c
      eileencodes 提交于
      Previously in some places we used symbol keys, and in some places we used
      string keys. That made it pretty confusing to figure out in a particular
      place what type of configuration object you were working with.
      
      Now internally, all configuration hashes are keyed by symbols and
      converted to such on the way in.
      
      A few exceptions:
      
      - `DatabaseConfigurations#to_h` still returns strings for backward compatibility
      - Same for `legacy_hash`
      - `default_hash` previously could return strings, but the associated
        comment mentions it returns symbol-key `Hash` and now it always does
      
      Because this is a change in behavior, a few method renames have happened:
      
      - `DatabaseConfig#config` is now `DatabaseConfig#configuration_hash` and returns a symbol-key `Hash`
      - `ConnectionSpecification#config` is now `ConnectionSpecification#underlying_configuration_hash` and returns the `Hash` of the underlying `DatabaseConfig`
      - `DatabaseConfig#config` was added back, returns `String`-keys for backward compatibility, and is deprecated in favor of the new `configuration_hash`
      Co-authored-by: Neileencodes <eileencodes@gmail.com>
      ce9b197c
  5. 29 9月, 2018 1 次提交
  6. 31 8月, 2018 1 次提交
    • E
      Add replica? check to DatabaseConfig · 8737dffc
      Eileen Uchitelle 提交于
      Checks if the config has a "replica" key, if so the configuration is for
      a replica database. This is useful for excluding replicas from the
      configurations list when creating the rake tasks or running rake tasks.
      For example, we don't want to create the primary and primary_readonly.
      They're the same database.
      8737dffc
  7. 30 8月, 2018 1 次提交
    • E
      Refactors Active Record connection management · fdf3f0b9
      Eileen Uchitelle 提交于
      While the three-tier config makes it easier to define databases for
      multiple database applications, it quickly became clear to offer full
      support for multiple databases we need to change the way the connections
      hash was handled.
      
      A three-tier config means that when Rails needed to choose a default
      configuration (in the case a user doesn't ask for a specific
      configuration) it wasn't clear to Rails which the default was. I
      [bandaid fixed this so the rake tasks could work](#32271) but that fix
      wasn't correct because it actually doubled up the configuration hashes.
      
      Instead of attemping to manipulate the hashes @tenderlove and I decided
      that it made more sense if we converted the hashes to objects so we can
      easily ask those object questions. In a three tier config like this:
      
      ```
      development:
        primary:
          database: "my_primary_db"
        animals:
          database; "my_animals_db"
      ```
      
      We end up with an object like this:
      
      ```
        @configurations=[
          #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
            @env_name="development",@spec_name="primary",
            @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>,
          #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90
            @env_name="development",@spec_name="animals",
            @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
      ]>
      ```
      
      The configurations setter takes the database configuration set by your
      application and turns them into an
      `ActiveRecord::DatabaseConfigurations` object that has one getter -
      `@configurations` which is an array of all the database objects.
      
      The configurations getter returns this object by default since it acts
      like a hash in most of the cases we need. For example if you need to
      access the default `development` database we can simply request it as we
      did before:
      
      ```
      ActiveRecord::Base.configurations["development"]
      ```
      
      This will return primary development database configuration hash:
      
      ```
      { "database" => "my_primary_db" }
      ```
      
      Internally all of Active Record has been converted to use the new
      objects. I've built this to be backwards compatible but allow for
      accessing the hash if needed for a deprecation period. To get the
      original hash instead of the object you can either add `to_h` on the
      configurations call or pass `legacy: true` to `configurations.
      
      ```
      ActiveRecord::Base.configurations.to_h
      => { "development => { "database" => "my_primary_db" } }
      
      ActiveRecord::Base.configurations(legacy: true)
      => { "development => { "database" => "my_primary_db" } }
      ```
      
      The new configurations object allows us to iterate over the Active
      Record configurations without losing the known environment or
      specification name for that configuration. You can also select all the
      configs for an env or env and spec. With this we can always ask
      any object what environment it belongs to:
      
      ```
      db_configs = ActiveRecord::Base.configurations.configurations_for("development")
      => #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800
        @configurations=[
          #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
            @env_name="development",@spec_name="primary",
            @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>,
          #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90
            @env_name="development",@spec_name="animals",
            @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
      ]>
      
      db_config.env_name
      => "development"
      
      db_config.spec_name
      => "primary"
      
      db_config.config
      => { "adapter"=>"sqlite3", "database"=>"db/development.sqlite3" }
      ```
      
      The configurations object is more flexible than the configurations hash
      and will allow us to build on top of the connection management in order
      to add support for primary/replica connections, sharding, and
      constructing queries for associations that live in multiple databases.
      fdf3f0b9