diff --git a/CHANGELOG.md b/CHANGELOG.md index f39e4b3a5..b64267770 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,12 @@ # 3.0.2 (unreleased) +* Allow string keys in options hash passed to `Redis.new` or + `Redis.connect`. + * Fix uncaught error triggering unrelated error (synchrony driver). See f7ffd5f1a628029691084de69e5b46699bb8b96d and #248. - # 3.0.1 * Fix reconnect logic not kicking in on a write error. diff --git a/lib/redis/client.rb b/lib/redis/client.rb index f108cbac0..73eedfd8e 100644 --- a/lib/redis/client.rb +++ b/lib/redis/client.rb @@ -4,6 +4,7 @@ class Redis class Client DEFAULTS = { + :url => lambda { ENV["REDIS_URL"] }, :scheme => "redis", :host => "127.0.0.1", :port => 6379, @@ -11,6 +12,8 @@ class Client :timeout => 5.0, :password => nil, :db => 0, + :driver => nil, + :id => nil, } def scheme @@ -295,8 +298,19 @@ def ensure_connected def _parse_options(options) defaults = DEFAULTS.dup + options = options.dup - url = options[:url] || ENV["REDIS_URL"] + defaults.keys.each do |key| + # Fill in defaults if needed + if defaults[key].respond_to?(:call) + defaults[key] = defaults[key].call + end + + # Symbolize only keys that are needed + options[key] = options[key.to_s] if options.has_key?(key.to_s) + end + + url = options[:url] || defaults[:url] # Override defaults from URL if given if url diff --git a/test/url_param_test.rb b/test/url_param_test.rb index 5784338ab..d96044a68 100644 --- a/test/url_param_test.rb +++ b/test/url_param_test.rb @@ -24,6 +24,15 @@ def test_allows_to_pass_in_a_url assert_equal "secr3t", redis.client.password end + def test_allows_to_pass_in_a_url_with_string_key + redis = Redis.new "url" => "redis://:secr3t@foo.com:999/2" + + assert_equal "foo.com", redis.client.host + assert_equal 999, redis.client.port + assert_equal 2, redis.client.db + assert_equal "secr3t", redis.client.password + end + def test_override_url_if_path_option_is_passed redis = Redis.new :url => "redis://:secr3t@foo.com/foo:999/2", :path => "/tmp/redis.sock" @@ -32,6 +41,14 @@ def test_override_url_if_path_option_is_passed assert_equal nil, redis.client.port end + def test_override_url_if_path_option_is_passed_with_string_key + redis = Redis.new :url => "redis://:secr3t@foo.com/foo:999/2", "path" => "/tmp/redis.sock" + + assert_equal "/tmp/redis.sock", redis.client.path + assert_equal nil, redis.client.host + assert_equal nil, redis.client.port + end + def test_overrides_url_if_another_connection_option_is_passed redis = Redis.new :url => "redis://:secr3t@foo.com:999/2", :port => 1000 @@ -41,6 +58,15 @@ def test_overrides_url_if_another_connection_option_is_passed assert_equal "secr3t", redis.client.password end + def test_overrides_url_if_another_connection_option_is_passed_with_string_key + redis = Redis.new :url => "redis://:secr3t@foo.com:999/2", "port" => 1000 + + assert_equal "foo.com", redis.client.host + assert_equal 1000, redis.client.port + assert_equal 2, redis.client.db + assert_equal "secr3t", redis.client.password + end + def test_does_not_modify_the_passed_options options = { :url => "redis://:secr3t@foo.com:999/2" }