From f846828dae77696daea3bafd91a25a62977be481 Mon Sep 17 00:00:00 2001 From: Matthew Draper Date: Wed, 2 Apr 2014 23:06:16 +1030 Subject: Revise 'sqlite3:' URL handling for smoother upgrades Restore the 4.0 behaviour for 'sqlite3:///', but deprecate it. We'll change to the absolute-path interpretation in 4.2. The current "correct" spellings for in-memory, relative, and absolute URLs, respectively, are: sqlite3::memory: sqlite3:relative/path sqlite3:/full/path Substantially reverses/defers fbb79b517f3127ba620fedd01849f9628b78d6ce. Uncovered by @guilleiguaran while investigating #14495, though that sounds like a different issue. --- .../connection_specification.rb | 63 +++++++++++++++------- 1 file changed, 45 insertions(+), 18 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters/connection_specification.rb') diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb index 9a133168f8..5ede946836 100644 --- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb @@ -35,7 +35,13 @@ module ActiveRecord @uri = URI.parse(url) @adapter = @uri.scheme @adapter = "postgresql" if @adapter == "postgres" - @query = @uri.query || '' + + if @uri.opaque + @uri.opaque, @query = @uri.opaque.split('?', 2) + else + @query = @uri.query + end + @authority = url =~ %r{\A[^:]*://} end # Converts the given URL to a full connection hash. @@ -65,30 +71,51 @@ module ActiveRecord # "localhost" # # => {} def query_hash - Hash[@query.split("&").map { |pair| pair.split("=") }] + 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 }) + 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.host }) + end 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 + # Sqlite3's handling of a leading slash is in transition as of + # Rails 4.1. + def database_from_path + if @authority && @adapter == 'sqlite3' + # 'sqlite3:///foo' is relative, for backwards compatibility. + + database_name = uri.path.sub(%r{^/}, "") + + msg = "Paths in SQLite3 database URLs of the form `sqlite3:///path` will be treated as absolute in Rails 4.2. " \ + "Please switch to `sqlite3:#{database_name}`." + ActiveSupport::Deprecation.warn(msg) + + database_name + + elsif @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 - uri.path.sub(%r{^/},"") + # Only SQLite uses a filename as the "database" name; for + # anything else, a leading slash would be silly. + + uri.path.sub(%r{^/}, "") end end end -- cgit v1.2.3 From 0a99fddc140d8aa54a8922e745624a250877658b Mon Sep 17 00:00:00 2001 From: Matthew Draper Date: Thu, 3 Apr 2014 01:41:34 +1030 Subject: Complete change of `sqlite3:///` path handling That which was now relative is now absolute. --- .../connection_adapters/connection_specification.rb | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters/connection_specification.rb') diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb index 5ede946836..56c533c401 100644 --- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb @@ -41,7 +41,6 @@ module ActiveRecord else @query = @uri.query end - @authority = url =~ %r{\A[^:]*://} end # Converts the given URL to a full connection hash. @@ -91,21 +90,8 @@ module ActiveRecord end # Returns name of the database. - # Sqlite3's handling of a leading slash is in transition as of - # Rails 4.1. def database_from_path - if @authority && @adapter == 'sqlite3' - # 'sqlite3:///foo' is relative, for backwards compatibility. - - database_name = uri.path.sub(%r{^/}, "") - - msg = "Paths in SQLite3 database URLs of the form `sqlite3:///path` will be treated as absolute in Rails 4.2. " \ - "Please switch to `sqlite3:#{database_name}`." - ActiveSupport::Deprecation.warn(msg) - - database_name - - elsif @adapter == 'sqlite3' + if @adapter == 'sqlite3' # 'sqlite3:/foo' is absolute, because that makes sense. The # corresponding relative version, 'sqlite3:foo', is handled # elsewhere, as an "opaque". -- cgit v1.2.3