redis 4.5.1 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +51 -0
- data/README.md +10 -10
- data/lib/redis/client.rb +14 -13
- data/lib/redis/cluster/command.rb +4 -6
- data/lib/redis/cluster/node.rb +12 -0
- data/lib/redis/cluster.rb +24 -0
- data/lib/redis/commands/bitmaps.rb +63 -0
- data/lib/redis/commands/cluster.rb +45 -0
- data/lib/redis/commands/connection.rb +58 -0
- data/lib/redis/commands/geo.rb +84 -0
- data/lib/redis/commands/hashes.rb +251 -0
- data/lib/redis/commands/hyper_log_log.rb +37 -0
- data/lib/redis/commands/keys.rb +411 -0
- data/lib/redis/commands/lists.rb +289 -0
- data/lib/redis/commands/pubsub.rb +72 -0
- data/lib/redis/commands/scripting.rb +114 -0
- data/lib/redis/commands/server.rb +188 -0
- data/lib/redis/commands/sets.rb +207 -0
- data/lib/redis/commands/sorted_sets.rb +804 -0
- data/lib/redis/commands/streams.rb +382 -0
- data/lib/redis/commands/strings.rb +313 -0
- data/lib/redis/commands/transactions.rb +92 -0
- data/lib/redis/commands.rb +242 -0
- data/lib/redis/connection/hiredis.rb +3 -2
- data/lib/redis/connection/ruby.rb +8 -5
- data/lib/redis/connection/synchrony.rb +10 -8
- data/lib/redis/connection.rb +1 -1
- data/lib/redis/distributed.rb +46 -9
- data/lib/redis/pipeline.rb +95 -2
- data/lib/redis/version.rb +1 -1
- data/lib/redis.rb +133 -3675
- metadata +21 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e99f4e628112a227719d2000dc5b081893273cfbd51ae25bf00a8f6b6594061
|
4
|
+
data.tar.gz: 42a8e0cf75aebbc14cdf680b4bc1f7bbdec9e20b53f150c6443c01126960a959
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8bc57fe306c601f27d32df4940d5632e9e7d75529f6ac5d42732b21fe04452a4a1ab89567492c6fb7249ef4d69ebb2c0b7c985e18b0ef4f9ee6fb816c31bcbda
|
7
|
+
data.tar.gz: 42b2f8c584d6f96d0fc783d0b36af0fd9415d1dbd43ad8fe7a980688e52fbdb51645a07960d9cb3faacf6696c460cf38a013e290d0b58d4bbbb07626f18f15c7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,56 @@
|
|
1
1
|
# Unreleased
|
2
2
|
|
3
|
+
# 4.6.0
|
4
|
+
|
5
|
+
* Deprecate `Redis.current`.
|
6
|
+
* Deprecate calling commands on `Redis` inside `Redis#pipelined`. See #1059.
|
7
|
+
```ruby
|
8
|
+
redis.pipelined do
|
9
|
+
redis.get("key")
|
10
|
+
end
|
11
|
+
```
|
12
|
+
|
13
|
+
should be replaced by:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
redis.pipelined do |pipeline|
|
17
|
+
pipeline.get("key")
|
18
|
+
end
|
19
|
+
```
|
20
|
+
* Deprecate calling commands on `Redis` inside `Redis#multi`. See #1059.
|
21
|
+
```ruby
|
22
|
+
redis.multi do
|
23
|
+
redis.get("key")
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
should be replaced by:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
redis.multi do |transaction|
|
31
|
+
transaction.get("key")
|
32
|
+
end
|
33
|
+
```
|
34
|
+
* Deprecate `Redis#queue` and `Redis#commit`. See #1059.
|
35
|
+
|
36
|
+
* Fix `zpopmax` and `zpopmin` when called inside a pipeline. See #1055.
|
37
|
+
* `Redis#synchronize` is now private like it should always have been.
|
38
|
+
|
39
|
+
* Add `Redis.silence_deprecations=` to turn off deprecation warnings.
|
40
|
+
If you don't wish to see warnings yet, you can set `Redis.silence_deprecations = false`.
|
41
|
+
It is however heavily recommended to fix them instead when possible.
|
42
|
+
* Add `Redis.raise_deprecations=` to turn deprecation warnings into errors.
|
43
|
+
This makes it easier to identitify the source of deprecated APIs usage.
|
44
|
+
It is recommended to set `Redis.raise_deprecations = true` in development and test environments.
|
45
|
+
* Add new options to ZRANGE. See #1053.
|
46
|
+
* Add ZRANGESTORE command. See #1053.
|
47
|
+
* Add SCAN support for `Redis::Cluster`. See #1049.
|
48
|
+
* Add COPY command. See #1053. See #1048.
|
49
|
+
* Add ZDIFFSTORE command. See #1046.
|
50
|
+
* Add ZDIFF command. See #1044.
|
51
|
+
* Add ZUNION command. See #1042.
|
52
|
+
* Add HRANDFIELD command. See #1040.
|
53
|
+
|
3
54
|
# 4.5.1
|
4
55
|
|
5
56
|
* Restore the accidential auth behavior of redis-rb 4.3.0 with a warning. If provided with the `default` user's password, but a wrong username,
|
data/README.md
CHANGED
@@ -184,9 +184,9 @@ commands to Redis and gathers their replies. These replies are returned
|
|
184
184
|
by the `#pipelined` method.
|
185
185
|
|
186
186
|
```ruby
|
187
|
-
redis.pipelined do
|
188
|
-
|
189
|
-
|
187
|
+
redis.pipelined do |pipeline|
|
188
|
+
pipeline.set "foo", "bar"
|
189
|
+
pipeline.incr "baz"
|
190
190
|
end
|
191
191
|
# => ["OK", 1]
|
192
192
|
```
|
@@ -200,9 +200,9 @@ the regular pipeline, the replies to the commands are returned by the
|
|
200
200
|
`#multi` method.
|
201
201
|
|
202
202
|
```ruby
|
203
|
-
redis.multi do
|
204
|
-
|
205
|
-
|
203
|
+
redis.multi do |transaction|
|
204
|
+
transaction.set "foo", "bar"
|
205
|
+
transaction.incr "baz"
|
206
206
|
end
|
207
207
|
# => ["OK", 1]
|
208
208
|
```
|
@@ -210,15 +210,15 @@ end
|
|
210
210
|
### Futures
|
211
211
|
|
212
212
|
Replies to commands in a pipeline can be accessed via the *futures* they
|
213
|
-
emit (since redis-rb 3.0). All calls
|
213
|
+
emit (since redis-rb 3.0). All calls on the pipeline object return a
|
214
214
|
`Future` object, which responds to the `#value` method. When the
|
215
215
|
pipeline has successfully executed, all futures are assigned their
|
216
216
|
respective replies and can be used.
|
217
217
|
|
218
218
|
```ruby
|
219
|
-
redis.pipelined do
|
220
|
-
@set =
|
221
|
-
@incr =
|
219
|
+
redis.pipelined do |pipeline|
|
220
|
+
@set = pipeline.set "foo", "bar"
|
221
|
+
@incr = pipeline.incr "baz"
|
222
222
|
end
|
223
223
|
|
224
224
|
@set.value
|
data/lib/redis/client.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "errors"
|
4
3
|
require "socket"
|
5
4
|
require "cgi"
|
5
|
+
require "redis/errors"
|
6
6
|
|
7
7
|
class Redis
|
8
8
|
class Client
|
@@ -32,7 +32,7 @@ class Redis
|
|
32
32
|
role: nil
|
33
33
|
}.freeze
|
34
34
|
|
35
|
-
attr_reader :options
|
35
|
+
attr_reader :options, :connection, :command_map
|
36
36
|
|
37
37
|
def scheme
|
38
38
|
@options[:scheme]
|
@@ -87,8 +87,6 @@ class Redis
|
|
87
87
|
end
|
88
88
|
|
89
89
|
attr_accessor :logger
|
90
|
-
attr_reader :connection
|
91
|
-
attr_reader :command_map
|
92
90
|
|
93
91
|
def initialize(options = {})
|
94
92
|
@options = _parse_options(options)
|
@@ -120,17 +118,18 @@ class Redis
|
|
120
118
|
begin
|
121
119
|
call [:auth, username, password]
|
122
120
|
rescue CommandError => err # Likely on Redis < 6
|
123
|
-
|
121
|
+
case err.message
|
122
|
+
when /ERR wrong number of arguments for 'auth' command/
|
124
123
|
call [:auth, password]
|
125
|
-
|
124
|
+
when /WRONGPASS invalid username-password pair/
|
126
125
|
begin
|
127
126
|
call [:auth, password]
|
128
127
|
rescue CommandError
|
129
128
|
raise err
|
130
129
|
end
|
131
|
-
::
|
130
|
+
::Redis.deprecate!(
|
132
131
|
"[redis-rb] The Redis connection was configured with username #{username.inspect}, but" \
|
133
|
-
" the provided password was for the default user. This will start failing in redis-rb
|
132
|
+
" the provided password was for the default user. This will start failing in redis-rb 5.0.0."
|
134
133
|
)
|
135
134
|
else
|
136
135
|
raise
|
@@ -252,7 +251,8 @@ class Redis
|
|
252
251
|
result
|
253
252
|
end
|
254
253
|
|
255
|
-
def call_with_timeout(command,
|
254
|
+
def call_with_timeout(command, extra_timeout, &blk)
|
255
|
+
timeout = extra_timeout == 0 ? 0 : self.timeout + extra_timeout
|
256
256
|
with_socket_timeout(timeout) do
|
257
257
|
call(command, &blk)
|
258
258
|
end
|
@@ -442,7 +442,7 @@ class Redis
|
|
442
442
|
defaults = DEFAULTS.dup
|
443
443
|
options = options.dup
|
444
444
|
|
445
|
-
defaults.
|
445
|
+
defaults.each_key do |key|
|
446
446
|
# Fill in defaults if needed
|
447
447
|
defaults[key] = defaults[key].call if defaults[key].respond_to?(:call)
|
448
448
|
|
@@ -459,9 +459,10 @@ class Redis
|
|
459
459
|
|
460
460
|
uri = URI(url)
|
461
461
|
|
462
|
-
|
462
|
+
case uri.scheme
|
463
|
+
when "unix"
|
463
464
|
defaults[:path] = uri.path
|
464
|
-
|
465
|
+
when "redis", "rediss"
|
465
466
|
defaults[:scheme] = uri.scheme
|
466
467
|
defaults[:host] = uri.host if uri.host
|
467
468
|
defaults[:port] = uri.port if uri.port
|
@@ -477,7 +478,7 @@ class Redis
|
|
477
478
|
end
|
478
479
|
|
479
480
|
# Use default when option is not specified or nil
|
480
|
-
defaults.
|
481
|
+
defaults.each_key do |key|
|
481
482
|
options[key] = defaults[key] if options[key].nil?
|
482
483
|
end
|
483
484
|
|
@@ -31,13 +31,13 @@ class Redis
|
|
31
31
|
private
|
32
32
|
|
33
33
|
def pick_details(details)
|
34
|
-
details.
|
35
|
-
|
34
|
+
details.transform_values do |detail|
|
35
|
+
{
|
36
36
|
first_key_position: detail[:first],
|
37
37
|
write: detail[:flags].include?('write'),
|
38
38
|
readonly: detail[:flags].include?('readonly')
|
39
|
-
}
|
40
|
-
end
|
39
|
+
}
|
40
|
+
end
|
41
41
|
end
|
42
42
|
|
43
43
|
def dig_details(command, key)
|
@@ -53,8 +53,6 @@ class Redis
|
|
53
53
|
when 'object' then 2
|
54
54
|
when 'memory'
|
55
55
|
command[1].to_s.casecmp('usage').zero? ? 2 : 0
|
56
|
-
when 'scan', 'sscan', 'hscan', 'zscan'
|
57
|
-
determine_optional_key_position(command, 'match')
|
58
56
|
when 'xread', 'xreadgroup'
|
59
57
|
determine_optional_key_position(command, 'streams')
|
60
58
|
else
|
data/lib/redis/cluster/node.rb
CHANGED
@@ -58,6 +58,18 @@ class Redis
|
|
58
58
|
try_map { |_, client| client.process(commands, &block) }.values
|
59
59
|
end
|
60
60
|
|
61
|
+
def scale_reading_clients
|
62
|
+
reading_clients = []
|
63
|
+
|
64
|
+
@clients.each do |node_key, client|
|
65
|
+
next unless replica_disabled? ? master?(node_key) : slave?(node_key)
|
66
|
+
|
67
|
+
reading_clients << client
|
68
|
+
end
|
69
|
+
|
70
|
+
reading_clients
|
71
|
+
end
|
72
|
+
|
61
73
|
private
|
62
74
|
|
63
75
|
def replica_disabled?
|
data/lib/redis/cluster.rb
CHANGED
@@ -137,6 +137,7 @@ class Redis
|
|
137
137
|
when 'wait' then @node.call_master(command, &block).reduce(:+)
|
138
138
|
when 'keys' then @node.call_slave(command, &block).flatten.sort
|
139
139
|
when 'dbsize' then @node.call_slave(command, &block).reduce(:+)
|
140
|
+
when 'scan' then _scan(command, &block)
|
140
141
|
when 'lastsave' then @node.call_all(command, &block).sort
|
141
142
|
when 'role' then @node.call_all(command, &block)
|
142
143
|
when 'config' then send_config_command(command, &block)
|
@@ -238,6 +239,29 @@ class Redis
|
|
238
239
|
raise
|
239
240
|
end
|
240
241
|
|
242
|
+
def _scan(command, &block)
|
243
|
+
input_cursor = Integer(command[1])
|
244
|
+
|
245
|
+
client_index = input_cursor % 256
|
246
|
+
raw_cursor = input_cursor >> 8
|
247
|
+
|
248
|
+
clients = @node.scale_reading_clients
|
249
|
+
|
250
|
+
client = clients[client_index]
|
251
|
+
return ['0', []] unless client
|
252
|
+
|
253
|
+
command[1] = raw_cursor.to_s
|
254
|
+
|
255
|
+
result_cursor, result_keys = client.call(command, &block)
|
256
|
+
result_cursor = Integer(result_cursor)
|
257
|
+
|
258
|
+
if result_cursor == 0
|
259
|
+
client_index += 1
|
260
|
+
end
|
261
|
+
|
262
|
+
[((result_cursor << 8) + client_index).to_s, result_keys]
|
263
|
+
end
|
264
|
+
|
241
265
|
def assign_redirection_node(err_msg)
|
242
266
|
_, slot, node_key = err_msg.split(' ')
|
243
267
|
slot = slot.to_i
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Redis
|
4
|
+
module Commands
|
5
|
+
module Bitmaps
|
6
|
+
# Sets or clears the bit at offset in the string value stored at key.
|
7
|
+
#
|
8
|
+
# @param [String] key
|
9
|
+
# @param [Integer] offset bit offset
|
10
|
+
# @param [Integer] value bit value `0` or `1`
|
11
|
+
# @return [Integer] the original bit value stored at `offset`
|
12
|
+
def setbit(key, offset, value)
|
13
|
+
send_command([:setbit, key, offset, value])
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the bit value at offset in the string value stored at key.
|
17
|
+
#
|
18
|
+
# @param [String] key
|
19
|
+
# @param [Integer] offset bit offset
|
20
|
+
# @return [Integer] `0` or `1`
|
21
|
+
def getbit(key, offset)
|
22
|
+
send_command([:getbit, key, offset])
|
23
|
+
end
|
24
|
+
|
25
|
+
# Count the number of set bits in a range of the string value stored at key.
|
26
|
+
#
|
27
|
+
# @param [String] key
|
28
|
+
# @param [Integer] start start index
|
29
|
+
# @param [Integer] stop stop index
|
30
|
+
# @return [Integer] the number of bits set to 1
|
31
|
+
def bitcount(key, start = 0, stop = -1)
|
32
|
+
send_command([:bitcount, key, start, stop])
|
33
|
+
end
|
34
|
+
|
35
|
+
# Perform a bitwise operation between strings and store the resulting string in a key.
|
36
|
+
#
|
37
|
+
# @param [String] operation e.g. `and`, `or`, `xor`, `not`
|
38
|
+
# @param [String] destkey destination key
|
39
|
+
# @param [String, Array<String>] keys one or more source keys to perform `operation`
|
40
|
+
# @return [Integer] the length of the string stored in `destkey`
|
41
|
+
def bitop(operation, destkey, *keys)
|
42
|
+
send_command([:bitop, operation, destkey, *keys])
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return the position of the first bit set to 1 or 0 in a string.
|
46
|
+
#
|
47
|
+
# @param [String] key
|
48
|
+
# @param [Integer] bit whether to look for the first 1 or 0 bit
|
49
|
+
# @param [Integer] start start index
|
50
|
+
# @param [Integer] stop stop index
|
51
|
+
# @return [Integer] the position of the first 1/0 bit.
|
52
|
+
# -1 if looking for 1 and it is not found or start and stop are given.
|
53
|
+
def bitpos(key, bit, start = nil, stop = nil)
|
54
|
+
raise(ArgumentError, 'stop parameter specified without start parameter') if stop && !start
|
55
|
+
|
56
|
+
command = [:bitpos, key, bit]
|
57
|
+
command << start if start
|
58
|
+
command << stop if stop
|
59
|
+
send_command(command)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Redis
|
4
|
+
module Commands
|
5
|
+
module Cluster
|
6
|
+
# Sends `CLUSTER *` command to random node and returns its reply.
|
7
|
+
#
|
8
|
+
# @see https://redis.io/commands#cluster Reference of cluster command
|
9
|
+
#
|
10
|
+
# @param subcommand [String, Symbol] the subcommand of cluster command
|
11
|
+
# e.g. `:slots`, `:nodes`, `:slaves`, `:info`
|
12
|
+
#
|
13
|
+
# @return [Object] depends on the subcommand
|
14
|
+
def cluster(subcommand, *args)
|
15
|
+
subcommand = subcommand.to_s.downcase
|
16
|
+
block = case subcommand
|
17
|
+
when 'slots'
|
18
|
+
HashifyClusterSlots
|
19
|
+
when 'nodes'
|
20
|
+
HashifyClusterNodes
|
21
|
+
when 'slaves'
|
22
|
+
HashifyClusterSlaves
|
23
|
+
when 'info'
|
24
|
+
HashifyInfo
|
25
|
+
else
|
26
|
+
Noop
|
27
|
+
end
|
28
|
+
|
29
|
+
# @see https://github.com/antirez/redis/blob/unstable/src/redis-trib.rb#L127 raw reply expected
|
30
|
+
block = Noop unless @cluster_mode
|
31
|
+
|
32
|
+
send_command([:cluster, subcommand] + args, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Sends `ASKING` command to random node and returns its reply.
|
36
|
+
#
|
37
|
+
# @see https://redis.io/topics/cluster-spec#ask-redirection ASK redirection
|
38
|
+
#
|
39
|
+
# @return [String] `'OK'`
|
40
|
+
def asking
|
41
|
+
send_command(%i[asking])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Redis
|
4
|
+
module Commands
|
5
|
+
module Connection
|
6
|
+
# Authenticate to the server.
|
7
|
+
#
|
8
|
+
# @param [Array<String>] args includes both username and password
|
9
|
+
# or only password
|
10
|
+
# @return [String] `OK`
|
11
|
+
# @see https://redis.io/commands/auth AUTH command
|
12
|
+
def auth(*args)
|
13
|
+
send_command([:auth, *args])
|
14
|
+
end
|
15
|
+
|
16
|
+
# Ping the server.
|
17
|
+
#
|
18
|
+
# @param [optional, String] message
|
19
|
+
# @return [String] `PONG`
|
20
|
+
def ping(message = nil)
|
21
|
+
send_command([:ping, message].compact)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Echo the given string.
|
25
|
+
#
|
26
|
+
# @param [String] value
|
27
|
+
# @return [String]
|
28
|
+
def echo(value)
|
29
|
+
send_command([:echo, value])
|
30
|
+
end
|
31
|
+
|
32
|
+
# Change the selected database for the current connection.
|
33
|
+
#
|
34
|
+
# @param [Integer] db zero-based index of the DB to use (0 to 15)
|
35
|
+
# @return [String] `OK`
|
36
|
+
def select(db)
|
37
|
+
synchronize do |client|
|
38
|
+
client.db = db
|
39
|
+
client.call([:select, db])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Close the connection.
|
44
|
+
#
|
45
|
+
# @return [String] `OK`
|
46
|
+
def quit
|
47
|
+
synchronize do |client|
|
48
|
+
begin
|
49
|
+
client.call([:quit])
|
50
|
+
rescue ConnectionError
|
51
|
+
ensure
|
52
|
+
client.disconnect
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Redis
|
4
|
+
module Commands
|
5
|
+
module Geo
|
6
|
+
# Adds the specified geospatial items (latitude, longitude, name) to the specified key
|
7
|
+
#
|
8
|
+
# @param [String] key
|
9
|
+
# @param [Array] member arguemnts for member or members: longitude, latitude, name
|
10
|
+
# @return [Integer] number of elements added to the sorted set
|
11
|
+
def geoadd(key, *member)
|
12
|
+
send_command([:geoadd, key, *member])
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns geohash string representing position for specified members of the specified key.
|
16
|
+
#
|
17
|
+
# @param [String] key
|
18
|
+
# @param [String, Array<String>] member one member or array of members
|
19
|
+
# @return [Array<String, nil>] returns array containg geohash string if member is present, nil otherwise
|
20
|
+
def geohash(key, member)
|
21
|
+
send_command([:geohash, key, member])
|
22
|
+
end
|
23
|
+
|
24
|
+
# Query a sorted set representing a geospatial index to fetch members matching a
|
25
|
+
# given maximum distance from a point
|
26
|
+
#
|
27
|
+
# @param [Array] args key, longitude, latitude, radius, unit(m|km|ft|mi)
|
28
|
+
# @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest
|
29
|
+
# or the farthest to the nearest relative to the center
|
30
|
+
# @param [Integer] count limit the results to the first N matching items
|
31
|
+
# @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information
|
32
|
+
# @return [Array<String>] may be changed with `options`
|
33
|
+
def georadius(*args, **geoptions)
|
34
|
+
geoarguments = _geoarguments(*args, **geoptions)
|
35
|
+
|
36
|
+
send_command([:georadius, *geoarguments])
|
37
|
+
end
|
38
|
+
|
39
|
+
# Query a sorted set representing a geospatial index to fetch members matching a
|
40
|
+
# given maximum distance from an already existing member
|
41
|
+
#
|
42
|
+
# @param [Array] args key, member, radius, unit(m|km|ft|mi)
|
43
|
+
# @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest
|
44
|
+
# to the nearest relative to the center
|
45
|
+
# @param [Integer] count limit the results to the first N matching items
|
46
|
+
# @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information
|
47
|
+
# @return [Array<String>] may be changed with `options`
|
48
|
+
def georadiusbymember(*args, **geoptions)
|
49
|
+
geoarguments = _geoarguments(*args, **geoptions)
|
50
|
+
|
51
|
+
send_command([:georadiusbymember, *geoarguments])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns longitude and latitude of members of a geospatial index
|
55
|
+
#
|
56
|
+
# @param [String] key
|
57
|
+
# @param [String, Array<String>] member one member or array of members
|
58
|
+
# @return [Array<Array<String>, nil>] returns array of elements, where each
|
59
|
+
# element is either array of longitude and latitude or nil
|
60
|
+
def geopos(key, member)
|
61
|
+
send_command([:geopos, key, member])
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns the distance between two members of a geospatial index
|
65
|
+
#
|
66
|
+
# @param [String ]key
|
67
|
+
# @param [Array<String>] members
|
68
|
+
# @param ['m', 'km', 'mi', 'ft'] unit
|
69
|
+
# @return [String, nil] returns distance in spefied unit if both members present, nil otherwise.
|
70
|
+
def geodist(key, member1, member2, unit = 'm')
|
71
|
+
send_command([:geodist, key, member1, member2, unit])
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def _geoarguments(*args, options: nil, sort: nil, count: nil)
|
77
|
+
args.push sort if sort
|
78
|
+
args.push 'count', count if count
|
79
|
+
args.push options if options
|
80
|
+
args
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|