Module: MockRedis::ZsetMethods

Includes:
Assertions, UtilityMethods
Included in:
Database
Defined in:
lib/mock_redis/zset_methods.rb

Instance Method Summary collapse

Instance Method Details

#zadd(key, *args) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/mock_redis/zset_methods.rb', line 10

def zadd(key, *args)
  zadd_options = {}
  zadd_options = args.pop if args.last.is_a?(Hash)

  if zadd_options&.include?(:nx) && zadd_options&.include?(:xx)
    raise Redis::CommandError, 'ERR XX and NX options at the same time are not compatible'
  end

  if args.size == 1 && args[0].is_a?(Array)
    zadd_multiple_members(key, args.first, zadd_options)
  elsif args.size == 2
    score, member = args
    zadd_one_member(key, score, member, zadd_options)
  else
    raise Redis::CommandError, 'ERR wrong number of arguments'
  end
end

#zcard(key) ⇒ Object



89
90
91
# File 'lib/mock_redis/zset_methods.rb', line 89

def zcard(key)
  with_zset_at(key, &:size)
end

#zcount(key, min, max) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/mock_redis/zset_methods.rb', line 93

def zcount(key, min, max)
  assert_range_args(min, max)

  with_zset_at(key) do |zset|
    zset.in_range(min, max).size
  end
end

#zincrby(key, increment, member) ⇒ Object



101
102
103
104
105
106
107
108
109
110
# File 'lib/mock_redis/zset_methods.rb', line 101

def zincrby(key, increment, member)
  assert_scorey(increment)
  member = member.to_s
  with_zset_at(key) do |z|
    old_score = z.include?(member) ? z.score(member) : 0
    new_score = old_score + increment
    z.add(new_score, member)
    new_score.to_f
  end
end

#zinterstore(destination, keys, options = {}) ⇒ Object



112
113
114
115
116
117
# File 'lib/mock_redis/zset_methods.rb', line 112

def zinterstore(destination, keys, options = {})
  assert_has_args(keys, 'zinterstore')

  data[destination] = combine_weighted_zsets(keys, options, :intersection)
  zcard(destination)
end

#zpopmax(key, count = 1) ⇒ Object



167
168
169
170
171
172
173
174
# File 'lib/mock_redis/zset_methods.rb', line 167

def zpopmax(key, count = 1)
  with_zset_at(key) do |z|
    pairs = z.sorted.reverse.first(count)
    pairs.each { |pair| z.delete?(pair.last) }
    retval = to_response(pairs, with_scores: true)
    count == 1 ? retval.first : retval
  end
end

#zpopmin(key, count = 1) ⇒ Object



158
159
160
161
162
163
164
165
# File 'lib/mock_redis/zset_methods.rb', line 158

def zpopmin(key, count = 1)
  with_zset_at(key) do |z|
    pairs = z.sorted.first(count)
    pairs.each { |pair| z.delete?(pair.last) }
    retval = to_response(pairs, with_scores: true)
    count == 1 ? retval.first : retval
  end
end

#zrange(key, start, stop, options = {}) ⇒ Object



119
120
121
122
123
124
125
# File 'lib/mock_redis/zset_methods.rb', line 119

def zrange(key, start, stop, options = {})
  with_zset_at(key) do |z|
    start = [start.to_i, -z.sorted.size].max
    stop = stop.to_i
    to_response(z.sorted[start..stop] || [], options)
  end
end

#zrangebyscore(key, min, max, options = {}) ⇒ Object



127
128
129
130
131
132
133
134
# File 'lib/mock_redis/zset_methods.rb', line 127

def zrangebyscore(key, min, max, options = {})
  assert_range_args(min, max)

  with_zset_at(key) do |zset|
    all_results = zset.in_range(min, max)
    to_response(apply_limit(all_results, options[:limit]), options)
  end
end

#zrank(key, member) ⇒ Object



136
137
138
# File 'lib/mock_redis/zset_methods.rb', line 136

def zrank(key, member)
  with_zset_at(key) { |z| z.sorted_members.index(member.to_s) }
end

#zrem(key, *args) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/mock_redis/zset_methods.rb', line 140

def zrem(key, *args)
  if !args.first.is_a?(Array)
    retval = with_zset_at(key) { |z| !!z.delete?(args.first.to_s) }
  else
    args = args.first
    if args.empty?
      raise Redis::CommandError, "ERR wrong number of arguments for 'zrem' command"
    else
      retval = args.map { |member| !!zscore(key, member.to_s) }.count(true)
      with_zset_at(key) do |z|
        args.each { |member| z.delete?(member) }
      end
    end
  end

  retval
end

#zremrangebyrank(key, start, stop) ⇒ Object



182
183
184
185
186
# File 'lib/mock_redis/zset_methods.rb', line 182

def zremrangebyrank(key, start, stop)
  zrange(key, start, stop).
    each { |member| zrem(key, member) }.
    size
end

#zremrangebyscore(key, min, max) ⇒ Object



188
189
190
191
192
193
194
# File 'lib/mock_redis/zset_methods.rb', line 188

def zremrangebyscore(key, min, max)
  assert_range_args(min, max)

  zrangebyscore(key, min, max).
    each { |member| zrem(key, member) }.
    size
end

#zrevrange(key, start, stop, options = {}) ⇒ Object



176
177
178
179
180
# File 'lib/mock_redis/zset_methods.rb', line 176

def zrevrange(key, start, stop, options = {})
  with_zset_at(key) do |z|
    to_response(z.sorted.reverse[start..stop] || [], options)
  end
end

#zrevrangebyscore(key, max, min, options = {}) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/mock_redis/zset_methods.rb', line 196

def zrevrangebyscore(key, max, min, options = {})
  assert_range_args(min, max)

  with_zset_at(key) do |zset|
    to_response(
      apply_limit(
        zset.in_range(min, max).reverse,
        options[:limit]
      ),
      options
    )
  end
end

#zrevrank(key, member) ⇒ Object



210
211
212
# File 'lib/mock_redis/zset_methods.rb', line 210

def zrevrank(key, member)
  with_zset_at(key) { |z| z.sorted_members.reverse.index(member.to_s) }
end

#zscan(key, cursor, opts = {}) ⇒ Object



214
215
216
217
# File 'lib/mock_redis/zset_methods.rb', line 214

def zscan(key, cursor, opts = {})
  opts = opts.merge(key: lambda { |x| x[0] })
  common_scan(zrange(key, 0, -1, withscores: true), cursor, opts)
end

#zscan_each(key, opts = {}, &block) ⇒ Object



219
220
221
222
223
224
225
226
227
# File 'lib/mock_redis/zset_methods.rb', line 219

def zscan_each(key, opts = {}, &block)
  return to_enum(:zscan_each, key, opts) unless block_given?
  cursor = 0
  loop do
    cursor, values = zscan(key, cursor, opts)
    values.each(&block)
    break if cursor == '0'
  end
end

#zscore(key, member) ⇒ Object



229
230
231
232
233
234
# File 'lib/mock_redis/zset_methods.rb', line 229

def zscore(key, member)
  with_zset_at(key) do |z|
    score = z.score(member.to_s)
    score&.to_f
  end
end

#zunionstore(destination, keys, options = {}) ⇒ Object



236
237
238
239
240
241
# File 'lib/mock_redis/zset_methods.rb', line 236

def zunionstore(destination, keys, options = {})
  assert_has_args(keys, 'zunionstore')

  data[destination] = combine_weighted_zsets(keys, options, :union)
  zcard(destination)
end