Skip to content

Commit

Permalink
Merge pull request #14570 from matthewd/uri_deprecation_warning
Browse files Browse the repository at this point in the history
Avoid a spurious deprecation warning for database URLs
  • Loading branch information
rafaelfranca committed Apr 3, 2014
1 parent a16824a commit d54d4af
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 24 deletions.
Expand Up @@ -124,7 +124,7 @@ def resolve(config)
if config
resolve_connection config
elsif env = ActiveRecord::ConnectionHandling::RAILS_ENV.call
resolve_env_connection env.to_sym
resolve_symbol_connection env.to_sym
else
raise AdapterNotSpecified
end
Expand Down Expand Up @@ -193,42 +193,41 @@ def spec(config)
#
def resolve_connection(spec)
case spec
when Symbol, String
resolve_env_connection spec
when Symbol
resolve_symbol_connection spec
when String
resolve_string_connection spec
when Hash
resolve_hash_connection spec
end
end

def resolve_string_connection(spec)
# Rails has historically accepted a string to mean either
# an environment key or a URL spec, so we have deprecated
# this ambiguous behaviour and in the future this function
# can be removed in favor of resolve_url_connection.
if configurations.key?(spec)
ActiveSupport::Deprecation.warn "Passing a string to ActiveRecord::Base.establish_connection " \
"for a configuration lookup is deprecated, please pass a symbol (#{spec.to_sym.inspect}) instead"
resolve_connection(configurations[spec])
else
resolve_url_connection(spec)
end
end

# Takes the environment such as `:production` or `:development`.
# This requires that the @configurations was initialized with a key that
# matches.
#
#
# Resolver.new("production" => {}).resolve_env_connection(:production)
# Resolver.new("production" => {}).resolve_symbol_connection(:production)
# # => {}
#
# Takes a connection URL.
#
# Resolver.new({}).resolve_env_connection("postgresql://localhost/foo")
# # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
#
def resolve_env_connection(spec)
# Rails has historically accepted a string to mean either
# an environment key or a URL spec, so we have deprecated
# this ambiguous behaviour and in the future this function
# can be removed in favor of resolve_string_connection and
# resolve_symbol_connection.
def resolve_symbol_connection(spec)
if config = configurations[spec.to_s]
if spec.is_a?(String)
ActiveSupport::Deprecation.warn "Passing a string to ActiveRecord::Base.establish_connection " \
"for a configuration lookup is deprecated, please pass a symbol (#{spec.to_sym.inspect}) instead"
end
resolve_connection(config)
elsif spec.is_a?(String)
resolve_string_connection(spec)
else
raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available configuration: #{configurations.inspect}")
raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available: #{configurations.keys.inspect}")
end
end

Expand All @@ -244,7 +243,12 @@ def resolve_hash_connection(spec)
spec
end

def resolve_string_connection(url)
# Takes a connection URL.
#
# Resolver.new({}).resolve_url_connection("postgresql://localhost/foo")
# # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
#
def resolve_url_connection(url)
ConnectionUrlResolver.new(url).to_hash
end
end
Expand Down
Expand Up @@ -17,6 +17,54 @@ def teardown
ENV["DATABASE_URL"] = @previous_database_url
end

def resolve(spec, config)
ConnectionSpecification::Resolver.new(klass.new(config).resolve).resolve(spec)
end

def spec(spec, config)
ConnectionSpecification::Resolver.new(klass.new(config).resolve).spec(spec)
end

def test_resolver_with_database_uri_and_known_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
actual = resolve(:production, config)
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end

def test_resolver_with_database_uri_and_known_string_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
actual = assert_deprecated { resolve("production", config) }
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end

def test_resolver_with_database_uri_and_unknown_symbol_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
actual = resolve(:production, config)
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end

def test_resolver_with_database_uri_and_unknown_string_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
assert_raises AdapterNotSpecified do
spec("production", config)
end
end

def test_resolver_with_database_uri_and_supplied_url
ENV['DATABASE_URL'] = "not-postgres://not-localhost/not_foo"
config = { "production" => { "adapter" => "also_not_postgres", "database" => "also_not_foo" } }
actual = resolve("postgres://localhost/foo", config)
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end

def test_jdbc_url
config = { "production" => { "url" => "jdbc:postgres://localhost/foo" } }
actual = klass.new(config).resolve
Expand Down

0 comments on commit d54d4af

Please sign in to comment.