Merge pull request #24965 from arthurnn/arthurnn/conn_api
Change some establish_connection logic
This commit is contained in:
commit
ff63bb8231
@ -837,7 +837,11 @@ def connection_pool_list
|
||||
end
|
||||
alias :connection_pools :connection_pool_list
|
||||
|
||||
def establish_connection(spec)
|
||||
def establish_connection(config)
|
||||
resolver = ConnectionSpecification::Resolver.new(Base.configurations)
|
||||
spec = resolver.spec(config)
|
||||
|
||||
remove_connection(spec.name)
|
||||
owner_to_pool[spec.name] = ConnectionAdapters::ConnectionPool.new(spec)
|
||||
end
|
||||
|
||||
@ -871,9 +875,9 @@ def clear_all_connections!
|
||||
# for (not necessarily the current class).
|
||||
def retrieve_connection(spec_name) #:nodoc:
|
||||
pool = retrieve_connection_pool(spec_name)
|
||||
raise ConnectionNotEstablished, "No connection pool with id #{spec_name} found." unless pool
|
||||
raise ConnectionNotEstablished, "No connection pool with id '#{spec_name}' found." unless pool
|
||||
conn = pool.connection
|
||||
raise ConnectionNotEstablished, "No connection for #{spec_name} in connection pool" unless conn
|
||||
raise ConnectionNotEstablished, "No connection for '#{spec_name}' in connection pool" unless conn
|
||||
conn
|
||||
end
|
||||
|
||||
@ -907,7 +911,7 @@ def retrieve_connection_pool(spec_name)
|
||||
# A connection was established in an ancestor process that must have
|
||||
# subsequently forked. We can't reuse the connection, but we can copy
|
||||
# the specification and establish a new connection with it.
|
||||
establish_connection(ancestor_pool.spec).tap do |pool|
|
||||
establish_connection(ancestor_pool.spec.to_hash).tap do |pool|
|
||||
pool.schema_cache = ancestor_pool.schema_cache if ancestor_pool.schema_cache
|
||||
end
|
||||
else
|
||||
|
@ -13,6 +13,10 @@ def initialize_dup(original)
|
||||
@config = original.config.dup
|
||||
end
|
||||
|
||||
def to_hash
|
||||
@config.merge(name: @name)
|
||||
end
|
||||
|
||||
# Expands a connection string into a hash.
|
||||
class ConnectionUrlResolver # :nodoc:
|
||||
|
||||
@ -164,7 +168,7 @@ def resolve_all
|
||||
# spec.config
|
||||
# # => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" }
|
||||
#
|
||||
def spec(config, name = nil)
|
||||
def spec(config)
|
||||
spec = resolve(config).symbolize_keys
|
||||
|
||||
raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
|
||||
@ -180,13 +184,11 @@ def spec(config, name = nil)
|
||||
|
||||
adapter_method = "#{spec[:adapter]}_connection"
|
||||
|
||||
name ||=
|
||||
if config.is_a?(Symbol)
|
||||
config.to_s
|
||||
else
|
||||
"primary"
|
||||
end
|
||||
ConnectionSpecification.new(name, spec, adapter_method)
|
||||
unless ActiveRecord::Base.respond_to?(adapter_method)
|
||||
raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
|
||||
end
|
||||
|
||||
ConnectionSpecification.new(spec.delete(:name) || "primary", spec, adapter_method)
|
||||
end
|
||||
|
||||
private
|
||||
@ -231,7 +233,7 @@ def resolve_connection(spec)
|
||||
#
|
||||
def resolve_symbol_connection(spec)
|
||||
if config = configurations[spec.to_s]
|
||||
resolve_connection(config)
|
||||
resolve_connection(config).merge("name" => spec.to_s)
|
||||
else
|
||||
raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available: #{configurations.keys.inspect}")
|
||||
end
|
||||
|
@ -44,21 +44,18 @@ module ConnectionHandling
|
||||
#
|
||||
# The exceptions AdapterNotSpecified, AdapterNotFound and +ArgumentError+
|
||||
# may be returned on an error.
|
||||
def establish_connection(spec = nil)
|
||||
def establish_connection(config = nil)
|
||||
raise "Anonymous class is not allowed." unless name
|
||||
|
||||
spec ||= DEFAULT_ENV.call.to_sym
|
||||
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new configurations
|
||||
# TODO: uses name on establish_connection, for backwards compatibility
|
||||
spec = resolver.spec(spec, self == Base ? "primary" : name)
|
||||
config ||= DEFAULT_ENV.call.to_sym
|
||||
spec_name = self == Base ? "primary" : name
|
||||
self.connection_specification_name = spec_name
|
||||
|
||||
unless respond_to?(spec.adapter_method)
|
||||
raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
|
||||
end
|
||||
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(Base.configurations)
|
||||
spec = resolver.resolve(config).symbolize_keys
|
||||
spec[:name] = spec_name
|
||||
|
||||
remove_connection(spec.name)
|
||||
self.connection_specification_name = spec.name
|
||||
connection_handler.establish_connection spec
|
||||
connection_handler.establish_connection(spec)
|
||||
end
|
||||
|
||||
class MergeAndResolveDefaultUrlConfig # :nodoc:
|
||||
|
@ -120,7 +120,7 @@ def create_all
|
||||
old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base.connection_specification_name)
|
||||
each_local_configuration { |configuration| create configuration }
|
||||
if old_pool
|
||||
ActiveRecord::Base.connection_handler.establish_connection(old_pool.spec)
|
||||
ActiveRecord::Base.connection_handler.establish_connection(old_pool.spec.to_hash)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -5,16 +5,15 @@ module ConnectionAdapters
|
||||
class ConnectionHandlerTest < ActiveRecord::TestCase
|
||||
def setup
|
||||
@handler = ConnectionHandler.new
|
||||
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new Base.configurations
|
||||
@spec_name = "primary"
|
||||
@pool = @handler.establish_connection(resolver.spec(:arunit, @spec_name))
|
||||
@pool = @handler.establish_connection(ActiveRecord::Base.configurations['arunit'])
|
||||
end
|
||||
|
||||
def test_establish_connection_uses_spec_name
|
||||
config = {"readonly" => {"adapter" => 'sqlite3'}}
|
||||
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(config)
|
||||
spec = resolver.spec(:readonly)
|
||||
@handler.establish_connection(spec)
|
||||
@handler.establish_connection(spec.to_hash)
|
||||
|
||||
assert_not_nil @handler.retrieve_connection_pool('readonly')
|
||||
ensure
|
||||
|
@ -27,7 +27,7 @@ def test_resolver_with_database_uri_and_current_env_symbol_key
|
||||
ENV['DATABASE_URL'] = "postgres://localhost/foo"
|
||||
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
|
||||
actual = resolve_spec(:default_env, config)
|
||||
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
|
||||
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost", "name"=>"default_env" }
|
||||
assert_equal expected, actual
|
||||
end
|
||||
|
||||
@ -37,7 +37,7 @@ def test_resolver_with_database_uri_and_current_env_symbol_key_and_rails_env
|
||||
|
||||
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
|
||||
actual = resolve_spec(:foo, config)
|
||||
expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost" }
|
||||
expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost","name"=>"foo" }
|
||||
assert_equal expected, actual
|
||||
end
|
||||
|
||||
@ -47,7 +47,7 @@ def test_resolver_with_database_uri_and_current_env_symbol_key_and_rack_env
|
||||
|
||||
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
|
||||
actual = resolve_spec(:foo, config)
|
||||
expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost" }
|
||||
expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost","name"=>"foo" }
|
||||
assert_equal expected, actual
|
||||
end
|
||||
|
||||
@ -55,7 +55,7 @@ def test_resolver_with_database_uri_and_known_key
|
||||
ENV['DATABASE_URL'] = "postgres://localhost/foo"
|
||||
config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
|
||||
actual = resolve_spec(:production, config)
|
||||
expected = { "adapter"=>"not_postgres", "database"=>"not_foo", "host"=>"localhost" }
|
||||
expected = { "adapter"=>"not_postgres", "database"=>"not_foo", "host"=>"localhost", "name"=>"production" }
|
||||
assert_equal expected, actual
|
||||
end
|
||||
|
||||
@ -93,7 +93,7 @@ def test_url_with_hyphenated_scheme
|
||||
ENV['DATABASE_URL'] = "ibm-db://localhost/foo"
|
||||
config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
|
||||
actual = resolve_spec(:default_env, config)
|
||||
expected = { "adapter"=>"ibm_db", "database"=>"foo", "host"=>"localhost" }
|
||||
expected = { "adapter"=>"ibm_db", "database"=>"foo", "host"=>"localhost", "name"=>"default_env" }
|
||||
assert_equal expected, actual
|
||||
end
|
||||
|
||||
|
@ -28,7 +28,8 @@ def test_url_from_environment
|
||||
assert_equal({
|
||||
"adapter" => "abstract",
|
||||
"host" => "foo",
|
||||
"encoding" => "utf8" }, spec)
|
||||
"encoding" => "utf8",
|
||||
"name" => "production"}, spec)
|
||||
end
|
||||
|
||||
def test_url_sub_key
|
||||
@ -36,7 +37,8 @@ def test_url_sub_key
|
||||
assert_equal({
|
||||
"adapter" => "abstract",
|
||||
"host" => "foo",
|
||||
"encoding" => "utf8" }, spec)
|
||||
"encoding" => "utf8",
|
||||
"name" => "production"}, spec)
|
||||
end
|
||||
|
||||
def test_url_sub_key_merges_correctly
|
||||
@ -46,7 +48,8 @@ def test_url_sub_key_merges_correctly
|
||||
"adapter" => "abstract",
|
||||
"host" => "foo",
|
||||
"encoding" => "utf8",
|
||||
"pool" => "3" }, spec)
|
||||
"pool" => "3",
|
||||
"name" => "production"}, spec)
|
||||
end
|
||||
|
||||
def test_url_host_no_db
|
||||
@ -113,7 +116,8 @@ def test_url_sub_key_for_sqlite3
|
||||
assert_equal({
|
||||
"adapter" => "sqlite3",
|
||||
"database" => "foo",
|
||||
"encoding" => "utf8" }, spec)
|
||||
"encoding" => "utf8",
|
||||
"name" => "production"}, spec)
|
||||
end
|
||||
|
||||
def test_spec_name_on_key_lookup
|
||||
|
Loading…
Reference in New Issue
Block a user