fakeredis 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +2 -0
- data/README.md +9 -2
- data/fakeredis.gemspec +3 -2
- data/lib/fakeredis.rb +3 -56
- data/lib/fakeredis/version.rb +1 -1
- data/lib/redis/connection/memory.rb +655 -0
- data/spec/compatibility_spec.rb +9 -0
- data/spec/connection_spec.rb +2 -2
- data/spec/hashes_spec.rb +1 -1
- data/spec/keys_spec.rb +2 -1
- data/spec/lists_spec.rb +1 -1
- data/spec/server_spec.rb +1 -7
- data/spec/sets_spec.rb +1 -1
- data/spec/sorted_sets_spec.rb +1 -1
- data/spec/strings_spec.rb +1 -1
- data/spec/transactions_spec.rb +2 -2
- metadata +74 -40
- data/lib/fakeredis/connection.rb +0 -25
- data/lib/fakeredis/hashes.rb +0 -98
- data/lib/fakeredis/keys.rb +0 -82
- data/lib/fakeredis/lists.rb +0 -108
- data/lib/fakeredis/server.rb +0 -65
- data/lib/fakeredis/sets.rb +0 -122
- data/lib/fakeredis/sorted_sets.rb +0 -108
- data/lib/fakeredis/strings.rb +0 -116
- data/lib/fakeredis/transactions.rb +0 -13
data/lib/fakeredis/lists.rb
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
module FakeRedis
|
2
|
-
class Redis
|
3
|
-
module ListsMethods
|
4
|
-
|
5
|
-
def lindex(key, index)
|
6
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
7
|
-
return unless @data[key]
|
8
|
-
@data[key][index]
|
9
|
-
end
|
10
|
-
|
11
|
-
def linsert(key, where, pivot, value)
|
12
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
13
|
-
return unless @data[key]
|
14
|
-
index = @data[key].index(pivot)
|
15
|
-
case where
|
16
|
-
when :before then @data[key].insert(index, value)
|
17
|
-
when :after then @data[key].insert(index + 1, value)
|
18
|
-
else raise ArgumentError.new
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def llen(key)
|
23
|
-
@data[key] ||= []
|
24
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
25
|
-
@data[key].size
|
26
|
-
end
|
27
|
-
|
28
|
-
def lpop(key)
|
29
|
-
return unless @data[key]
|
30
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
31
|
-
@data[key].delete_at(0)
|
32
|
-
end
|
33
|
-
|
34
|
-
def lpush(key, value)
|
35
|
-
@data[key] ||= []
|
36
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
37
|
-
@data[key] = [value] + @data[key]
|
38
|
-
@data[key].size
|
39
|
-
end
|
40
|
-
|
41
|
-
def lpushx(key, value)
|
42
|
-
return unless @data[key]
|
43
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
44
|
-
lpush(key, value)
|
45
|
-
end
|
46
|
-
|
47
|
-
def lrange(key, startidx, endidx)
|
48
|
-
return unless @data[key]
|
49
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
50
|
-
@data[key][startidx..endidx]
|
51
|
-
end
|
52
|
-
|
53
|
-
def lrem(key, count, value)
|
54
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
55
|
-
return unless @data[key]
|
56
|
-
old_size = @data[key].size
|
57
|
-
if count == 0
|
58
|
-
@data[key].delete(value)
|
59
|
-
old_size - @data[key].size
|
60
|
-
else
|
61
|
-
array = count > 0 ? @data[key].dup : @data[key].reverse
|
62
|
-
count.abs.times{ array.delete_at(array.index(value) || array.length) }
|
63
|
-
@data[key] = count > 0 ? array.dup : array.reverse
|
64
|
-
old_size - @data[key].size
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def lset(key, index, value)
|
69
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
70
|
-
return unless @data[key]
|
71
|
-
raise RuntimeError unless index < @data[key].size
|
72
|
-
@data[key][index] = value
|
73
|
-
end
|
74
|
-
|
75
|
-
def ltrim(key, start, stop)
|
76
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
77
|
-
return unless @data[key]
|
78
|
-
@data[key] = @data[key][start..stop]
|
79
|
-
end
|
80
|
-
|
81
|
-
def rpop(key)
|
82
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
83
|
-
@data[key].pop
|
84
|
-
end
|
85
|
-
|
86
|
-
def rpoplpush(key1, key2)
|
87
|
-
fail "Not a list" unless @data[key1].is_a?(Array)
|
88
|
-
elem = @data[key1].pop
|
89
|
-
lpush(key2, elem)
|
90
|
-
end
|
91
|
-
|
92
|
-
def rpush(key, value)
|
93
|
-
@data[key] ||= []
|
94
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
95
|
-
@data[key].push(value)
|
96
|
-
end
|
97
|
-
|
98
|
-
def rpushx(key, value)
|
99
|
-
return unless @data[key]
|
100
|
-
fail "Not a list" unless @data[key].is_a?(Array)
|
101
|
-
rpush(key, value)
|
102
|
-
end
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
include ListsMethods
|
107
|
-
end
|
108
|
-
end
|
data/lib/fakeredis/server.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
module FakeRedis
|
2
|
-
class Redis
|
3
|
-
module ServerMethods
|
4
|
-
|
5
|
-
def bgreriteaof ; end
|
6
|
-
|
7
|
-
def bgsave ; end
|
8
|
-
|
9
|
-
def config_get(param) ; end
|
10
|
-
|
11
|
-
def config_set(param, value) ; end
|
12
|
-
|
13
|
-
def config_resetstat ; end
|
14
|
-
|
15
|
-
def dbsize
|
16
|
-
@data.keys.count
|
17
|
-
end
|
18
|
-
|
19
|
-
def debug_object(key)
|
20
|
-
return @data[key].inspect
|
21
|
-
end
|
22
|
-
|
23
|
-
def flushdb
|
24
|
-
@data = {}
|
25
|
-
@expires = {}
|
26
|
-
end
|
27
|
-
|
28
|
-
alias flushall flushdb
|
29
|
-
|
30
|
-
def info
|
31
|
-
server_info = {
|
32
|
-
"redis_version" => "0.07",
|
33
|
-
"connected_clients" => "1",
|
34
|
-
"connected_slaves" => "0",
|
35
|
-
"used_memory" => "3187",
|
36
|
-
"changes_since_last_save" => "0",
|
37
|
-
"last_save_time" => "1237655729",
|
38
|
-
"total_connections_received" => "1",
|
39
|
-
"total_commands_processed" => "1",
|
40
|
-
"uptime_in_seconds" => "36000",
|
41
|
-
"uptime_in_days" => 0
|
42
|
-
}
|
43
|
-
return server_info
|
44
|
-
end
|
45
|
-
|
46
|
-
def lastsave
|
47
|
-
Time.now.to_i
|
48
|
-
end
|
49
|
-
|
50
|
-
def monitor ; end
|
51
|
-
|
52
|
-
def save ; end
|
53
|
-
|
54
|
-
def shutdown ; end
|
55
|
-
|
56
|
-
def slaveof(host, port) ; end
|
57
|
-
|
58
|
-
def sync ; end
|
59
|
-
|
60
|
-
alias reset flushdb
|
61
|
-
end
|
62
|
-
|
63
|
-
include ServerMethods
|
64
|
-
end
|
65
|
-
end
|
data/lib/fakeredis/sets.rb
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
module FakeRedis
|
2
|
-
class Redis
|
3
|
-
module SetsMethods
|
4
|
-
def sadd(key, value)
|
5
|
-
fail_unless_set(key)
|
6
|
-
case set = @data[key]
|
7
|
-
when nil then @data[key] = Set.new([value.to_s])
|
8
|
-
when Set then set.add(value.to_s)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def scard(key)
|
13
|
-
fail_unless_set(key)
|
14
|
-
case set = @data[key]
|
15
|
-
when nil then 0
|
16
|
-
when Set then set.size
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def sdiff(key1, *keys)
|
21
|
-
[key1, *keys].each { |k| fail_unless_set(k) }
|
22
|
-
keys = keys.map { |k| @data[k] || Set.new }
|
23
|
-
keys.inject(@data[key1]) do |memo, set|
|
24
|
-
memo - set
|
25
|
-
end.to_a
|
26
|
-
end
|
27
|
-
|
28
|
-
def sdiffstore(destination, key1, *keys)
|
29
|
-
fail_unless_set(destination)
|
30
|
-
result = sdiff(key1, *keys)
|
31
|
-
@data[destination] = Set.new(result)
|
32
|
-
end
|
33
|
-
|
34
|
-
def sinter(*keys)
|
35
|
-
keys.each { |k| fail_unless_set(k) }
|
36
|
-
return Set.new if keys.any? { |k| @data[k].nil? }
|
37
|
-
keys = keys.map { |k| @data[k] || Set.new }
|
38
|
-
keys.inject do |set, key|
|
39
|
-
set & key
|
40
|
-
end.to_a
|
41
|
-
end
|
42
|
-
|
43
|
-
def sinterstore(destination, *keys)
|
44
|
-
fail_unless_set(destination)
|
45
|
-
result = sinter(*keys)
|
46
|
-
@data[destination] = Set.new(result)
|
47
|
-
end
|
48
|
-
|
49
|
-
def sismember(key, value)
|
50
|
-
fail_unless_set(key)
|
51
|
-
case set = @data[key]
|
52
|
-
when nil then false
|
53
|
-
when Set then set.include?(value.to_s)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def smembers(key)
|
58
|
-
fail_unless_set(key)
|
59
|
-
case set = @data[key]
|
60
|
-
when nil then []
|
61
|
-
when Set then set.to_a.reverse
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def smove(source, destination, value)
|
66
|
-
fail_unless_set(destination)
|
67
|
-
if elem = self.srem(source, value)
|
68
|
-
self.sadd(destination, value)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def spop(key)
|
73
|
-
fail_unless_set(key)
|
74
|
-
elem = srandmember(key)
|
75
|
-
srem(key, elem)
|
76
|
-
elem
|
77
|
-
end
|
78
|
-
|
79
|
-
def srandmember(key)
|
80
|
-
fail_unless_set(key)
|
81
|
-
case set = @data[key]
|
82
|
-
when nil then nil
|
83
|
-
when Set then set.to_a[rand(set.size)]
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def srem(key, value)
|
88
|
-
fail_unless_set(key)
|
89
|
-
case set = @data[key]
|
90
|
-
when nil then return
|
91
|
-
when Set then set.delete(value.to_s)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def sunion(*keys)
|
96
|
-
keys.each { |k| fail_unless_set(k) }
|
97
|
-
keys = keys.map { |k| @data[k] || Set.new }
|
98
|
-
keys.inject(Set.new) do |set, key|
|
99
|
-
set | key
|
100
|
-
end.to_a
|
101
|
-
end
|
102
|
-
|
103
|
-
def sunionstore(destination, *keys)
|
104
|
-
fail_unless_set(destination)
|
105
|
-
result = sunion(*keys)
|
106
|
-
@data[destination] = Set.new(result)
|
107
|
-
end
|
108
|
-
|
109
|
-
private
|
110
|
-
|
111
|
-
def is_a_set?(key)
|
112
|
-
@data[key].is_a?(Set) || @data[key].nil?
|
113
|
-
end
|
114
|
-
|
115
|
-
def fail_unless_set(key)
|
116
|
-
fail "Not a set" unless is_a_set?(key)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
include SetsMethods
|
121
|
-
end
|
122
|
-
end
|
@@ -1,108 +0,0 @@
|
|
1
|
-
module FakeRedis
|
2
|
-
class Redis
|
3
|
-
module SortedSetsMethods
|
4
|
-
class Elem < String
|
5
|
-
attr_accessor :score
|
6
|
-
def initialize(str="", score)
|
7
|
-
super(str)
|
8
|
-
@score = score
|
9
|
-
end
|
10
|
-
def <=>(other)
|
11
|
-
@score <=> other.score
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class CustomSortedSet < SortedSet
|
16
|
-
attr_accessor :indexed_set
|
17
|
-
def add(o)
|
18
|
-
super(o)
|
19
|
-
@indexed_set ||= Set.new
|
20
|
-
@indexed_set.add(o)
|
21
|
-
end
|
22
|
-
|
23
|
-
def delete(o)
|
24
|
-
super(o)
|
25
|
-
@indexed_set ||= Set.new
|
26
|
-
@indexed_set.delete(o)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def zadd(key, score, value)
|
31
|
-
fail_unless_sorted_set(key)
|
32
|
-
case set = @data[key]
|
33
|
-
when nil then @data[key] = CustomSortedSet.new([Elem.new(value.to_s, score)])
|
34
|
-
when CustomSortedSet then set.delete(value.to_s) ; set.add(Elem.new(value.to_s, score))
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def zcard(key)
|
39
|
-
fail_unless_sorted_set(key)
|
40
|
-
case set = @data[key]
|
41
|
-
when nil then 0
|
42
|
-
when CustomSortedSet then set.size
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def zcount(key, min, max)
|
47
|
-
fail_unless_sorted_set(key)
|
48
|
-
case set = @data[key]
|
49
|
-
when nil then 0
|
50
|
-
when CustomSortedSet then set.select{|x| x.score >= min && x.score <= max }.size
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def zincrby(key, incr, value)
|
55
|
-
fail_unless_sorted_set(key)
|
56
|
-
case set = @data[key]
|
57
|
-
when nil then @data[key] = CustomSortedSet.new([Elem.new(value.to_s, incr)])
|
58
|
-
when CustomSortedSet then
|
59
|
-
score = set.to_a.select{|x| x == value.to_s}.first.score
|
60
|
-
set.delete(value.to_s)
|
61
|
-
set.add(Elem.new(value.to_s, score+incr))
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def zrange(key, start, stop)
|
66
|
-
fail_unless_sorted_set(key)
|
67
|
-
case set = @data[key]
|
68
|
-
when nil then []
|
69
|
-
when CustomSortedSet then set.indexed_set.to_a[start..stop]
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def zrangescore(key, start, stop)
|
74
|
-
fail_unless_sorted_set(key)
|
75
|
-
case set = @data[key]
|
76
|
-
when nil then []
|
77
|
-
when CustomSortedSet then set.to_a.reverse[start..stop]
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def zrank(key, value)
|
82
|
-
fail_unless_sorted_set(key)
|
83
|
-
case set = @data[key]
|
84
|
-
when nil then nil
|
85
|
-
when CustomSortedSet then set.to_a.index(value)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def zscore(key, value)
|
90
|
-
case set = @data[key]
|
91
|
-
when nil then 0
|
92
|
-
when CustomSortedSet then set.to_a.select{|x| x == value.to_s}.first.score
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
private
|
97
|
-
|
98
|
-
def is_a_sorted_set?(key)
|
99
|
-
@data[key].is_a?(CustomSortedSet) || @data[key].nil?
|
100
|
-
end
|
101
|
-
|
102
|
-
def fail_unless_sorted_set(key)
|
103
|
-
fail "Not a sorted set" unless is_a_sorted_set?(key)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
include SortedSetsMethods
|
107
|
-
end
|
108
|
-
end
|
data/lib/fakeredis/strings.rb
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
module FakeRedis
|
2
|
-
class Redis
|
3
|
-
module StringsMethods
|
4
|
-
|
5
|
-
def append(key, value)
|
6
|
-
@data[key] = (@data[key] || "")
|
7
|
-
@data[key] = @data[key] + value.to_s
|
8
|
-
end
|
9
|
-
|
10
|
-
def decr(key)
|
11
|
-
@data[key] = (@data[key] || "0")
|
12
|
-
@data[key] = (@data[key].to_i - 1).to_s
|
13
|
-
end
|
14
|
-
|
15
|
-
def decrby(key, by)
|
16
|
-
@data[key] = (@data[key] || "0")
|
17
|
-
@data[key] = (@data[key].to_i - by.to_i).to_s
|
18
|
-
end
|
19
|
-
|
20
|
-
def get(key)
|
21
|
-
#return if expired?(key)
|
22
|
-
@data[key]
|
23
|
-
end
|
24
|
-
|
25
|
-
def getbit(key, offset)
|
26
|
-
#return if expired?(key)
|
27
|
-
return unless @data[key]
|
28
|
-
@data[key].unpack('B8')[0].split("")[offset]
|
29
|
-
end
|
30
|
-
|
31
|
-
def getrange(key, start, ending)
|
32
|
-
return unless @data[key]
|
33
|
-
@data[key][start..ending]
|
34
|
-
end
|
35
|
-
|
36
|
-
def getset(key, value)
|
37
|
-
old_value = @data[key]
|
38
|
-
@data[key] = value
|
39
|
-
return old_value
|
40
|
-
end
|
41
|
-
|
42
|
-
def incr(key)
|
43
|
-
@data[key] = (@data[key] || "0")
|
44
|
-
@data[key] = (@data[key].to_i + 1).to_s
|
45
|
-
end
|
46
|
-
|
47
|
-
def incrby(key, by)
|
48
|
-
@data[key] = (@data[key] || "0")
|
49
|
-
@data[key] = (@data[key].to_i + by.to_i).to_s
|
50
|
-
end
|
51
|
-
|
52
|
-
def mget(*keys)
|
53
|
-
@data.values_at(*keys)
|
54
|
-
end
|
55
|
-
|
56
|
-
def mapped_mget(*keys)
|
57
|
-
reply = mget(*keys)
|
58
|
-
Hash[*keys.zip(reply).flatten]
|
59
|
-
end
|
60
|
-
|
61
|
-
def mset(*pairs)
|
62
|
-
pairs.each_slice(2) do |pair|
|
63
|
-
@data[pair[0].to_s] = pair[1].to_s
|
64
|
-
end
|
65
|
-
"OK"
|
66
|
-
end
|
67
|
-
|
68
|
-
def msetnx(*pairs)
|
69
|
-
keys = []
|
70
|
-
pairs.each_with_index{|item, index| keys << item.to_s if index % 2 == 0}
|
71
|
-
return if keys.any?{|key| @data.key?(key) }
|
72
|
-
mset(*pairs)
|
73
|
-
true
|
74
|
-
end
|
75
|
-
|
76
|
-
def set(key, value)
|
77
|
-
@data[key] = value.to_s
|
78
|
-
"OK"
|
79
|
-
end
|
80
|
-
|
81
|
-
def setbit(key, offset, bit)
|
82
|
-
return unless @data[key]
|
83
|
-
old_val = @data[key].unpack('B*')[0].split("")
|
84
|
-
old_val[offset] = bit.to_s
|
85
|
-
new_val = ""
|
86
|
-
old_val.each_slice(8){|b| new_val = new_val + b.join("").to_i(2).chr }
|
87
|
-
@data[key] = new_val
|
88
|
-
end
|
89
|
-
|
90
|
-
def setex(key, seconds, value)
|
91
|
-
@data[key] = value
|
92
|
-
expire(key, seconds)
|
93
|
-
end
|
94
|
-
|
95
|
-
def setnx(key, value)
|
96
|
-
set(key, value) unless @data.key?(key)
|
97
|
-
end
|
98
|
-
|
99
|
-
def setrange(key, offset, value)
|
100
|
-
return unless @data[key]
|
101
|
-
s = @data[key][offset,value.size]
|
102
|
-
@data[key][s] = value
|
103
|
-
end
|
104
|
-
|
105
|
-
def strlen(key)
|
106
|
-
return unless @data[key]
|
107
|
-
@data[key].size
|
108
|
-
end
|
109
|
-
|
110
|
-
alias [] get
|
111
|
-
alias []= set
|
112
|
-
end
|
113
|
-
|
114
|
-
include StringsMethods
|
115
|
-
end
|
116
|
-
end
|