mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Only build a ConnectionSpecification if required
This commit is contained in:
parent
d8336cab32
commit
d2ed433b0a
6 changed files with 60 additions and 60 deletions
6
Gemfile
6
Gemfile
|
@ -36,9 +36,9 @@ group :test do
|
|||
gem 'ruby-prof', '~> 0.11.2'
|
||||
end
|
||||
|
||||
platforms :mri_19, :mri_20 do
|
||||
gem 'debugger'
|
||||
end
|
||||
# platforms :mri_19, :mri_20 do
|
||||
# gem 'debugger'
|
||||
# end
|
||||
|
||||
gem 'benchmark-ips'
|
||||
end
|
||||
|
|
|
@ -32,6 +32,24 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def spec(config)
|
||||
spec = resolve(config).symbolize_keys
|
||||
|
||||
raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
|
||||
|
||||
path_to_adapter = "active_record/connection_adapters/#{spec[:adapter]}_adapter"
|
||||
begin
|
||||
require path_to_adapter
|
||||
rescue Gem::LoadError => e
|
||||
raise Gem::LoadError, "Specified '#{spec[:adapter]}' for database adapter, but the gem is not loaded. Add `gem '#{e.name}'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord)."
|
||||
rescue LoadError => e
|
||||
raise LoadError, "Could not load '#{path_to_adapter}'. Make sure that the adapter in config/database.yml is valid. If you use an adapter other than 'mysql', 'mysql2', 'postgresql' or 'sqlite3' add the necessary adapter gem to the Gemfile.", e.backtrace
|
||||
end
|
||||
|
||||
adapter_method = "#{spec[:adapter]}_connection"
|
||||
ConnectionSpecification.new(spec, adapter_method)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resolve_connection(spec) #:nodoc:
|
||||
|
@ -52,30 +70,15 @@ module ActiveRecord
|
|||
resolve_string_connection(spec) if spec.is_a?(String)
|
||||
end
|
||||
raise(AdapterNotSpecified, "#{spec} database is not configured") unless config
|
||||
resolve_connection config
|
||||
resolve_connection(config)
|
||||
end
|
||||
|
||||
def resolve_hash_connection(spec) # :nodoc:
|
||||
spec = spec.symbolize_keys
|
||||
|
||||
raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
|
||||
|
||||
path_to_adapter = "active_record/connection_adapters/#{spec[:adapter]}_adapter"
|
||||
begin
|
||||
require path_to_adapter
|
||||
rescue Gem::LoadError => e
|
||||
raise Gem::LoadError, "Specified '#{spec[:adapter]}' for database adapter, but the gem is not loaded. Add `gem '#{e.name}'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord)."
|
||||
rescue LoadError => e
|
||||
raise LoadError, "Could not load '#{path_to_adapter}'. Make sure that the adapter in config/database.yml is valid. If you use an adapter other than 'mysql', 'mysql2', 'postgresql' or 'sqlite3' add the necessary adapter gem to the Gemfile.", e.backtrace
|
||||
end
|
||||
|
||||
adapter_method = "#{spec[:adapter]}_connection"
|
||||
|
||||
ConnectionSpecification.new(spec, adapter_method)
|
||||
spec
|
||||
end
|
||||
|
||||
def resolve_string_connection(spec) # :nodoc:
|
||||
config = URI.parse spec
|
||||
config = URI.parse spec
|
||||
adapter = config.scheme
|
||||
adapter = "postgresql" if adapter == "postgres"
|
||||
|
||||
|
@ -89,12 +92,12 @@ module ActiveRecord
|
|||
config.path.sub(%r{^/},"")
|
||||
end
|
||||
|
||||
spec = { :adapter => adapter,
|
||||
:username => config.user,
|
||||
:password => config.password,
|
||||
:port => config.port,
|
||||
:database => database,
|
||||
:host => config.host }
|
||||
spec = { "adapter" => adapter,
|
||||
"username" => config.user,
|
||||
"password" => config.password,
|
||||
"port" => config.port,
|
||||
"database" => database,
|
||||
"host" => config.host }
|
||||
|
||||
spec.reject!{ |_,value| value.blank? }
|
||||
|
||||
|
@ -103,8 +106,7 @@ module ActiveRecord
|
|||
spec.map { |key,value| spec[key] = uri_parser.unescape(value) if value.is_a?(String) }
|
||||
|
||||
if config.query
|
||||
options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys
|
||||
|
||||
options = Hash[config.query.split("&").map{ |pair| pair.split("=") }]
|
||||
spec.merge!(options)
|
||||
end
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ module ActiveRecord
|
|||
# may be returned on an error.
|
||||
def establish_connection(spec = ENV["DATABASE_URL"])
|
||||
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new configurations
|
||||
spec = resolver.resolve(spec)
|
||||
spec = resolver.spec(spec)
|
||||
|
||||
unless respond_to?(spec.adapter_method)
|
||||
raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
|
||||
|
|
|
@ -56,7 +56,7 @@ module ActiveRecord
|
|||
resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(configuration)
|
||||
|
||||
configuration.each do |key, value|
|
||||
configuration[key] = resolver.resolve(value).config.stringify_keys if value
|
||||
configuration[key] = resolver.resolve(value) if value
|
||||
end
|
||||
|
||||
ActiveRecord::Tasks::DatabaseTasks.database_configuration = configuration
|
||||
|
|
|
@ -5,13 +5,19 @@ module ActiveRecord
|
|||
class ConnectionSpecification
|
||||
class ResolverTest < ActiveRecord::TestCase
|
||||
def resolve(spec, config={})
|
||||
Resolver.new(config).resolve(spec).config
|
||||
Resolver.new(config).resolve(spec)
|
||||
end
|
||||
|
||||
def spec(spec, config={})
|
||||
Resolver.new(config).spec(spec)
|
||||
end
|
||||
|
||||
def test_url_invalid_adapter
|
||||
assert_raises(LoadError) do
|
||||
resolve 'ridiculous://foo?encoding=utf8'
|
||||
error = assert_raises(LoadError) do
|
||||
spec 'ridiculous://foo?encoding=utf8'
|
||||
end
|
||||
|
||||
assert_match "Could not load 'active_record/connection_adapters/ridiculous_adapter'", error.message
|
||||
end
|
||||
|
||||
# The abstract adapter is used simply to bypass the bit of code that
|
||||
|
@ -20,60 +26,52 @@ module ActiveRecord
|
|||
def test_url_from_environment
|
||||
spec = resolve :production, 'production' => 'abstract://foo?encoding=utf8'
|
||||
assert_equal({
|
||||
adapter: "abstract",
|
||||
host: "foo",
|
||||
encoding: "utf8" }, spec)
|
||||
"adapter" => "abstract",
|
||||
"host" => "foo",
|
||||
"encoding" => "utf8" }, spec)
|
||||
end
|
||||
|
||||
def test_url_host_no_db
|
||||
spec = resolve 'abstract://foo?encoding=utf8'
|
||||
assert_equal({
|
||||
adapter: "abstract",
|
||||
host: "foo",
|
||||
encoding: "utf8" }, spec)
|
||||
"adapter" => "abstract",
|
||||
"host" => "foo",
|
||||
"encoding" => "utf8" }, spec)
|
||||
end
|
||||
|
||||
def test_url_host_db
|
||||
spec = resolve 'abstract://foo/bar?encoding=utf8'
|
||||
assert_equal({
|
||||
adapter: "abstract",
|
||||
database: "bar",
|
||||
host: "foo",
|
||||
encoding: "utf8" }, spec)
|
||||
"adapter" => "abstract",
|
||||
"database" => "bar",
|
||||
"host" => "foo",
|
||||
"encoding" => "utf8" }, spec)
|
||||
end
|
||||
|
||||
def test_url_port
|
||||
spec = resolve 'abstract://foo:123?encoding=utf8'
|
||||
assert_equal({
|
||||
adapter: "abstract",
|
||||
port: 123,
|
||||
host: "foo",
|
||||
encoding: "utf8" }, spec)
|
||||
"adapter" => "abstract",
|
||||
"port" => 123,
|
||||
"host" => "foo",
|
||||
"encoding" => "utf8" }, spec)
|
||||
end
|
||||
|
||||
def test_encoded_password
|
||||
password = 'am@z1ng_p@ssw0rd#!'
|
||||
encoded_password = URI.encode_www_form_component(password)
|
||||
spec = resolve "abstract://foo:#{encoded_password}@localhost/bar"
|
||||
assert_equal password, spec[:password]
|
||||
end
|
||||
|
||||
def test_descriptive_error_message_when_adapter_is_missing
|
||||
error = assert_raise(LoadError) do
|
||||
resolve(adapter: 'non-existing')
|
||||
end
|
||||
|
||||
assert_match "Could not load 'active_record/connection_adapters/non-existing_adapter'", error.message
|
||||
assert_equal password, spec["password"]
|
||||
end
|
||||
|
||||
def test_url_host_db_for_sqlite3
|
||||
spec = resolve 'sqlite3://foo:bar@dburl:9000/foo_test'
|
||||
assert_equal('/foo_test', spec[:database])
|
||||
assert_equal('/foo_test', spec["database"])
|
||||
end
|
||||
|
||||
def test_url_host_memory_db_for_sqlite3
|
||||
spec = resolve 'sqlite3://foo:bar@dburl:9000/:memory:'
|
||||
assert_equal(':memory:', spec[:database])
|
||||
assert_equal(':memory:', spec["database"])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -84,7 +84,7 @@ module Rails
|
|||
require APP_PATH
|
||||
ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(
|
||||
Rails.application.config.database_configuration || {}
|
||||
).resolve(ENV["DATABASE_URL"]).config.stringify_keys
|
||||
).resolve(ENV["DATABASE_URL"])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue