7#include <userver/logging/log_extra.hpp>
8#include <userver/utils/assert.hpp>
10#include <userver/storages/redis/impl/base.hpp>
11#include <userver/storages/redis/reply_status.hpp>
15USERVER_NAMESPACE_BEGIN
19class ReplyData
final {
21 using Array = std::vector<ReplyData>;
33 class KeyValues
final {
35 class KeyValue
final {
37 KeyValue(
const Array& array, size_t index)
38 : array_(array), index_(index) {}
40 std::string Key()
const {
return array_[index_ * 2].GetString(); }
41 std::string Value()
const {
return array_[index_ * 2 + 1].GetString(); }
48 class KeyValueIt
final {
50 KeyValueIt(
const Array& array, size_t index)
51 : array_(array), index_(index) {}
52 KeyValueIt& operator++() {
56 bool operator!=(
const KeyValueIt& r)
const {
return index_ != r.index_; }
57 KeyValue operator*()
const {
return {array_, index_}; }
64 explicit KeyValues(
const Array& array) : array_(array) {}
66 KeyValueIt begin()
const {
return {array_, 0}; }
67 KeyValueIt end()
const {
return {array_, size()}; }
69 size_t size()
const {
return array_.size() / 2; }
75 class MovableKeyValues
final {
77 class MovableKeyValue
final {
79 MovableKeyValue(ReplyData& key_data, ReplyData& value_data)
80 : key_data_(key_data), value_data_(value_data) {}
82 std::string& Key() {
return key_data_.GetString(); }
83 std::string& Value() {
return value_data_.GetString(); }
87 ReplyData& value_data_;
90 class MovableKeyValueIt
final {
92 MovableKeyValueIt(Array& array, size_t index)
93 : array_(array), index_(index) {}
94 MovableKeyValueIt& operator++() {
98 bool operator!=(
const MovableKeyValueIt& r)
const {
99 return index_ != r.index_;
101 MovableKeyValue operator*() {
102 return {array_[index_ * 2], array_[index_ * 2 + 1]};
110 explicit MovableKeyValues(Array& array) : array_(array) {}
112 MovableKeyValueIt begin()
const {
return {array_, 0}; }
113 MovableKeyValueIt end()
const {
return {array_, size()}; }
115 size_t size()
const {
return array_.size() / 2; }
121 MovableKeyValues GetMovableKeyValues();
123 ReplyData(
const redisReply* reply);
124 ReplyData(Array&& array);
125 ReplyData(std::string s);
126 ReplyData(
int value);
127 static ReplyData CreateError(std::string&& error_msg);
128 static ReplyData CreateStatus(std::string&& status_msg);
129 static ReplyData CreateNil();
131 explicit operator
bool()
const {
return type_ != Type::kNoReply; }
133 Type GetType()
const {
return type_; }
134 std::string GetTypeString()
const;
136 inline bool IsString()
const {
return type_ == Type::kString; }
137 inline bool IsArray()
const {
return type_ == Type::kArray; }
138 inline bool IsInt()
const {
return type_ == Type::kInteger; }
139 inline bool IsNil()
const {
return type_ == Type::kNil; }
140 inline bool IsStatus()
const {
return type_ == Type::kStatus; }
141 inline bool IsError()
const {
return type_ == Type::kError; }
142 bool IsUnusableInstanceError()
const;
143 bool IsReadonlyError()
const;
144 bool IsUnknownCommandError()
const;
146 bool IsErrorMoved()
const {
147 return IsError() && !string_.compare(0, 6,
"MOVED ");
150 bool IsErrorAsk()
const {
151 return IsError() && !string_.compare(0, 4,
"ASK ");
154 const std::string& GetString()
const {
159 std::string& GetString() {
164 const Array& GetArray()
const {
174 int64_t GetInt()
const {
179 const std::string& GetStatus()
const {
184 std::string& GetStatus() {
189 const std::string& GetError()
const {
194 std::string& GetError() {
199 const ReplyData& operator[](size_t idx)
const {
201 return array_.at(idx);
204 ReplyData& operator[](size_t idx) {
206 return array_.at(idx);
209 size_t GetSize()
const;
211 std::string ToDebugString()
const;
212 KeyValues GetKeyValues()
const;
213 static std::string TypeToString(Type type);
215 void ExpectType(ReplyData::Type type,
216 const std::string& request_description = {})
const;
218 void ExpectString(
const std::string& request_description = {})
const;
219 void ExpectArray(
const std::string& request_description = {})
const;
220 void ExpectInt(
const std::string& request_description = {})
const;
221 void ExpectNil(
const std::string& request_description = {})
const;
222 void ExpectStatus(
const std::string& request_description = {})
const;
223 void ExpectStatusEqualTo(
const std::string& expected_status_str,
224 const std::string& request_description = {})
const;
225 void ExpectError(
const std::string& request_description = {})
const;
228 ReplyData() =
default;
230 [[noreturn]]
void ThrowUnexpectedReplyType(
231 ReplyData::Type expected,
const std::string& request_description)
const;
233 Type type_ = Type::kNoReply;
242 Reply(std::string cmd, redisReply* redis_reply, ReplyStatus status);
243 Reply(std::string cmd, redisReply* redis_reply, ReplyStatus status,
244 std::string status_string);
245 Reply(std::string cmd, ReplyData&& data);
252 std::string status_string;
256 operator
bool()
const {
return IsOk(); }
259 bool IsLoggableError()
const;
260 bool IsUnusableInstanceError()
const;
261 bool IsReadonlyError()
const;
262 bool IsUnknownCommandError()
const;
263 const logging::LogExtra& GetLogExtra()
const;
264 void FillSpanTags(
tracing::Span& span)
const;
266 void ExpectIsOk(
const std::string& request_description = {})
const;
267 void ExpectType(ReplyData::Type type,
268 const std::string& request_description = {})
const;
270 void ExpectString(
const std::string& request_description = {})
const;
271 void ExpectArray(
const std::string& request_description = {})
const;
272 void ExpectInt(
const std::string& request_description = {})
const;
273 void ExpectNil(
const std::string& request_description = {})
const;
274 void ExpectStatus(
const std::string& request_description = {})
const;
275 void ExpectStatusEqualTo(
const std::string& expected_status_str,
276 const std::string& request_description = {})
const;
277 void ExpectError(
const std::string& request_description = {})
const;
279 const std::string& GetRequestDescription(
280 const std::string& request_description)
const;