diff options
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/connection_specification.rb')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/connection_specification.rb | 233 |
1 files changed, 117 insertions, 116 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb index 901c98b22b..849130ba43 100644 --- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb @@ -1,4 +1,4 @@ -require 'uri' +require "uri" module ActiveRecord module ConnectionAdapters @@ -13,9 +13,12 @@ module ActiveRecord @config = original.config.dup end + def to_hash + @config.merge(name: @name) + end + # Expands a connection string into a hash. class ConnectionUrlResolver # :nodoc: - # == Example # # url = "postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000" @@ -33,11 +36,11 @@ module ActiveRecord def initialize(url) raise "Database URL cannot be empty" if url.blank? @uri = uri_parser.parse(url) - @adapter = @uri.scheme && @uri.scheme.tr('-', '_') + @adapter = @uri.scheme && @uri.scheme.tr("-", "_") @adapter = "postgresql" if @adapter == "postgres" if @uri.opaque - @uri.opaque, @query = @uri.opaque.split('?', 2) + @uri.opaque, @query = @uri.opaque.split("?", 2) else @query = @uri.query end @@ -52,58 +55,58 @@ module ActiveRecord private - def uri - @uri - end + def uri + @uri + end - def uri_parser - @uri_parser ||= URI::Parser.new - end + def uri_parser + @uri_parser ||= URI::Parser.new + end - # Converts the query parameters of the URI into a hash. - # - # "localhost?pool=5&reaping_frequency=2" - # # => { "pool" => "5", "reaping_frequency" => "2" } - # - # returns empty hash if no query present. - # - # "localhost" - # # => {} - def query_hash - Hash[(@query || '').split("&").map { |pair| pair.split("=") }] - end + # Converts the query parameters of the URI into a hash. + # + # "localhost?pool=5&reaping_frequency=2" + # # => { "pool" => "5", "reaping_frequency" => "2" } + # + # returns empty hash if no query present. + # + # "localhost" + # # => {} + def query_hash + Hash[(@query || "").split("&").map { |pair| pair.split("=") }] + end - def raw_config - if uri.opaque - query_hash.merge({ - "adapter" => @adapter, - "database" => uri.opaque }) - else - query_hash.merge({ - "adapter" => @adapter, - "username" => uri.user, - "password" => uri.password, - "port" => uri.port, - "database" => database_from_path, - "host" => uri.hostname }) + def raw_config + if uri.opaque + query_hash.merge( + "adapter" => @adapter, + "database" => uri.opaque) + else + query_hash.merge( + "adapter" => @adapter, + "username" => uri.user, + "password" => uri.password, + "port" => uri.port, + "database" => database_from_path, + "host" => uri.hostname) + end end - end - # Returns name of the database. - def database_from_path - if @adapter == 'sqlite3' - # 'sqlite3:/foo' is absolute, because that makes sense. The - # corresponding relative version, 'sqlite3:foo', is handled - # elsewhere, as an "opaque". + # Returns name of the database. + def database_from_path + if @adapter == "sqlite3" + # 'sqlite3:/foo' is absolute, because that makes sense. The + # corresponding relative version, 'sqlite3:foo', is handled + # elsewhere, as an "opaque". - uri.path - else - # Only SQLite uses a filename as the "database" name; for - # anything else, a leading slash would be silly. + uri.path + else + # Only SQLite uses a filename as the "database" name; for + # anything else, a leading slash would be silly. - uri.path.sub(%r{^/}, "") + uri.path.sub(%r{^/}, "") + end end - end end ## @@ -164,7 +167,7 @@ module ActiveRecord # 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,83 +183,81 @@ module ActiveRecord 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 - # Returns fully resolved connection, accepts hash, string or symbol. - # Always returns a hash. - # - # == Examples - # - # Symbol representing current environment. - # - # Resolver.new("production" => {}).resolve_connection(:production) - # # => {} - # - # One layer deep hash of connection values. - # - # Resolver.new({}).resolve_connection("adapter" => "sqlite3") - # # => { "adapter" => "sqlite3" } - # - # Connection URL. - # - # Resolver.new({}).resolve_connection("postgresql://localhost/foo") - # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" } - # - def resolve_connection(spec) - case spec - when Symbol - resolve_symbol_connection spec - when String - resolve_url_connection spec - when Hash - resolve_hash_connection spec + # Returns fully resolved connection, accepts hash, string or symbol. + # Always returns a hash. + # + # == Examples + # + # Symbol representing current environment. + # + # Resolver.new("production" => {}).resolve_connection(:production) + # # => {} + # + # One layer deep hash of connection values. + # + # Resolver.new({}).resolve_connection("adapter" => "sqlite3") + # # => { "adapter" => "sqlite3" } + # + # Connection URL. + # + # Resolver.new({}).resolve_connection("postgresql://localhost/foo") + # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" } + # + def resolve_connection(spec) + case spec + when Symbol + resolve_symbol_connection spec + when String + resolve_url_connection spec + when Hash + resolve_hash_connection spec + end 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_symbol_connection(:production) - # # => {} - # - def resolve_symbol_connection(spec) - if config = configurations[spec.to_s] - resolve_connection(config) - else - raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available: #{configurations.keys.inspect}") + # Takes the environment such as +:production+ or +:development+. + # This requires that the @configurations was initialized with a key that + # matches. + # + # Resolver.new("production" => {}).resolve_symbol_connection(:production) + # # => {} + # + def resolve_symbol_connection(spec) + if config = configurations[spec.to_s] + resolve_connection(config).merge("name" => spec.to_s) + else + raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available: #{configurations.keys.inspect}") + end end - end - # Accepts a hash. Expands the "url" key that contains a - # URL database connection to a full connection - # hash and merges with the rest of the hash. - # Connection details inside of the "url" key win any merge conflicts - def resolve_hash_connection(spec) - if spec["url"] && spec["url"] !~ /^jdbc:/ - connection_hash = resolve_url_connection(spec.delete("url")) - spec.merge!(connection_hash) + # Accepts a hash. Expands the "url" key that contains a + # URL database connection to a full connection + # hash and merges with the rest of the hash. + # Connection details inside of the "url" key win any merge conflicts + def resolve_hash_connection(spec) + if spec["url"] && spec["url"] !~ /^jdbc:/ + connection_hash = resolve_url_connection(spec.delete("url")) + spec.merge!(connection_hash) + end + spec end - spec - end - # 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 + # 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 end end |