redis 5.4.0 → 6.0.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 +56 -1
- data/README.md +165 -12
- data/lib/redis/client.rb +45 -6
- data/lib/redis/commands/geo.rb +108 -6
- data/lib/redis/commands/hashes.rb +166 -2
- data/lib/redis/commands/keys.rb +5 -1
- data/lib/redis/commands/lists.rb +93 -0
- data/lib/redis/commands/modules/json.rb +530 -0
- data/lib/redis/commands/modules/search/aggregation.rb +418 -0
- data/lib/redis/commands/modules/search/dialect.rb +14 -0
- data/lib/redis/commands/modules/search/field.rb +306 -0
- data/lib/redis/commands/modules/search/hybrid.rb +359 -0
- data/lib/redis/commands/modules/search/index.rb +351 -0
- data/lib/redis/commands/modules/search/index_definition.rb +114 -0
- data/lib/redis/commands/modules/search/miscellaneous.rb +607 -0
- data/lib/redis/commands/modules/search/query.rb +738 -0
- data/lib/redis/commands/modules/search/result.rb +488 -0
- data/lib/redis/commands/modules/search/schema.rb +211 -0
- data/lib/redis/commands/modules/search.rb +19 -0
- data/lib/redis/commands/sets.rb +41 -0
- data/lib/redis/commands/sorted_sets.rb +0 -1
- data/lib/redis/commands/streams.rb +28 -8
- data/lib/redis/commands.rb +30 -10
- data/lib/redis/distributed.rb +271 -1
- data/lib/redis/errors.rb +5 -0
- data/lib/redis/lib_identity.rb +105 -0
- data/lib/redis/subscribe.rb +1 -1
- data/lib/redis/version.rb +1 -1
- data/lib/redis.rb +143 -11
- metadata +22 -9
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "redis-client"
|
|
4
|
+
require "redis/version"
|
|
5
|
+
|
|
6
|
+
class Redis
|
|
7
|
+
# Reports `redis-rb` as the connecting library via `CLIENT SETINFO`.
|
|
8
|
+
#
|
|
9
|
+
# `redis-client` builds its own `LIB-NAME` as `redis-client(<driver_info>)` and always
|
|
10
|
+
# reports its own version as `LIB-VER`, which would identify `redis-client` rather than
|
|
11
|
+
# `redis-rb` to the server. We append a second pair of `CLIENT SETINFO` commands, which wins
|
|
12
|
+
# because the command is last-write-wins, so that `CLIENT LIST` / `CLIENT INFO` report
|
|
13
|
+
# `lib-name=redis-rb` and `lib-ver=<Redis::VERSION>`.
|
|
14
|
+
#
|
|
15
|
+
# Libraries built on top of `redis-rb` can still identify themselves by passing `driver_info`,
|
|
16
|
+
# in which case they are reported inside the parentheses, e.g. `lib-name=redis-rb(my-gem_v1.0.0)`.
|
|
17
|
+
# The official convention for such suffixes is `<name>_v<version>` (matching
|
|
18
|
+
# `(?<custom-name>[ -~]+)[ -~]v(?<custom-version>[\d\.]+)`), with `;` delimiting multiple
|
|
19
|
+
# suffixes and parentheses avoided inside them — see
|
|
20
|
+
# https://redis.io/docs/latest/commands/client-setinfo/. Passing `driver_info: false` disables
|
|
21
|
+
# `CLIENT SETINFO` entirely, for peers that can't tolerate unknown commands during the handshake
|
|
22
|
+
# (e.g. some proxies).
|
|
23
|
+
#
|
|
24
|
+
# Applications that use `redis-client` directly are left untouched: the override only applies
|
|
25
|
+
# to configurations whose `driver_info` was built by this module.
|
|
26
|
+
module LibIdentity
|
|
27
|
+
# Follows the official suffix convention, so that the transient pair `redis-client` itself
|
|
28
|
+
# builds from this value (`lib-name=redis-client(redis-rb_v<version>)`) is well-formed too.
|
|
29
|
+
MARKER = "redis-rb_v"
|
|
30
|
+
LIB_NAME = "redis-rb"
|
|
31
|
+
SEPARATOR = ";"
|
|
32
|
+
# Interpolated strings are not frozen by the magic comment; explicit freezes keep these
|
|
33
|
+
# constants Ractor-shareable (lazy module ivars here would raise Ractor::IsolationError).
|
|
34
|
+
OWN_INFO = "#{MARKER}#{Redis::VERSION}".freeze
|
|
35
|
+
OWN_PREFIX = "#{OWN_INFO}#{SEPARATOR}".freeze
|
|
36
|
+
# `CLIENT SETINFO` values must be printable ASCII with no spaces — the server rejects anything
|
|
37
|
+
# else, and `redis-client` swallows that error, which would silently leave `lib-name` empty.
|
|
38
|
+
# Parentheses are excluded as well: they delimit the suffix in `lib-name=redis-rb(<suffix>)`,
|
|
39
|
+
# so a suffix containing them would corrupt the reported name.
|
|
40
|
+
INVALID_CHARS = /(?:[^!-~]|[()])+/
|
|
41
|
+
|
|
42
|
+
class << self
|
|
43
|
+
# Combines redis-rb's own identity with the `driver_info` a downstream library passed in,
|
|
44
|
+
# so that both can be recovered when the connection prelude is built. `false` is passed
|
|
45
|
+
# through untouched and, being falsy, turns `CLIENT SETINFO` off wholesale (`redis-client`
|
|
46
|
+
# gates its own commands on `driver_info` too). Any other non-String, non-Array value is
|
|
47
|
+
# also passed through, leaving `redis-client` to reject it.
|
|
48
|
+
def driver_info(downstream = nil)
|
|
49
|
+
case downstream
|
|
50
|
+
when nil then OWN_INFO
|
|
51
|
+
when String then combine(downstream)
|
|
52
|
+
when Array then combine(downstream.join(SEPARATOR))
|
|
53
|
+
else downstream
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# True only for values `driver_info` produced: exactly our own identity, or our identity
|
|
58
|
+
# followed by a downstream library's. Matching on the bare `MARKER` prefix instead would
|
|
59
|
+
# also capture a direct `redis-client` user whose own `driver_info` merely starts with
|
|
60
|
+
# `redis-rb_v` (say `redis-rb_viewer-1.0`) and would silently discard their identity.
|
|
61
|
+
def ours?(info)
|
|
62
|
+
info.is_a?(String) && (info == OWN_INFO || info.start_with?(OWN_PREFIX))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def setinfo_commands(info)
|
|
66
|
+
[
|
|
67
|
+
["CLIENT", "SETINFO", "LIB-NAME", lib_name(info)].freeze,
|
|
68
|
+
["CLIENT", "SETINFO", "LIB-VER", Redis::VERSION].freeze,
|
|
69
|
+
].freeze
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def combine(downstream)
|
|
75
|
+
downstream = downstream.scrub(" ") # invalid byte sequences would make gsub raise
|
|
76
|
+
.gsub(/\A#{INVALID_CHARS}|#{INVALID_CHARS}\z/o, "")
|
|
77
|
+
.gsub(INVALID_CHARS, "_")
|
|
78
|
+
downstream.empty? ? OWN_INFO : "#{OWN_PREFIX}#{downstream}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def lib_name(info)
|
|
82
|
+
downstream = info == OWN_INFO ? nil : info.delete_prefix(OWN_PREFIX)
|
|
83
|
+
downstream.nil? || downstream.empty? ? LIB_NAME : "#{LIB_NAME}(#{downstream})".freeze
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def connection_prelude
|
|
88
|
+
prelude = super
|
|
89
|
+
info = driver_info
|
|
90
|
+
return prelude unless LibIdentity.ours?(info)
|
|
91
|
+
|
|
92
|
+
# `CLIENT SETINFO` is last-write-wins, so appending after the commands `redis-client`
|
|
93
|
+
# already built overrides them, without having to recognise or remove them.
|
|
94
|
+
(prelude + LibIdentity.setinfo_commands(info)).freeze
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Prepended to the concrete config classes rather than to `RedisClient::Config::Common`, so that
|
|
100
|
+
# the two `redis-client` entry points are covered without altering the shared module for anything
|
|
101
|
+
# else that includes it. `RedisClient::SentinelConfig` is NOT a `RedisClient::Config` subclass, so
|
|
102
|
+
# both lines are required. `RedisClient::Cluster::Node::Config` does subclass `RedisClient::Config`
|
|
103
|
+
# and calls `super` in its own `connection_prelude`, so cluster nodes are covered by the first.
|
|
104
|
+
RedisClient::Config.prepend(Redis::LibIdentity)
|
|
105
|
+
RedisClient::SentinelConfig.prepend(Redis::LibIdentity)
|
data/lib/redis/subscribe.rb
CHANGED
data/lib/redis/version.rb
CHANGED
data/lib/redis.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "redis-client"
|
|
4
|
+
|
|
3
5
|
require "monitor"
|
|
4
6
|
require "redis/errors"
|
|
5
7
|
require "redis/commands"
|
|
@@ -51,8 +53,14 @@ class Redis
|
|
|
51
53
|
# @option options [String] :password Password to authenticate against server
|
|
52
54
|
# @option options [Integer] :db (0) Database to select after connect and on reconnects
|
|
53
55
|
# @option options [Symbol] :driver Driver to use, currently supported: `:ruby`, `:hiredis`
|
|
56
|
+
# @option options [Integer] :protocol (3) RESP protocol version to negotiate (`HELLO`). Defaults
|
|
57
|
+
# to RESP3; set to `2` for RESP2. Servers without RESP3 support automatically fall back to RESP2.
|
|
54
58
|
# @option options [String] :id ID for the client connection, assigns name to current connection by sending
|
|
55
59
|
# `CLIENT SETNAME`
|
|
60
|
+
# @option options [String, Array<String>, false] :driver_info Identity a library built on top of `redis-rb`
|
|
61
|
+
# reports to the server via `CLIENT SETINFO`, shown as `lib-name=redis-rb(<driver_info>)` in `CLIENT LIST`.
|
|
62
|
+
# The recommended format is `<name>_v<version>`; an Array is joined with `;`. Pass `false` to disable
|
|
63
|
+
# client identification entirely.
|
|
56
64
|
# @option options [Integer, Array<Integer, Float>] :reconnect_attempts Number of attempts trying to connect,
|
|
57
65
|
# or a list of sleep duration between attempts.
|
|
58
66
|
# @option options [Boolean] :inherit_socket (false) Whether to use socket in forked process or not
|
|
@@ -67,16 +75,29 @@ class Redis
|
|
|
67
75
|
if ENV["REDIS_URL"] && SERVER_URL_OPTIONS.none? { |o| @options.key?(o) }
|
|
68
76
|
@options[:url] = ENV["REDIS_URL"]
|
|
69
77
|
end
|
|
70
|
-
|
|
78
|
+
# Kept as state, not just a local: the RESP3->RESP2 fallback rebuilds @client and must re-apply
|
|
79
|
+
# socket inheritance, otherwise fork safety would be silently lost after a downgrade.
|
|
80
|
+
@inherit_socket = @options.delete(:inherit_socket)
|
|
81
|
+
# HIMPORT fieldsets are server session state that dies with the physical connection; the
|
|
82
|
+
# registry remembers each prepared schema so a lost session can be repaired (see the
|
|
83
|
+
# himport_* overrides below). Deleted from @options so it never reaches RedisClient::Config.
|
|
84
|
+
@himport_auto_prepare = @options.delete(:himport_auto_prepare) != false
|
|
85
|
+
@himport_fieldsets = {}
|
|
71
86
|
@subscription_client = nil
|
|
72
87
|
|
|
73
|
-
@client =
|
|
74
|
-
@client.inherit_socket! if inherit_socket
|
|
88
|
+
@client = build_client
|
|
75
89
|
end
|
|
76
90
|
|
|
77
91
|
# Run code without the client reconnecting
|
|
78
92
|
def without_reconnect(&block)
|
|
79
|
-
@client
|
|
93
|
+
# Route through #synchronize like every other @client access: it holds @monitor and applies the
|
|
94
|
+
# RESP3->RESP2 fallback. disable_reconnection establishes the connection eagerly, so if that
|
|
95
|
+
# handshake fails the fallback rebuilds @client and the whole block re-runs against the new
|
|
96
|
+
# (RESP2) client — keeping disable_reconnection bound to the live @client rather than a discarded
|
|
97
|
+
# one. Referencing the block argument (not @client) is what makes the retry pick up the rebuild.
|
|
98
|
+
synchronize do |client|
|
|
99
|
+
client.disable_reconnection(&block)
|
|
100
|
+
end
|
|
80
101
|
end
|
|
81
102
|
|
|
82
103
|
# Test whether or not the client is connected
|
|
@@ -116,7 +137,10 @@ class Redis
|
|
|
116
137
|
end
|
|
117
138
|
|
|
118
139
|
def dup
|
|
119
|
-
|
|
140
|
+
# inherit_socket and himport_auto_prepare are stripped from @options before the client config
|
|
141
|
+
# is built (RedisClient::Config doesn't know them); merge the live values back so the
|
|
142
|
+
# duplicate keeps the caller's settings instead of silently reverting to defaults.
|
|
143
|
+
self.class.new(@options.merge(inherit_socket: @inherit_socket, himport_auto_prepare: @himport_auto_prepare))
|
|
120
144
|
end
|
|
121
145
|
|
|
122
146
|
def connection
|
|
@@ -129,8 +153,70 @@ class Redis
|
|
|
129
153
|
}
|
|
130
154
|
end
|
|
131
155
|
|
|
156
|
+
# HIMPORT overrides adding fieldset-loss recovery on top of the transport-pure methods in
|
|
157
|
+
# Commands::Hashes. The connection can be transparently replaced under the caller (reconnect
|
|
158
|
+
# after a network error, failover, RESET by a proxy), destroying every prepared fieldset. The
|
|
159
|
+
# server then answers HIMPORT SET with "no such fieldset" — the authoritative signal that the
|
|
160
|
+
# session was lost. These overrides remember the last schema prepared per fieldset name and,
|
|
161
|
+
# on that error, re-prepare it and retry the SET exactly once. An explicitly discarded
|
|
162
|
+
# fieldset is removed from the registry and is never resurrected. Disable the recovery with
|
|
163
|
+
# `Redis.new(himport_auto_prepare: false)`; the registry is still recorded for manual use.
|
|
164
|
+
|
|
165
|
+
# Each method holds @monitor across the server command AND its registry mutation: the two must
|
|
166
|
+
# be atomic with respect to other threads, otherwise a himport_set failing between another
|
|
167
|
+
# thread's DISCARD reply and its registry delete would still see the schema and re-prepare,
|
|
168
|
+
# resurrecting the fieldset the discard just removed. @monitor is reentrant, so the nested
|
|
169
|
+
# send_command/himport_prepare calls re-enter it safely.
|
|
170
|
+
|
|
171
|
+
def himport_prepare(fieldset_name, *fields)
|
|
172
|
+
fields.flatten!(1)
|
|
173
|
+
@monitor.synchronize do
|
|
174
|
+
reply = super(fieldset_name, fields)
|
|
175
|
+
@himport_fieldsets[fieldset_name.to_s] = fields.dup.freeze
|
|
176
|
+
reply
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def himport_set(key, fieldset_name, *values)
|
|
181
|
+
@monitor.synchronize do
|
|
182
|
+
super
|
|
183
|
+
rescue CommandError => error
|
|
184
|
+
fields = @himport_fieldsets[fieldset_name.to_s]
|
|
185
|
+
raise unless @himport_auto_prepare && fields && error.message.include?("no such fieldset")
|
|
186
|
+
|
|
187
|
+
himport_prepare(fieldset_name, fields)
|
|
188
|
+
# `super` (not himport_set) so a second failure propagates instead of recovering again.
|
|
189
|
+
super
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def himport_discard(fieldset_name)
|
|
194
|
+
@monitor.synchronize do
|
|
195
|
+
reply = super
|
|
196
|
+
@himport_fieldsets.delete(fieldset_name.to_s)
|
|
197
|
+
reply
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def himport_discard_all
|
|
202
|
+
@monitor.synchronize do
|
|
203
|
+
reply = super
|
|
204
|
+
@himport_fieldsets.clear
|
|
205
|
+
reply
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
132
209
|
private
|
|
133
210
|
|
|
211
|
+
# Builds @client from @options and applies any instance-level settings (socket inheritance) that
|
|
212
|
+
# live outside @options. Used both at construction and when the RESP3->RESP2 fallback rebuilds the
|
|
213
|
+
# client, so those settings survive a protocol downgrade.
|
|
214
|
+
def build_client
|
|
215
|
+
client = initialize_client(@options)
|
|
216
|
+
client.inherit_socket! if @inherit_socket
|
|
217
|
+
client
|
|
218
|
+
end
|
|
219
|
+
|
|
134
220
|
def initialize_client(options)
|
|
135
221
|
if options.key?(:cluster)
|
|
136
222
|
raise "Redis Cluster support was moved to the `redis-clustering` gem."
|
|
@@ -143,22 +229,64 @@ class Redis
|
|
|
143
229
|
end
|
|
144
230
|
end
|
|
145
231
|
|
|
232
|
+
# All access to @client funnels through here: it serializes on @monitor and applies the RESP3
|
|
233
|
+
# protocol fallback. Routing pipelined/multi/watch (which all call synchronize) through the same
|
|
234
|
+
# path means they fall back to RESP2 against pre-HELLO servers just like single commands do.
|
|
146
235
|
def synchronize
|
|
147
|
-
@monitor.synchronize
|
|
236
|
+
@monitor.synchronize do
|
|
237
|
+
with_protocol_fallback do
|
|
238
|
+
yield(@client)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
148
241
|
end
|
|
149
242
|
|
|
150
243
|
def send_command(command, &block)
|
|
151
|
-
|
|
152
|
-
|
|
244
|
+
synchronize do |client|
|
|
245
|
+
client.call_v(command, &block)
|
|
153
246
|
end
|
|
154
247
|
rescue ::RedisClient::Error => error
|
|
155
248
|
Client.translate_error!(error)
|
|
156
249
|
end
|
|
157
250
|
|
|
158
251
|
def send_blocking_command(command, timeout, &block)
|
|
159
|
-
|
|
160
|
-
|
|
252
|
+
synchronize do |client|
|
|
253
|
+
client.blocking_call_v(timeout, command, &block)
|
|
254
|
+
end
|
|
255
|
+
rescue ::RedisClient::Error => error
|
|
256
|
+
Client.translate_error!(error)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# We default to RESP3. Servers that don't support it reject the `HELLO 3` handshake (most
|
|
260
|
+
# notably Redis < 6.0, which has no HELLO command). Rebuild the client as RESP2 once so those
|
|
261
|
+
# servers keep working without the user setting `protocol: 2`.
|
|
262
|
+
#
|
|
263
|
+
# This is the single fallback point for every client type. Each one surfaces the resp3-unsupported
|
|
264
|
+
# error here untranslated (still a RedisClient::Error): standalone/distributed via
|
|
265
|
+
# Redis::Client#call_v et al., sentinel via the plain RedisClient (which never translates), and
|
|
266
|
+
# cluster via Redis::Cluster::Client#handle_errors. Because every @client access — single commands,
|
|
267
|
+
# pipelined, multi, watch, and the pub/sub socket — flows through #synchronize, wrapping it here
|
|
268
|
+
# covers them all.
|
|
269
|
+
#
|
|
270
|
+
# Must be called while holding @monitor: it closes and replaces @client, so it has to be
|
|
271
|
+
# serialized with the command execution that uses @client. The retried block re-reads @client, so
|
|
272
|
+
# callers must reference the rebuilt instance (via the synchronize block argument), not a cached
|
|
273
|
+
# one.
|
|
274
|
+
def with_protocol_fallback
|
|
275
|
+
yield
|
|
276
|
+
rescue ::RedisClient::Error => error
|
|
277
|
+
if @options.fetch(:protocol, 3).to_i == 3 && Client.resp3_unsupported?(error)
|
|
278
|
+
@options = @options.merge(protocol: 2)
|
|
279
|
+
@client.close
|
|
280
|
+
@client = build_client
|
|
281
|
+
# Warn only once the RESP2 client is actually in place — if the rebuild itself raises we
|
|
282
|
+
# haven't really fallen back. Fires once per client: @options[:protocol] is now 2, so this
|
|
283
|
+
# branch never re-enters. Passing `protocol: 2` explicitly skips it (and silences this).
|
|
284
|
+
warn("Redis: the server does not support RESP3 (the HELLO 3 handshake failed); falling back " \
|
|
285
|
+
"to RESP2. Pass `protocol: 2` to select RESP2 explicitly and silence this warning.")
|
|
286
|
+
retry
|
|
161
287
|
end
|
|
288
|
+
|
|
289
|
+
raise
|
|
162
290
|
end
|
|
163
291
|
|
|
164
292
|
def _subscription(method, timeout, channels, block)
|
|
@@ -168,7 +296,10 @@ class Redis
|
|
|
168
296
|
end
|
|
169
297
|
|
|
170
298
|
begin
|
|
171
|
-
|
|
299
|
+
# The pub/sub second socket is opened via @client.pubsub, which connects through
|
|
300
|
+
# ensure_connected rather than a command path. Route it through #synchronize so the same
|
|
301
|
+
# RESP3->RESP2 fallback applies when subscribe is the first operation against an old server.
|
|
302
|
+
@subscription_client = SubscribedClient.new(synchronize(&:pubsub))
|
|
172
303
|
if timeout > 0
|
|
173
304
|
@subscription_client.send(method, timeout, *channels, &block)
|
|
174
305
|
else
|
|
@@ -189,6 +320,7 @@ class Redis
|
|
|
189
320
|
end
|
|
190
321
|
|
|
191
322
|
require "redis/version"
|
|
323
|
+
require "redis/lib_identity"
|
|
192
324
|
require "redis/client"
|
|
193
325
|
require "redis/pipeline"
|
|
194
326
|
require "redis/subscribe"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: redis
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 6.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ezra Zygmuntowicz
|
|
@@ -15,22 +15,22 @@ authors:
|
|
|
15
15
|
- Pieter Noordhuis
|
|
16
16
|
bindir: bin
|
|
17
17
|
cert_chain: []
|
|
18
|
-
date:
|
|
18
|
+
date: 2026-07-31 00:00:00.000000000 Z
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
21
21
|
name: redis-client
|
|
22
22
|
requirement: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- -
|
|
24
|
+
- - '='
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.
|
|
26
|
+
version: 0.30.1
|
|
27
27
|
type: :runtime
|
|
28
28
|
prerelease: false
|
|
29
29
|
version_requirements: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- -
|
|
31
|
+
- - '='
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 0.
|
|
33
|
+
version: 0.30.1
|
|
34
34
|
description: |2
|
|
35
35
|
A Ruby client that tries to match Redis' API one-to-one, while still
|
|
36
36
|
providing an idiomatic interface.
|
|
@@ -54,6 +54,18 @@ files:
|
|
|
54
54
|
- lib/redis/commands/hyper_log_log.rb
|
|
55
55
|
- lib/redis/commands/keys.rb
|
|
56
56
|
- lib/redis/commands/lists.rb
|
|
57
|
+
- lib/redis/commands/modules/json.rb
|
|
58
|
+
- lib/redis/commands/modules/search.rb
|
|
59
|
+
- lib/redis/commands/modules/search/aggregation.rb
|
|
60
|
+
- lib/redis/commands/modules/search/dialect.rb
|
|
61
|
+
- lib/redis/commands/modules/search/field.rb
|
|
62
|
+
- lib/redis/commands/modules/search/hybrid.rb
|
|
63
|
+
- lib/redis/commands/modules/search/index.rb
|
|
64
|
+
- lib/redis/commands/modules/search/index_definition.rb
|
|
65
|
+
- lib/redis/commands/modules/search/miscellaneous.rb
|
|
66
|
+
- lib/redis/commands/modules/search/query.rb
|
|
67
|
+
- lib/redis/commands/modules/search/result.rb
|
|
68
|
+
- lib/redis/commands/modules/search/schema.rb
|
|
57
69
|
- lib/redis/commands/pubsub.rb
|
|
58
70
|
- lib/redis/commands/scripting.rb
|
|
59
71
|
- lib/redis/commands/server.rb
|
|
@@ -65,6 +77,7 @@ files:
|
|
|
65
77
|
- lib/redis/distributed.rb
|
|
66
78
|
- lib/redis/errors.rb
|
|
67
79
|
- lib/redis/hash_ring.rb
|
|
80
|
+
- lib/redis/lib_identity.rb
|
|
68
81
|
- lib/redis/pipeline.rb
|
|
69
82
|
- lib/redis/subscribe.rb
|
|
70
83
|
- lib/redis/version.rb
|
|
@@ -74,9 +87,9 @@ licenses:
|
|
|
74
87
|
metadata:
|
|
75
88
|
bug_tracker_uri: https://github.com/redis/redis-rb/issues
|
|
76
89
|
changelog_uri: https://github.com/redis/redis-rb/blob/master/CHANGELOG.md
|
|
77
|
-
documentation_uri: https://www.rubydoc.info/gems/redis/
|
|
90
|
+
documentation_uri: https://www.rubydoc.info/gems/redis/6.0.0
|
|
78
91
|
homepage_uri: https://github.com/redis/redis-rb
|
|
79
|
-
source_code_uri: https://github.com/redis/redis-rb/tree/
|
|
92
|
+
source_code_uri: https://github.com/redis/redis-rb/tree/v6.0.0
|
|
80
93
|
rdoc_options: []
|
|
81
94
|
require_paths:
|
|
82
95
|
- lib
|
|
@@ -84,7 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
84
97
|
requirements:
|
|
85
98
|
- - ">="
|
|
86
99
|
- !ruby/object:Gem::Version
|
|
87
|
-
version: 2.
|
|
100
|
+
version: 3.2.0
|
|
88
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
102
|
requirements:
|
|
90
103
|
- - ">="
|