diff options
Diffstat (limited to 'activerecord')
7 files changed, 93 insertions, 43 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb index 7e16156408..a1664509df 100644 --- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb @@ -13,6 +13,83 @@ module ActiveRecord @config = original.config.dup end + # Expands a connection string into a hash + class ConnectionUrlResolver # :nodoc: + + # == Example + # url = 'postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000' + # ConnectionUrlResolver.new(url).to_hash + # # => { + # "adapter" => "postgresql", + # "host" => "localhost", + # "port" => 9000, + # "database" => "foo_test", + # "username" => "foo", + # "password" => "bar", + # "pool" => "5", + # "timeout" => "3000" + # } + def initialize(url) + raise "Database URL cannot be empty" if url.blank? + @uri = URI.parse(url) + @adapter = @uri.scheme + @adapter = "postgresql" if @adapter == "postgres" + @query = @uri.query || '' + end + + # Converts the given url to a full connection hash + def to_hash + config = raw_config.reject { |_,value| value.blank? } + config.map { |key,value| config[key] = uri_parser.unescape(value) if value.is_a? String } + config + end + + private + + def uri + @uri + end + + def uri_parser + @uri_parser ||= URI::Parser.new + end + + # Converts the query parameters of the uri into a hash + # "localhost?pool=5&reap_frequency=2" + # # => {"pool" => "5", "reap_frequency" => "2"} + # + # returns empty hash if no query present + # "localhost" + # # => {} + def query_hash + Hash[@query.split("&").map { |pair| pair.split("=") }] + end + + def raw_config + query_hash.merge({ + "adapter" => @adapter, + "username" => uri.user, + "password" => uri.password, + "port" => uri.port, + "database" => database, + "host" => uri.host }) + end + + # Returns name of the database + # sqlite3 expects this to be a full path or `:memory` + def database + if @adapter == 'sqlite3' + if '/:memory:' == uri.path + ':memory:' + else + uri.path + end + else + uri.path.sub(%r{^/},"") + end + end + end + ## # Builds a ConnectionSpecification from user input class Resolver # :nodoc: @@ -84,40 +161,8 @@ module ActiveRecord spec end - def resolve_string_connection(spec) # :nodoc: - config = URI.parse spec - adapter = config.scheme - adapter = "postgresql" if adapter == "postgres" - - database = if adapter == 'sqlite3' - if '/:memory:' == config.path - ':memory:' - else - config.path - end - else - config.path.sub(%r{^/},"") - end - - spec = { "adapter" => adapter, - "username" => config.user, - "password" => config.password, - "port" => config.port, - "database" => database, - "host" => config.host } - - spec.reject!{ |_,value| value.blank? } - - uri_parser = URI::Parser.new - - 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("=") }] - spec.merge!(options) - end - - spec + def resolve_string_connection(url) # :nodoc: + ConnectionUrlResolver.new(url).to_hash end end end diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 90dfc177e5..4b769aa11c 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -179,9 +179,6 @@ db_namespace = namespace :db do require 'active_record/fixtures' base_dir = if ENV['FIXTURES_PATH'] - STDERR.puts "Using FIXTURES_PATH env variable is deprecated, please use " + - "ActiveRecord::Tasks::DatabaseTasks.fixtures_path = '/path/to/fixtures' " + - "instead." File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten else ActiveRecord::Tasks::DatabaseTasks.fixtures_path @@ -204,9 +201,6 @@ db_namespace = namespace :db do puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::FixtureSet.identify(label)}.) if label base_dir = if ENV['FIXTURES_PATH'] - STDERR.puts "Using FIXTURES_PATH env variable is deprecated, please use " + - "ActiveRecord::Tasks::DatabaseTasks.fixtures_path = '/path/to/fixtures' " + - "instead." File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten else ActiveRecord::Tasks::DatabaseTasks.fixtures_path diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 3d0709266a..78da6a83ec 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -37,6 +37,8 @@ module ActiveRecord def not(opts, *rest) where_value = @scope.send(:build_where, opts, rest).map do |rel| case rel + when NilClass + raise ArgumentError, 'Invalid argument for .where.not(), got nil.' when Arel::Nodes::In Arel::Nodes::NotIn.new(rel.left, rel.right) when Arel::Nodes::Equality diff --git a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb index a85f3d4298..605a2d86e4 100644 --- a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb +++ b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb @@ -18,7 +18,8 @@ module ActiveRecord def test_bad_connection_mysql assert_raise ActiveRecord::NoDatabaseError do - connection = ActiveRecord::Base.mysql_connection(adapter: "mysql", database: "should_not_exist-cinco-dog-db") + configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'should_not_exist-cinco-dog-db') + connection = ActiveRecord::Base.mysql_connection(configuration) connection.exec_query('drop table if exists ex') end end diff --git a/activerecord/test/cases/adapters/mysql2/connection_test.rb b/activerecord/test/cases/adapters/mysql2/connection_test.rb index 91b780a7ee..8fe8bd7df3 100644 --- a/activerecord/test/cases/adapters/mysql2/connection_test.rb +++ b/activerecord/test/cases/adapters/mysql2/connection_test.rb @@ -15,7 +15,8 @@ class MysqlConnectionTest < ActiveRecord::TestCase def test_bad_connection assert_raise ActiveRecord::NoDatabaseError do - connection = ActiveRecord::Base.mysql2_connection(adapter: "mysql2", database: "should_not_exist-cinco-dog-db") + configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'should_not_exist-cinco-dog-db') + connection = ActiveRecord::Base.mysql2_connection(configuration) connection.exec_query('drop table if exists ex') end end diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb index 778175e2e8..131080913c 100644 --- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb +++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb @@ -12,7 +12,8 @@ module ActiveRecord def test_bad_connection assert_raise ActiveRecord::NoDatabaseError do - connection = ActiveRecord::Base.postgresql_connection(database: "should_not_exist-cinco-dog-db", adapter: "postgresql") + configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'should_not_exist-cinco-dog-db') + connection = ActiveRecord::Base.postgresql_connection(configuration) connection.exec_query('drop table if exists ex') end end diff --git a/activerecord/test/cases/relation/where_chain_test.rb b/activerecord/test/cases/relation/where_chain_test.rb index d44b4dfe3d..fd2420cb88 100644 --- a/activerecord/test/cases/relation/where_chain_test.rb +++ b/activerecord/test/cases/relation/where_chain_test.rb @@ -23,6 +23,12 @@ module ActiveRecord assert_equal([expected], relation.where_values) end + def test_not_with_nil + assert_raise ArgumentError do + Post.where.not(nil) + end + end + def test_not_in expected = Arel::Nodes::NotIn.new(Post.arel_table[@name], %w[hello goodbye]) relation = Post.where.not(title: %w[hello goodbye]) |