6#include <unordered_map>
7#include <unordered_set>
10#include <userver/storages/redis/impl/exception.hpp>
11#include <userver/storages/redis/reply_types.hpp>
12#include <userver/storages/redis/request_data_base.hpp>
13#include <userver/storages/redis/scan_tag.hpp>
15USERVER_NAMESPACE_BEGIN
17namespace storages::
redis {
19template <ScanTag scan_tag>
22template <
typename Result,
typename ReplyType = Result>
23class [[nodiscard]] Request final {
25 using Reply = ReplyType;
27 explicit Request(std::unique_ptr<RequestDataBase<ReplyType>>&& impl)
28 : impl_(std::move(impl)) {}
30 void Wait() { impl_->Wait(); }
32 void IgnoreResult()
const {}
34 ReplyType Get(
const std::string& request_description = {}) {
35 return impl_->Get(request_description);
38 template <
typename T1,
typename T2>
39 friend class RequestEval;
41 template <
typename T1,
typename T2>
42 friend class RequestEvalSha;
44 template <ScanTag scan_tag>
45 friend class RequestScanData;
48 ReplyPtr GetRaw() {
return impl_->GetRaw(); }
50 std::unique_ptr<RequestDataBase<ReplyType>> impl_;
53template <ScanTag scan_tag>
54class ScanRequest final {
56 using ReplyElem =
typename ScanReplyElem<scan_tag>::type;
58 explicit ScanRequest(std::unique_ptr<RequestScanDataBase<scan_tag>>&& impl)
59 : impl_(std::move(impl)) {}
61 template <
typename T = std::vector<ReplyElem>>
62 T GetAll(std::string request_description) {
63 SetRequestDescription(std::move(request_description));
67 template <
typename T = std::vector<ReplyElem>>
69 return T{begin(), end()};
72 void SetRequestDescription(std::string request_description) {
73 impl_->SetRequestDescription(std::move(request_description));
78 using iterator_category = std::input_iterator_tag;
80 using value_type = ReplyElem;
81 using reference = value_type&;
82 using pointer = value_type*;
84 explicit Iterator(ScanRequest* stream) : stream_(stream) {
85 if (stream_ && !stream_->HasMore()) stream_ =
nullptr;
90 ReplyElemHolder(value_type reply_elem)
91 : reply_elem_(std::move(reply_elem)) {}
93 value_type& operator*() {
return reply_elem_; }
96 value_type reply_elem_;
107 if (!stream_->HasMore()) stream_ =
nullptr;
111 reference operator*() {
return stream_->Current(); }
113 pointer operator->() {
return &**
this; }
115 bool operator==(
const Iterator& rhs)
const {
116 return stream_ == rhs.stream_;
119 bool operator!=(
const Iterator& rhs)
const {
return !(*
this == rhs); }
122 ScanRequest* stream_;
130 using USERVER_NAMESPACE::redis::
Exception::Exception;
134 ReplyElem& Current() {
return impl_->Current(); }
136 ReplyElem Get() {
return impl_->Get(); }
138 bool HasMore() {
return !impl_->Eof(); }
142 std::unique_ptr<RequestScanDataBase<scan_tag>> impl_;
152using RequestExec = Request<ReplyData,
void>;
169using RequestHmset = Request<StatusOk,
void>;
170using RequestHscan = ScanRequest<ScanTag::kHscan>;
183using RequestLtrim = Request<StatusOk,
void>;
185using RequestMset = Request<StatusOk,
void>;
188using RequestPing = Request<StatusPong,
void>;
191using RequestRename = Request<StatusOk,
void>;
196using RequestScan = ScanRequest<ScanTag::kScan>;
198using RequestSet = Request<StatusOk,
void>;
199using RequestSetIfExist = Request<std::optional<StatusOk>,
bool>;
200using RequestSetIfNotExist = Request<std::optional<StatusOk>,
bool>;
202using RequestSetex = Request<StatusOk,
void>;
208using RequestSscan = ScanRequest<ScanTag::kSscan>;
225using RequestZscan = ScanRequest<ScanTag::kZscan>;