module Rediska::Driver

Attributes

database_id[RW]
replies[W]

Public Instance Methods

[](key) click to toggle source
# File lib/rediska/driver.rb, line 760
def [](key)
  get(key)
end
[]=(key, value) click to toggle source
# File lib/rediska/driver.rb, line 764
def []=(key, value)
  set(key, value)
end
append(key, value) click to toggle source
# File lib/rediska/driver.rb, line 166
def append(key, value)
  data[key] = (data[key] || '')
  data[key] = data[key] + value.to_s
end
auth(password) click to toggle source
# File lib/rediska/driver.rb, line 56
def auth(password)
  'OK'
end
bgrewriteaof() click to toggle source
# File lib/rediska/driver.rb, line 82
def bgrewriteaof
end
bgsave() click to toggle source
# File lib/rediska/driver.rb, line 79
def bgsave
end
bitcount(key, start_index = 0, end_index = -1) click to toggle source
# File lib/rediska/driver.rb, line 139
def bitcount(key, start_index = 0, end_index = -1)
  return 0 unless data[key]

  data[key][start_index..end_index].unpack('B*')[0].count('1')
end
blpop(keys, timeout = 0) click to toggle source
# File lib/rediska/driver.rb, line 421
def blpop(keys, timeout = 0)
  keys = Array(keys)
  keys.each do |key|
    if data[key] && data[key].size > 0
      return [key, data[key].shift]
    end
  end
  sleep(timeout.to_f)
  nil
end
brpop(keys, timeout = 0) click to toggle source
# File lib/rediska/driver.rb, line 390
def brpop(keys, timeout = 0)
  keys = Array(keys)
  keys.each do |key|
    if data[key] && data[key].size > 0
      return [key, data[key].pop]
    end
  end
  sleep(timeout.to_f)
  nil
end
brpoplpush(key1, key2, opts = {}) click to toggle source
# File lib/rediska/driver.rb, line 408
def brpoplpush(key1, key2, opts = {})
  data_type_check(key1, Array)
  brpop(key1).tap do |elem|
    lpush(key2, elem) unless elem.nil?
  end
end
client(command, _options = {}) click to toggle source
# File lib/rediska/driver.rb, line 20
def client(command, _options = {})
  case command
  when :setname then true
  when :getname then nil
  when :client then true
  else
    raise Redis::CommandError, "ERR unknown command '#{command}'"
  end
end
connect_unix(path, timeout) click to toggle source
# File lib/rediska/driver.rb, line 14
def connect_unix(path, timeout)
end
connected?() click to toggle source
# File lib/rediska/driver.rb, line 10
def connected?
  true
end
dbsize() click to toggle source
# File lib/rediska/driver.rb, line 272
def dbsize
  data.keys.count
end
decr(key) click to toggle source
# File lib/rediska/driver.rb, line 853
def decr(key)
  data.merge!({ key => (data[key].to_i - 1).to_s || '-1'})
  data[key].to_i
end
decrby(key, by) click to toggle source
# File lib/rediska/driver.rb, line 858
def decrby(key, by)
  data.merge!({ key => ((data[key].to_i - by.to_i) || (by.to_i * -1)).to_s })
  data[key].to_i
end
del(*keys) click to toggle source
# File lib/rediska/driver.rb, line 586
def del(*keys)
  keys = keys.flatten(1)
  raise_argument_error('del') if keys.empty?

  old_count = data.keys.size
  keys.each do |key|
    data.delete(key)
  end
  old_count - data.keys.size
end
disconnect() click to toggle source
# File lib/rediska/driver.rb, line 17
def disconnect
end
dump(key) click to toggle source
# File lib/rediska/driver.rb, line 94
def dump(key)
  return nil unless exists(key)

  Marshal.dump(value: data[key], version: Rediska::VERSION)
end
echo(string) click to toggle source
# File lib/rediska/driver.rb, line 255
def echo(string)
  string
end
exists(key) click to toggle source
# File lib/rediska/driver.rb, line 276
def exists(key)
  data.key?(key)
end
expire(key, ttl) click to toggle source
# File lib/rediska/driver.rb, line 622
def expire(key, ttl)
  return 0 unless data[key]
  data.expires[key] = Time.now + ttl
  1
end
expireat(key, timestamp) click to toggle source
# File lib/rediska/driver.rb, line 652
def expireat(key, timestamp)
  data.expires[key] = Time.at(timestamp)
  true
end
flushall() click to toggle source
# File lib/rediska/driver.rb, line 49
def flushall
  db_class.flushall(database_instance_key)
  self.class.databases[database_instance_key] = []

  'OK'
end
flushdb() click to toggle source

NOT IMPLEMENTED:

  • subscribe

  • psubscribe

  • publish

# File lib/rediska/driver.rb, line 42
def flushdb
  db_class.flushdb(database_instance_key, database_id)
  databases.delete_at(database_id)

  'OK'
end
get(key) click to toggle source
# File lib/rediska/driver.rb, line 129
def get(key)
  data_type_check(key, String)
  data[key]
end
getbit(key, offset) click to toggle source
# File lib/rediska/driver.rb, line 134
def getbit(key, offset)
  return unless data[key]
  data[key].unpack('B*')[0].split('')[offset].to_i
end
getrange(key, start, ending) click to toggle source
# File lib/rediska/driver.rb, line 145
def getrange(key, start, ending)
  return unless data[key]
  data[key][start..ending]
end
Also aliased as: substr
getset(key, value) click to toggle source
# File lib/rediska/driver.rb, line 151
def getset(key, value)
  data_type_check(key, String)
  data[key].tap do
    set(key, value)
  end
end
hdel(key, field) click to toggle source
# File lib/rediska/driver.rb, line 186
def hdel(key, field)
  data_type_check(key, Hash)
  return 0 unless data[key]

  if field.is_a?(Array)
    old_keys_count = data[key].size
    fields = field.map(&:to_s)

    data[key].delete_if { |k, v| fields.include? k }
    deleted = old_keys_count - data[key].size
  else
    field = field.to_s
    deleted = data[key].delete(field) ? 1 : 0
  end

  remove_key_for_empty_collection(key)
  deleted
end
hexists(key, field) click to toggle source
# File lib/rediska/driver.rb, line 752
def hexists(key, field)
  data_type_check(key, Hash)
  return false unless data[key]
  data[key].key?(field.to_s)
end
hget(key, field) click to toggle source
# File lib/rediska/driver.rb, line 181
def hget(key, field)
  data_type_check(key, Hash)
  data[key] && data[key][field.to_s]
end
hgetall(key) click to toggle source
# File lib/rediska/driver.rb, line 176
def hgetall(key)
  data_type_check(key, Hash)
  data[key].to_a.flatten || {}
end
hincrby(key, field, increment) click to toggle source
# File lib/rediska/driver.rb, line 730
def hincrby(key, field, increment)
  data_type_check(key, Hash)
  field = field.to_s
  if data[key]
    data[key][field] = (data[key][field].to_i + increment.to_i).to_s
  else
    data[key] = { field => increment.to_s }
  end
  data[key][field].to_i
end
hincrbyfloat(key, field, increment) click to toggle source
# File lib/rediska/driver.rb, line 741
def hincrbyfloat(key, field, increment)
  data_type_check(key, Hash)
  field = field.to_s
  if data[key]
    data[key][field] = (data[key][field].to_f + increment.to_f).to_s
  else
    data[key] = { field => increment.to_s }
  end
  data[key][field]
end
hkeys(key) click to toggle source
# File lib/rediska/driver.rb, line 205
def hkeys(key)
  data_type_check(key, Hash)
  return [] if data[key].nil?
  data[key].keys
end
hlen(key) click to toggle source
# File lib/rediska/driver.rb, line 718
def hlen(key)
  data_type_check(key, Hash)
  return 0 unless data[key]
  data[key].size
end
hmget(key, *fields) click to toggle source
# File lib/rediska/driver.rb, line 704
def hmget(key, *fields)
  raise_argument_error('hmget') if fields.empty?

  data_type_check(key, Hash)
  fields.flatten.map do |field|
    field = field.to_s
    if data[key]
      data[key][field]
    else
      nil
    end
  end
end
hmset(key, *fields) click to toggle source
# File lib/rediska/driver.rb, line 681
def hmset(key, *fields)
  fields = fields[0] if mapped_param?(fields)
  raise_argument_error('hmset') if fields.empty?

  is_list_of_arrays = fields.all?{|field| field.instance_of?(Array)}

  raise_argument_error('hmset') if fields.size.odd? and !is_list_of_arrays
  raise_argument_error('hmset') if is_list_of_arrays and !fields.all?{|field| field.length == 2}

  data_type_check(key, Hash)
  data[key] ||= {}

  if is_list_of_arrays
    fields.each do |pair|
      data[key][pair[0].to_s] = pair[1].to_s
    end
  else
    fields.each_slice(2) do |field|
      data[key][field[0].to_s] = field[1].to_s
    end
  end
end
hscan(key, start_cursor, *args) click to toggle source
# File lib/rediska/driver.rb, line 211
def hscan(key, start_cursor, *args)
  data_type_check(key, Hash)
  return ['0', []] unless data[key]

  match = '*'
  count = 10

  raise_argument_error('hscan') if args.size.odd?

  if idx = args.index('MATCH')
    match = args[idx + 1]
  end

  if idx = args.index('COUNT')
    count = args[idx + 1]
  end

  start_cursor = start_cursor.to_i

  cursor = start_cursor
  next_keys = []

  if start_cursor + count >= data[key].length
    next_keys = (data[key].to_a)[start_cursor..-1]
    cursor = 0
  else
    cursor = start_cursor + count
    next_keys = (data[key].to_a)[start_cursor..cursor-1]
  end

  filtered_next_keys = next_keys.select{|k,v| File.fnmatch(match, k)}
  result = filtered_next_keys.flatten.map(&:to_s)

  return ["#{cursor}", result]
end
hset(key, field, value) click to toggle source
# File lib/rediska/driver.rb, line 661
def hset(key, field, value)
  data_type_check(key, Hash)
  field = field.to_s
  if data[key]
    result = !data[key].include?(field)
    data[key][field] = value.to_s
    result
  else
    data[key] = { field => value.to_s }
    true
  end
end
hsetnx(key, field, value) click to toggle source
# File lib/rediska/driver.rb, line 674
def hsetnx(key, field, value)
  data_type_check(key, Hash)
  field = field.to_s
  return false if data[key] && data[key][field]
  hset(key, field, value)
end
hvals(key) click to toggle source
# File lib/rediska/driver.rb, line 724
def hvals(key)
  data_type_check(key, Hash)
  return [] unless data[key]
  data[key].values
end
incr(key) click to toggle source
# File lib/rediska/driver.rb, line 838
def incr(key)
  data.merge!({ key => (data[key].to_i + 1).to_s || '1'})
  data[key].to_i
end
incrby(key, by) click to toggle source
# File lib/rediska/driver.rb, line 843
def incrby(key, by)
  data.merge!({ key => (data[key].to_i + by.to_i).to_s || by })
  data[key].to_i
end
incrbyfloat(key, by) click to toggle source
# File lib/rediska/driver.rb, line 848
def incrbyfloat(key, by)
  data.merge!({ key => (data[key].to_f + by.to_f).to_s || by })
  data[key]
end
info() click to toggle source
# File lib/rediska/driver.rb, line 67
def info
  {
    'redis_version' => '3.0.5',
  }
end
keys(pattern = '*') click to toggle source
# File lib/rediska/driver.rb, line 247
def keys(pattern = '*')
  data.keys.select { |key| File.fnmatch(pattern, key) }
end
lastsave() click to toggle source
# File lib/rediska/driver.rb, line 263
def lastsave
  Time.now.to_i
end
lindex(key, index) click to toggle source
# File lib/rediska/driver.rb, line 305
def lindex(key, index)
  data_type_check(key, Array)
  data[key] && data[key][index]
end
linsert(key, where, pivot, value) click to toggle source
# File lib/rediska/driver.rb, line 310
def linsert(key, where, pivot, value)
  data_type_check(key, Array)
  return unless data[key]
  index = data[key].index(pivot)
  case where
    when :before then data[key].insert(index, value)
    when :after  then data[key].insert(index + 1, value)
    else raise_syntax_error
  end
end
llen(key) click to toggle source
# File lib/rediska/driver.rb, line 280
def llen(key)
  data_type_check(key, Array)
  return 0 unless data[key]
  data[key].size
end
lpop(key) click to toggle source
# File lib/rediska/driver.rb, line 415
def lpop(key)
  data_type_check(key, Array)
  return unless data[key]
  data[key].shift
end
lpush(key, value) click to toggle source
# File lib/rediska/driver.rb, line 365
def lpush(key, value)
  raise_argument_error('lpush') if value.respond_to?(:each) && value.empty?

  data_type_check(key, Array)
  data[key] ||= []
  [value].flatten.each do |val|
    data[key].unshift(val.to_s)
  end
  data[key].size
end
lpushx(key, value) click to toggle source
# File lib/rediska/driver.rb, line 376
def lpushx(key, value)
  raise_argument_error('lpushx') if value.respond_to?(:each) && value.empty?

  data_type_check(key, Array)
  return unless data[key]
  lpush(key, value)
end
lrange(key, startidx, endidx) click to toggle source
# File lib/rediska/driver.rb, line 286
def lrange(key, startidx, endidx)
  data_type_check(key, Array)
  (data[key] && data[key][startidx..endidx]) || []
end
lrem(key, count, value) click to toggle source
# File lib/rediska/driver.rb, line 328
def lrem(key, count, value)
  data_type_check(key, Array)
  return 0 unless data[key]
  old_size = data[key].size
  diff =
    if count == 0
      data[key].delete(value)
      old_size - data[key].size
    else
      array = count > 0 ? data[key].dup : data[key].reverse
      count.abs.times{ array.delete_at(array.index(value) || array.length) }
      data[key] = count > 0 ? array.dup : array.reverse
      old_size - data[key].size
    end
  remove_key_for_empty_collection(key)
  diff
end
lset(key, index, value) click to toggle source
# File lib/rediska/driver.rb, line 321
def lset(key, index, value)
  data_type_check(key, Array)
  return unless data[key]
  raise Redis::CommandError, 'ERR index out of range' if index >= data[key].size
  data[key][index] = value
end
ltrim(key, start, stop) click to toggle source
# File lib/rediska/driver.rb, line 291
def ltrim(key, start, stop)
  data_type_check(key, Array)
  return unless data[key]

  # Example: we have a list of 3 elements and we give it a ltrim list, -5, -1. This means it
  # should trim to a max of 5. Since 3 < 5 we should not touch the list. This is consistent
  # with behavior of real Redis's ltrim with a negative start argument.
  unless start < 0 && data[key].count < start.abs
    data[key] = data[key][start..stop]
  end

  'OK'
end
mget(*keys) click to toggle source
# File lib/rediska/driver.rb, line 158
def mget(*keys)
  raise_argument_error('mget') if keys.empty?

  # We work with either an array, or list of arguments
  keys = keys.first if keys.size == 1
  data.values_at(*keys)
end
monitor() click to toggle source
# File lib/rediska/driver.rb, line 73
def monitor
end
move(key, destination_id) click to toggle source
# File lib/rediska/driver.rb, line 85
def move(key, destination_id)
  raise Redis::CommandError, 'ERR source and destination objects are the same' if destination_id == database_id
  destination = find_database(destination_id)
  return false unless data.has_key?(key)
  return false if destination.has_key?(key)
  destination[key] = data.delete(key)
  true
end
mset(*pairs) click to toggle source
# File lib/rediska/driver.rb, line 813
def mset(*pairs)
  # Handle pairs for mapped_mset command
  pairs = pairs[0] if mapped_param?(pairs)
  raise_argument_error('mset') if pairs.empty? || pairs.size == 1
  # We have to reply with a different error message here to be consistent with
  # redis-rb 3.0.6 / redis-server 2.8.1.
  raise_argument_error('mset', 'mset_odd') if pairs.size.odd?

  pairs.each_slice(2) do |pair|
    data[pair[0].to_s] = pair[1].to_s
  end

  'OK'
end
msetnx(*pairs) click to toggle source
# File lib/rediska/driver.rb, line 828
def msetnx(*pairs)
  # Handle pairs for mapped_msetnx command
  pairs = pairs[0] if mapped_param?(pairs)
  keys = []
  pairs.each_with_index{|item, index| keys << item.to_s if index % 2 == 0}
  return false if keys.any?{|key| data.key?(key) }
  mset(*pairs)
  true
end
persist(key) click to toggle source
# File lib/rediska/driver.rb, line 657
def persist(key)
  !!data.expires.delete(key)
end
pexpire(key, ttl) click to toggle source
# File lib/rediska/driver.rb, line 628
def pexpire(key, ttl)
  return 0 unless data[key]

  data.expires[key] = Time.now + (ttl / 1000.0)

  1
end
ping() click to toggle source
# File lib/rediska/driver.rb, line 259
def ping
  'PONG'
end
pttl(key) click to toggle source
# File lib/rediska/driver.rb, line 644
def pttl(key)
  if data.expires.include?(key) && (ttl = data.expires[key].to_f - Time.now.to_f) > 0
    ttl * 1000
  else
    exists(key) ? -1 : -2
  end
end
quit() click to toggle source
# File lib/rediska/driver.rb, line 874
def quit
end
randomkey() click to toggle source
# File lib/rediska/driver.rb, line 251
def randomkey
  data.keys[rand(dbsize)]
end
read() click to toggle source
# File lib/rediska/driver.rb, line 33
def read
  replies.shift
end
rename(key, new_key) click to toggle source
# File lib/rediska/driver.rb, line 606
def rename(key, new_key)
  return unless data[key]
  data[new_key] = data[key]
  data.expires[new_key] = data.expires[key] if data.expires.include?(key)
  data.delete(key)
end
renamenx(key, new_key) click to toggle source
# File lib/rediska/driver.rb, line 613
def renamenx(key, new_key)
  if exists(new_key)
    false
  else
    rename(key, new_key)
    true
  end
end
replies() click to toggle source
# File lib/rediska/driver.rb, line 6
def replies
  @replies ||= []
end
restore(key, ttl, serialized_value) click to toggle source
# File lib/rediska/driver.rb, line 100
def restore(key, ttl, serialized_value)
  raise Redis::CommandError, 'ERR Target key name is busy.' if exists(key)

  if serialized_value.nil?
    raise Redis::CommandError, 'ERR DUMP payload version or checksum are wrong'
  end

  parsed_value = begin
    Marshal.load(serialized_value)
  rescue TypeError
    raise Redis::CommandError, 'ERR DUMP payload version or checksum are wrong'
  end

  if parsed_value[:version] != Rediska::VERSION
    raise Redis::CommandError, 'ERR DUMP payload version or checksum are wrong'
  end

  # We could figure out what type the key was and set it with the public API here, or we could
  # just assign the value. If we presume the serialized_value is only ever a return value from
  # `dump` then we've only been given something that was in the internal data structure anyway.
  data[key] = parsed_value[:value]

  # Set a TTL if one has been passed
  ttl = ttl.to_i # Makes nil into 0
  expire(key, ttl / 1000) unless ttl.zero?

  'OK'
end
rpop(key) click to toggle source
# File lib/rediska/driver.rb, line 384
def rpop(key)
  data_type_check(key, Array)
  return unless data[key]
  data[key].pop
end
rpoplpush(key1, key2) click to toggle source
# File lib/rediska/driver.rb, line 401
def rpoplpush(key1, key2)
  data_type_check(key1, Array)
  rpop(key1).tap do |elem|
    lpush(key2, elem) unless elem.nil?
  end
end
rpush(key, value) click to toggle source
# File lib/rediska/driver.rb, line 346
def rpush(key, value)
  raise_argument_error('rpush') if value.respond_to?(:each) && value.empty?

  data_type_check(key, Array)
  data[key] ||= []
  [value].flatten.each do |val|
    data[key].push(val.to_s)
  end
  data[key].size
end
rpushx(key, value) click to toggle source
# File lib/rediska/driver.rb, line 357
def rpushx(key, value)
  raise_argument_error('rpushx') if value.respond_to?(:each) && value.empty?

  data_type_check(key, Array)
  return unless data[key]
  rpush(key, value)
end
sadd(key, value) click to toggle source
# File lib/rediska/driver.rb, line 444
def sadd(key, value)
  data_type_check(key, ::Set)
  value = Array(value)
  raise_argument_error('sadd') if value.empty?

  result = if data[key]
    old_set = data[key].dup
    data[key].merge(value.map(&:to_s))
    (data[key] - old_set).size
  else
    data[key] = ::Set.new(value.map(&:to_s))
    data[key].size
  end

  # 0 = false, 1 = true, 2+ untouched
  return result == 1 if result < 2
  result
end
save() click to toggle source
# File lib/rediska/driver.rb, line 76
def save
end
scan(start_cursor, *args) click to toggle source
# File lib/rediska/driver.rb, line 883
def scan(start_cursor, *args)
  match = '*'
  count = 10

  if args.size.odd?
    raise_argument_error('scan')
  end

  if idx = args.index('MATCH')
    match = args[idx + 1]
  end

  if idx = args.index('COUNT')
    count = args[idx + 1]
  end

  start_cursor = start_cursor.to_i
  data_type_check(start_cursor, Integer)

  cursor = start_cursor
  next_keys = []

  if start_cursor + count >= data.length
    next_keys = keys(match)[start_cursor..-1]
    cursor = 0
  else
    cursor = start_cursor + 10
    next_keys = keys(match)[start_cursor..cursor]
  end

  return "#{cursor}", next_keys
end
scard(key) click to toggle source
# File lib/rediska/driver.rb, line 493
def scard(key)
  data_type_check(key, ::Set)
  return 0 unless data[key]
  data[key].size
end
sdiff(key1, *keys) click to toggle source
# File lib/rediska/driver.rb, line 530
def sdiff(key1, *keys)
  [key1, *keys].each { |k| data_type_check(k, ::Set) }
  keys = keys.map { |k| data[k] || ::Set.new }
  keys.inject(data[key1] || Set.new) do |memo, set|
    memo - set
  end.to_a
end
sdiffstore(destination, key1, *keys) click to toggle source
# File lib/rediska/driver.rb, line 538
def sdiffstore(destination, key1, *keys)
  data_type_check(destination, ::Set)
  result = sdiff(key1, *keys)
  data[destination] = ::Set.new(result)
end
select(index) click to toggle source
# File lib/rediska/driver.rb, line 60
def select(index)
  data_type_check(index, Integer)
  self.database_id = index

  'OK'
end
set(key, value, *array_options) click to toggle source
# File lib/rediska/driver.rb, line 768
def set(key, value, *array_options)
  option_nx = array_options.delete('NX')
  option_xx = array_options.delete('XX')

  return false if option_nx && option_xx

  return false if option_nx && exists(key)
  return false if option_xx && !exists(key)

  data[key] = value.to_s

  options = Hash[array_options.each_slice(2).to_a]
  ttl_in_seconds = options['EX'] if options['EX']
  ttl_in_seconds = options['PX'] / 1000.0 if options['PX']

  expire(key, ttl_in_seconds) if ttl_in_seconds

  'OK'
end
setbit(key, offset, bit) click to toggle source
# File lib/rediska/driver.rb, line 788
def setbit(key, offset, bit)
  old_val = data[key] ? data[key].unpack('B*')[0].split('') : []
  size_increment = [((offset/8)+1)*8-old_val.length, 0].max
  old_val += Array.new(size_increment).map{'0'}
  original_val = old_val[offset].to_i
  old_val[offset] = bit.to_s
  new_val = ''
  old_val.each_slice(8){|b| new_val = new_val + b.join('').to_i(2).chr }
  data[key] = new_val
  original_val
end
setex(key, seconds, value) click to toggle source
# File lib/rediska/driver.rb, line 800
def setex(key, seconds, value)
  data[key] = value.to_s
  expire(key, seconds)

  'OK'
end
setnx(key, value) click to toggle source
# File lib/rediska/driver.rb, line 597
def setnx(key, value)
  if exists(key)
    0
  else
    set(key, value)
    1
  end
end
setrange(key, offset, value) click to toggle source
# File lib/rediska/driver.rb, line 807
def setrange(key, offset, value)
  return unless data[key]
  s = data[key][offset,value.size]
  data[key][s] = value
end
shutdown() click to toggle source
# File lib/rediska/driver.rb, line 877
def shutdown
end
sinter(*keys) click to toggle source
# File lib/rediska/driver.rb, line 499
def sinter(*keys)
  raise_argument_error('sinter') if keys.empty?

  keys.each { |k| data_type_check(k, ::Set) }
  return ::Set.new if keys.any? { |k| data[k].nil? }
  keys = keys.map { |k| data[k] || ::Set.new }
  keys.inject do |set, key|
    set & key
  end.to_a
end
sinterstore(destination, *keys) click to toggle source
# File lib/rediska/driver.rb, line 510
def sinterstore(destination, *keys)
  data_type_check(destination, ::Set)
  result = sinter(*keys)
  data[destination] = ::Set.new(result)
end
sismember(key, value) click to toggle source
# File lib/rediska/driver.rb, line 438
def sismember(key, value)
  data_type_check(key, ::Set)
  return false unless data[key]
  data[key].include?(value.to_s)
end
slaveof(host, port) click to toggle source
# File lib/rediska/driver.rb, line 880
def slaveof(host, port)
end
smembers(key) click to toggle source
# File lib/rediska/driver.rb, line 432
def smembers(key)
  data_type_check(key, ::Set)
  return [] unless data[key]
  data[key].to_a.reverse
end
smove(source, destination, value) click to toggle source
# File lib/rediska/driver.rb, line 479
def smove(source, destination, value)
  data_type_check(destination, ::Set)
  result = self.srem(source, value)
  self.sadd(destination, value) if result
  result
end
spop(key) click to toggle source
# File lib/rediska/driver.rb, line 486
def spop(key)
  data_type_check(key, ::Set)
  elem = srandmember(key)
  srem(key, elem)
  elem
end
srandmember(key, number = nil) click to toggle source
# File lib/rediska/driver.rb, line 544
def srandmember(key, number = nil)
  number.nil? ? srandmember_single(key) : srandmember_multiple(key, number)
end
srem(key, value) click to toggle source
# File lib/rediska/driver.rb, line 463
def srem(key, value)
  data_type_check(key, ::Set)
  return false unless data[key]

  if value.is_a?(Array)
    old_size = data[key].size
    value.map(&:to_s).each { |v| data[key].delete(v) }
    deleted = old_size - data[key].size
  else
    deleted = !!data[key].delete?(value.to_s)
  end

  remove_key_for_empty_collection(key)
  deleted
end
sscan(key, start_cursor, *args) click to toggle source
# File lib/rediska/driver.rb, line 548
def sscan(key, start_cursor, *args)
  data_type_check(key, ::Set)
  return ['0', []] unless data[key]

  match = '*'
  count = 10

  if args.size.odd?
    raise_argument_error('sscan')
  end

  if idx = args.index('MATCH')
    match = args[idx + 1]
  end

  if idx = args.index('COUNT')
    count = args[idx + 1]
  end

  start_cursor = start_cursor.to_i

  cursor = start_cursor
  next_keys = []

  if start_cursor + count >= data[key].length
    next_keys = (data[key].to_a)[start_cursor..-1]
    cursor = 0
  else
    cursor = start_cursor + count
    next_keys = (data[key].to_a)[start_cursor..cursor-1]
  end

  filtered_next_keys = next_keys.select{ |k,v| File.fnmatch(match, k)}
  result = filtered_next_keys.flatten.map(&:to_s)

  return ["#{cursor}", result]
end
strlen(key) click to toggle source
# File lib/rediska/driver.rb, line 171
def strlen(key)
  return unless data[key]
  data[key].size
end
substr(key, start, ending)
Alias for: getrange
sunion(*keys) click to toggle source
# File lib/rediska/driver.rb, line 516
def sunion(*keys)
  keys.each { |k| data_type_check(k, ::Set) }
  keys = keys.map { |k| data[k] || ::Set.new }
  keys.inject(::Set.new) do |set, key|
    set | key
  end.to_a
end
sunionstore(destination, *keys) click to toggle source
# File lib/rediska/driver.rb, line 524
def sunionstore(destination, *keys)
  data_type_check(destination, ::Set)
  result = sunion(*keys)
  data[destination] = ::Set.new(result)
end
sync() click to toggle source
# File lib/rediska/driver.rb, line 758
def sync ; end
time() click to toggle source
# File lib/rediska/driver.rb, line 267
def time
  microseconds = (Time.now.to_f * 1000000).to_i
  [microseconds / 1000000, microseconds % 1000000]
end
timeout=(usecs) click to toggle source
# File lib/rediska/driver.rb, line 30
def timeout=(usecs)
end
ttl(key) click to toggle source
# File lib/rediska/driver.rb, line 636
def ttl(key)
  if data.expires.include?(key) && (ttl = data.expires[key].to_i - Time.now.to_i) > 0
    ttl
  else
    exists(key) ? -1 : -2
  end
end
type(key) click to toggle source
# File lib/rediska/driver.rb, line 863
def type(key)
  case data[key]
    when nil then 'none'
    when String then 'string'
    when ZSet then 'zset'
    when Hash then 'hash'
    when Array then 'list'
    when ::Set then 'set'
  end
end
zadd(key, *args) click to toggle source
# File lib/rediska/driver.rb, line 916
def zadd(key, *args)
  if !args.first.is_a?(Array)
    if args.size < 2
      raise_argument_error('zadd')
    elsif args.size.odd?
      raise_syntax_error
    end
  else
    unless args.all? {|pair| pair.size == 2 }
      raise_syntax_error
    end
  end

  data_type_check(key, ZSet)
  data[key] ||= ZSet.new

  if args.size == 2 && !(Array === args.first)
    score, value = args
    exists = !data[key].key?(value.to_s)
    data[key][value.to_s] = score
  else
    # Turn [1, 2, 3, 4] into [[1, 2], [3, 4]] unless it is already
    args = args.each_slice(2).to_a unless args.first.is_a?(Array)
    exists = args.map(&:last).map { |el| data[key].key?(el.to_s) }.count(false)
    args.each { |s, v| data[key][v.to_s] = s }
  end

  exists
end
zcard(key) click to toggle source
# File lib/rediska/driver.rb, line 959
def zcard(key)
  data_type_check(key, ZSet)
  data[key] ? data[key].size : 0
end
zcount(key, min, max) click to toggle source
# File lib/rediska/driver.rb, line 970
def zcount(key, min, max)
  data_type_check(key, ZSet)
  return 0 unless data[key]
  data[key].select_by_score(min, max).size
end
zincrby(key, num, value) click to toggle source
# File lib/rediska/driver.rb, line 976
def zincrby(key, num, value)
  data_type_check(key, ZSet)
  data[key] ||= ZSet.new
  data[key][value.to_s] ||= 0
  data[key].increment(value.to_s, num)
  data[key][value.to_s].to_s
end
zinterstore(out, *args) click to toggle source
# File lib/rediska/driver.rb, line 1075
def zinterstore(out, *args)
  data_type_check(out, ZSet)
  args_handler = SortedSetArgumentHandler.new(args)
  data[out] = SortedSetIntersectStore.new(args_handler, data).call
  data[out].size
end
zrange(key, start, stop, with_scores = nil) click to toggle source
# File lib/rediska/driver.rb, line 998
def zrange(key, start, stop, with_scores = nil)
  data_type_check(key, ZSet)
  return [] unless data[key]

  results = sort_keys(data[key])

  # Select just the keys unless we want scores
  results = results.map(&:first) unless with_scores
  results[start..stop].flatten.map(&:to_s)
end
zrangebyscore(key, min, max, *opts) click to toggle source
# File lib/rediska/driver.rb, line 1020
def zrangebyscore(key, min, max, *opts)
  data_type_check(key, ZSet)
  return [] unless data[key]

  range = data[key].select_by_score(min, max)
  vals = if opts.include?('WITHSCORES')
    range.sort_by {|_,v| v }
  else
    range.keys.sort_by {|k| range[k] }
  end

  limit = get_limit(opts, vals)
  vals = vals[*limit] if limit

  vals.flatten.map(&:to_s)
end
zrank(key, value) click to toggle source
# File lib/rediska/driver.rb, line 984
def zrank(key, value)
  data_type_check(key, ZSet)
  z = data[key]
  return unless z
  z.keys.sort_by {|k| z[k] }.index(value.to_s)
end
zrem(key, value) click to toggle source
# File lib/rediska/driver.rb, line 946
def zrem(key, value)
  data_type_check(key, ZSet)
  values = Array(value)
  return 0 unless data[key]

  response = values.map do |v|
    data[key].delete(v.to_s) if data[key].has_key?(v.to_s)
  end.compact.size

  remove_key_for_empty_collection(key)
  response
end
zremrangebyrank(key, start, stop) click to toggle source
# File lib/rediska/driver.rb, line 1064
def zremrangebyrank(key, start, stop)
  data_type_check(key, ZSet)
  return 0 unless data[key]

  sorted_elements = data[key].sort_by { |k, v| v }
  start = sorted_elements.length if start > sorted_elements.length
  elements_to_delete = sorted_elements[start..stop]
  elements_to_delete.each { |elem, rank| data[key].delete(elem) }
  elements_to_delete.size
end
zremrangebyscore(key, min, max) click to toggle source
# File lib/rediska/driver.rb, line 1055
def zremrangebyscore(key, min, max)
  data_type_check(key, ZSet)
  return 0 unless data[key]

  range = data[key].select_by_score(min, max)
  range.each {|k,_| data[key].delete(k) }
  range.size
end
zrevrange(key, start, stop, with_scores = nil) click to toggle source
# File lib/rediska/driver.rb, line 1009
def zrevrange(key, start, stop, with_scores = nil)
  data_type_check(key, ZSet)
  return [] unless data[key]

  if with_scores
    data[key].sort_by {|_,v| -v }
  else
    data[key].keys.sort_by {|k| -data[key][k] }
  end[start..stop].flatten.map(&:to_s)
end
zrevrangebyscore(key, max, min, *opts) click to toggle source
# File lib/rediska/driver.rb, line 1037
def zrevrangebyscore(key, max, min, *opts)
  opts = opts.flatten
  data_type_check(key, ZSet)
  return [] unless data[key]

  range = data[key].select_by_score(min, max)
  vals = if opts.include?('WITHSCORES')
    range.sort_by {|_,v| -v }
  else
    range.keys.sort_by {|k| -range[k] }
  end

  limit = get_limit(opts, vals)
  vals = vals[*limit] if limit

  vals.flatten.map(&:to_s)
end
zrevrank(key, value) click to toggle source
# File lib/rediska/driver.rb, line 991
def zrevrank(key, value)
  data_type_check(key, ZSet)
  z = data[key]
  return unless z
  z.keys.sort_by {|k| -z[k] }.index(value.to_s)
end
zscan(key, start_cursor, *args) click to toggle source
# File lib/rediska/driver.rb, line 1089
def zscan(key, start_cursor, *args)
  data_type_check(key, ZSet)
  return [] unless data[key]

  match = '*'
  count = 10

  if args.size.odd?
    raise_argument_error('zscan')
  end

  if idx = args.index('MATCH')
    match = args[idx + 1]
  end

  if idx = args.index('COUNT')
    count = args[idx + 1]
  end

  start_cursor = start_cursor.to_i
  data_type_check(start_cursor, Integer)

  cursor = start_cursor
  next_keys = []

  sorted_keys = sort_keys(data[key])

  if start_cursor + count >= sorted_keys.length
    next_keys = sorted_keys.to_a.select { |k| File.fnmatch(match, k[0]) } [start_cursor..-1]
    cursor = 0
  else
   cursor = start_cursor + count
   next_keys = sorted_keys.to_a.select { |k| File.fnmatch(match, k[0]) } [start_cursor..cursor-1]
  end

  return "#{cursor}", next_keys.flatten.map(&:to_s)
end
zscan_each(key, *args, &block) click to toggle source

Originally from redis-rb

# File lib/rediska/driver.rb, line 1128
def zscan_each(key, *args, &block)
  data_type_check(key, ZSet)
  return [] unless data[key]

  return to_enum(:zscan_each, key, options) unless block_given?
  cursor = 0
  loop do
    cursor, values = zscan(key, cursor, options)
    values.each(&block)
    break if cursor == '0'
  end
end
zscore(key, value) click to toggle source
# File lib/rediska/driver.rb, line 964
def zscore(key, value)
  data_type_check(key, ZSet)
  value = data[key] && data[key][value.to_s]
  value && value.to_s
end
zunionstore(out, *args) click to toggle source
# File lib/rediska/driver.rb, line 1082
def zunionstore(out, *args)
  data_type_check(out, ZSet)
  args_handler = SortedSetArgumentHandler.new(args)
  data[out] = SortedSetUnionStore.new(args_handler, data).call
  data[out].size
end

Private Instance Methods

data_type_check(key, klass) click to toggle source
# File lib/rediska/driver.rb, line 1160
def data_type_check(key, klass)
  if data[key] && !data[key].is_a?(klass)
    raise Redis::CommandError.new('WRONGTYPE Operation against a key holding the wrong kind of value')
  end
end
get_limit(opts, vals) click to toggle source
# File lib/rediska/driver.rb, line 1166
def get_limit(opts, vals)
  index = opts.index('LIMIT')

  if index
    offset = opts[index + 1]

    count = opts[index + 2]
    count = vals.size if count < 0

    [offset, count]
  end
end
mapped_param?(param) click to toggle source
# File lib/rediska/driver.rb, line 1179
def mapped_param? param
  param.size == 1 && param[0].is_a?(Array)
end
raise_argument_error(command, match_string = command) click to toggle source
# File lib/rediska/driver.rb, line 1142
def raise_argument_error(command, match_string = command)
  error_message = if %w(hmset mset_odd).include?(match_string.downcase)
    "ERR wrong number of arguments for #{command.upcase}"
  else
    "ERR wrong number of arguments for '#{command}' command"
  end

  raise Redis::CommandError, error_message
end
raise_syntax_error() click to toggle source
# File lib/rediska/driver.rb, line 1152
def raise_syntax_error
  raise Redis::CommandError, 'ERR syntax error'
end
remove_key_for_empty_collection(key) click to toggle source
# File lib/rediska/driver.rb, line 1156
def remove_key_for_empty_collection(key)
  del(key) if data[key] && data[key].empty?
end
sort_keys(arr) click to toggle source
# File lib/rediska/driver.rb, line 1198
def sort_keys(arr)
  # Sort by score, or if scores are equal, key alphanum
  arr.sort do |(k1, v1), (k2, v2)|
    if v1 == v2
      k1 <=> k2
    else
      v1 <=> v2
    end
  end
end
srandmember_multiple(key, number) click to toggle source
# File lib/rediska/driver.rb, line 1189
def srandmember_multiple(key, number)
  return [] unless data[key]
  if number >= 0
    data[key].to_a.sample(number)
  else
    (1..-number).map { data[key].to_a[rand(data[key].size)] }.flatten
  end
end
srandmember_single(key) click to toggle source
# File lib/rediska/driver.rb, line 1183
def srandmember_single(key)
  data_type_check(key, ::Set)
  return nil unless data[key]
  data[key].to_a[rand(data[key].size)]
end