class MockRedis::Database
Attributes
data[R]
expire_times[R]
Public Class Methods
new(base, *_args)
click to toggle source
# File lib/mock_redis/database.rb, line 32 def initialize(base, *_args) @base = base @data = MockRedis::IndifferentHash.new @expire_times = [] end
Public Instance Methods
auth(_)
click to toggle source
Redis commands go below this line and above 'private'
# File lib/mock_redis/database.rb, line 46 def auth(_) 'OK' end
bgrewriteaof()
click to toggle source
# File lib/mock_redis/database.rb, line 50 def bgrewriteaof 'Background append only file rewriting started' end
bgsave()
click to toggle source
# File lib/mock_redis/database.rb, line 54 def bgsave 'Background saving started' end
connected?()
click to toggle source
# File lib/mock_redis/database.rb, line 64 def connected? true end
dbsize()
click to toggle source
# File lib/mock_redis/database.rb, line 68 def dbsize data.keys.length end
del(*keys)
click to toggle source
# File lib/mock_redis/database.rb, line 72 def del(*keys) keys = keys.flatten.map(&:to_s) assert_has_args(keys, 'del') keys. find_all { |key| data[key] }. each { |k| persist(k) }. each { |k| data.delete(k) }. length end
Also aliased as: unlink
disconnect()
click to toggle source
# File lib/mock_redis/database.rb, line 58 def disconnect nil end
Also aliased as: close
dump(key)
click to toggle source
# File lib/mock_redis/database.rb, line 134 def dump(key) value = data[key] value ? Marshal.dump(value) : nil end
echo(msg)
click to toggle source
# File lib/mock_redis/database.rb, line 84 def echo(msg) msg.to_s end
eval(*args)
click to toggle source
# File lib/mock_redis/database.rb, line 279 def eval(*args); end
evalsha(*args)
click to toggle source
# File lib/mock_redis/database.rb, line 277 def evalsha(*args); end
exists(*keys)
click to toggle source
# File lib/mock_redis/database.rb, line 120 def exists(*keys) keys.count { |key| data.key?(key) } end
exists?(*keys)
click to toggle source
# File lib/mock_redis/database.rb, line 124 def exists?(*keys) keys.each { |key| return true if data.key?(key) } false end
expire(key, seconds)
click to toggle source
# File lib/mock_redis/database.rb, line 88 def expire(key, seconds) pexpire(key, seconds.to_i * 1000) end
expire_keys()
click to toggle source
This method isn't private, but it also isn't a Redis command, so it doesn't belong up above with all the Redis commands.
# File lib/mock_redis/database.rb, line 360 def expire_keys now_sec, miliseconds = now now_ms = now_sec * 1_000 + miliseconds to_delete = expire_times.take_while do |(time, _key)| (time.to_r * 1_000).to_i <= now_ms end to_delete.each do |(_time, key)| del(key) end end
expireat(key, timestamp)
click to toggle source
# File lib/mock_redis/database.rb, line 98 def expireat(key, timestamp) unless looks_like_integer?(timestamp.to_s) raise Redis::CommandError, 'ERR value is not an integer or out of range' end pexpireat(key, timestamp.to_i * 1000) end
flushdb()
click to toggle source
# File lib/mock_redis/database.rb, line 129 def flushdb data.each_key { |k| del(k) } 'OK' end
initialize_copy(_source)
click to toggle source
# File lib/mock_redis/database.rb, line 38 def initialize_copy(_source) @data = @data.clone @data.each_key { |k| @data[k] = @data[k].clone } @expire_times = @expire_times.map(&:clone) end
keys(format = '*')
click to toggle source
# File lib/mock_redis/database.rb, line 150 def keys(format = '*') data.keys.grep(redis_pattern_to_ruby_regex(format)) end
lastsave()
click to toggle source
# File lib/mock_redis/database.rb, line 168 def lastsave now.first end
now()
click to toggle source
# File lib/mock_redis/database.rb, line 250 def now current_time = @base.options[:time_class].now miliseconds = (current_time.to_r - current_time.to_i) * 1_000 [current_time.to_i, miliseconds.to_i] end
Also aliased as: time
persist(key)
click to toggle source
# File lib/mock_redis/database.rb, line 172 def persist(key) if exists?(key) && has_expiration?(key) remove_expiration(key) true else false end end
pexpire(key, ms)
click to toggle source
# File lib/mock_redis/database.rb, line 92 def pexpire(key, ms) now, miliseconds = @base.now now_ms = (now * 1000) + miliseconds pexpireat(key, now_ms + ms.to_i) end
pexpireat(key, timestamp_ms)
click to toggle source
# File lib/mock_redis/database.rb, line 106 def pexpireat(key, timestamp_ms) unless looks_like_integer?(timestamp_ms.to_s) raise Redis::CommandError, 'ERR value is not an integer or out of range' end if exists?(key) timestamp = Rational(timestamp_ms.to_i, 1000) set_expiration(key, @base.time_at(timestamp)) true else false end end
ping()
click to toggle source
# File lib/mock_redis/database.rb, line 181 def ping 'PONG' end
pttl(key)
click to toggle source
# File lib/mock_redis/database.rb, line 237 def pttl(key) now, miliseconds = @base.now now_ms = now * 1000 + miliseconds if !exists?(key) -2 elsif has_expiration?(key) (expiration(key).to_r * 1000).to_i - now_ms else -1 end end
quit()
click to toggle source
# File lib/mock_redis/database.rb, line 185 def quit 'OK' end
randomkey()
click to toggle source
# File lib/mock_redis/database.rb, line 189 def randomkey data.keys[rand(data.length)] end
rename(key, newkey)
click to toggle source
# File lib/mock_redis/database.rb, line 193 def rename(key, newkey) unless data.include?(key) raise Redis::CommandError, 'ERR no such key' end if key != newkey data[newkey] = data.delete(key) if has_expiration?(key) set_expiration(newkey, expiration(key)) remove_expiration(key) end end 'OK' end
renamenx(key, newkey)
click to toggle source
# File lib/mock_redis/database.rb, line 209 def renamenx(key, newkey) unless data.include?(key) raise Redis::CommandError, 'ERR no such key' end if exists?(newkey) false else rename(key, newkey) true end end
restore(key, ttl, value, replace: false)
click to toggle source
# File lib/mock_redis/database.rb, line 139 def restore(key, ttl, value, replace: false) if !replace && exists?(key) raise Redis::CommandError, 'BUSYKEY Target key name already exists.' end data[key] = Marshal.load(value) # rubocop:disable Security/MarshalLoad if ttl > 0 pexpire(key, ttl) end 'OK' end
save()
click to toggle source
# File lib/mock_redis/database.rb, line 222 def save 'OK' end
scan(cursor, opts = {})
click to toggle source
# File lib/mock_redis/database.rb, line 154 def scan(cursor, opts = {}) common_scan(data.keys, cursor, opts) end
scan_each(opts = {}, &block)
click to toggle source
# File lib/mock_redis/database.rb, line 158 def scan_each(opts = {}, &block) return to_enum(:scan_each, opts) unless block_given? cursor = 0 loop do cursor, keys = scan(cursor, opts) keys.each(&block) break if cursor == '0' end end
script(subcommand, *args)
click to toggle source
# File lib/mock_redis/database.rb, line 275 def script(subcommand, *args); end
ttl(key)
click to toggle source
# File lib/mock_redis/database.rb, line 226 def ttl(key) if !exists?(key) -2 elsif has_expiration?(key) now, = @base.now expiration(key).to_i - now else -1 end end
type(key)
click to toggle source
# File lib/mock_redis/database.rb, line 257 def type(key) if !exists?(key) 'none' elsif hashy?(key) 'hash' elsif stringy?(key) 'string' elsif listy?(key) 'list' elsif sety?(key) 'set' elsif zsety?(key) 'zset' else raise ArgumentError, "Not sure how #{data[key].inspect} got in here" end end
Private Instance Methods
assert_valid_timeout(timeout)
click to toggle source
# File lib/mock_redis/database.rb, line 283 def assert_valid_timeout(timeout) if !looks_like_integer?(timeout.to_s) raise Redis::CommandError, 'ERR timeout is not an integer or out of range' elsif timeout < 0 raise Redis::CommandError, 'ERR timeout is negative' end timeout end
can_incr?(value)
click to toggle source
# File lib/mock_redis/database.rb, line 292 def can_incr?(value) value.nil? || looks_like_integer?(value) end
can_incr_float?(value)
click to toggle source
# File lib/mock_redis/database.rb, line 296 def can_incr_float?(value) value.nil? || looks_like_float?(value) end
expiration(key)
click to toggle source
# File lib/mock_redis/database.rb, line 313 def expiration(key) expire_times.find { |(_, k)| k == key.to_s }.first end
extract_timeout(arglist)
click to toggle source
# File lib/mock_redis/database.rb, line 300 def extract_timeout(arglist) options = arglist.last if options.is_a?(Hash) && options[:timeout] timeout = assert_valid_timeout(options[:timeout]) [arglist[0..-2], timeout] elsif options.is_a?(Integer) timeout = assert_valid_timeout(options) [arglist[0..-2], timeout] else [arglist, 0] end end
has_expiration?(key)
click to toggle source
# File lib/mock_redis/database.rb, line 317 def has_expiration?(key) expire_times.any? { |(_, k)| k == key.to_s } end
looks_like_float?(str)
click to toggle source
# File lib/mock_redis/database.rb, line 325 def looks_like_float?(str) !!Float(str) rescue false end
looks_like_integer?(str)
click to toggle source
# File lib/mock_redis/database.rb, line 321 def looks_like_integer?(str) str =~ /^-?\d+$/ end
redis_pattern_to_ruby_regex(pattern)
click to toggle source
# File lib/mock_redis/database.rb, line 329 def redis_pattern_to_ruby_regex(pattern) Regexp.new( "^#{pattern}$". gsub(/([+|()])/, '\\\\\1'). gsub(/(?<!\\)\?/, '\\1.'). gsub(/([^\\])\*/, '\\1.*') ) end
remove_expiration(key)
click to toggle source
# File lib/mock_redis/database.rb, line 338 def remove_expiration(key) expire_times.delete_if do |(_t, k)| key.to_s == k end end
set_expiration(key, time)
click to toggle source
# File lib/mock_redis/database.rb, line 344 def set_expiration(key, time) remove_expiration(key) found = expire_times.each_with_index.to_a.bsearch { |item, _| item.first >= time } index = found ? found.last : -1 expire_times.insert(index, [time, key.to_s]) end
zero_pad(string, desired_length)
click to toggle source
# File lib/mock_redis/database.rb, line 351 def zero_pad(string, desired_length) padding = "\000" * [(desired_length - string.length), 0].max string + padding end