module Redis::Commands::Keys

Public Instance Methods

copy(source, destination, db: nil, replace: false) click to toggle source

Copy a value from one key to another.

@example Copy a value to another key

redis.set "foo", "value"
  # => "OK"
redis.copy "foo", "bar"
  # => true
redis.get "bar"
  # => "value"

@example Copy a value to a key in another database

redis.set "foo", "value"
  # => "OK"
redis.copy "foo", "bar", db: 2
  # => true
redis.select 2
  # => "OK"
redis.get "bar"
  # => "value"

@param [String] source @param [String] destination @param [Integer] db @param [Boolean] replace removes the ‘destination` key before copying value to it @return [Boolean] whether the key was copied or not

# File lib/redis/commands/keys.rb, line 327
def copy(source, destination, db: nil, replace: false)
  command = [:copy, source, destination]
  command << "DB" << db if db
  command << "REPLACE" if replace

  send_command(command, &Boolify)
end
del(*keys) click to toggle source

Delete one or more keys.

@param [String, Array<String>] keys @return [Integer] number of keys that were deleted

# File lib/redis/commands/keys.rb, line 232
def del(*keys)
  keys.flatten!(1)
  return 0 if keys.empty?

  send_command([:del] + keys)
end
dump(key) click to toggle source

Return a serialized version of the value stored at a key.

@param [String] key @return [String] serialized_value

# File lib/redis/commands/keys.rb, line 183
def dump(key)
  send_command([:dump, key])
end
exists(*keys) click to toggle source

Determine how many of the keys exists.

@param [String, Array<String>] keys @return [Integer]

# File lib/redis/commands/keys.rb, line 251
def exists(*keys)
  send_command([:exists, *keys])
end
exists?(*keys) click to toggle source

Determine if any of the keys exists.

@param [String, Array<String>] keys @return [Boolean]

# File lib/redis/commands/keys.rb, line 259
def exists?(*keys)
  send_command([:exists, *keys]) do |value|
    value > 0
  end
end
expire(key, seconds, nx: nil, xx: nil, gt: nil, lt: nil) click to toggle source

Set a key’s time to live in seconds.

@param [String] key @param [Integer] seconds time to live @param [Hash] options

- `:nx => true`: Set expiry only when the key has no expiry.
- `:xx => true`: Set expiry only when the key has an existing expiry.
- `:gt => true`: Set expiry only when the new expiry is greater than current one.
- `:lt => true`: Set expiry only when the new expiry is less than current one.

@return [Boolean] whether the timeout was set or not

# File lib/redis/commands/keys.rb, line 78
def expire(key, seconds, nx: nil, xx: nil, gt: nil, lt: nil)
  args = [:expire, key, Integer(seconds)]
  args << "NX" if nx
  args << "XX" if xx
  args << "GT" if gt
  args << "LT" if lt

  send_command(args, &Boolify)
end
expireat(key, unix_time, nx: nil, xx: nil, gt: nil, lt: nil) click to toggle source

Set the expiration for a key as a UNIX timestamp.

@param [String] key @param [Integer] unix_time expiry time specified as a UNIX timestamp @param [Hash] options

- `:nx => true`: Set expiry only when the key has no expiry.
- `:xx => true`: Set expiry only when the key has an existing expiry.
- `:gt => true`: Set expiry only when the new expiry is greater than current one.
- `:lt => true`: Set expiry only when the new expiry is less than current one.

@return [Boolean] whether the timeout was set or not

# File lib/redis/commands/keys.rb, line 98
def expireat(key, unix_time, nx: nil, xx: nil, gt: nil, lt: nil)
  args = [:expireat, key, Integer(unix_time)]
  args << "NX" if nx
  args << "XX" if xx
  args << "GT" if gt
  args << "LT" if lt

  send_command(args, &Boolify)
end
keys(pattern = "*") click to toggle source

Find all keys matching the given pattern.

@param [String] pattern @return [Array<String>]

# File lib/redis/commands/keys.rb, line 269
def keys(pattern = "*")
  send_command([:keys, pattern]) do |reply|
    if reply.is_a?(String)
      reply.split(" ")
    else
      reply
    end
  end
end
migrate(key, options) click to toggle source

Transfer a key from the connected instance to another instance.

@param [String, Array<String>] key @param [Hash] options

- `:host => String`: host of instance to migrate to
- `:port => Integer`: port of instance to migrate to
- `:db => Integer`: database to migrate to (default: same as source)
- `:timeout => Integer`: timeout (default: same as connection timeout)
- `:copy => Boolean`: Do not remove the key from the local instance.
- `:replace => Boolean`: Replace existing key on the remote instance.

@return [String] ‘“OK”`

# File lib/redis/commands/keys.rb, line 214
def migrate(key, options)
  args = [:migrate]
  args << (options[:host] || raise(':host not specified'))
  args << (options[:port] || raise(':port not specified'))
  args << (key.is_a?(String) ? key : '')
  args << (options[:db] || @client.db).to_i
  args << (options[:timeout] || @client.timeout).to_i
  args << 'COPY' if options[:copy]
  args << 'REPLACE' if options[:replace]
  args += ['KEYS', *key] if key.is_a?(Array)

  send_command(args)
end
move(key, db) click to toggle source

Move a key to another database.

@example Move a key to another database

redis.set "foo", "bar"
  # => "OK"
redis.move "foo", 2
  # => true
redis.exists "foo"
  # => false
redis.select 2
  # => "OK"
redis.exists "foo"
  # => true
redis.get "foo"
  # => "bar"

@param [String] key @param [Integer] db @return [Boolean] whether the key was moved or not

# File lib/redis/commands/keys.rb, line 298
def move(key, db)
  send_command([:move, key, db], &Boolify)
end
object(*args) click to toggle source
# File lib/redis/commands/keys.rb, line 335
def object(*args)
  send_command([:object] + args)
end
persist(key) click to toggle source

Remove the expiration from a key.

@param [String] key @return [Boolean] whether the timeout was removed or not

# File lib/redis/commands/keys.rb, line 64
def persist(key)
  send_command([:persist, key], &Boolify)
end
pexpire(key, milliseconds, nx: nil, xx: nil, gt: nil, lt: nil) click to toggle source

Set a key’s time to live in milliseconds.

@param [String] key @param [Integer] milliseconds time to live @param [Hash] options

- `:nx => true`: Set expiry only when the key has no expiry.
- `:xx => true`: Set expiry only when the key has an existing expiry.
- `:gt => true`: Set expiry only when the new expiry is greater than current one.
- `:lt => true`: Set expiry only when the new expiry is less than current one.

@return [Boolean] whether the timeout was set or not

# File lib/redis/commands/keys.rb, line 134
def pexpire(key, milliseconds, nx: nil, xx: nil, gt: nil, lt: nil)
  args = [:pexpire, key, Integer(milliseconds)]
  args << "NX" if nx
  args << "XX" if xx
  args << "GT" if gt
  args << "LT" if lt

  send_command(args, &Boolify)
end
pexpireat(key, ms_unix_time, nx: nil, xx: nil, gt: nil, lt: nil) click to toggle source

Set the expiration for a key as number of milliseconds from UNIX Epoch.

@param [String] key @param [Integer] ms_unix_time expiry time specified as number of milliseconds from UNIX Epoch. @param [Hash] options

- `:nx => true`: Set expiry only when the key has no expiry.
- `:xx => true`: Set expiry only when the key has an existing expiry.
- `:gt => true`: Set expiry only when the new expiry is greater than current one.
- `:lt => true`: Set expiry only when the new expiry is less than current one.

@return [Boolean] whether the timeout was set or not

# File lib/redis/commands/keys.rb, line 154
def pexpireat(key, ms_unix_time, nx: nil, xx: nil, gt: nil, lt: nil)
  args = [:pexpireat, key, Integer(ms_unix_time)]
  args << "NX" if nx
  args << "XX" if xx
  args << "GT" if gt
  args << "LT" if lt

  send_command(args, &Boolify)
end
pttl(key) click to toggle source

Get the time to live (in milliseconds) for a key.

@param [String] key @return [Integer] remaining time to live in milliseconds In Redis 2.6 or older the command returns -1 if the key does not exist or if the key exist but has no associated expire.

Starting with Redis 2.8 the return value in case of error changed:

- The command returns -2 if the key does not exist.
- The command returns -1 if the key exists but has no associated expire.
# File lib/redis/commands/keys.rb, line 175
def pttl(key)
  send_command([:pttl, key])
end
randomkey() click to toggle source

Return a random key from the keyspace.

@return [String]

# File lib/redis/commands/keys.rb, line 342
def randomkey
  send_command([:randomkey])
end
rename(old_name, new_name) click to toggle source

Rename a key. If the new key already exists it is overwritten.

@param [String] old_name @param [String] new_name @return [String] ‘OK`

# File lib/redis/commands/keys.rb, line 351
def rename(old_name, new_name)
  send_command([:rename, old_name, new_name])
end
renamenx(old_name, new_name) click to toggle source

Rename a key, only if the new key does not exist.

@param [String] old_name @param [String] new_name @return [Boolean] whether the key was renamed or not

# File lib/redis/commands/keys.rb, line 360
def renamenx(old_name, new_name)
  send_command([:renamenx, old_name, new_name], &Boolify)
end
restore(key, ttl, serialized_value, replace: nil) click to toggle source

Create a key using the serialized value, previously obtained using DUMP.

@param [String] key @param [String] ttl @param [String] serialized_value @param [Hash] options

- `:replace => Boolean`: if false, raises an error if key already exists

@raise [Redis::CommandError] @return [String] ‘“OK”`

# File lib/redis/commands/keys.rb, line 196
def restore(key, ttl, serialized_value, replace: nil)
  args = [:restore, key, ttl, serialized_value]
  args << 'REPLACE' if replace

  send_command(args)
end
scan(cursor, **options) click to toggle source

Scan the keyspace

@example Retrieve the first batch of keys

redis.scan(0)
  # => ["4", ["key:21", "key:47", "key:42"]]

@example Retrieve a batch of keys matching a pattern

redis.scan(4, :match => "key:1?")
  # => ["92", ["key:13", "key:18"]]

@example Retrieve a batch of keys of a certain type

redis.scan(92, :type => "zset")
  # => ["173", ["sortedset:14", "sortedset:78"]]

@param [String, Integer] cursor the cursor of the iteration @param [Hash] options

- `:match => String`: only return keys matching the pattern
- `:count => Integer`: return count keys at most per iteration
- `:type => String`: return keys only of the given type

@return [String, Array<String>] the next cursor and all found keys

# File lib/redis/commands/keys.rb, line 25
def scan(cursor, **options)
  _scan(:scan, cursor, [], **options)
end
scan_each(**options, &block) click to toggle source

Scan the keyspace

@example Retrieve all of the keys (with possible duplicates)

redis.scan_each.to_a
  # => ["key:21", "key:47", "key:42"]

@example Execute block for each key matching a pattern

redis.scan_each(:match => "key:1?") {|key| puts key}
  # => key:13
  # => key:18

@example Execute block for each key of a type

redis.scan_each(:type => "hash") {|key| puts redis.type(key)}
  # => "hash"
  # => "hash"

@param [Hash] options

- `:match => String`: only return keys matching the pattern
- `:count => Integer`: return count keys at most per iteration
- `:type => String`: return keys only of the given type

@return [Enumerator] an enumerator for all found keys

# File lib/redis/commands/keys.rb, line 49
def scan_each(**options, &block)
  return to_enum(:scan_each, **options) unless block_given?

  cursor = 0
  loop do
    cursor, keys = scan(cursor, **options)
    keys.each(&block)
    break if cursor == "0"
  end
end
sort(key, by: nil, limit: nil, get: nil, order: nil, store: nil) click to toggle source

Sort the elements in a list, set or sorted set.

@example Retrieve the first 2 elements from an alphabetically sorted “list”

redis.sort("list", :order => "alpha", :limit => [0, 2])
  # => ["a", "b"]

@example Store an alphabetically descending list in “target”

redis.sort("list", :order => "desc alpha", :store => "target")
  # => 26

@param [String] key @param [Hash] options

- `:by => String`: use external key to sort elements by
- `:limit => [offset, count]`: skip `offset` elements, return a maximum
of `count` elements
- `:get => [String, Array<String>]`: single key or array of keys to
retrieve per element in the result
- `:order => String`: combination of `ASC`, `DESC` and optionally `ALPHA`
- `:store => String`: key to store the result at

@return [Array<String>, Array<Array<String>>, Integer]

- when `:get` is not specified, or holds a single element, an array of elements
- when `:get` is specified, and holds more than one element, an array of
elements where every element is an array with the result for every
element specified in `:get`
- when `:store` is specified, the number of elements in the stored result
# File lib/redis/commands/keys.rb, line 389
def sort(key, by: nil, limit: nil, get: nil, order: nil, store: nil)
  args = [:sort, key]
  args << "BY" << by if by

  if limit
    args << "LIMIT"
    args.concat(limit)
  end

  get = Array(get)
  get.each do |item|
    args << "GET" << item
  end

  args.concat(order.split(" ")) if order
  args << "STORE" << store if store

  send_command(args) do |reply|
    if get.size > 1 && !store
      reply.each_slice(get.size).to_a if reply
    else
      reply
    end
  end
end
ttl(key) click to toggle source

Get the time to live (in seconds) for a key.

@param [String] key @return [Integer] remaining time to live in seconds.

In Redis 2.6 or older the command returns -1 if the key does not exist or if the key exist but has no associated expire.

Starting with Redis 2.8 the return value in case of error changed:

- The command returns -2 if the key does not exist.
- The command returns -1 if the key exists but has no associated expire.
# File lib/redis/commands/keys.rb, line 120
def ttl(key)
  send_command([:ttl, key])
end
type(key) click to toggle source

Determine the type stored at key.

@param [String] key @return [String] ‘string`, `list`, `set`, `zset`, `hash` or `none`

# File lib/redis/commands/keys.rb, line 419
def type(key)
  send_command([:type, key])
end

Private Instance Methods

_scan(command, cursor, args, match: nil, count: nil, type: nil, &block) click to toggle source
# File lib/redis/commands/keys.rb, line 425
def _scan(command, cursor, args, match: nil, count: nil, type: nil, &block)
  # SSCAN/ZSCAN/HSCAN already prepend the key to +args+.

  args << cursor
  args << "MATCH" << match if match
  args << "COUNT" << Integer(count) if count
  args << "TYPE" << type if type

  send_command([command] + args, &block)
end