valkey 0.1.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 +7 -0
- data/.rubocop.yml +12 -0
- data/README.md +25 -0
- data/Rakefile +12 -0
- data/lib/valkey/bindings.rb +95 -0
- data/lib/valkey/commands/connection.rb +59 -0
- data/lib/valkey/commands/server.rb +193 -0
- data/lib/valkey/commands/strings.rb +48 -0
- data/lib/valkey/commands.rb +13 -0
- data/lib/valkey/errors.rb +41 -0
- data/lib/valkey/libglide_ffi.so +0 -0
- data/lib/valkey/protobuf/command_request_pb.rb +47 -0
- data/lib/valkey/protobuf/connection_request_pb.rb +46 -0
- data/lib/valkey/protobuf/response_pb.rb +38 -0
- data/lib/valkey/request_type.rb +421 -0
- data/lib/valkey/response_type.rb +16 -0
- data/lib/valkey/version.rb +5 -0
- data/lib/valkey.rb +94 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e2b7ce5f8e5e8d2398b9c9e8c9c8e064e88d165ffb53d408d137deeae7b55520
|
4
|
+
data.tar.gz: fed8dc344aee90bdca008f64b935f89164303679000328024bd63d01b418c95f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a09a5e4c81ebf875ebc41613679d480e49b08826e233f67f2a0e5d45b8fdb5cc25e0267a2c0fd17cac8a5e638b843c3c0ca62ff440c38d036a0b5fc15ea417f6
|
7
|
+
data.tar.gz: 55a87cfcf18c1f78aa41e0964c3bd95520bc9e3f2369cae958ce095582d547d201a422a9e7f2f0ea3df0255d73561ea05fe01cad66d708f56c1245749f4ee5cd
|
data/.rubocop.yml
ADDED
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Valkey
|
2
|
+
|
3
|
+
Valkey gem is based on redis-rb and provides a Ruby client for Valkey
|
4
|
+
|
5
|
+
## Getting started
|
6
|
+
|
7
|
+
Install with:
|
8
|
+
|
9
|
+
```
|
10
|
+
$ gem install valkey
|
11
|
+
```
|
12
|
+
|
13
|
+
You can connect to Valkey by instantiating the `Valkey` class:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require "valkey"
|
17
|
+
|
18
|
+
valkey = Valkey.new
|
19
|
+
|
20
|
+
valkey.set("mykey", "hello world")
|
21
|
+
# => "OK"
|
22
|
+
|
23
|
+
valkey.get("mykey")
|
24
|
+
# => "hello world"
|
25
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Valkey
|
4
|
+
module Bindings
|
5
|
+
extend FFI::Library
|
6
|
+
|
7
|
+
ffi_lib File.expand_path("./libglide_ffi.so", __dir__)
|
8
|
+
|
9
|
+
class ClientType < FFI::Struct
|
10
|
+
layout(
|
11
|
+
:tag, :uint # 0 = AsyncClient, 1 = SyncClient
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
class ConnectionResponse < FFI::Struct
|
16
|
+
layout(
|
17
|
+
:conn_ptr, :pointer, # *const c_void
|
18
|
+
:connection_error_message, :string # *const c_char (null-terminated C string)
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
class CommandError < FFI::Struct
|
23
|
+
layout(
|
24
|
+
:command_error_message, :string,
|
25
|
+
:command_error_type, :int # Assuming RequestErrorType is repr(C) enum
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
class CommandResponse < FFI::Struct
|
30
|
+
layout(
|
31
|
+
:response_type, :int, # Assuming ResponseType is repr(C) enum
|
32
|
+
:int_value, :int64,
|
33
|
+
:float_value, :double,
|
34
|
+
:bool_value, :bool,
|
35
|
+
:string_value, :pointer, # points to C string
|
36
|
+
:string_value_len, :long,
|
37
|
+
:array_value, :pointer, # points to CommandResponse array
|
38
|
+
:array_value_len, :long,
|
39
|
+
:map_key, :pointer, # CommandResponse*
|
40
|
+
:map_value, :pointer, # CommandResponse*
|
41
|
+
:sets_value, :pointer, # CommandResponse*
|
42
|
+
:sets_value_len, :long
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
callback :success_callback, %i[ulong pointer], :void
|
47
|
+
callback :failure_callback, %i[ulong string int], :void
|
48
|
+
|
49
|
+
class AsyncClientData < FFI::Struct
|
50
|
+
layout(
|
51
|
+
:success_callback, :success_callback,
|
52
|
+
:failure_callback, :failure_callback
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
class ClientData < FFI::Union
|
57
|
+
layout(
|
58
|
+
:async_client, AsyncClientData
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
class CommandResult < FFI::Struct
|
63
|
+
layout(
|
64
|
+
:response, CommandResponse.by_ref,
|
65
|
+
:command_error, CommandError.by_ref
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
callback :pubsub_callback, [
|
70
|
+
:ulong, # client_ptr
|
71
|
+
:int, # kind (PushKind enum)
|
72
|
+
:pointer, :long, # message + length
|
73
|
+
:pointer, :long, # channel + length
|
74
|
+
:pointer, :long # pattern + length
|
75
|
+
], :void
|
76
|
+
|
77
|
+
attach_function :create_client, [
|
78
|
+
:pointer, # *const u8 (connection_request_bytes)
|
79
|
+
:ulong, # usize (connection_request_len)
|
80
|
+
ClientType.by_ref, # *const ClientType
|
81
|
+
:pubsub_callback # callback
|
82
|
+
], :pointer # *const ConnectionResponse
|
83
|
+
|
84
|
+
attach_function :command, [
|
85
|
+
:pointer, # client_adapter_ptr
|
86
|
+
:ulong, # channel
|
87
|
+
:int, # command_type
|
88
|
+
:ulong, # arg_count
|
89
|
+
:pointer, # args (pointer to usize[])
|
90
|
+
:pointer, # args_len (pointer to c_ulong[])
|
91
|
+
:pointer, # route_bytes
|
92
|
+
:ulong # route_bytes_len
|
93
|
+
], :pointer # returns *mut CommandResult
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Valkey
|
4
|
+
module Commands
|
5
|
+
# This module contains commands related to connection management.
|
6
|
+
module Connection
|
7
|
+
# Authenticate to the server.
|
8
|
+
#
|
9
|
+
# @param [Array<String>] args includes both username and password
|
10
|
+
# or only password
|
11
|
+
# @return [String] `OK`
|
12
|
+
# @see https://redis.io/commands/auth AUTH command
|
13
|
+
def auth(*args)
|
14
|
+
# TODO:
|
15
|
+
# send_command([:auth, *args])
|
16
|
+
end
|
17
|
+
|
18
|
+
# Ping the server.
|
19
|
+
#
|
20
|
+
# @param [optional, String] message
|
21
|
+
# @return [String] `PONG`
|
22
|
+
def ping(message = nil)
|
23
|
+
# TODO:
|
24
|
+
# send_command([:ping, message].compact)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Echo the given string.
|
28
|
+
#
|
29
|
+
# @param [String] value
|
30
|
+
# @return [String]
|
31
|
+
def echo(value)
|
32
|
+
# TODO:
|
33
|
+
# send_command([:echo, value])
|
34
|
+
end
|
35
|
+
|
36
|
+
# Change the selected database for the current connection.
|
37
|
+
#
|
38
|
+
# @param [Integer] db zero-based index of the DB to use (0 to 15)
|
39
|
+
# @return [String] `OK`
|
40
|
+
def select(db)
|
41
|
+
# TODO:
|
42
|
+
# send_command(RequestType::SELECT, [db.to_s])
|
43
|
+
end
|
44
|
+
|
45
|
+
# Close the connection.
|
46
|
+
#
|
47
|
+
# @return [String] `OK`
|
48
|
+
def quit
|
49
|
+
# TODO:
|
50
|
+
# synchronize do |client|
|
51
|
+
# client.call_v([:quit])
|
52
|
+
# rescue ConnectionError
|
53
|
+
# ensure
|
54
|
+
# client.close
|
55
|
+
# end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Valkey
|
4
|
+
module Commands
|
5
|
+
# This module contains commands related to server config.
|
6
|
+
module Server
|
7
|
+
# Asynchronously rewrite the append-only file.
|
8
|
+
#
|
9
|
+
# @return [String] `OK`
|
10
|
+
def bgrewriteaof
|
11
|
+
# TODO:
|
12
|
+
# send_command([:bgrewriteaof])
|
13
|
+
end
|
14
|
+
|
15
|
+
# Asynchronously save the dataset to disk.
|
16
|
+
#
|
17
|
+
# @return [String] `OK`
|
18
|
+
def bgsave
|
19
|
+
# TODO:
|
20
|
+
# send_command([:bgsave])
|
21
|
+
end
|
22
|
+
|
23
|
+
# Get or set server configuration parameters.
|
24
|
+
#
|
25
|
+
# @param [Symbol] action e.g. `:get`, `:set`, `:resetstat`
|
26
|
+
# @return [String, Hash] string reply, or hash when retrieving more than one
|
27
|
+
# property with `CONFIG GET`
|
28
|
+
def config(action, *args)
|
29
|
+
send_command([:config, action] + args) do |reply|
|
30
|
+
if reply.is_a?(Array) && action == :get
|
31
|
+
Hashify.call(reply)
|
32
|
+
else
|
33
|
+
reply
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Manage client connections.
|
39
|
+
#
|
40
|
+
# @param [String, Symbol] subcommand e.g. `kill`, `list`, `getname`, `setname`
|
41
|
+
# @return [String, Hash] depends on subcommand
|
42
|
+
def client(subcommand, *args)
|
43
|
+
send_command([:client, subcommand] + args) do |reply|
|
44
|
+
if subcommand.to_s == "list"
|
45
|
+
reply.lines.map do |line|
|
46
|
+
entries = line.chomp.split(/[ =]/)
|
47
|
+
Hash[entries.each_slice(2).to_a]
|
48
|
+
end
|
49
|
+
else
|
50
|
+
reply
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Return the number of keys in the selected database.
|
56
|
+
#
|
57
|
+
# @return [Integer]
|
58
|
+
def dbsize
|
59
|
+
send_command([:dbsize])
|
60
|
+
end
|
61
|
+
|
62
|
+
# Remove all keys from all databases.
|
63
|
+
#
|
64
|
+
# @param [Hash] options
|
65
|
+
# - `:async => Boolean`: async flush (default: false)
|
66
|
+
# @return [String] `OK`
|
67
|
+
def flushall(options = nil)
|
68
|
+
# TODO:
|
69
|
+
# if options && options[:async]
|
70
|
+
# send_command(%i[flushall async])
|
71
|
+
# else
|
72
|
+
# send_command([:flushall])
|
73
|
+
# end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Remove all keys from the current database.
|
77
|
+
#
|
78
|
+
# @param [Hash] options
|
79
|
+
# - `:async => Boolean`: async flush (default: false)
|
80
|
+
# @return [String] `OK`
|
81
|
+
def flushdb(options = nil)
|
82
|
+
# TODO:
|
83
|
+
# if options && options[:async]
|
84
|
+
# send_command(%i[flushdb async])
|
85
|
+
# else
|
86
|
+
# send_command([:flushdb])
|
87
|
+
# end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Get information and statistics about the server.
|
91
|
+
#
|
92
|
+
# @param [String, Symbol] cmd e.g. "commandstats"
|
93
|
+
# @return [Hash<String, String>]
|
94
|
+
def info(cmd = nil)
|
95
|
+
send_command([:info, cmd].compact) do |reply|
|
96
|
+
if reply.is_a?(String)
|
97
|
+
reply = HashifyInfo.call(reply)
|
98
|
+
|
99
|
+
if cmd && cmd.to_s == "commandstats"
|
100
|
+
# Extract nested hashes for INFO COMMANDSTATS
|
101
|
+
reply = Hash[reply.map do |k, v|
|
102
|
+
v = v.split(",").map { |e| e.split("=") }
|
103
|
+
[k[/^cmdstat_(.*)$/, 1], Hash[v]]
|
104
|
+
end]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
reply
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Get the UNIX time stamp of the last successful save to disk.
|
113
|
+
#
|
114
|
+
# @return [Integer]
|
115
|
+
def lastsave
|
116
|
+
send_command([:lastsave])
|
117
|
+
end
|
118
|
+
|
119
|
+
# Listen for all requests received by the server in real time.
|
120
|
+
#
|
121
|
+
# There is no way to interrupt this command.
|
122
|
+
#
|
123
|
+
# @yield a block to be called for every line of output
|
124
|
+
# @yieldparam [String] line timestamp and command that was executed
|
125
|
+
def monitor
|
126
|
+
synchronize do |client|
|
127
|
+
client = client.pubsub
|
128
|
+
client.call_v([:monitor])
|
129
|
+
loop do
|
130
|
+
yield client.next_event
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Synchronously save the dataset to disk.
|
136
|
+
#
|
137
|
+
# @return [String]
|
138
|
+
def save
|
139
|
+
send_command([:save])
|
140
|
+
end
|
141
|
+
|
142
|
+
# Synchronously save the dataset to disk and then shut down the server.
|
143
|
+
def shutdown
|
144
|
+
synchronize do |client|
|
145
|
+
client.disable_reconnection do
|
146
|
+
client.call_v([:shutdown])
|
147
|
+
rescue ConnectionError
|
148
|
+
# This means Redis has probably exited.
|
149
|
+
nil
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Make the server a slave of another instance, or promote it as master.
|
155
|
+
def slaveof(host, port)
|
156
|
+
send_command([:slaveof, host, port])
|
157
|
+
end
|
158
|
+
|
159
|
+
# Interact with the slowlog (get, len, reset)
|
160
|
+
#
|
161
|
+
# @param [String] subcommand e.g. `get`, `len`, `reset`
|
162
|
+
# @param [Integer] length maximum number of entries to return
|
163
|
+
# @return [Array<String>, Integer, String] depends on subcommand
|
164
|
+
def slowlog(subcommand, length = nil)
|
165
|
+
args = [:slowlog, subcommand]
|
166
|
+
args << Integer(length) if length
|
167
|
+
send_command(args)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Internal command used for replication.
|
171
|
+
def sync
|
172
|
+
send_command([:sync])
|
173
|
+
end
|
174
|
+
|
175
|
+
# Return the server time.
|
176
|
+
#
|
177
|
+
# @example
|
178
|
+
# r.time # => [ 1333093196, 606806 ]
|
179
|
+
#
|
180
|
+
# @return [Array<Integer>] tuple of seconds since UNIX epoch and
|
181
|
+
# microseconds in the current second
|
182
|
+
def time
|
183
|
+
send_command([:time]) do |reply|
|
184
|
+
reply&.map(&:to_i)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def debug(*args)
|
189
|
+
send_command([:debug] + args)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Valkey
|
4
|
+
module Commands
|
5
|
+
# This module contains commands related to strings.
|
6
|
+
module Strings
|
7
|
+
# Set the string value of a key.
|
8
|
+
#
|
9
|
+
# @param [String] key
|
10
|
+
# @param [String] value
|
11
|
+
# @param [Hash] options
|
12
|
+
# - `:ex => Integer`: Set the specified expire time, in seconds.
|
13
|
+
# - `:px => Integer`: Set the specified expire time, in milliseconds.
|
14
|
+
# - `:exat => Integer` : Set the specified Unix time at which the key will expire, in seconds.
|
15
|
+
# - `:pxat => Integer` : Set the specified Unix time at which the key will expire, in milliseconds.
|
16
|
+
# - `:nx => true`: Only set the key if it does not already exist.
|
17
|
+
# - `:xx => true`: Only set the key if it already exist.
|
18
|
+
# - `:keepttl => true`: Retain the time to live associated with the key.
|
19
|
+
# - `:get => true`: Return the old string stored at key, or nil if key did not exist.
|
20
|
+
# @return [String, Boolean] `"OK"` or true, false if `:nx => true` or `:xx => true`
|
21
|
+
def set(key, value, ex: nil, px: nil, exat: nil, pxat: nil, nx: nil, xx: nil, keepttl: nil, get: nil)
|
22
|
+
args = [key, value.to_s]
|
23
|
+
args << "EX" << Integer(ex) if ex
|
24
|
+
args << "PX" << Integer(px) if px
|
25
|
+
args << "EXAT" << Integer(exat) if exat
|
26
|
+
args << "PXAT" << Integer(pxat) if pxat
|
27
|
+
args << "NX" if nx
|
28
|
+
args << "XX" if xx
|
29
|
+
args << "KEEPTTL" if keepttl
|
30
|
+
args << "GET" if get
|
31
|
+
|
32
|
+
if nx || xx
|
33
|
+
send_command(RequestType::SET(args, &BoolifySet))
|
34
|
+
else
|
35
|
+
send_command(RequestType::SET, args)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get the value of a key.
|
40
|
+
#
|
41
|
+
# @param [String] key
|
42
|
+
# @return [String]
|
43
|
+
def get(key)
|
44
|
+
send_command(RequestType::GET, [key])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Valkey
|
4
|
+
class BaseError < StandardError; end
|
5
|
+
|
6
|
+
class ProtocolError < BaseError
|
7
|
+
def initialize(reply_type)
|
8
|
+
super(<<-EOS.gsub(/(?:^|\n)\s*/, " "))
|
9
|
+
Got '#{reply_type}' as initial reply byte.
|
10
|
+
If you're in a forking environment, such as Unicorn, you need to
|
11
|
+
connect to Valkey after forking.
|
12
|
+
EOS
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class CommandError < BaseError; end
|
17
|
+
|
18
|
+
class PermissionError < CommandError; end
|
19
|
+
|
20
|
+
class WrongTypeError < CommandError; end
|
21
|
+
|
22
|
+
class OutOfMemoryError < CommandError; end
|
23
|
+
|
24
|
+
class NoScriptError < CommandError; end
|
25
|
+
|
26
|
+
class BaseConnectionError < BaseError; end
|
27
|
+
|
28
|
+
class CannotConnectError < BaseConnectionError; end
|
29
|
+
|
30
|
+
class ConnectionError < BaseConnectionError; end
|
31
|
+
|
32
|
+
class TimeoutError < BaseConnectionError; end
|
33
|
+
|
34
|
+
class InheritedError < BaseConnectionError; end
|
35
|
+
|
36
|
+
class ReadOnlyError < BaseConnectionError; end
|
37
|
+
|
38
|
+
class InvalidClientOptionError < BaseError; end
|
39
|
+
|
40
|
+
class SubscriptionError < BaseError; end
|
41
|
+
end
|
Binary file
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
+
# source: command_request.proto
|
5
|
+
|
6
|
+
descriptor_data = "\n\x15\x63ommand_request.proto\x12\x0f\x63ommand_request\"M\n\x0bSlotIdRoute\x12-\n\tslot_type\x18\x01 \x01(\x0e\x32\x1a.command_request.SlotTypes\x12\x0f\n\x07slot_id\x18\x02 \x01(\x05\"O\n\x0cSlotKeyRoute\x12-\n\tslot_type\x18\x01 \x01(\x0e\x32\x1a.command_request.SlotTypes\x12\x10\n\x08slot_key\x18\x02 \x01(\t\",\n\x0e\x42yAddressRoute\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\x05\"\xf6\x01\n\x06Routes\x12\x36\n\rsimple_routes\x18\x01 \x01(\x0e\x32\x1d.command_request.SimpleRoutesH\x00\x12\x37\n\x0eslot_key_route\x18\x02 \x01(\x0b\x32\x1d.command_request.SlotKeyRouteH\x00\x12\x35\n\rslot_id_route\x18\x03 \x01(\x0b\x32\x1c.command_request.SlotIdRouteH\x00\x12;\n\x10\x62y_address_route\x18\x04 \x01(\x0b\x32\x1f.command_request.ByAddressRouteH\x00\x42\x07\n\x05value\"\xb6\x01\n\x07\x43ommand\x12\x32\n\x0crequest_type\x18\x01 \x01(\x0e\x32\x1c.command_request.RequestType\x12\x38\n\nargs_array\x18\x02 \x01(\x0b\x32\".command_request.Command.ArgsArrayH\x00\x12\x1a\n\x10\x61rgs_vec_pointer\x18\x03 \x01(\x04H\x00\x1a\x19\n\tArgsArray\x12\x0c\n\x04\x61rgs\x18\x01 \x03(\x0c\x42\x06\n\x04\x61rgs\"\x80\x01\n\x18ScriptInvocationPointers\x12\x0c\n\x04hash\x18\x01 \x01(\t\x12\x19\n\x0ckeys_pointer\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x19\n\x0c\x61rgs_pointer\x18\x03 \x01(\x04H\x01\x88\x01\x01\x42\x0f\n\r_keys_pointerB\x0f\n\r_args_pointer\"<\n\x10ScriptInvocation\x12\x0c\n\x04hash\x18\x01 \x01(\t\x12\x0c\n\x04keys\x18\x02 \x03(\x0c\x12\x0c\n\x04\x61rgs\x18\x03 \x03(\x0c\"9\n\x0bTransaction\x12*\n\x08\x63ommands\x18\x01 \x03(\x0b\x32\x18.command_request.Command\"\xb4\x01\n\x0b\x43lusterScan\x12\x0e\n\x06\x63ursor\x18\x01 \x01(\t\x12\x1a\n\rmatch_pattern\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\x05\x63ount\x18\x03 \x01(\x03H\x01\x88\x01\x01\x12\x18\n\x0bobject_type\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x1f\n\x17\x61llow_non_covered_slots\x18\x05 \x01(\x08\x42\x10\n\x0e_match_patternB\x08\n\x06_countB\x0e\n\x0c_object_type\"V\n\x18UpdateConnectionPassword\x12\x15\n\x08password\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x16\n\x0eimmediate_auth\x18\x02 \x01(\x08\x42\x0b\n\t_password\"\xda\x03\n\x0e\x43ommandRequest\x12\x14\n\x0c\x63\x61llback_idx\x18\x01 \x01(\r\x12\x32\n\x0esingle_command\x18\x02 \x01(\x0b\x32\x18.command_request.CommandH\x00\x12\x33\n\x0btransaction\x18\x03 \x01(\x0b\x32\x1c.command_request.TransactionH\x00\x12>\n\x11script_invocation\x18\x04 \x01(\x0b\x32!.command_request.ScriptInvocationH\x00\x12O\n\x1ascript_invocation_pointers\x18\x05 \x01(\x0b\x32).command_request.ScriptInvocationPointersH\x00\x12\x34\n\x0c\x63luster_scan\x18\x06 \x01(\x0b\x32\x1c.command_request.ClusterScanH\x00\x12O\n\x1aupdate_connection_password\x18\x07 \x01(\x0b\x32).command_request.UpdateConnectionPasswordH\x00\x12&\n\x05route\x18\x08 \x01(\x0b\x32\x17.command_request.RoutesB\t\n\x07\x63ommand*:\n\x0cSimpleRoutes\x12\x0c\n\x08\x41llNodes\x10\x00\x12\x10\n\x0c\x41llPrimaries\x10\x01\x12\n\n\x06Random\x10\x02*%\n\tSlotTypes\x12\x0b\n\x07Primary\x10\x00\x12\x0b\n\x07Replica\x10\x01*\xc7/\n\x0bRequestType\x12\x12\n\x0eInvalidRequest\x10\x00\x12\x11\n\rCustomCommand\x10\x01\x12\x0c\n\x08\x42itCount\x10\x65\x12\x0c\n\x08\x42itField\x10\x66\x12\x14\n\x10\x42itFieldReadOnly\x10g\x12\t\n\x05\x42itOp\x10h\x12\n\n\x06\x42itPos\x10i\x12\n\n\x06GetBit\x10j\x12\n\n\x06SetBit\x10k\x12\x0b\n\x06\x41sking\x10\xc9\x01\x12\x14\n\x0f\x43lusterAddSlots\x10\xca\x01\x12\x19\n\x14\x43lusterAddSlotsRange\x10\xcb\x01\x12\x15\n\x10\x43lusterBumpEpoch\x10\xcc\x01\x12\x1f\n\x1a\x43lusterCountFailureReports\x10\xcd\x01\x12\x1b\n\x16\x43lusterCountKeysInSlot\x10\xce\x01\x12\x14\n\x0f\x43lusterDelSlots\x10\xcf\x01\x12\x19\n\x14\x43lusterDelSlotsRange\x10\xd0\x01\x12\x14\n\x0f\x43lusterFailover\x10\xd1\x01\x12\x16\n\x11\x43lusterFlushSlots\x10\xd2\x01\x12\x12\n\rClusterForget\x10\xd3\x01\x12\x19\n\x14\x43lusterGetKeysInSlot\x10\xd4\x01\x12\x10\n\x0b\x43lusterInfo\x10\xd5\x01\x12\x13\n\x0e\x43lusterKeySlot\x10\xd6\x01\x12\x11\n\x0c\x43lusterLinks\x10\xd7\x01\x12\x10\n\x0b\x43lusterMeet\x10\xd8\x01\x12\x10\n\x0b\x43lusterMyId\x10\xd9\x01\x12\x15\n\x10\x43lusterMyShardId\x10\xda\x01\x12\x11\n\x0c\x43lusterNodes\x10\xdb\x01\x12\x14\n\x0f\x43lusterReplicas\x10\xdc\x01\x12\x15\n\x10\x43lusterReplicate\x10\xdd\x01\x12\x11\n\x0c\x43lusterReset\x10\xde\x01\x12\x16\n\x11\x43lusterSaveConfig\x10\xdf\x01\x12\x1a\n\x15\x43lusterSetConfigEpoch\x10\xe0\x01\x12\x13\n\x0e\x43lusterSetslot\x10\xe1\x01\x12\x12\n\rClusterShards\x10\xe2\x01\x12\x12\n\rClusterSlaves\x10\xe3\x01\x12\x11\n\x0c\x43lusterSlots\x10\xe4\x01\x12\r\n\x08ReadOnly\x10\xe5\x01\x12\x0e\n\tReadWrite\x10\xe6\x01\x12\t\n\x04\x41uth\x10\xad\x02\x12\x12\n\rClientCaching\x10\xae\x02\x12\x12\n\rClientGetName\x10\xaf\x02\x12\x13\n\x0e\x43lientGetRedir\x10\xb0\x02\x12\r\n\x08\x43lientId\x10\xb1\x02\x12\x0f\n\nClientInfo\x10\xb2\x02\x12\x15\n\x10\x43lientKillSimple\x10\xb3\x02\x12\x0f\n\nClientKill\x10\xb4\x02\x12\x0f\n\nClientList\x10\xb5\x02\x12\x12\n\rClientNoEvict\x10\xb6\x02\x12\x12\n\rClientNoTouch\x10\xb7\x02\x12\x10\n\x0b\x43lientPause\x10\xb8\x02\x12\x10\n\x0b\x43lientReply\x10\xb9\x02\x12\x12\n\rClientSetInfo\x10\xba\x02\x12\x12\n\rClientSetName\x10\xbb\x02\x12\x13\n\x0e\x43lientTracking\x10\xbc\x02\x12\x17\n\x12\x43lientTrackingInfo\x10\xbd\x02\x12\x12\n\rClientUnblock\x10\xbe\x02\x12\x12\n\rClientUnpause\x10\xbf\x02\x12\t\n\x04\x45\x63ho\x10\xc0\x02\x12\n\n\x05Hello\x10\xc1\x02\x12\t\n\x04Ping\x10\xc2\x02\x12\t\n\x04Quit\x10\xc3\x02\x12\n\n\x05Reset\x10\xc4\x02\x12\x0b\n\x06Select\x10\xc5\x02\x12\t\n\x04\x43opy\x10\x91\x03\x12\x08\n\x03\x44\x65l\x10\x92\x03\x12\t\n\x04\x44ump\x10\x93\x03\x12\x0b\n\x06\x45xists\x10\x94\x03\x12\x0b\n\x06\x45xpire\x10\x95\x03\x12\r\n\x08\x45xpireAt\x10\x96\x03\x12\x0f\n\nExpireTime\x10\x97\x03\x12\t\n\x04Keys\x10\x98\x03\x12\x0c\n\x07Migrate\x10\x99\x03\x12\t\n\x04Move\x10\x9a\x03\x12\x13\n\x0eObjectEncoding\x10\x9b\x03\x12\x0f\n\nObjectFreq\x10\x9c\x03\x12\x13\n\x0eObjectIdleTime\x10\x9d\x03\x12\x13\n\x0eObjectRefCount\x10\x9e\x03\x12\x0c\n\x07Persist\x10\x9f\x03\x12\x0c\n\x07PExpire\x10\xa0\x03\x12\x0e\n\tPExpireAt\x10\xa1\x03\x12\x10\n\x0bPExpireTime\x10\xa2\x03\x12\t\n\x04PTTL\x10\xa3\x03\x12\x0e\n\tRandomKey\x10\xa4\x03\x12\x0b\n\x06Rename\x10\xa5\x03\x12\r\n\x08RenameNX\x10\xa6\x03\x12\x0c\n\x07Restore\x10\xa7\x03\x12\t\n\x04Scan\x10\xa8\x03\x12\t\n\x04Sort\x10\xa9\x03\x12\x11\n\x0cSortReadOnly\x10\xaa\x03\x12\n\n\x05Touch\x10\xab\x03\x12\x08\n\x03TTL\x10\xac\x03\x12\t\n\x04Type\x10\xad\x03\x12\x0b\n\x06Unlink\x10\xae\x03\x12\t\n\x04Wait\x10\xaf\x03\x12\x0c\n\x07WaitAof\x10\xb0\x03\x12\x0b\n\x06GeoAdd\x10\xf5\x03\x12\x0c\n\x07GeoDist\x10\xf6\x03\x12\x0c\n\x07GeoHash\x10\xf7\x03\x12\x0b\n\x06GeoPos\x10\xf8\x03\x12\x0e\n\tGeoRadius\x10\xf9\x03\x12\x16\n\x11GeoRadiusReadOnly\x10\xfa\x03\x12\x16\n\x11GeoRadiusByMember\x10\xfb\x03\x12\x1e\n\x19GeoRadiusByMemberReadOnly\x10\xfc\x03\x12\x0e\n\tGeoSearch\x10\xfd\x03\x12\x13\n\x0eGeoSearchStore\x10\xfe\x03\x12\t\n\x04HDel\x10\xd9\x04\x12\x0c\n\x07HExists\x10\xda\x04\x12\t\n\x04HGet\x10\xdb\x04\x12\x0c\n\x07HGetAll\x10\xdc\x04\x12\x0c\n\x07HIncrBy\x10\xdd\x04\x12\x11\n\x0cHIncrByFloat\x10\xde\x04\x12\n\n\x05HKeys\x10\xdf\x04\x12\t\n\x04HLen\x10\xe0\x04\x12\n\n\x05HMGet\x10\xe1\x04\x12\n\n\x05HMSet\x10\xe2\x04\x12\x0f\n\nHRandField\x10\xe3\x04\x12\n\n\x05HScan\x10\xe4\x04\x12\t\n\x04HSet\x10\xe5\x04\x12\x0b\n\x06HSetNX\x10\xe6\x04\x12\x0c\n\x07HStrlen\x10\xe7\x04\x12\n\n\x05HVals\x10\xe8\x04\x12\n\n\x05PfAdd\x10\xbd\x05\x12\x0c\n\x07PfCount\x10\xbe\x05\x12\x0c\n\x07PfMerge\x10\xbf\x05\x12\x0b\n\x06\x42LMove\x10\xa1\x06\x12\x0b\n\x06\x42LMPop\x10\xa2\x06\x12\n\n\x05\x42LPop\x10\xa3\x06\x12\n\n\x05\x42RPop\x10\xa4\x06\x12\x0f\n\nBRPopLPush\x10\xa5\x06\x12\x0b\n\x06LIndex\x10\xa6\x06\x12\x0c\n\x07LInsert\x10\xa7\x06\x12\t\n\x04LLen\x10\xa8\x06\x12\n\n\x05LMove\x10\xa9\x06\x12\n\n\x05LMPop\x10\xaa\x06\x12\t\n\x04LPop\x10\xab\x06\x12\t\n\x04LPos\x10\xac\x06\x12\n\n\x05LPush\x10\xad\x06\x12\x0b\n\x06LPushX\x10\xae\x06\x12\x0b\n\x06LRange\x10\xaf\x06\x12\t\n\x04LRem\x10\xb0\x06\x12\t\n\x04LSet\x10\xb1\x06\x12\n\n\x05LTrim\x10\xb2\x06\x12\t\n\x04RPop\x10\xb3\x06\x12\x0e\n\tRPopLPush\x10\xb4\x06\x12\n\n\x05RPush\x10\xb5\x06\x12\x0b\n\x06RPushX\x10\xb6\x06\x12\x0f\n\nPSubscribe\x10\x85\x07\x12\x0c\n\x07Publish\x10\x86\x07\x12\x13\n\x0ePubSubChannels\x10\x87\x07\x12\x11\n\x0cPubSubNumPat\x10\x88\x07\x12\x11\n\x0cPubSubNumSub\x10\x89\x07\x12\x18\n\x13PubSubShardChannels\x10\x8a\x07\x12\x16\n\x11PubSubShardNumSub\x10\x8b\x07\x12\x11\n\x0cPUnsubscribe\x10\x8c\x07\x12\r\n\x08SPublish\x10\x8d\x07\x12\x0f\n\nSSubscribe\x10\x8e\x07\x12\x0e\n\tSubscribe\x10\x8f\x07\x12\x11\n\x0cSUnsubscribe\x10\x90\x07\x12\x10\n\x0bUnsubscribe\x10\x91\x07\x12\t\n\x04\x45val\x10\xe9\x07\x12\x11\n\x0c\x45valReadOnly\x10\xea\x07\x12\x0c\n\x07\x45valSha\x10\xeb\x07\x12\x14\n\x0f\x45valShaReadOnly\x10\xec\x07\x12\n\n\x05\x46\x43\x61ll\x10\xed\x07\x12\x12\n\rFCallReadOnly\x10\xee\x07\x12\x13\n\x0e\x46unctionDelete\x10\xef\x07\x12\x11\n\x0c\x46unctionDump\x10\xf0\x07\x12\x12\n\rFunctionFlush\x10\xf1\x07\x12\x11\n\x0c\x46unctionKill\x10\xf2\x07\x12\x11\n\x0c\x46unctionList\x10\xf3\x07\x12\x11\n\x0c\x46unctionLoad\x10\xf4\x07\x12\x14\n\x0f\x46unctionRestore\x10\xf5\x07\x12\x12\n\rFunctionStats\x10\xf6\x07\x12\x10\n\x0bScriptDebug\x10\xf7\x07\x12\x11\n\x0cScriptExists\x10\xf8\x07\x12\x10\n\x0bScriptFlush\x10\xf9\x07\x12\x0f\n\nScriptKill\x10\xfa\x07\x12\x0f\n\nScriptLoad\x10\xfb\x07\x12\x0f\n\nScriptShow\x10\xfc\x07\x12\x0b\n\x06\x41\x63lCat\x10\xcd\x08\x12\x0f\n\nAclDelUser\x10\xce\x08\x12\x0e\n\tAclDryRun\x10\xcf\x08\x12\x0f\n\nAclGenPass\x10\xd0\x08\x12\x0f\n\nAclGetUser\x10\xd1\x08\x12\x0c\n\x07\x41\x63lList\x10\xd2\x08\x12\x0c\n\x07\x41\x63lLoad\x10\xd3\x08\x12\x0b\n\x06\x41\x63lLog\x10\xd4\x08\x12\x0c\n\x07\x41\x63lSave\x10\xd5\x08\x12\x0f\n\nAclSetSser\x10\xd6\x08\x12\r\n\x08\x41\x63lUsers\x10\xd7\x08\x12\x0e\n\tAclWhoami\x10\xd8\x08\x12\x11\n\x0c\x42gRewriteAof\x10\xd9\x08\x12\x0b\n\x06\x42gSave\x10\xda\x08\x12\r\n\x08\x43ommand_\x10\xdb\x08\x12\x11\n\x0c\x43ommandCount\x10\xdc\x08\x12\x10\n\x0b\x43ommandDocs\x10\xdd\x08\x12\x13\n\x0e\x43ommandGetKeys\x10\xde\x08\x12\x1b\n\x16\x43ommandGetKeysAndFlags\x10\xdf\x08\x12\x10\n\x0b\x43ommandInfo\x10\xe0\x08\x12\x10\n\x0b\x43ommandList\x10\xe1\x08\x12\x0e\n\tConfigGet\x10\xe2\x08\x12\x14\n\x0f\x43onfigResetStat\x10\xe3\x08\x12\x12\n\rConfigRewrite\x10\xe4\x08\x12\x0e\n\tConfigSet\x10\xe5\x08\x12\x0b\n\x06\x44\x42Size\x10\xe6\x08\x12\r\n\x08\x46\x61ilOver\x10\xe7\x08\x12\r\n\x08\x46lushAll\x10\xe8\x08\x12\x0c\n\x07\x46lushDB\x10\xe9\x08\x12\t\n\x04Info\x10\xea\x08\x12\r\n\x08LastSave\x10\xeb\x08\x12\x12\n\rLatencyDoctor\x10\xec\x08\x12\x11\n\x0cLatencyGraph\x10\xed\x08\x12\x15\n\x10LatencyHistogram\x10\xee\x08\x12\x13\n\x0eLatencyHistory\x10\xef\x08\x12\x12\n\rLatencyLatest\x10\xf0\x08\x12\x11\n\x0cLatencyReset\x10\xf1\x08\x12\x0b\n\x06Lolwut\x10\xf2\x08\x12\x11\n\x0cMemoryDoctor\x10\xf3\x08\x12\x16\n\x11MemoryMallocStats\x10\xf4\x08\x12\x10\n\x0bMemoryPurge\x10\xf5\x08\x12\x10\n\x0bMemoryStats\x10\xf6\x08\x12\x10\n\x0bMemoryUsage\x10\xf7\x08\x12\x0f\n\nModuleList\x10\xf8\x08\x12\x0f\n\nModuleLoad\x10\xf9\x08\x12\x11\n\x0cModuleLoadEx\x10\xfa\x08\x12\x11\n\x0cModuleUnload\x10\xfb\x08\x12\x0c\n\x07Monitor\x10\xfc\x08\x12\n\n\x05PSync\x10\xfd\x08\x12\r\n\x08ReplConf\x10\xfe\x08\x12\x0e\n\tReplicaOf\x10\xff\x08\x12\x12\n\rRestoreAsking\x10\x80\t\x12\t\n\x04Role\x10\x81\t\x12\t\n\x04Save\x10\x82\t\x12\r\n\x08ShutDown\x10\x83\t\x12\x0c\n\x07SlaveOf\x10\x84\t\x12\x0f\n\nSlowLogGet\x10\x85\t\x12\x0f\n\nSlowLogLen\x10\x86\t\x12\x11\n\x0cSlowLogReset\x10\x87\t\x12\x0b\n\x06SwapDb\x10\x88\t\x12\t\n\x04Sync\x10\x89\t\x12\t\n\x04Time\x10\x8a\t\x12\t\n\x04SAdd\x10\xb1\t\x12\n\n\x05SCard\x10\xb2\t\x12\n\n\x05SDiff\x10\xb3\t\x12\x0f\n\nSDiffStore\x10\xb4\t\x12\x0b\n\x06SInter\x10\xb5\t\x12\x0f\n\nSInterCard\x10\xb6\t\x12\x10\n\x0bSInterStore\x10\xb7\t\x12\x0e\n\tSIsMember\x10\xb8\t\x12\r\n\x08SMembers\x10\xb9\t\x12\x0f\n\nSMIsMember\x10\xba\t\x12\n\n\x05SMove\x10\xbb\t\x12\t\n\x04SPop\x10\xbc\t\x12\x10\n\x0bSRandMember\x10\xbd\t\x12\t\n\x04SRem\x10\xbe\t\x12\n\n\x05SScan\x10\xbf\t\x12\x0b\n\x06SUnion\x10\xc0\t\x12\x10\n\x0bSUnionStore\x10\xc1\t\x12\x0b\n\x06\x42ZMPop\x10\x95\n\x12\r\n\x08\x42ZPopMax\x10\x96\n\x12\r\n\x08\x42ZPopMin\x10\x97\n\x12\t\n\x04ZAdd\x10\x98\n\x12\n\n\x05ZCard\x10\x99\n\x12\x0b\n\x06ZCount\x10\x9a\n\x12\n\n\x05ZDiff\x10\x9b\n\x12\x0f\n\nZDiffStore\x10\x9c\n\x12\x0c\n\x07ZIncrBy\x10\x9d\n\x12\x0b\n\x06ZInter\x10\x9e\n\x12\x0f\n\nZInterCard\x10\x9f\n\x12\x10\n\x0bZInterStore\x10\xa0\n\x12\x0e\n\tZLexCount\x10\xa1\n\x12\n\n\x05ZMPop\x10\xa2\n\x12\x0c\n\x07ZMScore\x10\xa3\n\x12\x0c\n\x07ZPopMax\x10\xa4\n\x12\x0c\n\x07ZPopMin\x10\xa5\n\x12\x10\n\x0bZRandMember\x10\xa6\n\x12\x0b\n\x06ZRange\x10\xa7\n\x12\x10\n\x0bZRangeByLex\x10\xa8\n\x12\x12\n\rZRangeByScore\x10\xa9\n\x12\x10\n\x0bZRangeStore\x10\xaa\n\x12\n\n\x05ZRank\x10\xab\n\x12\t\n\x04ZRem\x10\xac\n\x12\x13\n\x0eZRemRangeByLex\x10\xad\n\x12\x14\n\x0fZRemRangeByRank\x10\xae\n\x12\x15\n\x10ZRemRangeByScore\x10\xaf\n\x12\x0e\n\tZRevRange\x10\xb0\n\x12\x13\n\x0eZRevRangeByLex\x10\xb1\n\x12\x15\n\x10ZRevRangeByScore\x10\xb2\n\x12\r\n\x08ZRevRank\x10\xb3\n\x12\n\n\x05ZScan\x10\xb4\n\x12\x0b\n\x06ZScore\x10\xb5\n\x12\x0b\n\x06ZUnion\x10\xb6\n\x12\x10\n\x0bZUnionStore\x10\xb7\n\x12\t\n\x04XAck\x10\xf9\n\x12\t\n\x04XAdd\x10\xfa\n\x12\x0f\n\nXAutoClaim\x10\xfb\n\x12\x0b\n\x06XClaim\x10\xfc\n\x12\t\n\x04XDel\x10\xfd\n\x12\x11\n\x0cXGroupCreate\x10\xfe\n\x12\x19\n\x14XGroupCreateConsumer\x10\xff\n\x12\x16\n\x11XGroupDelConsumer\x10\x80\x0b\x12\x12\n\rXGroupDestroy\x10\x81\x0b\x12\x10\n\x0bXGroupSetId\x10\x82\x0b\x12\x13\n\x0eXInfoConsumers\x10\x83\x0b\x12\x10\n\x0bXInfoGroups\x10\x84\x0b\x12\x10\n\x0bXInfoStream\x10\x85\x0b\x12\t\n\x04XLen\x10\x86\x0b\x12\r\n\x08XPending\x10\x87\x0b\x12\x0b\n\x06XRange\x10\x88\x0b\x12\n\n\x05XRead\x10\x89\x0b\x12\x0f\n\nXReadGroup\x10\x8a\x0b\x12\x0e\n\tXRevRange\x10\x8b\x0b\x12\x0b\n\x06XSetId\x10\x8c\x0b\x12\n\n\x05XTrim\x10\x8d\x0b\x12\x0b\n\x06\x41ppend\x10\xdd\x0b\x12\t\n\x04\x44\x65\x63r\x10\xde\x0b\x12\x0b\n\x06\x44\x65\x63rBy\x10\xdf\x0b\x12\x08\n\x03Get\x10\xe0\x0b\x12\x0b\n\x06GetDel\x10\xe1\x0b\x12\n\n\x05GetEx\x10\xe2\x0b\x12\r\n\x08GetRange\x10\xe3\x0b\x12\x0b\n\x06GetSet\x10\xe4\x0b\x12\t\n\x04Incr\x10\xe5\x0b\x12\x0b\n\x06IncrBy\x10\xe6\x0b\x12\x10\n\x0bIncrByFloat\x10\xe7\x0b\x12\x08\n\x03LCS\x10\xe8\x0b\x12\t\n\x04MGet\x10\xe9\x0b\x12\t\n\x04MSet\x10\xea\x0b\x12\x0b\n\x06MSetNX\x10\xeb\x0b\x12\x0b\n\x06PSetEx\x10\xec\x0b\x12\x08\n\x03Set\x10\xed\x0b\x12\n\n\x05SetEx\x10\xee\x0b\x12\n\n\x05SetNX\x10\xef\x0b\x12\r\n\x08SetRange\x10\xf0\x0b\x12\x0b\n\x06Strlen\x10\xf1\x0b\x12\x0b\n\x06Substr\x10\xf2\x0b\x12\x0c\n\x07\x44iscard\x10\xc1\x0c\x12\t\n\x04\x45xec\x10\xc2\x0c\x12\n\n\x05Multi\x10\xc3\x0c\x12\x0c\n\x07UnWatch\x10\xc4\x0c\x12\n\n\x05Watch\x10\xc5\x0c\x12\x12\n\rJsonArrAppend\x10\xd1\x0f\x12\x11\n\x0cJsonArrIndex\x10\xd2\x0f\x12\x12\n\rJsonArrInsert\x10\xd3\x0f\x12\x0f\n\nJsonArrLen\x10\xd4\x0f\x12\x0f\n\nJsonArrPop\x10\xd5\x0f\x12\x10\n\x0bJsonArrTrim\x10\xd6\x0f\x12\x0e\n\tJsonClear\x10\xd7\x0f\x12\x0e\n\tJsonDebug\x10\xd8\x0f\x12\x0c\n\x07JsonDel\x10\xd9\x0f\x12\x0f\n\nJsonForget\x10\xda\x0f\x12\x0c\n\x07JsonGet\x10\xdb\x0f\x12\r\n\x08JsonMGet\x10\xdc\x0f\x12\x12\n\rJsonNumIncrBy\x10\xdd\x0f\x12\x12\n\rJsonNumMultBy\x10\xde\x0f\x12\x10\n\x0bJsonObjKeys\x10\xdf\x0f\x12\x0f\n\nJsonObjLen\x10\xe0\x0f\x12\r\n\x08JsonResp\x10\xe1\x0f\x12\x0c\n\x07JsonSet\x10\xe2\x0f\x12\x12\n\rJsonStrAppend\x10\xe3\x0f\x12\x0f\n\nJsonStrLen\x10\xe4\x0f\x12\x0f\n\nJsonToggle\x10\xe5\x0f\x12\r\n\x08JsonType\x10\xe6\x0f\x12\x0b\n\x06\x46tList\x10\xb5\x10\x12\x10\n\x0b\x46tAggregate\x10\xb6\x10\x12\x0f\n\nFtAliasAdd\x10\xb7\x10\x12\x0f\n\nFtAliasDel\x10\xb8\x10\x12\x10\n\x0b\x46tAliasList\x10\xb9\x10\x12\x12\n\rFtAliasUpdate\x10\xba\x10\x12\r\n\x08\x46tCreate\x10\xbb\x10\x12\x10\n\x0b\x46tDropIndex\x10\xbc\x10\x12\x0e\n\tFtExplain\x10\xbd\x10\x12\x11\n\x0c\x46tExplainCli\x10\xbe\x10\x12\x0b\n\x06\x46tInfo\x10\xbf\x10\x12\x0e\n\tFtProfile\x10\xc0\x10\x12\r\n\x08\x46tSearch\x10\xc1\x10\x62\x06proto3"
|
7
|
+
|
8
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
9
|
+
|
10
|
+
begin
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
rescue TypeError
|
13
|
+
# Compatibility code: will be removed in the next major version.
|
14
|
+
require "google/protobuf/descriptor_pb"
|
15
|
+
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
|
16
|
+
parsed.clear_dependency
|
17
|
+
serialized = parsed.class.encode(parsed)
|
18
|
+
file = pool.add_serialized_file(serialized)
|
19
|
+
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
|
20
|
+
imports = []
|
21
|
+
imports.each do |type_name, expected_filename|
|
22
|
+
import_file = pool.lookup(type_name).file_descriptor
|
23
|
+
if import_file.name != expected_filename
|
24
|
+
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
warn "Each proto file must use a consistent fully-qualified name."
|
28
|
+
warn "This will become an error in the next major version."
|
29
|
+
end
|
30
|
+
|
31
|
+
module CommandRequest
|
32
|
+
SlotIdRoute = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.SlotIdRoute").msgclass
|
33
|
+
SlotKeyRoute = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.SlotKeyRoute").msgclass
|
34
|
+
ByAddressRoute = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.ByAddressRoute").msgclass
|
35
|
+
Routes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.Routes").msgclass
|
36
|
+
Command = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.Command").msgclass
|
37
|
+
Command::ArgsArray = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.Command.ArgsArray").msgclass
|
38
|
+
ScriptInvocationPointers = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.ScriptInvocationPointers").msgclass
|
39
|
+
ScriptInvocation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.ScriptInvocation").msgclass
|
40
|
+
Transaction = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.Transaction").msgclass
|
41
|
+
ClusterScan = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.ClusterScan").msgclass
|
42
|
+
UpdateConnectionPassword = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.UpdateConnectionPassword").msgclass
|
43
|
+
CommandRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.CommandRequest").msgclass
|
44
|
+
SimpleRoutes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.SimpleRoutes").enummodule
|
45
|
+
SlotTypes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.SlotTypes").enummodule
|
46
|
+
RequestType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("command_request.RequestType").enummodule
|
47
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
+
# source: connection_request.proto
|
5
|
+
|
6
|
+
require "google/protobuf"
|
7
|
+
|
8
|
+
descriptor_data = "\n\x18\x63onnection_request.proto\x12\x12\x63onnection_request\")\n\x0bNodeAddress\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\r\"8\n\x12\x41uthenticationInfo\x12\x10\n\x08password\x18\x01 \x01(\t\x12\x10\n\x08username\x18\x02 \x01(\t\"7\n\x1cPeriodicChecksManualInterval\x12\x17\n\x0f\x64uration_in_sec\x18\x01 \x01(\r\"\x18\n\x16PeriodicChecksDisabled\"8\n\x18PubSubChannelsOrPatterns\x12\x1c\n\x14\x63hannels_or_patterns\x18\x01 \x03(\x0c\"\xf1\x01\n\x13PubSubSubscriptions\x12k\n\x1c\x63hannels_or_patterns_by_type\x18\x01 \x03(\x0b\x32\x45.connection_request.PubSubSubscriptions.ChannelsOrPatternsByTypeEntry\x1am\n\x1d\x43hannelsOrPatternsByTypeEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12;\n\x05value\x18\x02 \x01(\x0b\x32,.connection_request.PubSubChannelsOrPatterns:\x02\x38\x01\"\x8f\x06\n\x11\x43onnectionRequest\x12\x32\n\taddresses\x18\x01 \x03(\x0b\x32\x1f.connection_request.NodeAddress\x12-\n\x08tls_mode\x18\x02 \x01(\x0e\x32\x1b.connection_request.TlsMode\x12\x1c\n\x14\x63luster_mode_enabled\x18\x03 \x01(\x08\x12\x17\n\x0frequest_timeout\x18\x04 \x01(\r\x12/\n\tread_from\x18\x05 \x01(\x0e\x32\x1c.connection_request.ReadFrom\x12N\n\x19\x63onnection_retry_strategy\x18\x06 \x01(\x0b\x32+.connection_request.ConnectionRetryStrategy\x12\x43\n\x13\x61uthentication_info\x18\x07 \x01(\x0b\x32&.connection_request.AuthenticationInfo\x12\x13\n\x0b\x64\x61tabase_id\x18\x08 \x01(\r\x12\x35\n\x08protocol\x18\t \x01(\x0e\x32#.connection_request.ProtocolVersion\x12\x13\n\x0b\x63lient_name\x18\n \x01(\t\x12[\n\x1fperiodic_checks_manual_interval\x18\x0b \x01(\x0b\x32\x30.connection_request.PeriodicChecksManualIntervalH\x00\x12N\n\x18periodic_checks_disabled\x18\x0c \x01(\x0b\x32*.connection_request.PeriodicChecksDisabledH\x00\x12\x45\n\x14pubsub_subscriptions\x18\r \x01(\x0b\x32\'.connection_request.PubSubSubscriptions\x12\x1f\n\x17inflight_requests_limit\x18\x0e \x01(\r\x12\x11\n\tclient_az\x18\x0f \x01(\tB\x11\n\x0fperiodic_checks\"[\n\x17\x43onnectionRetryStrategy\x12\x19\n\x11number_of_retries\x18\x01 \x01(\r\x12\x0e\n\x06\x66\x61\x63tor\x18\x02 \x01(\r\x12\x15\n\rexponent_base\x18\x03 \x01(\r*M\n\x08ReadFrom\x12\x0b\n\x07Primary\x10\x00\x12\x11\n\rPreferReplica\x10\x01\x12\x11\n\rLowestLatency\x10\x02\x12\x0e\n\nAZAffinity\x10\x03*4\n\x07TlsMode\x12\t\n\x05NoTls\x10\x00\x12\r\n\tSecureTls\x10\x01\x12\x0f\n\x0bInsecureTls\x10\x02*\'\n\x0fProtocolVersion\x12\t\n\x05RESP3\x10\x00\x12\t\n\x05RESP2\x10\x01*8\n\x11PubSubChannelType\x12\t\n\x05\x45xact\x10\x00\x12\x0b\n\x07Pattern\x10\x01\x12\x0b\n\x07Sharded\x10\x02\x62\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
|
12
|
+
begin
|
13
|
+
pool.add_serialized_file(descriptor_data)
|
14
|
+
rescue TypeError
|
15
|
+
# Compatibility code: will be removed in the next major version.
|
16
|
+
require "google/protobuf/descriptor_pb"
|
17
|
+
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
|
18
|
+
parsed.clear_dependency
|
19
|
+
serialized = parsed.class.encode(parsed)
|
20
|
+
file = pool.add_serialized_file(serialized)
|
21
|
+
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
|
22
|
+
imports = []
|
23
|
+
imports.each do |type_name, expected_filename|
|
24
|
+
import_file = pool.lookup(type_name).file_descriptor
|
25
|
+
if import_file.name != expected_filename
|
26
|
+
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
warn "Each proto file must use a consistent fully-qualified name."
|
30
|
+
warn "This will become an error in the next major version."
|
31
|
+
end
|
32
|
+
|
33
|
+
module ConnectionRequest
|
34
|
+
NodeAddress = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.NodeAddress").msgclass
|
35
|
+
AuthenticationInfo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.AuthenticationInfo").msgclass
|
36
|
+
PeriodicChecksManualInterval = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.PeriodicChecksManualInterval").msgclass
|
37
|
+
PeriodicChecksDisabled = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.PeriodicChecksDisabled").msgclass
|
38
|
+
PubSubChannelsOrPatterns = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.PubSubChannelsOrPatterns").msgclass
|
39
|
+
PubSubSubscriptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.PubSubSubscriptions").msgclass
|
40
|
+
ConnectionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.ConnectionRequest").msgclass
|
41
|
+
ConnectionRetryStrategy = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.ConnectionRetryStrategy").msgclass
|
42
|
+
ReadFrom = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.ReadFrom").enummodule
|
43
|
+
TlsMode = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.TlsMode").enummodule
|
44
|
+
ProtocolVersion = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.ProtocolVersion").enummodule
|
45
|
+
PubSubChannelType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("connection_request.PubSubChannelType").enummodule
|
46
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
+
# source: response.proto
|
5
|
+
|
6
|
+
require "google/protobuf"
|
7
|
+
|
8
|
+
descriptor_data = "\n\x0eresponse.proto\x12\x08response\"I\n\x0cRequestError\x12(\n\x04type\x18\x01 \x01(\x0e\x32\x1a.response.RequestErrorType\x12\x0f\n\x07message\x18\x02 \x01(\t\"\xd5\x01\n\x08Response\x12\x14\n\x0c\x63\x61llback_idx\x18\x01 \x01(\r\x12\x16\n\x0cresp_pointer\x18\x02 \x01(\x04H\x00\x12\x37\n\x11\x63onstant_response\x18\x03 \x01(\x0e\x32\x1a.response.ConstantResponseH\x00\x12/\n\rrequest_error\x18\x04 \x01(\x0b\x32\x16.response.RequestErrorH\x00\x12\x17\n\rclosing_error\x18\x05 \x01(\tH\x00\x12\x0f\n\x07is_push\x18\x06 \x01(\x08\x42\x07\n\x05value*O\n\x10RequestErrorType\x12\x0f\n\x0bUnspecified\x10\x00\x12\r\n\tExecAbort\x10\x01\x12\x0b\n\x07Timeout\x10\x02\x12\x0e\n\nDisconnect\x10\x03*\x1a\n\x10\x43onstantResponse\x12\x06\n\x02OK\x10\x00\x62\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
|
12
|
+
begin
|
13
|
+
pool.add_serialized_file(descriptor_data)
|
14
|
+
rescue TypeError
|
15
|
+
# Compatibility code: will be removed in the next major version.
|
16
|
+
require "google/protobuf/descriptor_pb"
|
17
|
+
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
|
18
|
+
parsed.clear_dependency
|
19
|
+
serialized = parsed.class.encode(parsed)
|
20
|
+
file = pool.add_serialized_file(serialized)
|
21
|
+
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
|
22
|
+
imports = []
|
23
|
+
imports.each do |type_name, expected_filename|
|
24
|
+
import_file = pool.lookup(type_name).file_descriptor
|
25
|
+
if import_file.name != expected_filename
|
26
|
+
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
warn "Each proto file must use a consistent fully-qualified name."
|
30
|
+
warn "This will become an error in the next major version."
|
31
|
+
end
|
32
|
+
|
33
|
+
module Response
|
34
|
+
RequestError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("response.RequestError").msgclass
|
35
|
+
Response = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("response.Response").msgclass
|
36
|
+
RequestErrorType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("response.RequestErrorType").enummodule
|
37
|
+
ConstantResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("response.ConstantResponse").enummodule
|
38
|
+
end
|
@@ -0,0 +1,421 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Valkey
|
4
|
+
module RequestType
|
5
|
+
INVALID_REQUEST = 0
|
6
|
+
CUSTOM_COMMAND = 1
|
7
|
+
|
8
|
+
# Bitmap commands
|
9
|
+
BIT_COUNT = 101
|
10
|
+
BIT_FIELD = 102
|
11
|
+
BIT_FIELD_READ_ONLY = 103
|
12
|
+
BIT_OP = 104
|
13
|
+
BIT_POS = 105
|
14
|
+
GET_BIT = 106
|
15
|
+
SET_BIT = 107
|
16
|
+
|
17
|
+
# Cluster commands
|
18
|
+
ASKING = 201
|
19
|
+
CLUSTER_ADD_SLOTS = 202
|
20
|
+
CLUSTER_ADD_SLOTS_RANGE = 203
|
21
|
+
CLUSTER_BUMP_EPOCH = 204
|
22
|
+
CLUSTER_COUNT_FAILURE_REPORTS = 205
|
23
|
+
CLUSTER_COUNT_KEYS_IN_SLOT = 206
|
24
|
+
CLUSTER_DEL_SLOTS = 207
|
25
|
+
CLUSTER_DEL_SLOTS_RANGE = 208
|
26
|
+
CLUSTER_FAILOVER = 209
|
27
|
+
CLUSTER_FLUSH_SLOTS = 210
|
28
|
+
CLUSTER_FORGET = 211
|
29
|
+
CLUSTER_GET_KEYS_IN_SLOT = 212
|
30
|
+
CLUSTER_INFO = 213
|
31
|
+
CLUSTER_KEY_SLOT = 214
|
32
|
+
CLUSTER_LINKS = 215
|
33
|
+
CLUSTER_MEET = 216
|
34
|
+
CLUSTER_MY_ID = 217
|
35
|
+
CLUSTER_MY_SHARD_ID = 218
|
36
|
+
CLUSTER_NODES = 219
|
37
|
+
CLUSTER_REPLICAS = 220
|
38
|
+
CLUSTER_REPLICATE = 221
|
39
|
+
CLUSTER_RESET = 222
|
40
|
+
CLUSTER_SAVE_CONFIG = 223
|
41
|
+
CLUSTER_SET_CONFIG_EPOCH = 224
|
42
|
+
CLUSTER_SETSLOT = 225
|
43
|
+
CLUSTER_SHARDS = 226
|
44
|
+
CLUSTER_SLAVES = 227
|
45
|
+
CLUSTER_SLOTS = 228
|
46
|
+
READ_ONLY = 229
|
47
|
+
READ_WRITE = 230
|
48
|
+
|
49
|
+
# Connection Management commands
|
50
|
+
AUTH = 301
|
51
|
+
CLIENT_CACHING = 302
|
52
|
+
CLIENT_GET_NAME = 303
|
53
|
+
CLIENT_GET_REDIR = 304
|
54
|
+
CLIENT_ID = 305
|
55
|
+
CLIENT_INFO = 306
|
56
|
+
CLIENT_KILL_SIMPLE = 307
|
57
|
+
CLIENT_KILL = 308
|
58
|
+
CLIENT_LIST = 309
|
59
|
+
CLIENT_NO_EVICT = 310
|
60
|
+
CLIENT_NO_TOUCH = 311
|
61
|
+
CLIENT_PAUSE = 312
|
62
|
+
CLIENT_REPLY = 313
|
63
|
+
CLIENT_SET_INFO = 314
|
64
|
+
CLIENT_SET_NAME = 315
|
65
|
+
CLIENT_TRACKING = 316
|
66
|
+
CLIENT_TRACKING_INFO = 317
|
67
|
+
CLIENT_UNBLOCK = 318
|
68
|
+
CLIENT_UNPAUSE = 319
|
69
|
+
ECHO = 320
|
70
|
+
HELLO = 321
|
71
|
+
PING = 322
|
72
|
+
QUIT = 323 # deprecated in 7.2.0
|
73
|
+
RESET = 324
|
74
|
+
SELECT = 325
|
75
|
+
|
76
|
+
# Generic commands
|
77
|
+
COPY = 401
|
78
|
+
DEL = 402
|
79
|
+
DUMP = 403
|
80
|
+
EXISTS = 404
|
81
|
+
EXPIRE = 405
|
82
|
+
EXPIRE_AT = 406
|
83
|
+
EXPIRE_TIME = 407
|
84
|
+
KEYS = 408
|
85
|
+
MIGRATE = 409
|
86
|
+
MOVE = 410
|
87
|
+
OBJECT_ENCODING = 411
|
88
|
+
OBJECT_FREQ = 412
|
89
|
+
OBJECT_IDLE_TIME = 413
|
90
|
+
OBJECT_REF_COUNT = 414
|
91
|
+
PERSIST = 415
|
92
|
+
PEXPIRE = 416
|
93
|
+
PEXPIRE_AT = 417
|
94
|
+
PEXPIRE_TIME = 418
|
95
|
+
PTTL = 419
|
96
|
+
RANDOM_KEY = 420
|
97
|
+
RENAME = 421
|
98
|
+
RENAME_NX = 422
|
99
|
+
RESTORE = 423
|
100
|
+
SCAN = 424
|
101
|
+
SORT = 425
|
102
|
+
SORT_READ_ONLY = 426
|
103
|
+
TOUCH = 427
|
104
|
+
TTL = 428
|
105
|
+
TYPE = 429
|
106
|
+
UNLINK = 430
|
107
|
+
WAIT = 431
|
108
|
+
WAIT_AOF = 432
|
109
|
+
|
110
|
+
# Geospatial indices commands
|
111
|
+
GEO_ADD = 501
|
112
|
+
GEO_DIST = 502
|
113
|
+
GEO_HASH = 503
|
114
|
+
GEO_POS = 504
|
115
|
+
GEO_RADIUS = 505
|
116
|
+
GEO_RADIUS_READ_ONLY = 506 # deprecated in 6.2.0
|
117
|
+
GEO_RADIUS_BY_MEMBER = 507
|
118
|
+
GEO_RADIUS_BY_MEMBER_READ_ONLY = 508 # deprecated in 6.2.0
|
119
|
+
GEO_SEARCH = 509
|
120
|
+
GEO_SEARCH_STORE = 510
|
121
|
+
|
122
|
+
# Hash commands
|
123
|
+
HDEL = 601
|
124
|
+
HEXISTS = 602
|
125
|
+
HGET = 603
|
126
|
+
HGET_ALL = 604
|
127
|
+
HINCR_BY = 605
|
128
|
+
HINCR_BY_FLOAT = 606
|
129
|
+
HKEYS = 607
|
130
|
+
HLEN = 608
|
131
|
+
HMGET = 609
|
132
|
+
HMSET = 610
|
133
|
+
HRAND_FIELD = 611
|
134
|
+
HSCAN = 612
|
135
|
+
HSET = 613
|
136
|
+
HSET_NX = 614
|
137
|
+
HSTRLEN = 615
|
138
|
+
HVALS = 616
|
139
|
+
|
140
|
+
# HyperLogLog commands
|
141
|
+
PFADD = 701
|
142
|
+
PFCOUNT = 702
|
143
|
+
PFMERGE = 703
|
144
|
+
|
145
|
+
# List commands
|
146
|
+
BLMOVE = 801
|
147
|
+
BLMPop = 802
|
148
|
+
BLPOP = 803
|
149
|
+
BRPOP = 804
|
150
|
+
BRPOPLPUSH = 805 # deprecated in 6.2.0
|
151
|
+
LINDEX = 806
|
152
|
+
LINSERT = 807
|
153
|
+
LLEN = 808
|
154
|
+
LMOVE = 809
|
155
|
+
LMPOP = 810
|
156
|
+
LPOP = 811
|
157
|
+
LPOS = 812
|
158
|
+
LPUSH = 813
|
159
|
+
LPUSHX = 814
|
160
|
+
LRANGE = 815
|
161
|
+
LREM = 816
|
162
|
+
LSET = 817
|
163
|
+
LTRIM = 818
|
164
|
+
RPOP = 819
|
165
|
+
RPOPLPUSH = 820 # deprecated in 6.2.0
|
166
|
+
RPUSH = 821
|
167
|
+
RPUSHX = 822
|
168
|
+
|
169
|
+
# Pub/Sub commands
|
170
|
+
PSUBSCRIBE = 901
|
171
|
+
PUBLISH = 902
|
172
|
+
PUBSUB_CHANNELS = 903
|
173
|
+
PUBSUB_NUM_PAT = 904
|
174
|
+
PUBSUB_NUM_SUB = 905
|
175
|
+
PUBSUB_SHARD_CHANNELS = 906
|
176
|
+
PUBSUB_SHARD_NUM_SUB = 907
|
177
|
+
PUNSUBSCRIBE = 908
|
178
|
+
SPUBLISH = 909
|
179
|
+
SSUBSCRIBE = 910
|
180
|
+
SUBSCRIBE = 911
|
181
|
+
SUNSUBSCRIBE = 912
|
182
|
+
UNSUBSCRIBE = 913
|
183
|
+
|
184
|
+
# Scripting and Functions commands
|
185
|
+
EVAL = 1001
|
186
|
+
EVAL_READ_ONLY = 1002
|
187
|
+
EVAL_SHA = 1003
|
188
|
+
EVAL_SHA_READ_ONLY = 1004
|
189
|
+
FCALL = 1005
|
190
|
+
FCALL_READ_ONLY = 1006
|
191
|
+
FUNCTION_DELETE = 1007
|
192
|
+
FUNCTION_DUMP = 1008
|
193
|
+
FUNCTION_FLUSH = 1009
|
194
|
+
FUNCTION_KILL = 1010
|
195
|
+
FUNCTION_LIST = 1011
|
196
|
+
FUNCTION_LOAD = 1012
|
197
|
+
FUNCTION_RESTORE = 1013
|
198
|
+
FUNCTION_STATS = 1014
|
199
|
+
SCRIPT_DEBUG = 1015
|
200
|
+
SCRIPT_EXISTS = 1016
|
201
|
+
SCRIPT_FLUSH = 1017
|
202
|
+
SCRIPT_KILL = 1018
|
203
|
+
SCRIPT_LOAD = 1019
|
204
|
+
SCRIPT_SHOW = 1020
|
205
|
+
|
206
|
+
# Server management commands
|
207
|
+
ACL_CAT = 1101
|
208
|
+
ACL_DEL_USER = 1102
|
209
|
+
ACL_DRY_RUN = 1103
|
210
|
+
ACL_GEN_PASS = 1104
|
211
|
+
ACL_GET_USER = 1105
|
212
|
+
ACL_LIST = 1106
|
213
|
+
ACL_LOAD = 1107
|
214
|
+
ACL_LOG = 1108
|
215
|
+
ACL_SAVE = 1109
|
216
|
+
ACL_SET_USER = 1110
|
217
|
+
ACL_USERS = 1111
|
218
|
+
ACL_WHOAMI = 1112
|
219
|
+
BG_REWRITE_AOF = 1113
|
220
|
+
BG_SAVE = 1114
|
221
|
+
COMMAND_ = 1115 # Command - renamed to avoid collisions
|
222
|
+
COMMAND_COUNT = 1116
|
223
|
+
COMMAND_DOCS = 1117
|
224
|
+
COMMAND_GET_KEYS = 1118
|
225
|
+
COMMAND_GET_KEYS_AND_FLAGS = 1119
|
226
|
+
COMMAND_INFO = 1120
|
227
|
+
COMMAND_LIST = 1121
|
228
|
+
CONFIG_GET = 1122
|
229
|
+
CONFIG_RESET_STAT = 1123
|
230
|
+
CONFIG_REWRITE = 1124
|
231
|
+
CONFIG_SET = 1125
|
232
|
+
DB_SIZE = 1126
|
233
|
+
FAIL_OVER = 1127
|
234
|
+
FLUSH_ALL = 1128
|
235
|
+
FLUSH_DB = 1129
|
236
|
+
INFO = 1130
|
237
|
+
LAST_SAVE = 1131
|
238
|
+
LATENCY_DOCTOR = 1132
|
239
|
+
LATENCY_GRAPH = 1133
|
240
|
+
LATENCY_HISTOGRAM = 1134
|
241
|
+
LATENCY_HISTORY = 1135
|
242
|
+
LATENCY_LATEST = 1136
|
243
|
+
LATENCY_RESET = 1137
|
244
|
+
LOLWUT = 1138
|
245
|
+
MEMORY_DOCTOR = 1139
|
246
|
+
MEMORY_MALLOC_STATS = 1140
|
247
|
+
MEMORY_PURGE = 1141
|
248
|
+
MEMORY_STATS = 1142
|
249
|
+
MEMORY_USAGE = 1143
|
250
|
+
MODULE_LIST = 1144
|
251
|
+
MODULE_LOAD = 1145
|
252
|
+
MODULE_LOAD_EX = 1146
|
253
|
+
MODULE_UNLOAD = 1147
|
254
|
+
MONITOR = 1148
|
255
|
+
PSYNC = 1149
|
256
|
+
REPL_CONF = 1150
|
257
|
+
REPLICA_OF = 1151
|
258
|
+
RESTORE_ASKING = 1152
|
259
|
+
ROLE = 1153
|
260
|
+
SAVE = 1154
|
261
|
+
SHUT_DOWN = 1155
|
262
|
+
SLAVE_OF = 1156
|
263
|
+
SLOWLOG_GET = 1157
|
264
|
+
SLOWLOG_LEN = 1158
|
265
|
+
SLOWLOG_RESET = 1159
|
266
|
+
SWAP_DB = 1160
|
267
|
+
SYNC = 1161
|
268
|
+
TIME = 1162
|
269
|
+
|
270
|
+
# Set commands
|
271
|
+
SADD = 1201
|
272
|
+
SCARD = 1202
|
273
|
+
SDIFF = 1203
|
274
|
+
SDIFF_STORE = 1204
|
275
|
+
SINTER = 1205
|
276
|
+
SINTER_CARD = 1206
|
277
|
+
SINTER_STORE = 1207
|
278
|
+
SISMEMBER = 1208
|
279
|
+
SMEMBERS = 1209
|
280
|
+
SMISMEMBER = 1210
|
281
|
+
|
282
|
+
# Set commands
|
283
|
+
S_MOVE = 1211
|
284
|
+
S_POP = 1212
|
285
|
+
S_RAND_MEMBER = 1213
|
286
|
+
S_REM = 1214
|
287
|
+
S_SCAN = 1215
|
288
|
+
S_UNION = 1216
|
289
|
+
S_UNION_STORE = 1217
|
290
|
+
|
291
|
+
# Sorted set commands
|
292
|
+
BZ_MPOP = 1301
|
293
|
+
BZ_POP_MAX = 1302
|
294
|
+
BZ_POP_MIN = 1303
|
295
|
+
Z_ADD = 1304
|
296
|
+
Z_CARD = 1305
|
297
|
+
Z_COUNT = 1306
|
298
|
+
Z_DIFF = 1307
|
299
|
+
Z_DIFF_STORE = 1308
|
300
|
+
Z_INCR_BY = 1309
|
301
|
+
Z_INTER = 1310
|
302
|
+
Z_INTER_CARD = 1311
|
303
|
+
Z_INTER_STORE = 1312
|
304
|
+
Z_LEX_COUNT = 1313
|
305
|
+
Z_MPOP = 1314
|
306
|
+
Z_MSCORE = 1315
|
307
|
+
Z_POP_MAX = 1316
|
308
|
+
Z_POP_MIN = 1317
|
309
|
+
Z_RAND_MEMBER = 1318
|
310
|
+
Z_RANGE = 1319
|
311
|
+
Z_RANGE_BY_LEX = 1320
|
312
|
+
Z_RANGE_BY_SCORE = 1321
|
313
|
+
Z_RANGE_STORE = 1322
|
314
|
+
Z_RANK = 1323
|
315
|
+
Z_REM = 1324
|
316
|
+
Z_REM_RANGE_BY_LEX = 1325
|
317
|
+
Z_REM_RANGE_BY_RANK = 1326
|
318
|
+
Z_REM_RANGE_BY_SCORE = 1327
|
319
|
+
Z_REV_RANGE = 1328
|
320
|
+
Z_REV_RANGE_BY_LEX = 1329
|
321
|
+
Z_REV_RANGE_BY_SCORE = 1330
|
322
|
+
Z_REV_RANK = 1331
|
323
|
+
Z_SCAN = 1332
|
324
|
+
Z_SCORE = 1333
|
325
|
+
Z_UNION = 1334
|
326
|
+
Z_UNION_STORE = 1335
|
327
|
+
|
328
|
+
# Stream commands
|
329
|
+
X_ACK = 1401
|
330
|
+
X_ADD = 1402
|
331
|
+
X_AUTO_CLAIM = 1403
|
332
|
+
X_CLAIM = 1404
|
333
|
+
X_DEL = 1405
|
334
|
+
X_GROUP_CREATE = 1406
|
335
|
+
X_GROUP_CREATE_CONSUMER = 1407
|
336
|
+
X_GROUP_DEL_CONSUMER = 1408
|
337
|
+
X_GROUP_DESTROY = 1409
|
338
|
+
X_GROUP_SET_ID = 1410
|
339
|
+
X_INFO_CONSUMERS = 1411
|
340
|
+
X_INFO_GROUPS = 1412
|
341
|
+
X_INFO_STREAM = 1413
|
342
|
+
X_LEN = 1414
|
343
|
+
X_PENDING = 1415
|
344
|
+
X_RANGE = 1416
|
345
|
+
X_READ = 1417
|
346
|
+
X_READ_GROUP = 1418
|
347
|
+
X_REV_RANGE = 1419
|
348
|
+
X_SET_ID = 1420
|
349
|
+
X_TRIM = 1421
|
350
|
+
|
351
|
+
# String commands
|
352
|
+
APPEND = 1501
|
353
|
+
DECR = 1502
|
354
|
+
DECR_BY = 1503
|
355
|
+
GET = 1504
|
356
|
+
GET_DEL = 1505
|
357
|
+
GET_EX = 1506
|
358
|
+
GET_RANGE = 1507
|
359
|
+
GET_SET = 1508 # deprecated in 6.2.0
|
360
|
+
INCR = 1509
|
361
|
+
INCR_BY = 1510
|
362
|
+
INCR_BY_FLOAT = 1511
|
363
|
+
LCS = 1512
|
364
|
+
MGET = 1513
|
365
|
+
MSET = 1514
|
366
|
+
MSET_NX = 1515
|
367
|
+
PSET_EX = 1516 # deprecated in 2.6.12
|
368
|
+
SET = 1517
|
369
|
+
SET_EX = 1518 # deprecated in 2.6.12
|
370
|
+
SET_NX = 1519 # deprecated in 2.6.12
|
371
|
+
SET_RANGE = 1520
|
372
|
+
STRLEN = 1521
|
373
|
+
SUBSTR = 1522
|
374
|
+
|
375
|
+
# Transaction commands
|
376
|
+
DISCARD = 1601
|
377
|
+
EXEC = 1602
|
378
|
+
MULTI = 1603
|
379
|
+
UNWATCH = 1604
|
380
|
+
WATCH = 1605
|
381
|
+
|
382
|
+
# JSON commands
|
383
|
+
JSON_ARR_APPEND = 2001
|
384
|
+
JSON_ARR_INDEX = 2002
|
385
|
+
JSON_ARR_INSERT = 2003
|
386
|
+
JSON_ARR_LEN = 2004
|
387
|
+
JSON_ARR_POP = 2005
|
388
|
+
JSON_ARR_TRIM = 2006
|
389
|
+
JSON_CLEAR = 2007
|
390
|
+
JSON_DEBUG = 2008
|
391
|
+
JSON_DEL = 2009
|
392
|
+
JSON_FORGET = 2010
|
393
|
+
JSON_GET = 2011
|
394
|
+
JSON_MGET = 2012
|
395
|
+
JSON_NUM_INCR_BY = 2013
|
396
|
+
JSON_NUM_MULT_BY = 2014
|
397
|
+
JSON_OBJ_KEYS = 2015
|
398
|
+
JSON_OBJ_LEN = 2016
|
399
|
+
JSON_RESP = 2017
|
400
|
+
JSON_SET = 2018
|
401
|
+
JSON_STR_APPEND = 2019
|
402
|
+
JSON_STR_LEN = 2020
|
403
|
+
JSON_TOGGLE = 2021
|
404
|
+
JSON_TYPE = 2022
|
405
|
+
|
406
|
+
# Vector Search commands
|
407
|
+
FT_LIST = 2101
|
408
|
+
FT_AGGREGATE = 2102
|
409
|
+
FT_ALIAS_ADD = 2103
|
410
|
+
FT_ALIAS_DEL = 2104
|
411
|
+
FT_ALIAS_LIST = 2105
|
412
|
+
FT_ALIAS_UPDATE = 2106
|
413
|
+
FT_CREATE = 2107
|
414
|
+
FT_DROP_INDEX = 2108
|
415
|
+
FT_EXPLAIN = 2109
|
416
|
+
FT_EXPLAIN_CLI = 2110
|
417
|
+
FT_INFO = 2111
|
418
|
+
FT_PROFILE = 2112
|
419
|
+
FT_SEARCH = 2113
|
420
|
+
end
|
421
|
+
end
|
data/lib/valkey.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ffi"
|
4
|
+
require "google/protobuf"
|
5
|
+
|
6
|
+
require "valkey/version"
|
7
|
+
require "valkey/request_type"
|
8
|
+
require "valkey/response_type"
|
9
|
+
require "valkey/protobuf/command_request_pb"
|
10
|
+
require "valkey/protobuf/connection_request_pb"
|
11
|
+
require "valkey/protobuf/response_pb"
|
12
|
+
require "valkey/bindings"
|
13
|
+
require "valkey/commands"
|
14
|
+
require "valkey/errors"
|
15
|
+
|
16
|
+
class Valkey
|
17
|
+
extend Bindings
|
18
|
+
include Commands
|
19
|
+
|
20
|
+
def your_pubsub_callback(_client_ptr, kind, msg_ptr, msg_len, chan_ptr, chan_len, pat_ptr, pat_len)
|
21
|
+
puts "PubSub received kind=#{kind}, message=#{msg_ptr.read_string(msg_len)}, channel=#{chan_ptr.read_string(chan_len)}, pattern=#{pat_ptr.read_string(pat_len)}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def send_command(command_type, command_args = [])
|
25
|
+
channel = 0
|
26
|
+
route = "" # empty or some serialized route bytes
|
27
|
+
|
28
|
+
arg_ptrs = FFI::MemoryPointer.new(:pointer, command_args.size)
|
29
|
+
arg_lens = FFI::MemoryPointer.new(:ulong, command_args.size)
|
30
|
+
buffers = []
|
31
|
+
|
32
|
+
command_args.each_with_index do |arg, i|
|
33
|
+
buf = FFI::MemoryPointer.from_string(arg)
|
34
|
+
buffers << buf # prevent garbage collection
|
35
|
+
arg_ptrs.put_pointer(i * FFI::Pointer.size, buf)
|
36
|
+
arg_lens.put_ulong(i * 8, arg.bytesize)
|
37
|
+
end
|
38
|
+
|
39
|
+
route_buf = FFI::MemoryPointer.from_string(route)
|
40
|
+
|
41
|
+
res = Bindings.command(
|
42
|
+
@connection, # Assuming @connection is set after create
|
43
|
+
channel,
|
44
|
+
command_type,
|
45
|
+
command_args.size,
|
46
|
+
arg_ptrs,
|
47
|
+
arg_lens,
|
48
|
+
route_buf,
|
49
|
+
route.bytesize
|
50
|
+
)
|
51
|
+
|
52
|
+
result = Bindings::CommandResult.new(res)[:response]
|
53
|
+
|
54
|
+
case result[:response_type]
|
55
|
+
when ResponseType::STRING
|
56
|
+
result[:string_value].read_string(result[:string_value_len])
|
57
|
+
when ResponseType::OK
|
58
|
+
"OK"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# TODO: use options
|
63
|
+
def initialize(_options = {})
|
64
|
+
request = ConnectionRequest::ConnectionRequest.new(
|
65
|
+
addresses: [ConnectionRequest::NodeAddress.new(host: "127.0.0.1", port: 6379)]
|
66
|
+
)
|
67
|
+
|
68
|
+
client_type = Bindings::ClientType.new
|
69
|
+
client_type[:tag] = 1 # AsyncClient
|
70
|
+
|
71
|
+
request_str = ConnectionRequest::ConnectionRequest.encode(request)
|
72
|
+
request_buf = FFI::MemoryPointer.new(:char, request_str.bytesize)
|
73
|
+
request_buf.put_bytes(0, request_str)
|
74
|
+
|
75
|
+
request_len = request_str.bytesize
|
76
|
+
|
77
|
+
response_ptr = Bindings.create_client(
|
78
|
+
request_buf,
|
79
|
+
request_len,
|
80
|
+
client_type,
|
81
|
+
method(:your_pubsub_callback) # Pass the pubsub callback
|
82
|
+
)
|
83
|
+
|
84
|
+
res = Bindings::ConnectionResponse.new(response_ptr)
|
85
|
+
|
86
|
+
@connection = res[:conn_ptr]
|
87
|
+
end
|
88
|
+
|
89
|
+
def close
|
90
|
+
# TODO: handle closing the connection properly
|
91
|
+
end
|
92
|
+
|
93
|
+
alias disconnect! close
|
94
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: valkey
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mohsen Alizadeh
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-07-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.17.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.17.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: google-protobuf
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.29.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.29.2
|
41
|
+
description: A Ruby client library for Valkey based on redis-rb.
|
42
|
+
email:
|
43
|
+
- mohsen@alizadeh.us
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".rubocop.yml"
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- lib/valkey.rb
|
52
|
+
- lib/valkey/bindings.rb
|
53
|
+
- lib/valkey/commands.rb
|
54
|
+
- lib/valkey/commands/connection.rb
|
55
|
+
- lib/valkey/commands/server.rb
|
56
|
+
- lib/valkey/commands/strings.rb
|
57
|
+
- lib/valkey/errors.rb
|
58
|
+
- lib/valkey/libglide_ffi.so
|
59
|
+
- lib/valkey/protobuf/command_request_pb.rb
|
60
|
+
- lib/valkey/protobuf/connection_request_pb.rb
|
61
|
+
- lib/valkey/protobuf/response_pb.rb
|
62
|
+
- lib/valkey/request_type.rb
|
63
|
+
- lib/valkey/response_type.rb
|
64
|
+
- lib/valkey/version.rb
|
65
|
+
homepage: https://github.com/mohsen-alizadeh/valkey-rb
|
66
|
+
licenses: []
|
67
|
+
metadata:
|
68
|
+
homepage_uri: https://github.com/mohsen-alizadeh/valkey-rb
|
69
|
+
source_code_uri: https://github.com/mohsen-alizadeh/valkey-rb
|
70
|
+
changelog_uri: https://github.com/mohsen-alizadeh/valkey-rb
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 3.1.0
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubygems_version: 3.5.22
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: A Ruby client library for Valkey based on redis-rb.
|
90
|
+
test_files: []
|