Skip to content

Commit

Permalink
Use built-in ActiveRecord URL resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
mlarraz committed Feb 5, 2021
1 parent abd3bf4 commit a364e16
Showing 1 changed file with 5 additions and 91 deletions.
96 changes: 5 additions & 91 deletions lib/makara/config_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,99 +37,13 @@ class ConfigParser
master_ttl: :primary_ttl
}.freeze

# ConnectionUrlResolver is borrowed from Rails 4-2 since its location and implementation
# vary slightly among Rails versions, but the behavior is the same. Thus, borrowing the
# class should be the most future-safe way to parse a database url.
#
# 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.tr('-', '_')
@adapter = "postgresql" if @adapter == "postgres"

if @uri.opaque
@uri.opaque, @query = @uri.opaque.split('?', 2)
else
@query = @uri.query
end
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] = CGI.unescape(value) if value.is_a? String }
config
end

private

def uri
@uri
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("=") }]
ConnectionUrlResolver =
if ActiveRecord::VERSION::STRING >= "6.1.0"
::ActiveRecord::DatabaseConfigurations::ConnectionUrlResolver
else
ActiveRecord::ConnectionAdapters::ConnectionSpecification::ConnectionUrlResolver
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.host })
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".

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{^/}, "")
end
end
end

# NOTE: url format must be, e.g.
# url: mysql2://...
# NOT
Expand Down

0 comments on commit a364e16

Please sign in to comment.