1. 04 1月, 2020 1 次提交
    • J
      Pass env_name as a string in test databases · 1f938f52
      John Crepezzi 提交于
      In 154abcab we switched from using `Rails.env` to fetch the `env_name` to
      `ActiveRecord::ConnectionHandling::DEFAULT_ENV.call.to_sym` which
      changed the type from a `String` to a `Symbol`.
      
      This commit brings things back to the original state, so we can find the
      configurations correctly!
      
      It also modifies the configuration in the configurations array, so that
      future connections can find the database with the updated keyword value.
      1f938f52
  2. 19 12月, 2019 1 次提交
    • E
      Don't allow mutations on configuration_hash · 154abcab
      eileencodes 提交于
      We want to introduce an object-based DSL for building and modifying
      configuration objects. As part of that we want to make sure that users
      don't think they can modify configuration_hash values and have them
      change the configuration. For that reason we're going to freeze the
      Hash here, and have modified places in tests where we were modifying
      these hashes.
      
      The commit here also adds a test for the Test Databases and in that work
      we found that we were calling `Rails.env` and Active Record doesn't load
      Rails.
      Co-authored-by: NJohn Crepezzi <john.crepezzi@gmail.com>
      154abcab
  3. 19 9月, 2019 1 次提交
    • E
      Make DatabaseTasks use DatabaseConfig objects · aa3e92fd
      eileencodes 提交于
      We're moving in the direction of getting `DatabaseConfig` to be used in
      more places instead of `Hash` connections configurations being passed
      around directly.
      
      Here we're making all of `DatabaseTasks` and `databases.rake` use
      database configuration objects.
      
      A few notes:
      
      * This also contains some tests that were missing for public methods on
        `DatabaseTasks`: `charset_current` & `collation_current`
      
      * There is a deprecation of some arguments in `schema_up_to_date?` that
        are now duplicative/confusing. One of them wasn't used previously
        (`environment`), and now `spec_name` can be pulled directly off of the
        `db_config (DatatabaseConfig)` object.
      Co-authored-by: Neileencodes <eileencodes@gmail.com>
      aa3e92fd
  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. 09 8月, 2019 1 次提交
    • J
      Sync parallel test DBs to schema using SHA · d8b81713
      John Hawthorn 提交于
      Previously, every time we ran tests in parallel we would load the schema
      for all N DBs.
      
      Now that we have the ability to sync DBs with the schema file exactly
      using metadata and a SHA, we can instead only load the schemas when they
      change.
      d8b81713
  6. 01 9月, 2018 1 次提交
    • E
      Convert configs_for to kwargs, add include_replicas · a572d228
      Eileen Uchitelle 提交于
      Changes the `configs_for` method from using traditional arguments to
      using kwargs. This is so I can add the `include_replicas` kwarg without
      having to always include `env_name` and `spec_name` in the method call.
      
      `include_replicas` defaults to false because everywhere internally in
      Rails we don't want replicas. `configs_for` is for iterating over
      configurations to create / run rake tasks, so we really don't ever need
      replicas in that case.
      a572d228
  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
  8. 02 8月, 2018 1 次提交
  9. 01 8月, 2018 1 次提交
  10. 16 2月, 2018 1 次提交
    • E
      Add test parallelization to Rails · 26821d9b
      eileencodes 提交于
      Provides both a forked process and threaded parallelization options. To
      use add `parallelize` to your test suite.
      
      Takes a `workers` argument that controls how many times the process
      is forked. For each process a new database will be created suffixed
      with the worker number; test-database-0 and test-database-1
      respectively.
      
      If `ENV["PARALLEL_WORKERS"]` is set the workers argument will be ignored
      and the environment variable will be used instead. This is useful for CI
      environments, or other environments where you may need more workers than
      you do for local testing.
      
      If the number of workers is set to `1` or fewer, the tests will not be
      parallelized.
      
      The default parallelization method is to fork processes. If you'd like to
      use threads instead you can pass `with: :threads` to the `parallelize`
      method. Note the threaded parallelization does not create multiple
      database and will not work with system tests at this time.
      
      parallelize(workers: 2, with: :threads)
      
      The threaded parallelization uses Minitest's parallel exector directly.
      The processes paralleliztion uses a Ruby Drb server.
      
      For parallelization via threads a setup hook and cleanup hook are
      provided.
      
      ```
      class ActiveSupport::TestCase
        parallelize_setup do |worker|
          # setup databases
        end
      
        parallelize_teardown do |worker|
          # cleanup database
        end
      
        parallelize(workers: 2)
      end
      ```
      
      [Eileen M. Uchitelle, Aaron Patterson]
      26821d9b