diff options
Diffstat (limited to 'activerecord')
15 files changed, 138 insertions, 103 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 5cb5fa56b3..8d90b8e819 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,4 +1,4 @@ -* As promised, switch `sqlite3:///` URLs (which were temporarily +* Switch `sqlite3:///` URLs (which were temporarily deprecated in 4.1) from relative to absolute. If you still want the previous interpretation, you should replace @@ -6,22 +6,13 @@ *Matthew Draper* -* (Temporarily) deprecate SQLite database URLs containing an - authority. +* Treat blank UUID values as `nil`. - The current "correct" spellings for in-memory, relative, and - absolute URLs, respectively, are: - - sqlite3::memory: - sqlite3:relative/path - sqlite3:/full/path + Example: - The previous spelling (`sqlite3:///relative/path`) continues to work - as it did in Rails 4.0, but with a deprecation warning: in the next - release, that spelling will instead be interpreted as an absolute - path. + Sample.new(uuid_field: '') #=> <Sample id: nil, uuid_field: nil> - *Matthew Draper* + *Dmitry Lavrov* * Enable support for materialized views on PostgreSQL >= 9.3. diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb index 56c533c401..e0715f7ce9 100644 --- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb @@ -137,7 +137,7 @@ module ActiveRecord if config resolve_connection config elsif env = ActiveRecord::ConnectionHandling::RAILS_ENV.call - resolve_env_connection env.to_sym + resolve_symbol_connection env.to_sym else raise AdapterNotSpecified end @@ -206,42 +206,41 @@ module ActiveRecord # def resolve_connection(spec) case spec - when Symbol, String - resolve_env_connection spec + when Symbol + resolve_symbol_connection spec + when String + resolve_string_connection spec when Hash resolve_hash_connection spec end end + def resolve_string_connection(spec) + # Rails has historically accepted a string to mean either + # an environment key or a URL spec, so we have deprecated + # this ambiguous behaviour and in the future this function + # can be removed in favor of resolve_url_connection. + if configurations.key?(spec) + ActiveSupport::Deprecation.warn "Passing a string to ActiveRecord::Base.establish_connection " \ + "for a configuration lookup is deprecated, please pass a symbol (#{spec.to_sym.inspect}) instead" + resolve_connection(configurations[spec]) + else + resolve_url_connection(spec) + 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_env_connection(:production) + # Resolver.new("production" => {}).resolve_symbol_connection(:production) # # => {} # - # Takes a connection URL. - # - # Resolver.new({}).resolve_env_connection("postgresql://localhost/foo") - # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" } - # - def resolve_env_connection(spec) - # Rails has historically accepted a string to mean either - # an environment key or a URL spec, so we have deprecated - # this ambiguous behaviour and in the future this function - # can be removed in favor of resolve_string_connection and - # resolve_symbol_connection. + def resolve_symbol_connection(spec) if config = configurations[spec.to_s] - if spec.is_a?(String) - ActiveSupport::Deprecation.warn "Passing a string to ActiveRecord::Base.establish_connection " \ - "for a configuration lookup is deprecated, please pass a symbol (#{spec.to_sym.inspect}) instead" - end resolve_connection(config) - elsif spec.is_a?(String) - resolve_string_connection(spec) else - raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available configuration: #{configurations.inspect}") + raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available: #{configurations.keys.inspect}") end end @@ -257,7 +256,12 @@ module ActiveRecord spec end - def resolve_string_connection(url) + # 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 diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb index 57bdc3bb19..9e898015a6 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb @@ -330,6 +330,13 @@ This is not reliable and will be removed in the future. end end + class Uuid < Type + def type; :uuid end + def type_cast(value) + value.presence + end + end + class TypeMap def initialize @mapping = {} @@ -418,10 +425,10 @@ This is not reliable and will be removed in the future. register_type 'json', OID::Json.new register_type 'cidr', OID::Cidr.new register_type 'inet', OID::Inet.new + register_type 'uuid', OID::Uuid.new register_type 'xml', SpecializedString.new(:xml) register_type 'tsvector', SpecializedString.new(:tsvector) register_type 'macaddr', SpecializedString.new(:macaddr) - register_type 'uuid', SpecializedString.new(:uuid) register_type 'citext', SpecializedString.new(:citext) register_type 'ltree', SpecializedString.new(:ltree) diff --git a/activerecord/test/cases/adapters/mysql/active_schema_test.rb b/activerecord/test/cases/adapters/mysql/active_schema_test.rb index d1c644c016..7c0f11b033 100644 --- a/activerecord/test/cases/adapters/mysql/active_schema_test.rb +++ b/activerecord/test/cases/adapters/mysql/active_schema_test.rb @@ -1,10 +1,10 @@ require "cases/helper" +require 'support/connection_helper' class ActiveSchemaTest < ActiveRecord::TestCase - def setup - @connection = ActiveRecord::Base.remove_connection - ActiveRecord::Base.establish_connection(@connection) + include ConnectionHelper + def setup ActiveRecord::Base.connection.singleton_class.class_eval do alias_method :execute_without_stub, :execute def execute(sql, name = nil) return sql end @@ -12,8 +12,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase end teardown do - ActiveRecord::Base.remove_connection - ActiveRecord::Base.establish_connection(@connection) + reset_connection end def test_add_index diff --git a/activerecord/test/cases/adapters/mysql/connection_test.rb b/activerecord/test/cases/adapters/mysql/connection_test.rb index 42ffb91095..412efa22ff 100644 --- a/activerecord/test/cases/adapters/mysql/connection_test.rb +++ b/activerecord/test/cases/adapters/mysql/connection_test.rb @@ -1,7 +1,9 @@ require "cases/helper" +require 'support/connection_helper' require 'support/ddl_helper' class MysqlConnectionTest < ActiveRecord::TestCase + include ConnectionHelper include DdlHelper class Klass < ActiveRecord::Base @@ -160,15 +162,6 @@ class MysqlConnectionTest < ActiveRecord::TestCase private - def run_without_connection - original_connection = ActiveRecord::Base.remove_connection - begin - yield original_connection - ensure - ActiveRecord::Base.establish_connection(original_connection) - end - end - def with_example_table(&block) definition ||= <<-SQL `id` int(11) auto_increment PRIMARY KEY, diff --git a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb index 81c614924f..cefc3e3c7e 100644 --- a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb +++ b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb @@ -1,10 +1,10 @@ require "cases/helper" +require 'support/connection_helper' class ActiveSchemaTest < ActiveRecord::TestCase - def setup - @connection = ActiveRecord::Base.remove_connection - ActiveRecord::Base.establish_connection(@connection) + include ConnectionHelper + def setup ActiveRecord::Base.connection.singleton_class.class_eval do alias_method :execute_without_stub, :execute def execute(sql, name = nil) return sql end @@ -12,8 +12,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase end teardown do - ActiveRecord::Base.remove_connection - ActiveRecord::Base.establish_connection(@connection) + reset_connection end def test_add_index diff --git a/activerecord/test/cases/adapters/mysql2/connection_test.rb b/activerecord/test/cases/adapters/mysql2/connection_test.rb index 57d8b8dd99..182d9409c7 100644 --- a/activerecord/test/cases/adapters/mysql2/connection_test.rb +++ b/activerecord/test/cases/adapters/mysql2/connection_test.rb @@ -1,6 +1,9 @@ require "cases/helper" +require 'support/connection_helper' class MysqlConnectionTest < ActiveRecord::TestCase + include ConnectionHelper + def setup super @subscriber = SQLSubscriber.new @@ -103,15 +106,4 @@ class MysqlConnectionTest < ActiveRecord::TestCase assert_equal "'1970-01-01 00:00:00.000000'", @connection.quote(Time.at(0).to_datetime) end end - - private - - def run_without_connection - original_connection = ActiveRecord::Base.remove_connection - begin - yield original_connection - ensure - ActiveRecord::Base.establish_connection(original_connection) - end - end end diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb index 514ae20e3c..5f84c893c0 100644 --- a/activerecord/test/cases/adapters/postgresql/connection_test.rb +++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb @@ -1,7 +1,10 @@ require "cases/helper" +require 'support/connection_helper' module ActiveRecord class PostgresqlConnectionTest < ActiveRecord::TestCase + include ConnectionHelper + class NonExistentTable < ActiveRecord::Base end @@ -198,17 +201,5 @@ module ActiveRecord ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:debug_print_plan => :default}})) end end - - private - - def run_without_connection - original_connection = ActiveRecord::Base.remove_connection - begin - yield original_connection - ensure - ActiveRecord::Base.establish_connection(original_connection) - end - end - end end diff --git a/activerecord/test/cases/adapters/postgresql/domain_test.rb b/activerecord/test/cases/adapters/postgresql/domain_test.rb index ba25a64fac..214e89dd7f 100644 --- a/activerecord/test/cases/adapters/postgresql/domain_test.rb +++ b/activerecord/test/cases/adapters/postgresql/domain_test.rb @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- require "cases/helper" -require 'support/postgresql_helper' +require 'support/connection_helper' require 'active_record/base' require 'active_record/connection_adapters/postgresql_adapter' class PostgresqlDomainTest < ActiveRecord::TestCase - include PostgresqlHelper + include ConnectionHelper class PostgresqlDomain < ActiveRecord::Base self.table_name = "postgresql_domains" @@ -27,7 +27,7 @@ class PostgresqlDomainTest < ActiveRecord::TestCase teardown do @connection.execute 'DROP TABLE IF EXISTS postgresql_domains' @connection.execute 'DROP DOMAIN IF EXISTS custom_money' - reset_pg_session + reset_connection end def test_column diff --git a/activerecord/test/cases/adapters/postgresql/enum_test.rb b/activerecord/test/cases/adapters/postgresql/enum_test.rb index fde01314a5..73da5a74ab 100644 --- a/activerecord/test/cases/adapters/postgresql/enum_test.rb +++ b/activerecord/test/cases/adapters/postgresql/enum_test.rb @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- require "cases/helper" -require 'support/postgresql_helper' +require 'support/connection_helper' require 'active_record/base' require 'active_record/connection_adapters/postgresql_adapter' class PostgresqlEnumTest < ActiveRecord::TestCase - include PostgresqlHelper + include ConnectionHelper class PostgresqlEnum < ActiveRecord::Base self.table_name = "postgresql_enums" @@ -28,7 +28,7 @@ class PostgresqlEnumTest < ActiveRecord::TestCase teardown do @connection.execute 'DROP TABLE IF EXISTS postgresql_enums' @connection.execute 'DROP TYPE IF EXISTS mood' - reset_pg_session + reset_connection end def test_column diff --git a/activerecord/test/cases/adapters/postgresql/range_test.rb b/activerecord/test/cases/adapters/postgresql/range_test.rb index b57568dbad..57c7da2657 100644 --- a/activerecord/test/cases/adapters/postgresql/range_test.rb +++ b/activerecord/test/cases/adapters/postgresql/range_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/postgresql_helper' +require 'support/connection_helper' require 'active_record/base' require 'active_record/connection_adapters/postgresql_adapter' @@ -10,13 +10,7 @@ if ActiveRecord::Base.connection.supports_ranges? class PostgresqlRangeTest < ActiveRecord::TestCase self.use_transactional_fixtures = false - include PostgresqlHelper - - teardown do - @connection.execute 'DROP TABLE IF EXISTS postgresql_ranges' - @connection.execute 'DROP TYPE IF EXISTS floatrange' - reset_pg_session - end + include ConnectionHelper def setup @connection = PostgresqlRange.connection @@ -99,6 +93,12 @@ _SQL @empty_range = PostgresqlRange.find(105) end + teardown do + @connection.execute 'DROP TABLE IF EXISTS postgresql_ranges' + @connection.execute 'DROP TYPE IF EXISTS floatrange' + reset_connection + end + def test_data_type_of_range_types assert_equal :daterange, @first_range.column_for_attribute(:date_range).type assert_equal :numrange, @first_range.column_for_attribute(:num_range).type diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb index f79a7a598b..9e03ea6bee 100644 --- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb +++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb @@ -50,6 +50,11 @@ class PostgresqlUUIDTest < ActiveRecord::TestCase assert_not column.array end + def test_treat_blank_uuid_as_nil + UUIDType.create! guid: '' + assert_equal(nil, UUIDType.last.guid) + end + def test_uuid_formats ["A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11", "{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}", diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb index 2992ceb211..e097449029 100644 --- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb +++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb @@ -17,6 +17,54 @@ module ActiveRecord ENV["DATABASE_URL"] = @previous_database_url end + def resolve(spec, config) + ConnectionSpecification::Resolver.new(klass.new(config).resolve).resolve(spec) + end + + def spec(spec, config) + ConnectionSpecification::Resolver.new(klass.new(config).resolve).spec(spec) + end + + def test_resolver_with_database_uri_and_known_key + ENV['DATABASE_URL'] = "postgres://localhost/foo" + config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo" } } + actual = resolve(:production, config) + expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" } + assert_equal expected, actual + end + + def test_resolver_with_database_uri_and_known_string_key + ENV['DATABASE_URL'] = "postgres://localhost/foo" + config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo" } } + actual = assert_deprecated { resolve("production", config) } + expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" } + assert_equal expected, actual + end + + def test_resolver_with_database_uri_and_unknown_symbol_key + ENV['DATABASE_URL'] = "postgres://localhost/foo" + config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } } + actual = resolve(:production, config) + expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" } + assert_equal expected, actual + end + + def test_resolver_with_database_uri_and_unknown_string_key + ENV['DATABASE_URL'] = "postgres://localhost/foo" + config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } } + assert_raises AdapterNotSpecified do + spec("production", config) + end + end + + def test_resolver_with_database_uri_and_supplied_url + ENV['DATABASE_URL'] = "not-postgres://not-localhost/not_foo" + config = { "production" => { "adapter" => "also_not_postgres", "database" => "also_not_foo" } } + actual = resolve("postgres://localhost/foo", config) + expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" } + assert_equal expected, actual + end + def test_jdbc_url config = { "production" => { "url" => "jdbc:postgres://localhost/foo" } } actual = klass.new(config).resolve diff --git a/activerecord/test/support/connection_helper.rb b/activerecord/test/support/connection_helper.rb new file mode 100644 index 0000000000..4a19e5df44 --- /dev/null +++ b/activerecord/test/support/connection_helper.rb @@ -0,0 +1,14 @@ +module ConnectionHelper + def run_without_connection + original_connection = ActiveRecord::Base.remove_connection + yield original_connection + ensure + ActiveRecord::Base.establish_connection(original_connection) + end + + # Used to drop all cache query plans in tests. + def reset_connection + original_connection = ActiveRecord::Base.remove_connection + ActiveRecord::Base.establish_connection(original_connection) + end +end diff --git a/activerecord/test/support/postgresql_helper.rb b/activerecord/test/support/postgresql_helper.rb deleted file mode 100644 index fa40a46499..0000000000 --- a/activerecord/test/support/postgresql_helper.rb +++ /dev/null @@ -1,8 +0,0 @@ -module PostgresqlHelper - # Make sure to drop all cached query plans to prevent invalid reference errors like: - # cache lookup failed for type XYZ - def reset_pg_session - original_connection = ActiveRecord::Base.remove_connection - ActiveRecord::Base.establish_connection(original_connection) - end -end |