From dde21138673c111099890301ffce8b6185e9ea3c Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 28 Nov 2011 13:07:42 -0800 Subject: Move connection resoluion logic to it's own testable class. --- .../abstract/connection_specification.rb | 132 ++++++++++++--------- 1 file changed, 74 insertions(+), 58 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb') diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb index 65570da0d9..f2e7f88011 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb @@ -5,6 +5,78 @@ module ActiveRecord def initialize (config, adapter_method) @config, @adapter_method = config, adapter_method end + + ## + # Builds a ConnectionSpecification from user input + class Resolver # :nodoc: + attr_reader :config, :klass, :configurations + + def initialize(config, klass, configurations) + @config = config + @klass = klass + @configurations = configurations + end + + def spec + case config + when nil + raise AdapterNotSpecified unless defined?(Rails.env) + resolve_string_connection Rails.env + when Symbol, String + resolve_string_connection config.to_s + when Hash + resolve_hash_connection config + end + end + + private + def resolve_string_connection(spec) # :nodoc: + hash = configurations.fetch(spec) do |k| + connection_url_to_hash(k) + end + + raise(AdapterNotSpecified, "#{spec} database is not configured") unless hash + + resolve_hash_connection hash + end + + def resolve_hash_connection(spec) # :nodoc: + spec = spec.symbolize_keys + + raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter) + + begin + require "active_record/connection_adapters/#{spec[:adapter]}_adapter" + rescue LoadError => e + raise LoadError, "Please install the #{spec[:adapter]} adapter: `gem install activerecord-#{spec[:adapter]}-adapter` (#{e.message})", e.backtrace + end + + adapter_method = "#{spec[:adapter]}_connection" + unless klass.respond_to?(adapter_method) + raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter" + end + + ConnectionSpecification.new(spec, adapter_method) + end + + def connection_url_to_hash(url) # :nodoc: + config = URI.parse url + adapter = config.scheme + adapter = "postgresql" if adapter == "postgres" + spec = { :adapter => adapter, + :username => config.user, + :password => config.password, + :port => config.port, + :database => config.path.sub(%r{^/},""), + :host => config.host } + spec.reject!{ |_,value| !value } + if config.query + options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys + spec.merge!(options) + end + spec + end + end end ## @@ -55,65 +127,9 @@ module ActiveRecord # The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError # may be returned on an error. def self.establish_connection(spec = ENV["DATABASE_URL"]) - config = case spec - when nil - raise AdapterNotSpecified unless defined?(Rails.env) - resolve_string_connection Rails.env - when Symbol, String - resolve_string_connection spec.to_s - when Hash - resolve_hash_connection spec - end - - connection_handler.establish_connection(name, config) - end - - def self.resolve_string_connection(spec) # :nodoc: - hash = configurations.fetch(spec) do |k| - connection_url_to_hash(k) - end - - raise(AdapterNotSpecified, "#{spec} database is not configured") unless hash - - resolve_hash_connection hash - end - - def self.resolve_hash_connection(spec) # :nodoc: - spec = spec.symbolize_keys - - raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter) - - begin - require "active_record/connection_adapters/#{spec[:adapter]}_adapter" - rescue LoadError => e - raise LoadError, "Please install the #{spec[:adapter]} adapter: `gem install activerecord-#{spec[:adapter]}-adapter` (#{e.message})", e.backtrace - end - - adapter_method = "#{spec[:adapter]}_connection" - unless respond_to?(adapter_method) - raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter" - end - + resolver = ConnectionSpecification::Resolver.new spec, self, configurations remove_connection - ConnectionSpecification.new(spec, adapter_method) - end - - def self.connection_url_to_hash(url) # :nodoc: - config = URI.parse url - adapter = config.scheme - adapter = "postgresql" if adapter == "postgres" - spec = { :adapter => adapter, - :username => config.user, - :password => config.password, - :port => config.port, - :database => config.path.sub(%r{^/},""), - :host => config.host } - spec.reject!{ |_,value| !value } - if config.query - options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys - spec.merge!(options) - end - spec + connection_handler.establish_connection name, resolver.spec end class << self -- cgit v1.2.3