rails/activerecord/test/cases/connection_adapters
eileencodes 3d004435b4
Allow applications to register custom database configurations
Previously, applications could only have two types of database
configuration objects, `HashConfig` and `UrlConfig`. This meant that if
you wanted your config to implement custom methods you had to monkey
patch `DatabaseConfigurations` to take a custom class into account. This
PR allows applications to register a custom db_config handler so that
custom configs can respond to needed methods. This is especially useful
for tools like Vitess where we may want to indicate it's sharded, but
not give Rails direct access to that knowledge.

Using the following database.yml as an example:

```yaml
development:
  primary:
    database: my_db
  animals:
    database: my_animals_db
    vitess:
      sharded: 1
```

We can register a custom handler that will generate `VitessConfig`
objects instead of a `HashConfig` object in an initializer:

```ruby
ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config|
  next unless config.key?(:vitess)

  VitessConfig.new(env_name, name, config)
end
```

and create the `VitessConfig` class:

```ruby
class VitessConfig < ActiveRecord::DatabaseConfigurations::UrlConfig
  def sharded?
    vitess_config.fetch("sharded", false)
  end

  private
    def vitess_config
      configuration_hash.fetch(:vitess_config)
    end
end
```

Now when the application is booted, the config with the `vitess` key
will generate a `VitessConfig` object where all others will generate a
`HashConfig`.

Things to keep in mind:

1) It is recommended but not required that these custom configs inherit
from Rails so you don't need to reimplement all the existing methods.
2) Applications must implement the configuration in which their config
should be used, otherwise first config wins (so all their configs
will be the custom one.)
3) The procs must support 4 arguments to accommodate `UrlConfig`. I am
thinking of deprecating this and forcing the URL parsing to happen in
the `UrlConfig` directly.
4) There is one tiny behavior change where when we have a nil url key in
the config hash we no longer merge it back into the configuration hash.
We also end up with a `HashConfig` instead of a `UrlConfig`. I think
this is fine because a `nil` URL is...useless.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2023-02-28 10:12:28 -05:00
..
adapter_leasing_test.rb Automatically reconnect to database mid-request 2022-07-26 22:07:35 +09:30
connection_handler_test.rb Support string or symbol for owner_name 2023-02-17 10:45:57 -05:00
connection_handlers_multi_db_test.rb Add ActiveRecord.deprecator 2022-10-25 14:23:08 -05:00
connection_handlers_multi_pool_config_test.rb Remove unnecessary calls to establish_connection 2023-02-15 08:47:21 -05:00
connection_handlers_sharding_db_test.rb Remove unnecessary or incorrect calls to connection_handler 2022-07-13 14:26:04 -04:00
connection_swapping_nested_test.rb Fix granular swapping for primary_abstract_class 2022-07-19 08:22:35 -04:00
merge_and_resolve_default_url_config_test.rb Allow applications to register custom database configurations 2023-02-28 10:12:28 -05:00
mysql_type_lookup_test.rb AR adapter helpers are now available only within AR::TestCase class 2023-01-01 21:43:24 +09:00
schema_cache_test.rb SchemaCache#init_with skip deduplicate if specified 2023-02-15 13:56:49 +01:00
standalone_connection_test.rb PoC: Active Record API for general async queries 2022-04-14 09:53:54 +02:00
type_lookup_test.rb AR adapter helpers are now available only within AR::TestCase class 2023-01-01 21:43:24 +09:00