lib/oxblood/session.rb in oxblood-0.1.0.dev8 vs lib/oxblood/session.rb in oxblood-0.1.0.dev9
- old
+ new
@@ -1,1386 +1,31 @@
+require 'oxblood/commands'
+require 'oxblood/protocol'
+
module Oxblood
- # Implements usual Request/Response protocol
+ # Implements usual Request/Response protocol.
+ # Error responses will be raised.
#
# @note {Session} don't maintain threadsafety! In multithreaded environment
# please use {Pool}
#
# @example
# conn = Oxblood::Connection.new
# session = Oxblood::Session.new(conn)
# session.ping # => 'PONG'
class Session
+ include Oxblood::Commands
+
def initialize(connection)
@connection = connection
end
- #
- # Hashes
- #
+ private
- # Removes the specified fields from the hash stored at key
- # @see http://redis.io/commands/hdel
- #
- # @param [String] key under which hash is stored
- # @param [Array<#to_s>] fields to delete
- #
- # @return [Integer] the number of fields that were removed from the hash
- def hdel(key, fields)
- run(:HDEL, key, fields)
- end
-
- # Returns if field is an existing field in the hash stored at key
- # @see http://redis.io/commands/hexists
- #
- # @param [String] key under which hash is stored
- # @param [String] field to check for existence
- #
- # @return [Boolean] do hash contains field or not
- def hexists(key, field)
- 1 == run(:HEXISTS, key, field)
- end
-
- # Get the value of a hash field
- # @see http://redis.io/commands/hget
- #
- # @param [String] key under which hash is stored
- # @param [String] field name
- #
- # @return [String, nil] the value associated with field
- # or nil when field is not present in the hash or key does not exist.
- def hget(key, field)
- run(:HGET, key, field)
- end
-
- # Get all the fields and values in a hash
- # @see http://redis.io/commands/hgetall
- #
- # @param [String] key under which hash is stored
- #
- # @return [Hash] of fields and their values
- def hgetall(key)
- Hash[*run(:HGETALL, key)]
- end
-
- # Increment the integer value of a hash field by the given number
- # @see http://redis.io/commands/hincrby
- #
- # @param [String] key under which hash is stored
- # @param [String] field to increment
- # @param [Integer] increment by value
- #
- # @return [Integer] the value at field after the increment operation
- def hincrby(key, field, increment)
- run(:HINCRBY, key, field, increment)
- end
-
- # Increment the float value of a hash field by the given number
- # @see http://redis.io/commands/hincrby
- #
- # @param [String] key under which hash is stored
- # @param [String] field to increment
- # @param [Integer] increment by value
- #
- # @return [String] the value of field after the increment
- # @return [RError] field contains a value of the wrong type (not a string).
- # Or the current field content or the specified increment are not parsable
- # as a double precision floating point number.
- def hincrbyfloat(key, field, increment)
- run(:HINCRBYFLOAT, key, field, increment)
- end
-
- # Get all the keys in a hash
- # @see http://redis.io/commands/hkeys
- #
- # @param [String] key
- #
- # @return [Array] list of fields in the hash, or an empty list when
- # key does not exist.
- def hkeys(key)
- run(:HKEYS, key)
- end
-
- # Get the number of keys in a hash
- # @see http://redis.io/commands/hlen
- #
- # @param [String] key
- #
- # @return [Integer] number of fields in the hash, or 0 when
- # key does not exist.
- def hlen(key)
- run(:HLEN, key)
- end
-
- # Get the field values of all given hash fields
- # @see http://redis.io/commands/hmget
- #
- # @param [String] key under which hash is stored
- # @param [String, Array<String>] fields to get
- #
- # @return [Array] list of values associated with the given fields,
- # in the same order as they are requested.
- def hmget(key, *fields)
- run(*fields.unshift(:HMGET, key))
- end
-
- # Set multiple hash fields to multiple values
- # @see http://redis.io/commands/hmset
- #
- # @param [String] key under which store hash
- # @param [[String, String], Array<[String, String]>] args fields and values
- #
- # @return [String] 'OK'
- def hmset(key, *args)
- run(*args.unshift(:HMSET, key))
- end
-
-
- # Set the string value of a hash field
- # @see http://redis.io/commands/hset
- #
- # @param [String] key
- # @param [String] field
- # @param [String] value
- #
- # @return [Integer] 1 if field is a new field in the hash and value was set.
- # 0 if field already exists in the hash and the value was updated.
- def hset(key, field, value)
- run(:HSET, key, field, value)
- end
-
- # Set the value of a hash field, only if the field does not exist
- # @see http://redis.io/commands/hsetnx
- #
- # @param [String] key
- # @param [String] field
- # @param [String] value
- #
- # @return [Integer] 1 if field is a new field in the hash and value was set.
- # 0 if field already exists in the hash and no operation was performed.
- def hsetnx(key, field, value)
- run(:HSETNX, key, field, value)
- end
-
- # Get the length of the value of a hash field
- # @see http://redis.io/commands/hstrlen
- #
- # @param [String] key
- # @param [String] field
- #
- # @return [Integer] the string length of the value associated with field,
- # or 0 when field is not present in the hash or key does not exist at all.
- def hstrlen(key, field)
- run(:HSTRLEN, key, field)
- end
-
- # Get all values in a hash
- # @see http://redis.io/commands/hvals
- #
- # @param [String] key
- #
- # @return [Array] list of values in the hash, or an empty list when
- # key does not exist
- def hvals(key)
- run(:HVALS, key)
- end
-
- #
- # Strings
- #
-
- # Append a value to a key
- # @see http://redis.io/commands/append
- #
- # @param [String] key
- # @param [String] value
- #
- # @return [Integer] the length of the string after the append operation
- def append(key, value)
- run(:APPEND, key, value)
- end
-
- # Count set bits in a string
- # @see http://redis.io/commands/bitcount
- #
- # @param [String] key
- # @param [Array] interval to count in
- #
- # @return [Integer] the number of bits set to 1
- def bitcount(key, *interval)
- run(*interval.unshift(:BITCOUNT, key))
- end
-
- # Perform bitwise operations between strings
- # @see http://redis.io/commands/bitop
- #
- # @param [String] operation
- # @param [String] destkey
- # @param [Array] keys
- #
- # @return [Integer] the size of the string stored in the destination key,
- # that is equal to the size of the longest input string
- def bitop(operation, destkey, *keys)
- run(*keys.unshift(:BITOP, operation, destkey))
- end
-
- # Find first bit set or clear in a string
- # @see http://redis.io/commands/bitpos
- #
- # @param [String] key
- # @param [Integer] bit
- # @param [Array] interval
- #
- # @return [Integer] the command returns the position of the first bit set to
- # 1 or 0 according to the request
- def bitpos(key, bit, *interval)
- run(*interval.unshift(:BITPOS, key, bit))
- end
-
- # Decrement the integer value of a key by one
- # @see http://redis.io/commands/decr
- #
- # @param [String] key
- #
- # @return [Integer] the value of key after the decrement
- # @return [RError] if value is not an integer or out of range
- def decr(key)
- run(:DECR, key)
- end
-
- # Decrement the integer value of a key by the given number
- # @see http://redis.io/commands/decrby
- #
- # @param [String] key
- # @param [Integer] decrement
- #
- # @return [Integer] the value of key after the decrement
- # @return [RError] if the key contains a value of the wrong type or contains
- # a string that can not be represented as integer
- def decrby(key, decrement)
- run(:DECRBY, key, decrement)
- end
-
- # Get the value of a key
- # @see http://redis.io/commands/get
- #
- # @param [String] key
- #
- # @return [String, nil] the value of key, or nil when key does not exists
- def get(key)
- run(:GET, key)
- end
-
- # Returns the bit value at offset in the string value stored at key
- # @see http://redis.io/commands/getbit
- #
- # @param [String] key
- # @param [Integer] offset
- #
- # @return [Integer] the bit value stored at offset
- def getbit(key, offset)
- run(:GETBIT, key, offset)
- end
-
- # Get a substring of the string stored at a key
- # @see http://redis.io/commands/getrange
- #
- # @param [String] key
- # @param [Integer] start_pos
- # @param [Integer] end_pos
- #
- # @return [String] substring
- def getrange(key, start_pos, end_pos)
- run(:GETRANGE, key, start_pos, end_pos)
- end
-
- # Set the string value of a key and return its old value
- # @see http://redis.io/commands/getset
- #
- # @param [String] key
- # @param [String] value
- #
- # @return [String, nil] the old value stored at key, or nil when
- # key did not exist
- def getset(key, value)
- run(:GETSET, key, value)
- end
-
- # Increment the integer value of a key by one
- # @see http://redis.io/commands/incr
- #
- # @param [String] key
- #
- # @return [Integer] the value of key after the increment
- # @return [RError] if the key contains a value of the wrong type or contains
- # a string that can not be represented as integer
- def incr(key)
- run(:INCR, key)
- end
-
- # Increment the integer value of a key by the given amount
- # @see http://redis.io/commands/incrby
- #
- # @param [String] key
- # @param [Integer] increment
- #
- # @return [Integer] the value of key after the increment
- def incrby(key, increment)
- run(:INCRBY, key, increment)
- end
-
- # Increment the float value of a key by the given amount
- # @see http://redis.io/commands/incrbyfloat
- #
- # @param [String] key
- # @param [Float] increment
- #
- # @return [String] the value of key after the increment
- def incrbyfloat(key, increment)
- run(:INCRBYFLOAT, key, increment)
- end
-
- # Get the values of all the given keys
- # @see http://redis.io/commands/mget
- #
- # @param [Array<String>] keys to retrieve
- #
- # @return [Array] list of values at the specified keys
- def mget(*keys)
- run(*keys.unshift(:MGET))
- end
-
- # Set multiple keys to multiple values
- # @see http://redis.io/commands/mset
- #
- # @param [Array] keys_and_values
- #
- # @return [String] 'OK'
- def mset(*keys_and_values)
- run(*keys_and_values.unshift(:MSET))
- end
-
- # Set multiple keys to multiple values, only if none of the keys exist
- # @see http://redis.io/commands/msetnx
- #
- # @param [Array] keys_and_values
- #
- # @return [Integer] 1 if the all the keys were set, or
- # 0 if no key was set (at least one key already existed)
- def msetnx(*keys_and_values)
- run(*keys_and_values.unshift(:MSETNX))
- end
-
- # Set the value and expiration in milliseconds of a key
- # @see http://redis.io/commands/psetex
- #
- # @param [String] key
- # @param [Integer] milliseconds expire time
- # @param [String] value
- #
- # @return [String] 'OK'
- def psetex(key, milliseconds, value)
- run(:PSETEX, key, milliseconds, value)
- end
-
- # Set the string value of a key
- # @see http://redis.io/commands/set
- #
- # @todo Add support for set options
- # http://redis.io/commands/set#options
- #
- # @param [String] key
- # @param [String] value
- #
- # @return [String] 'OK' if SET was executed correctly
- def set(key, value)
- run(:SET, key, value)
- end
-
- # Set or clear the bit at offset in the string value stored at key
- # @see http://redis.io/commands/setbit
- #
- # @param [String] key
- # @param [Integer] offset
- # @param [String] value
- #
- # @return [Integer] the original bit value stored at offset
- def setbit(key, offset, value)
- run(:SETBIT, key, offset, value)
- end
-
- # Set the value and expiration of a key
- # @see http://redis.io/commands/setex
- #
- # @param [String] key
- # @param [Integer] seconds expire time
- # @param [String] value
- #
- # @return [String] 'OK'
- def setex(key, seconds, value)
- run(:SETEX, key, seconds, value)
- end
-
- # Set the value of a key, only if the key does not exist
- # @see http://redis.io/commands/setnx
- #
- # @param [String] key
- # @param [String] value
- #
- # @return [Integer] 1 if the key was set, or 0 if the key was not set
- def setnx(key, value)
- run(:SETNX, key, value)
- end
-
- # Overwrite part of a string at key starting at the specified offset
- # @see http://redis.io/commands/setrange
- #
- # @param [String] key
- # @param [Integer] offset
- # @param [String] value
- #
- # @return [Integer] the length of the string after it was modified by
- # the command
- def setrange(key, offset, value)
- run(:SETRANGE, key, offset, value)
- end
-
- # Get the length of the value stored in a key
- # @see http://redis.io/commands/strlen
- #
- # @param [String] key
- #
- # @return [Integer] the length of the string at key,
- # or 0 when key does not exist
- def strlen(key)
- run(:STRLEN, key)
- end
-
- #
- # Connection
- #
-
- # Authenticate to the server
- # @see http://redis.io/commands/auth
- #
- # @param [String] password
- #
- # @return [String] 'OK'
- # @return [RError] if wrong password was passed or server does not require
- # password
- def auth(password)
- run(:AUTH, password)
- end
-
- # Echo the given string
- # @see http://redis.io/commands/echo
- #
- # @param [String] message
- #
- # @return [String] given string
- def echo(message)
- run(:ECHO, message)
- end
-
- # Like {#auth}, except that if error returned, raises it.
- #
- # @param [String] password
- #
- # @raise [Protocol::RError] if error returned
- #
- # @return [String] 'OK'
- def auth!(password)
- response = auth(password)
+ def run(*command)
+ response = @connection.run_command(*command)
error?(response) ? (raise response) : response
end
-
- # Returns PONG if no argument is provided, otherwise return a copy of
- # the argument as a bulk
- # @see http://redis.io/commands/ping
- #
- # @param [String] message to return
- #
- # @return [String] message passed as argument
- def ping(message = nil)
- message ? run(:PING, message) : run(:PING)
- end
-
- # Change the selected database for the current connection
- # @see http://redis.io/commands/select
- #
- # @param [Integer] index database to switch
- #
- # @return [String] 'OK'
- # @return [RError] if wrong index was passed
- def select(index)
- run(:SELECT, index)
- end
-
- # Close the connection
- # @see http://redis.io/commands/quit
- #
- # @return [String] 'OK'
- def quit
- run(:QUIT)
- ensure
- @connection.socket.close
- end
-
- #
- # Server
- #
-
- # Remove all keys from the current database
- # @see http://redis.io/commands/flushdb
- #
- # @return [String] should always return 'OK'
- def flushdb
- run(:FLUSHDB)
- end
-
- # Returns information and statistics about the server in a format that is
- # simple to parse by computers and easy to read by humans
- # @see http://redis.io/commands/info
- #
- # @param [String] section used to select a specific section of information
- #
- # @return [String] raw redis server response as a collection of text lines.
- def info(section = nil)
- section ? run(:INFO, section) : run(:INFO)
- end
-
- #
- # Keys
- #
-
- # Delete a key
- # @see http://redis.io/commands/del
- #
- # @param [String, Array<String>] keys to delete
- #
- # @return [Integer] the number of keys that were removed
- def del(*keys)
- run(*keys.unshift(:DEL))
- end
-
- # Return a serialized version of the value stored at specified key.
- # @see http://redis.io/commands/dump
- #
- # @param [String] key
- #
- # @return [String] serialized value
- def dump(key)
- run(:DUMP, key)
- end
-
- # Determine if a key exists
- # @see http://redis.io/commands/exists
- #
- # @param [String, Array<String>] keys to check
- #
- # @return [Integer] the number of keys existing among the ones specified as
- # arguments. Keys mentioned multiple times and existing are counted
- # multiple times.
- def exists(*keys)
- run(*keys.unshift(:EXISTS))
- end
-
- # Set a key's time to live in seconds
- # @see http://redis.io/commands/expire
- #
- # @param [String] key to expire
- # @param [Integer] seconds number of seconds
- #
- # @return [Integer] 1 if the timeout was set. 0 if key does not exist or
- # the timeout could not be set.
- def expire(key, seconds)
- run(:EXPIRE, key, seconds)
- end
-
- # Set the expiration for a key as a UNIX timestamp
- # @see http://redis.io/commands/expireat
- #
- # @param [String] key
- # @param [Integer] timestamp in UNIX format
- #
- # @return [Integer] 1 if the timeout was set. 0 if key does not exist or
- # the timeout could not be set.
- def expireat(key, timestamp)
- run(:EXPIREAT, key, timestamp)
- end
-
- # Find all keys matching the given pattern
- # @see http://redis.io/commands/keys
- #
- # @param [String] pattern used to match keys
- def keys(pattern)
- run(:KEYS, pattern)
- end
-
- # Move a key to another database
- # @see http://redis.io/commands/move
- #
- # @param [String] key
- # @param [Integer] db index
- #
- # @return [Integer] 1 if key was moved and 0 otherwise.
- def move(key, db)
- run(:MOVE, key, db)
- end
-
- # Inspect the internals of Redis objects
- # @see http://redis.io/commands/object
- #
- # @param [String] subcommand `REFCOUNT`, `ENCODING`, `IDLETIME`
- # @param [String] key
- #
- # @return [Integer] in case of `REFCOUNT` and `IDLETIME` subcommands
- # @return [String] in case of `ENCODING` subcommand
- # @return [nil] if object you try to inspect is missing
- def object(subcommand, key)
- run(:OBJECT, subcommand, key)
- end
-
- # Remove expiration from a key
- # @see http://redis.io/commands/persist
- # @param [String] key
- #
- # @return [Integer] 1 if the timeout was removed and 0 otherwise
- def persist(key)
- run(:PERSIST, key)
- end
-
- # Set a key's time to live in milliseconds
- # @see http://redis.io/commands/pexpire
- #
- # @param [String] key
- # @param [Integer] milliseconds
- #
- # @return [Integer] 1 if the timeout was set and 0 otherwise
- def pexpire(key, milliseconds)
- run(:PEXPIRE, key, milliseconds)
- end
-
- # Set the expiration for a key as a UNIX timestamp specified in milliseconds
- # @see http://redis.io/commands/pexpireat
- #
- # @param [String] key
- # @param [Integer] timestamp in milliseconds
- #
- # @return [Integer] 1 if the timeout was set and 0 otherwise
- def pexpireat(key, timestamp)
- run(:PEXPIREAT, key, timestamp)
- end
-
- # Get the time to live for a key in milliseconds
- # @see http://redis.io/commands/pttl
- #
- # @param [String] key
- #
- # @return [Integer] TTL in milliseconds, or a negative value in order to
- # signal an error
- def pttl(key)
- run(:PTTL, key)
- end
-
- # Return a random key from the keyspace
- # @see http://redis.io/commands/randomkey
- #
- # @return [String] the random key
- # @return [nil] if database is empty
- def randomkey
- run(:RANDOMKEY)
- end
-
- # Rename a key
- # @see http://redis.io/commands/rename
- #
- # @param [String] key to rename
- # @param [String] newkey
- #
- # @return [String] OK in case of success
- # @return [RError] if key does not exist. Before Redis 3.2.0, an error is
- # returned if source and destination names are the same.
- def rename(key, newkey)
- run(:RENAME, key, newkey)
- end
-
- # Rename a key, only if the new key does not exist
- # @see http://redis.io/commands/renamenx
- #
- # @param [String] key to rename
- # @param [String] newkey
- #
- # @return [Integer] 1 if key was renamed to newkey. 0 if newkey already
- # exists.
- # @return [RError] if key does not exist. Before Redis 3.2.0, an error is
- # returned if source and destination names are the same.
- def renamenx(key, newkey)
- run(:RENAMENX, key, newkey)
- end
-
- # Create a key using the provided serialized value, previously obtained
- # using DUMP
- # @see http://redis.io/commands/restore
- #
- # @param [String] key
- # @param [Integer] ttl expire time in milliseconds
- # @param [String] serialized_value obtained using DUMP command
- # @param [Hash] opts
- #
- # @option opts [Boolean] :replace (false) Override key if it already exists
- #
- # @return [String] OK on success
- # @return [RError] if replace is false and key already exists or RDB version
- # and data checksum don't match.
- def restore(key, ttl, serialized_value, opts = {})
- args = [:RESTORE, key, ttl, serialized_value]
- args << :REPLACE if opts[:replace]
-
- run(*args)
- end
-
- # Get the time to live for a key
- # @see http://redis.io/commands/ttl
- #
- # @param [String] key
- #
- # @return [Integer] TTL in seconds, or a negative value in order to signal
- # an error
- def ttl(key)
- run(:TTL, key)
- end
-
- # Determine the type stored at key
- # @see http://redis.io/commands/type
- #
- # @param [String] key
- #
- # @return [String] type of key, or none when key does not exist.
- def type(key)
- run(:TYPE, key)
- end
-
- #
- # Lists
- #
-
- # Get an element from a list by its index
- # @see http://www.redis.io/commands/lindex
- #
- # @param [String] key
- # @param [Integer] index zero-based of element in the list
- #
- # @return [String] the requested element, or nil when index is out of range.
- def lindex(key, index)
- run(:LINDEX, key, index)
- end
-
- # Insert an element before or after another element in a list
- # @see http://www.redis.io/commands/linsert
- #
- # @param [String] key
- # @param [Symbol] place could be :before or :after
- # @param [String] pivot reference value
- # @param [String] value to insert
- #
- # @return [Integer] the length of the list after the insert operation,
- # or -1 when the value pivot was not found
- def linsert(key, place, pivot, value)
- run(:LINSERT, key, place, pivot, value)
- end
-
- # Get the length of a list
- # @see http://redis.io/commands/llen
- #
- # @param [String] key
- #
- # @return [Integer] the length of the list at key
- # @return [RError] if the value stored at key is not a list
- def llen(key)
- run(:LLEN, key)
- end
-
- # Remove and get the first element in a list
- # @see http://redis.io/commands/lpop
- #
- # @param [String] key
- #
- # @return [String, nil] the value of the first element,
- # or nil when key does not exist.
- def lpop(key)
- run(:LPOP, key)
- end
-
- # Prepend one or multiple values to a list
- # @see http://redis.io/commands/lpush
- #
- # @param [String] key
- # @param [Array] values to prepend
- #
- # @return [Integer] the length of the list after the push operations
- def lpush(key, *values)
- run(*values.unshift(:LPUSH, key))
- end
-
- # Prepend a value to a list, only if the list exists
- # @see http://www.redis.io/commands/lpushx
- #
- # @param [String] key
- # @param [String] value
- #
- # @return [Integer] the length of the list after the push operation
- def lpushx(key, value)
- run(:LPUSHX, key, value)
- end
-
- # Get a range of elements from a list
- # @see http://redis.io/commands/lrange
- #
- # @param [String] key
- # @param [Integer] start index
- # @param [Integer] stop index
- #
- # @return [Array] list of elements in the specified range
- def lrange(key, start, stop)
- run(:LRANGE, key, start, stop)
- end
-
- # Remove elements from a list
- # @see http://www.redis.io/commands/lrem
- #
- # @param [String] key
- # @param [Integer] count (please look into official docs for more info)
- # @param [String] value to remove
- #
- # @return [Integer] the number of removed elements
- def lrem(key, count, value)
- run(:LREM, key, count, value)
- end
-
- # Set the value of an element in a list by its index
- # @see http://www.redis.io/commands/lset
- #
- # @param [String] key
- # @param [Integer] index
- # @param [String] value
- #
- # @return [String] 'OK'
- # @return [RError] if index is out of range
- def lset(key, index, value)
- run(:LSET, key, index, value)
- end
-
- # Trim a list to the specified range
- # @see http://www.redis.io/commands/ltrim
- #
- # @param [String] key
- # @param [Integer] start
- # @param [Integer] stop
- #
- # @return [String] 'OK'
- def ltrim(key, start, stop)
- run(:LTRIM, key, start, stop)
- end
-
- # Remove and get the last element in a list
- # @see http://redis.io/commands/rpop
- #
- # @param [String] key
- #
- # @return [String, nil] the value of the last element, or nil when key does
- # not exist
- def rpop(key)
- run(:RPOP, key)
- end
-
- # Remove the last element in a list, prepend it to another list and return
- # @see http://www.redis.io/commands/rpoplpush
- #
- # @param [String] source
- # @param [String] destination
- #
- # @return [String, nil] the element being popped and pushed, or nil when
- # source does not exist
- def rpoplpush(source, destination)
- run(:RPOPLPUSH, source, destination)
- end
-
- # Append one or multiple values to a list
- # @see http://redis.io/commands/rpush
- #
- # @param [String] key
- # @param [Array] values to add
- #
- # @return [Integer] the length of the list after the push operation
- # @return [RError] if key holds a value that is not a list
- def rpush(key, *values)
- run(*values.unshift(:RPUSH, key))
- end
-
- # Append a value to a list, only if the list exists
- # @see http://www.redis.io/commands/rpushx
- #
- # @param [String] key
- # @param [String] value
- #
- # @return [Integer] the length of the list after the push operation
- def rpushx(key, value)
- run(:RPUSHX, key, value)
- end
-
- #
- # Sets
- #
-
- # Add one or more members to a set
- # @see http://redis.io/commands/sadd
- #
- # @param [String] key under which store set
- # @param [String, Array<String>] members to store
- #
- # @return [Integer] the number of elements that were added to the set,
- # not including all the elements already present into the set.
- def sadd(key, *members)
- run(*members.unshift(:SADD, key))
- end
-
- # Get the number of members in a set
- # @see http://redis.io/commands/scard
- #
- # @param [String] key
- #
- # @return [Integer] the cardinality (number of elements) of the set, or 0 if
- # key does not exist
- def scard(key)
- run(:SCARD, key)
- end
-
- # Subtract multiple sets
- # @see http://redis.io/commands/sdiff
- #
- # @param [String, Array<String>] keys
- #
- # @return [Array] array with members of the resulting set
- def sdiff(*keys)
- run(*keys.unshift(:SDIFF))
- end
-
- # Subtract multiple sets and store the resulting set in a key
- # @see http://redis.io/commands/sdiffstore
- #
- # @param [String] destination key
- # @param [String, Array<String>] keys of sets to diff
- #
- # @return [Integer] the number of elements in the resulting set
- def sdiffstore(destination, *keys)
- run(*keys.unshift(:SDIFFSTORE, destination))
- end
-
- # Intersect multiple sets
- # @see http://redis.io/commands/sinter
- #
- # @param [String, Array<String>] keys to intersect
- #
- # @return [Array] array with members of the resulting set
- def sinter(*keys)
- run(*keys.unshift(:SINTER))
- end
-
- # Intersect multiple sets and store the resulting key in a key
- # @see http://redis.io/commands/sinterstore
- #
- # @param [String] destination key
- # @param [String, Array<String>] keys of sets to intersect
- #
- # @return [Integer] the number of elements in the resulting set
- def sinterstore(destination, *keys)
- run(*keys.unshift(:SINTERSTORE, destination))
- end
-
- # Determine if a given value is a member of a set
- # @see http://redis.io/commands/sismember
- #
- # @param [String] key
- # @param [String] member
- #
- # @return [Integer] 1 if the element is a member of the set or
- # 0 if the element is not a member of the set, or if key does not exist
- def sismember(key, member)
- run(:SISMEMBER, key, member)
- end
-
- # Get all the members in a set
- # @see http://redis.io/commands/smembers
- #
- # @param [String] key
- #
- # @return [Array] all elements of the set
- def smembers(key)
- run(:SMEMBERS, key)
- end
-
- # Move a member from one set to another
- # @see http://redis.io/commands/smove
- #
- # @param [String] source
- # @param [String] destination
- # @param [String] member
- #
- # @return [Integer] 1 if the element is moved, or 0 if the element is not
- # a member of source and no operation was performed
- def smove(source, destination, member)
- run(:SMOVE, source, destination, member)
- end
-
- # Remove and return one or multiple random members from a set
- # @see http://redis.io/commands/spop
- #
- # @param [String] key
- # @param [Integer] count
- #
- # @return [String] without the additional count argument the command returns
- # the removed element, or nil when key does not exist
- # @return [Array] when the additional count argument is passed the command
- # returns an array of removed elements, or an empty array when key does
- # not exist.
- def spop(key, count = nil)
- args = [:SPOP, key]
- args << count if count
- run(*args)
- end
-
- # Get one or multiple random members from a set
- # @see http://redis.io/commands/srandmember
- #
- # @param [String] key
- # @param [Integer] count
- #
- # @return [String, nil] without the additional count argument the command
- # returns string with the randomly selected element, or nil when key
- # does not exist
- # @return [Array] when the additional count argument is passed the command
- # returns an array of elements, or an empty array when key does not exist
- def srandmember(key, count = nil)
- args = [:SRANDMEMBER, key]
- args << count if count
- run(*args)
- end
-
- # Remove one or more members from a set
- # @see http://redis.io/commands/srem
- #
- # @param [String] key
- # @param [Array] members to remove
- #
- # @return [Integer] the number of members that were removed from the set,
- # not including non existing members
- def srem(key, *members)
- run(*members.unshift(:SREM, key))
- end
-
- # Add multiple sets
- # @see http://redis.io/commands/sunion
- #
- # @param [String, Array<String>] keys
- #
- # @return [Array] list with members of the resulting set
- def sunion(*keys)
- run(*keys.unshift(:SUNION))
- end
-
- # Add multipe sets and store the resulting set in a key
- # @see http://redis.io/commands/sunionstore
- #
- # @param [String] destination
- # @param [String, Array<String>] keys
- #
- # @return [Integer] the number of elements in the resulting set
- def sunionstore(destination, *keys)
- run(*keys.unshift(:SUNIONSTORE, destination))
- end
-
- #
- # Sorted Sets
- #
-
- # Add one or more members to a sorted set, or update its score if it already
- # exists.
- # @see http://redis.io/commands/zadd
- #
- # @todo Add support for zadd options
- # http://redis.io/commands/zadd#zadd-options-redis-302-or-greater
- #
- # @param [String] key under which store set
- # @param [[Float, String], Array<[Float, String]>] args scores and members
- #
- # @return [Integer] The number of elements added to the sorted sets, not
- # including elements already existing for which the score was updated
- def zadd(key, *args)
- run(*args.unshift(:ZADD, key))
- end
-
- # Get the number of members in a sorted set
- # @see http://redis.io/commands/zcard
- #
- # @param [String] key
- #
- # @return [Integer] the cardinality (number of elements) of the sorted set,
- # or 0 if key does not exists
- def zcard(key)
- run(:ZCARD, key)
- end
-
- # Count the members in a sorted set with scores within the given values
- # @see http://redis.io/commands/zcount
- #
- # @param [String] key
- # @param [String] min
- # @param [String] max
- #
- # @return [Integer] the number of elements in the specified score range
- def zcount(key, min, max)
- run(:ZCOUNT, key, min, max)
- end
-
- # Increment the score of a member in a sorted set
- # @see http://redis.io/commands/zincrby
- #
- # @param [String] key
- # @param [Float] increment
- # @param [String] member
- #
- # @return [String] the new score of member (a double precision floating
- # point number), represented as string
- def zincrby(key, increment, member)
- run(:ZINCRBY, key, increment, member)
- end
-
- # Count the number of members in a sorted set between a given
- # lexicographical range
- # @see http://redis.io/commands/zlexcount
- #
- # @param [String] key
- # @param [String] min
- # @param [String] max
- #
- # @return the number of elements in the specified score range
- def zlexcount(key, min, max)
- run(:ZLEXCOUNT, key, min, max)
- end
-
- # Return a range of members in a sorted set, by index
- # @see http://redis.io/commands/zrange
- #
- # @example
- # session.zrange('myzset', 0, -1)
- # # => ['one', 'two']
- #
- # @example
- # session.zrange('myzset', 0, -1, withscores: true)
- # # => [['one', '1'], ['two', '2']]
- #
- # @param [String] key
- # @param [Integer] start index
- # @param [Integer] stop index
- # @param [Hash] opts
- #
- # @option opts [Boolean] :withscores (false) Return the scores of
- # the elements together with the elements
- #
- # @return [Array] list of elements in the specified range (optionally with
- # their scores, in case the :withscores option is given)
- def zrange(key, start, stop, opts = {})
- args = [:ZRANGE, key, start, stop]
- args << :WITHSCORES if opts[:withscores]
- run(*args)
- end
-
- # Return a range of members in a sorted set, by score
- # @see http://redis.io/commands/zrangebyscore
- #
- # @param [String] key under which set is stored
- # @param [String] min score
- # @param [String] max score
- # @param [Hash] opts
- #
- # @option opts [Boolean] :withscores (false) Return the scores of
- # the elements together with the elements
- # @option opts [Array<Integer, Integer>] :limit Get a range of the matching
- # elements (similar to SELECT LIMIT offset, count in SQL)
- #
- # @example
- # session.zrangebyscore('myzset', '-inf', '+inf')
- # # => ['one', 'two', 'three']
- #
- # @example
- # session.zrangebyscore('myzset', '(1', 2, withscores: true)
- # # => [['two', '2']]
- #
- # @example
- # opts = { withscores: true, limit: [1, 1] }
- # session.zrangebyscore('myzset', '-inf', '+inf', opts)
- # # => [['two', '2']]
- #
- # @return [Array] list of elements in the specified score range (optionally
- # with their scores, in case the :withscores option is given)
- def zrangebyscore(key, min, max, opts = {})
- args = [:ZRANGEBYSCORE, key, min, max]
- args << :WITHSCORES if opts[:withscores]
- args.push(:LIMIT).concat(opts[:limit]) if opts[:limit].is_a?(Array)
-
- run(*args)
- end
-
- # Determine the index of a member in a sorted set
- # @see http://redis.io/commands/zrank
- #
- # @param [String] key
- # @param [String] member
- #
- # @return [Integer, nil] the rank of member or nil if member does not exist
- # in the sorted set or key does not exist
- def zrank(key, member)
- run(:ZRANK, key, member)
- end
-
- # Remove one or more members from a sorted set
- # @see http://redis.io/commands/zrem
- #
- # @param [String] key
- # @param [Array<String>] members to delete
- #
- # @return [Integer] number of deleted members
- # @return [RError] when key exists and does not hold a sorted set.
- def zrem(key, *members)
- run(*members.unshift(:ZREM, key))
- end
-
- # Remove all members in a sorted set within the given indexes
- # @see http://redis.io/commands/zremrangebyrank
- #
- # @param [String] key
- # @param [String] start
- # @param [String] stop
- #
- # @return [Integer] the number of elements removed
- def zremrangebyrank(key, start, stop)
- run(:ZREMRANGEBYRANK, key, start, stop)
- end
-
- # Remove all members in a sorted set within the given scores
- # @see http://redis.io/commands/zremrangebyscore
- #
- # @param [String] key
- # @param [String] min score
- # @param [String] max score
- #
- # @return [Integer] the number of elements removed
- def zremrangebyscore(key, min, max)
- run(:ZREMRANGEBYSCORE, key, min, max)
- end
-
- # Return a range of members in a sorted set, by index, with scores ordered
- # from high to low
- # @see http://redis.io/commands/zrevrange
- #
- # @example
- # session.zrevrange('myzset', 0, -1)
- # # => ['two', 'one']
- #
- # @example
- # session.zrevrange('myzset', 0, -1, withscores: true)
- # # => [['two', '2'], ['one', '1']]
- #
- # @param [String] key
- # @param [Integer] start index
- # @param [Integer] stop index
- # @param [Hash] opts
- #
- # @option opts [Boolean] :withscores (false) Return the scores of
- # the elements together with the elements
- #
- # @return [Array] list of elements in the specified range (optionally with
- # their scores, in case the :withscores option is given)
- def zrevrange(key, start, stop, opts = {})
- args = [:ZREVRANGE, key, start, stop]
- args << :WITHSCORES if opts[:withscores]
- run(*args)
- end
-
- # Return a range of members in a sorted set, by score, with scores ordered
- # from high to low
- # @see http://redis.io/commands/zrevrangebyscore
- #
- # @param [String] key under which set is stored
- # @param [String] min score
- # @param [String] max score
- # @param [Hash] opts
- #
- # @option opts [Boolean] :withscores (false) Return the scores of
- # the elements together with the elements
- # @option opts [Array<Integer, Integer>] :limit Get a range of the matching
- # elements (similar to SELECT LIMIT offset, count in SQL)
- #
- # @example
- # session.zrevrangebyscore('myzset', '+inf', '-inf')
- # # => ['three', 'two', 'one']
- #
- # @example
- # session.zrevrangebyscore('myzset', 2, '(1', withscores: true)
- # # => [['two', '2']]
- #
- # @example
- # opts = { withscores: true, limit: [1, 1] }
- # session.zrevrangebyscore('myzset', '+inf', '-inf', opts)
- # # => [['two', '2']]
- #
- # @return [Array] list of elements in the specified score range (optionally
- # with their scores, in case the :withscores option is given)
- def zrevrangebyscore(key, min, max, opts = {})
- args = [:ZREVRANGEBYSCORE, key, min, max]
- args << :WITHSCORES if opts[:withscores]
- args.push(:LIMIT).concat(opts[:limit]) if opts[:limit].is_a?(Array)
-
- run(*args)
- end
-
- # Determine the index of a member in a sorted set, with scores ordered from
- # high to low
- # @see http://redis.io/commands/zrevrank
- #
- # @param [String] key
- # @param [String] member
- #
- # @return [Integer, nil] the rank of member, or nil if member does not
- # exists in the sorted set or key does not exists
- def zrevrank(key, member)
- run(:ZREVRANK, key, member)
- end
-
- # Get the score associated with the given member in a sorted set
- # @see http://redis.io/commands/zscore
- #
- # @param [String] key
- # @param [String] member
- #
- # @return [String, nil] the score of member (a double precision floating
- # point number), represented as string, or nil if member does not exist in
- # the sorted set, or key does not exists
- def zscore(key, member)
- run(:ZSCORE, key, member)
- end
-
- protected
-
- def serialize(*command)
- Protocol.build_command(*command)
- end
-
- def run(*command)
- @connection.run_command(*command)
- end
-
- private
def error?(response)
Protocol::RError === response
end
end