X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/cd71a5705d16e5af90bc6be7ad960133391a5932..fc9aeaeaf8d6d9a96b1b22ec5641c8e4290bc673:/client-libraries/ruby_2/rubyredis.rb diff --git a/client-libraries/ruby_2/rubyredis.rb b/client-libraries/ruby_2/rubyredis.rb index a6a7408f..620bab17 100644 --- a/client-libraries/ruby_2/rubyredis.rb +++ b/client-libraries/ruby_2/rubyredis.rb @@ -14,13 +14,37 @@ class RedisClient "echo"=>true, "getset"=>true, "smove"=>true } + ConvertToBool = lambda{|r| r == 0 ? false : r} + + ReplyProcessor = { + "exists" => ConvertToBool, + "sismember"=> ConvertToBool, + "sadd"=> ConvertToBool, + "srem"=> ConvertToBool, + "smove"=> ConvertToBool, + "move"=> ConvertToBool, + "setnx"=> ConvertToBool, + "del"=> ConvertToBool, + "renamenx"=> ConvertToBool, + "expire"=> ConvertToBool, + "keys" => lambda{|r| r.split(" ")}, + "info" => lambda{|r| + info = {} + r.each_line {|kv| + k,v = kv.split(':', 2) + k,v = k.chomp, v = v.chomp + info[k.to_sym] = v + } + info + } + } + def initialize(opts={}) opts = {:host => 'localhost', :port => '6379', :db => 0}.merge(opts) @host = opts[:host] @port = opts[:port] @db = opts[:db] - @sock = connect_to_server - call_command(["select",@db]) if @db != 0 + connect_to_server end def to_s @@ -28,7 +52,8 @@ class RedisClient end def connect_to_server - TCPSocket.new(@host, @port, 0) + @sock = TCPSocket.new(@host, @port, 0) + call_command(["select",@db]) if @db != 0 end def method_missing(*argv) @@ -36,23 +61,48 @@ class RedisClient end def call_command(argv) + # this wrapper to raw_call_command handle reconnection on socket + # error. We try to reconnect just one time, otherwise let the error + # araise. + begin + raw_call_command(argv) + rescue Errno::ECONNRESET + @sock.close + connect_to_server + raw_call_command(argv) + end + end + + def raw_call_command(argv) bulk = nil argv[0] = argv[0].to_s.downcase if BulkCommands[argv[0]] - bulk = argv[-1] + bulk = argv[-1].to_s argv[-1] = bulk.length end @sock.write(argv.join(" ")+"\r\n") @sock.write(bulk+"\r\n") if bulk - read_reply + + # Post process the reply if needed + processor = ReplyProcessor[argv[0]] + processor ? processor.call(read_reply) : read_reply end def select(*args) raise "SELECT not allowed, use the :db option when creating the object" end + def [](key) + get(key) + end + + def []=(key,value) + set(key,value) + end + def read_reply line = @sock.gets + raise Errno::ECONNRESET,"Connection lost" if !line case line[0..0] when "-" raise line.strip