diff options
author | José Valim <jose.valim@plataformatec.com.br> | 2013-12-24 10:02:07 +0100 |
---|---|---|
committer | José Valim <jose.valim@plataformatec.com.br> | 2013-12-24 10:02:07 +0100 |
commit | d2ed433b0af948da78e971bf342c506b27f6072f (patch) | |
tree | 56c97a391d79ff47ff0b03782f84cd7b9ebf5e1a /activerecord | |
parent | d8336cab32d0d8e8c2877cac26111cbecb5ac872 (diff) | |
download | rails-d2ed433b0af948da78e971bf342c506b27f6072f.tar.gz rails-d2ed433b0af948da78e971bf342c506b27f6072f.tar.bz2 rails-d2ed433b0af948da78e971bf342c506b27f6072f.zip |
Only build a ConnectionSpecification if required
Diffstat (limited to 'activerecord')
4 files changed, 56 insertions, 56 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb index 5f50ca6aae..a3c645c53c 100644 --- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb @@ -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 diff --git a/activerecord/lib/active_record/connection_handling.rb b/activerecord/lib/active_record/connection_handling.rb index 6035e674ce..f274f74619 100644 --- a/activerecord/lib/active_record/connection_handling.rb +++ b/activerecord/lib/active_record/connection_handling.rb @@ -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" diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index 19e27ccb37..2c796f97e6 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -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 diff --git a/activerecord/test/cases/connection_specification/resolver_test.rb b/activerecord/test/cases/connection_specification/resolver_test.rb index 8d3813b47f..ba8440a16b 100644 --- a/activerecord/test/cases/connection_specification/resolver_test.rb +++ b/activerecord/test/cases/connection_specification/resolver_test.rb @@ -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 |