protocol-redis 0.9.0 → 0.11.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
- checksums.yaml.gz.sig +1 -2
- data/context/getting-started.md +55 -0
- data/context/index.yaml +13 -0
- data/lib/protocol/redis/cluster/methods/generic.rb +94 -0
- data/lib/protocol/redis/cluster/methods/pubsub.rb +27 -0
- data/lib/protocol/redis/cluster/methods/scripting.rb +93 -0
- data/lib/protocol/redis/cluster/methods/streams.rb +204 -0
- data/lib/protocol/redis/cluster/methods/strings.rb +304 -0
- data/lib/protocol/redis/cluster/methods.rb +27 -0
- data/lib/protocol/redis/connection.rb +41 -12
- data/lib/protocol/redis/error.rb +6 -0
- data/lib/protocol/redis/methods/cluster.rb +9 -7
- data/lib/protocol/redis/methods/connection.rb +9 -8
- data/lib/protocol/redis/methods/counting.rb +9 -8
- data/lib/protocol/redis/methods/generic.rb +100 -99
- data/lib/protocol/redis/methods/geospatial.rb +42 -49
- data/lib/protocol/redis/methods/hashes.rb +84 -83
- data/lib/protocol/redis/methods/lists.rb +75 -74
- data/lib/protocol/redis/methods/pubsub.rb +5 -4
- data/lib/protocol/redis/methods/scripting.rb +19 -20
- data/lib/protocol/redis/methods/server.rb +13 -9
- data/lib/protocol/redis/methods/sets.rb +42 -41
- data/lib/protocol/redis/methods/sorted_sets.rb +110 -109
- data/lib/protocol/redis/methods/streams.rb +48 -47
- data/lib/protocol/redis/methods/strings.rb +112 -109
- data/lib/protocol/redis/methods.rb +16 -14
- data/lib/protocol/redis/version.rb +1 -1
- data/lib/protocol/redis.rb +9 -2
- data/readme.md +49 -21
- data/releases.md +98 -0
- data.tar.gz.sig +0 -0
- metadata +13 -9
- metadata.gz.sig +0 -0
@@ -0,0 +1,304 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protocol
|
4
|
+
module Redis
|
5
|
+
module Cluster
|
6
|
+
module Methods
|
7
|
+
# Provides Redis String commands for cluster environments.
|
8
|
+
# String operations are routed to the appropriate shard based on the key.
|
9
|
+
module Strings
|
10
|
+
# Append a value to a key.
|
11
|
+
# @parameter key [String] The key to append to.
|
12
|
+
# @parameter value [String] The value to append.
|
13
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
14
|
+
# @returns [Integer] The length of the string after the append operation.
|
15
|
+
def append(key, value, role: :master)
|
16
|
+
slot = slot_for(key)
|
17
|
+
client = client_for(slot, role)
|
18
|
+
|
19
|
+
return client.call("APPEND", key, value)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Count set bits in a string.
|
23
|
+
# @parameter key [String] The key to count bits in.
|
24
|
+
# @parameter range [Array] Optional start and end positions.
|
25
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
26
|
+
# @returns [Integer] The number of set bits.
|
27
|
+
def bitcount(key, *range, role: :master)
|
28
|
+
slot = slot_for(key)
|
29
|
+
client = client_for(slot, role)
|
30
|
+
|
31
|
+
return client.call("BITCOUNT", key, *range)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Decrement the integer value of a key by one.
|
35
|
+
# @parameter key [String] The key to decrement.
|
36
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
37
|
+
# @returns [Integer] The value after decrementing.
|
38
|
+
def decr(key, role: :master)
|
39
|
+
slot = slot_for(key)
|
40
|
+
client = client_for(slot, role)
|
41
|
+
|
42
|
+
return client.call("DECR", key)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Decrement the integer value of a key by the given number.
|
46
|
+
# @parameter key [String] The key to decrement.
|
47
|
+
# @parameter decrement [Integer] The amount to decrement by.
|
48
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
49
|
+
# @returns [Integer] The value after decrementing.
|
50
|
+
def decrby(key, decrement, role: :master)
|
51
|
+
slot = slot_for(key)
|
52
|
+
client = client_for(slot, role)
|
53
|
+
|
54
|
+
return client.call("DECRBY", key, decrement)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Get the value of a key.
|
58
|
+
# @parameter key [String] The key to get.
|
59
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
60
|
+
# @returns [String | nil] The value, or `nil` if key doesn't exist.
|
61
|
+
def get(key, role: :master)
|
62
|
+
slot = slot_for(key)
|
63
|
+
client = client_for(slot, role)
|
64
|
+
|
65
|
+
return client.call("GET", key)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Get the bit value at offset in the string value stored at key.
|
69
|
+
# @parameter key [String] The key to get bit from.
|
70
|
+
# @parameter offset [Integer] The bit offset.
|
71
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
72
|
+
# @returns [Integer] The bit value (0 or 1).
|
73
|
+
def getbit(key, offset, role: :master)
|
74
|
+
slot = slot_for(key)
|
75
|
+
client = client_for(slot, role)
|
76
|
+
|
77
|
+
return client.call("GETBIT", key, offset)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Get a substring of the string stored at a key.
|
81
|
+
# @parameter key [String] The key to get range from.
|
82
|
+
# @parameter start_index [Integer] The start position.
|
83
|
+
# @parameter end_index [Integer] The end position.
|
84
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
85
|
+
# @returns [String] The substring.
|
86
|
+
def getrange(key, start_index, end_index, role: :master)
|
87
|
+
slot = slot_for(key)
|
88
|
+
client = client_for(slot, role)
|
89
|
+
|
90
|
+
return client.call("GETRANGE", key, start_index, end_index)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Set the string value of a key and return its old value.
|
94
|
+
# @parameter key [String] The key to set.
|
95
|
+
# @parameter value [String] The new value.
|
96
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
97
|
+
# @returns [String | nil] The old value, or `nil` if key didn't exist.
|
98
|
+
def getset(key, value, role: :master)
|
99
|
+
slot = slot_for(key)
|
100
|
+
client = client_for(slot, role)
|
101
|
+
|
102
|
+
return client.call("GETSET", key, value)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Increment the integer value of a key by one.
|
106
|
+
# @parameter key [String] The key to increment.
|
107
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
108
|
+
# @returns [Integer] The value after incrementing.
|
109
|
+
def incr(key, role: :master)
|
110
|
+
slot = slot_for(key)
|
111
|
+
client = client_for(slot, role)
|
112
|
+
|
113
|
+
return client.call("INCR", key)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Increment the integer value of a key by the given amount.
|
117
|
+
# @parameter key [String] The key to increment.
|
118
|
+
# @parameter increment [Integer] The amount to increment by.
|
119
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
120
|
+
# @returns [Integer] The value after incrementing.
|
121
|
+
def incrby(key, increment, role: :master)
|
122
|
+
slot = slot_for(key)
|
123
|
+
client = client_for(slot, role)
|
124
|
+
|
125
|
+
return client.call("INCRBY", key, increment)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Increment the float value of a key by the given amount.
|
129
|
+
# @parameter key [String] The key to increment.
|
130
|
+
# @parameter increment [Float] The amount to increment by.
|
131
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
132
|
+
# @returns [String] The value after incrementing (as string).
|
133
|
+
def incrbyfloat(key, increment, role: :master)
|
134
|
+
slot = slot_for(key)
|
135
|
+
client = client_for(slot, role)
|
136
|
+
|
137
|
+
return client.call("INCRBYFLOAT", key, increment)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Get the values of all the given keys.
|
141
|
+
# Uses the cluster-aware multi-key handling from generic methods.
|
142
|
+
# @parameter keys [Array(String)] The keys to get.
|
143
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
144
|
+
# @returns [Array] The values for the given keys, in order.
|
145
|
+
def mget(*keys, role: :master)
|
146
|
+
return [] if keys.empty?
|
147
|
+
|
148
|
+
results = Array.new(keys.size)
|
149
|
+
key_to_index = keys.each_with_index.to_h
|
150
|
+
|
151
|
+
clients_for(*keys, role: role) do |client, grouped_keys|
|
152
|
+
values = client.call("MGET", *grouped_keys)
|
153
|
+
grouped_keys.each_with_index do |key, i|
|
154
|
+
results[key_to_index[key]] = values[i]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
return results
|
159
|
+
end
|
160
|
+
|
161
|
+
# Set multiple keys to multiple values.
|
162
|
+
# Redis will return a CROSSSLOT error if keys span multiple slots.
|
163
|
+
# @parameter pairs [Hash] The key-value pairs to set.
|
164
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
165
|
+
# @returns [String] Status reply.
|
166
|
+
def mset(pairs, role: :master)
|
167
|
+
return if pairs.empty?
|
168
|
+
|
169
|
+
if pairs.is_a?(Hash)
|
170
|
+
pairs = pairs.to_a.flatten
|
171
|
+
end
|
172
|
+
|
173
|
+
slot = slot_for(pairs.first)
|
174
|
+
client = client_for(slot, role)
|
175
|
+
|
176
|
+
return client.call("MSET", *pairs)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Set multiple keys to multiple values, only if none exist.
|
180
|
+
# Redis will return a CROSSSLOT error if keys span multiple slots.
|
181
|
+
# @parameter pairs [Hash] The key-value pairs to set.
|
182
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
183
|
+
# @returns [Integer] 1 if all keys were set, 0 otherwise.
|
184
|
+
def msetnx(pairs, role: :master)
|
185
|
+
keys = pairs.keys
|
186
|
+
return 0 if keys.empty?
|
187
|
+
|
188
|
+
flattened_pairs = pairs.keys.zip(pairs.values).flatten
|
189
|
+
slot = slot_for(keys.first)
|
190
|
+
client = client_for(slot, role)
|
191
|
+
|
192
|
+
return client.call("MSETNX", *flattened_pairs)
|
193
|
+
end
|
194
|
+
|
195
|
+
# Set the value and expiration in milliseconds of a key.
|
196
|
+
# @parameter key [String] The key to set.
|
197
|
+
# @parameter milliseconds [Integer] The expiration time in milliseconds.
|
198
|
+
# @parameter value [String] The value to set.
|
199
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
200
|
+
# @returns [String] Status reply.
|
201
|
+
def psetex(key, milliseconds, value, role: :master)
|
202
|
+
slot = slot_for(key)
|
203
|
+
client = client_for(slot, role)
|
204
|
+
|
205
|
+
return client.call("PSETEX", key, milliseconds, value)
|
206
|
+
end
|
207
|
+
|
208
|
+
# Set the string value of a key.
|
209
|
+
# @parameter key [String] The key to set.
|
210
|
+
# @parameter value [String] The value to set.
|
211
|
+
# @parameter update [Boolean | nil] If `true`, only update existing keys. If `false`, only set new keys.
|
212
|
+
# @parameter seconds [Integer | nil] Expiration time in seconds.
|
213
|
+
# @parameter milliseconds [Integer | nil] Expiration time in milliseconds.
|
214
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
215
|
+
# @returns [String] Status reply.
|
216
|
+
def set(key, value, update: nil, seconds: nil, milliseconds: nil, role: :master)
|
217
|
+
arguments = []
|
218
|
+
|
219
|
+
if seconds
|
220
|
+
arguments << "EX" << seconds
|
221
|
+
end
|
222
|
+
|
223
|
+
if milliseconds
|
224
|
+
arguments << "PX" << milliseconds
|
225
|
+
end
|
226
|
+
|
227
|
+
if update == true
|
228
|
+
arguments << "XX"
|
229
|
+
elsif update == false
|
230
|
+
arguments << "NX"
|
231
|
+
end
|
232
|
+
|
233
|
+
slot = slot_for(key)
|
234
|
+
client = client_for(slot, role)
|
235
|
+
|
236
|
+
return client.call("SET", key, value, *arguments)
|
237
|
+
end
|
238
|
+
|
239
|
+
# Set or clear the bit at offset in the string value stored at key.
|
240
|
+
# @parameter key [String] The key to modify.
|
241
|
+
# @parameter offset [Integer] The bit offset.
|
242
|
+
# @parameter value [Integer] The bit value (0 or 1).
|
243
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
244
|
+
# @returns [Integer] The original bit value.
|
245
|
+
def setbit(key, offset, value, role: :master)
|
246
|
+
slot = slot_for(key)
|
247
|
+
client = client_for(slot, role)
|
248
|
+
|
249
|
+
return client.call("SETBIT", key, offset, value)
|
250
|
+
end
|
251
|
+
|
252
|
+
# Set the value and expiration of a key.
|
253
|
+
# @parameter key [String] The key to set.
|
254
|
+
# @parameter seconds [Integer] The expiration time in seconds.
|
255
|
+
# @parameter value [String] The value to set.
|
256
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
257
|
+
# @returns [String] Status reply.
|
258
|
+
def setex(key, seconds, value, role: :master)
|
259
|
+
slot = slot_for(key)
|
260
|
+
client = client_for(slot, role)
|
261
|
+
|
262
|
+
return client.call("SETEX", key, seconds, value)
|
263
|
+
end
|
264
|
+
|
265
|
+
# Set the value of a key, only if the key does not exist.
|
266
|
+
# @parameter key [String] The key to set.
|
267
|
+
# @parameter value [String] The value to set.
|
268
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
269
|
+
# @returns [Boolean] `true` if the key was set, `false` otherwise.
|
270
|
+
def setnx(key, value, role: :master)
|
271
|
+
slot = slot_for(key)
|
272
|
+
client = client_for(slot, role)
|
273
|
+
|
274
|
+
return client.call("SETNX", key, value) == 1
|
275
|
+
end
|
276
|
+
|
277
|
+
# Overwrite part of a string at key starting at the specified offset.
|
278
|
+
# @parameter key [String] The key to modify.
|
279
|
+
# @parameter offset [Integer] The offset to start overwriting at.
|
280
|
+
# @parameter value [String] The value to write.
|
281
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
282
|
+
# @returns [Integer] The length of the string after modification.
|
283
|
+
def setrange(key, offset, value, role: :master)
|
284
|
+
slot = slot_for(key)
|
285
|
+
client = client_for(slot, role)
|
286
|
+
|
287
|
+
return client.call("SETRANGE", key, offset, value)
|
288
|
+
end
|
289
|
+
|
290
|
+
# Get the length of the value stored in a key.
|
291
|
+
# @parameter key [String] The key to get length of.
|
292
|
+
# @parameter role [Symbol] The role of node to use (`:master` or `:slave`).
|
293
|
+
# @returns [Integer] The length of the string value, or 0 if key doesn't exist.
|
294
|
+
def strlen(key, role: :master)
|
295
|
+
slot = slot_for(key)
|
296
|
+
client = client_for(slot, role)
|
297
|
+
|
298
|
+
return client.call("STRLEN", key)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2025, by Samuel Williams.
|
5
|
+
|
6
|
+
require_relative "methods/generic"
|
7
|
+
require_relative "methods/pubsub"
|
8
|
+
require_relative "methods/streams"
|
9
|
+
require_relative "methods/strings"
|
10
|
+
|
11
|
+
module Protocol
|
12
|
+
module Redis
|
13
|
+
# @namespace
|
14
|
+
module Cluster
|
15
|
+
# A collection of methods for interacting with Redis in cluster mode.
|
16
|
+
module Methods
|
17
|
+
# Includes all Redis methods into the given class.
|
18
|
+
def self.included(klass)
|
19
|
+
klass.include Methods::Generic
|
20
|
+
klass.include Methods::Pubsub
|
21
|
+
klass.include Methods::Streams
|
22
|
+
klass.include Methods::Strings
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -3,13 +3,16 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2019-2023, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "error"
|
7
7
|
|
8
8
|
module Protocol
|
9
9
|
module Redis
|
10
|
+
# Represents a Redis protocol connection handling low-level communication.
|
10
11
|
class Connection
|
11
12
|
CRLF = "\r\n".freeze
|
12
13
|
|
14
|
+
# Initialize a new connection with the provided stream.
|
15
|
+
# @parameter stream [IO] The underlying stream for communication.
|
13
16
|
def initialize(stream)
|
14
17
|
@stream = stream
|
15
18
|
|
@@ -22,18 +25,23 @@ module Protocol
|
|
22
25
|
# @attr [Integer] Number of requests sent.
|
23
26
|
attr :count
|
24
27
|
|
28
|
+
# Close the underlying stream connection.
|
25
29
|
def close
|
26
30
|
@stream.close
|
27
31
|
end
|
28
32
|
|
29
33
|
class << self
|
34
|
+
# Create a new client connection instance.
|
30
35
|
alias client new
|
31
36
|
end
|
32
37
|
|
38
|
+
# Flush any buffered data to the stream.
|
33
39
|
def flush
|
34
40
|
@stream.flush
|
35
41
|
end
|
36
42
|
|
43
|
+
# Check if the connection is closed.
|
44
|
+
# @returns [Boolean] True if the connection is closed.
|
37
45
|
def closed?
|
38
46
|
@stream.closed?
|
39
47
|
end
|
@@ -51,6 +59,8 @@ module Protocol
|
|
51
59
|
end
|
52
60
|
end
|
53
61
|
|
62
|
+
# Write a Redis object to the stream.
|
63
|
+
# @parameter object [Object] The object to write (String, Array, Integer, or object with to_redis method).
|
54
64
|
def write_object(object)
|
55
65
|
case object
|
56
66
|
when String
|
@@ -59,11 +69,26 @@ module Protocol
|
|
59
69
|
write_array(object)
|
60
70
|
when Integer
|
61
71
|
write_lines(":#{object}")
|
72
|
+
when nil
|
73
|
+
write_lines("$-1")
|
62
74
|
else
|
63
75
|
write_object(object.to_redis)
|
64
76
|
end
|
65
77
|
end
|
66
78
|
|
79
|
+
# Write a Redis array to the stream.
|
80
|
+
# @parameter array [Array] The array to write.
|
81
|
+
def write_array(array)
|
82
|
+
write_lines("*#{array.size}")
|
83
|
+
|
84
|
+
array.each do |element|
|
85
|
+
write_object(element)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Read data of specified length from the stream.
|
90
|
+
# @parameter length [Integer] The number of bytes to read.
|
91
|
+
# @returns [String] The data read from the stream.
|
67
92
|
def read_data(length)
|
68
93
|
buffer = @stream.read(length) or @stream.eof!
|
69
94
|
|
@@ -73,13 +98,17 @@ module Protocol
|
|
73
98
|
return buffer
|
74
99
|
end
|
75
100
|
|
101
|
+
# Read and parse a Redis object from the stream.
|
102
|
+
# @returns [Object] The parsed Redis object (String, Array, Integer, or nil).
|
103
|
+
# @raises [ServerError] If the server returns an error response.
|
104
|
+
# @raises [EOFError] If the stream reaches end of file.
|
76
105
|
def read_object
|
77
106
|
line = read_line or raise EOFError
|
78
107
|
|
79
108
|
token = line.slice!(0, 1)
|
80
109
|
|
81
110
|
case token
|
82
|
-
when
|
111
|
+
when "$"
|
83
112
|
length = line.to_i
|
84
113
|
|
85
114
|
if length == -1
|
@@ -87,7 +116,7 @@ module Protocol
|
|
87
116
|
else
|
88
117
|
return read_data(length)
|
89
118
|
end
|
90
|
-
when
|
119
|
+
when "*"
|
91
120
|
count = line.to_i
|
92
121
|
|
93
122
|
# Null array (https://redis.io/topics/protocol#resp-arrays):
|
@@ -96,28 +125,28 @@ module Protocol
|
|
96
125
|
array = Array.new(count) {read_object}
|
97
126
|
|
98
127
|
return array
|
99
|
-
when
|
128
|
+
when ":"
|
100
129
|
return line.to_i
|
101
|
-
|
102
|
-
when
|
130
|
+
|
131
|
+
when "-"
|
103
132
|
raise ServerError.new(line)
|
104
|
-
|
105
|
-
when
|
133
|
+
|
134
|
+
when "+"
|
106
135
|
return line
|
107
|
-
|
136
|
+
|
108
137
|
else
|
109
138
|
@stream.flush
|
110
139
|
|
111
|
-
raise
|
140
|
+
raise UnknownTokenError, token.inspect
|
112
141
|
end
|
113
142
|
|
114
143
|
# TODO: If an exception (e.g. Async::TimeoutError) propagates out of this function, perhaps @stream should be closed? Otherwise it might be in a weird state.
|
115
144
|
end
|
116
145
|
|
117
146
|
alias read_response read_object
|
118
|
-
|
147
|
+
|
119
148
|
private
|
120
|
-
|
149
|
+
|
121
150
|
# In the case of Redis, we do not want to perform a flush in every line,
|
122
151
|
# because each Redis command contains several lines. Flushing once per
|
123
152
|
# command is more efficient because it avoids unnecessary writes to the
|
data/lib/protocol/redis/error.rb
CHANGED
@@ -5,10 +5,16 @@
|
|
5
5
|
|
6
6
|
module Protocol
|
7
7
|
module Redis
|
8
|
+
# Represents a general Redis protocol error.
|
8
9
|
class Error < StandardError
|
9
10
|
end
|
10
11
|
|
12
|
+
# Represents an error response from the Redis server.
|
11
13
|
class ServerError < Error
|
12
14
|
end
|
15
|
+
|
16
|
+
# Represents an unknown token error in the Redis protocol.
|
17
|
+
class UnknownTokenError < Error
|
18
|
+
end
|
13
19
|
end
|
14
20
|
end
|
@@ -2,25 +2,27 @@
|
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2023, by Nick Burwell.
|
5
|
+
# Copyright, 2024, by Samuel Williams.
|
5
6
|
|
6
7
|
module Protocol
|
7
8
|
module Redis
|
8
9
|
module Methods
|
10
|
+
# Methods for managing Redis clusters.
|
9
11
|
module Cluster
|
10
12
|
# Sends the `CLUSTER *` command to random node and returns its reply.
|
11
|
-
#
|
12
|
-
# @
|
13
|
+
# See <https://redis.io/commands/cluster-addslots/> for more details.
|
14
|
+
# @parameter subcommand [String, Symbol] the subcommand of cluster command
|
13
15
|
# e.g. `:addslots`, `:delslots`, `:nodes`, `:replicas`, `:info`
|
14
16
|
#
|
15
|
-
# @
|
16
|
-
def cluster(subcommand, *
|
17
|
-
call("CLUSTER", subcommand.to_s, *
|
17
|
+
# @returns [Object] depends on the subcommand provided
|
18
|
+
def cluster(subcommand, *arguments)
|
19
|
+
call("CLUSTER", subcommand.to_s, *arguments)
|
18
20
|
end
|
19
21
|
|
20
22
|
# Sends `ASKING` command to random node and returns its reply.
|
21
|
-
#
|
23
|
+
# See <https://redis.io/commands/asking/> for more details.
|
22
24
|
#
|
23
|
-
# @
|
25
|
+
# @returns [String] `'OK'`
|
24
26
|
def asking
|
25
27
|
call("ASKING")
|
26
28
|
end
|
@@ -6,31 +6,32 @@
|
|
6
6
|
module Protocol
|
7
7
|
module Redis
|
8
8
|
module Methods
|
9
|
+
# Methods for managing Redis connections.
|
9
10
|
module Connection
|
10
11
|
# Authenticate to the server.
|
11
|
-
#
|
12
|
-
# @
|
13
|
-
# @
|
12
|
+
# See <https://redis.io/commands/auth> for more details.
|
13
|
+
# @parameter username [String] Optional username, if Redis ACLs are used.
|
14
|
+
# @parameter password [String] Required password.
|
14
15
|
def auth(*arguments)
|
15
16
|
call("AUTH", *arguments)
|
16
17
|
end
|
17
18
|
|
18
19
|
# Echo the given string.
|
19
|
-
#
|
20
|
-
# @
|
20
|
+
# See <https://redis.io/commands/echo> for more details.
|
21
|
+
# @parameter message [String]
|
21
22
|
def echo(message)
|
22
23
|
call("ECHO", message)
|
23
24
|
end
|
24
25
|
|
25
26
|
# Ping the server.
|
26
|
-
#
|
27
|
-
# @
|
27
|
+
# See <https://redis.io/commands/ping> for more details.
|
28
|
+
# @parameter message [String]
|
28
29
|
def ping(message)
|
29
30
|
call("PING", message)
|
30
31
|
end
|
31
32
|
|
32
33
|
# Close the connection.
|
33
|
-
#
|
34
|
+
# See <https://redis.io/commands/quit> for more details.
|
34
35
|
def quit
|
35
36
|
call("QUIT")
|
36
37
|
end
|
@@ -6,26 +6,27 @@
|
|
6
6
|
module Protocol
|
7
7
|
module Redis
|
8
8
|
module Methods
|
9
|
+
# Methods for managing Redis HyperLogLogs.
|
9
10
|
module Counting
|
10
11
|
# Adds the specified elements to the specified HyperLogLog. O(1) to add every element.
|
11
|
-
#
|
12
|
-
# @
|
13
|
-
# @
|
12
|
+
# See <https://redis.io/commands/pfadd> for more details.
|
13
|
+
# @parameter key [Key]
|
14
|
+
# @parameter element [String]
|
14
15
|
def pfadd(key, element, *elements)
|
15
16
|
call("PFADD", key, element, *elements)
|
16
17
|
end
|
17
18
|
|
18
19
|
# Return the approximated cardinality of the set(s) observed by the HyperLogLog at key(s). O(1) with a very small average constant time when called with a single key. O(N) with N being the number of keys, and much bigger constant times, when called with multiple keys.
|
19
|
-
#
|
20
|
-
# @
|
20
|
+
# See <https://redis.io/commands/pfcount> for more details.
|
21
|
+
# @parameter key [Key]
|
21
22
|
def pfcount(key, *keys)
|
22
23
|
call("PFCOUNT", key, *keys)
|
23
24
|
end
|
24
25
|
|
25
26
|
# Merge N different HyperLogLogs into a single one. O(N) to merge N HyperLogLogs, but with high constant times.
|
26
|
-
#
|
27
|
-
# @
|
28
|
-
# @
|
27
|
+
# See <https://redis.io/commands/pfmerge> for more details.
|
28
|
+
# @parameter destkey [Key]
|
29
|
+
# @parameter sourcekey [Key]
|
29
30
|
def pfmerge(destkey, sourcekey, *sourcekeys)
|
30
31
|
call("PFMERGE", destkey, sourcekey, *sourcekeys)
|
31
32
|
end
|