6#include <unordered_map>
7#include <unordered_set>
10#include <userver/engine/impl/context_accessor.hpp>
11#include <userver/storages/redis/exception.hpp>
12#include <userver/storages/redis/reply_types.hpp>
13#include <userver/storages/redis/request_data_base.hpp>
14#include <userver/storages/redis/scan_tag.hpp>
16USERVER_NAMESPACE_BEGIN
20template <ScanTag scan_tag>
23template <
typename Result,
typename ReplyType = Result>
24class [[nodiscard]] Request final {
26 using Reply = ReplyType;
28 explicit Request(std::unique_ptr<RequestDataBase<ReplyType>>&& impl)
29 : impl_(std::move(impl)) {}
31 void Wait() { impl_->Wait(); }
33 void IgnoreResult()
const {}
35 ReplyType Get(
const std::string& request_description = {}) {
36 return impl_->Get(request_description);
41 engine::impl::ContextAccessor* TryGetContextAccessor()
noexcept {
42 return impl_->TryGetContextAccessor();
46 template <
typename T1,
typename T2>
47 friend class RequestEval;
49 template <
typename T1,
typename T2>
50 friend class RequestEvalSha;
52 template <ScanTag scan_tag>
53 friend class RequestScanData;
56 ReplyPtr GetRaw() {
return impl_->GetRaw(); }
58 std::unique_ptr<RequestDataBase<ReplyType>> impl_;
61template <ScanTag scan_tag>
62class ScanRequest final {
64 using ReplyElem =
typename ScanReplyElem<scan_tag>::type;
66 explicit ScanRequest(std::unique_ptr<RequestScanDataBase<scan_tag>>&& impl)
67 : impl_(std::move(impl)) {}
69 template <
typename T = std::vector<ReplyElem>>
70 T GetAll(std::string request_description) {
71 SetRequestDescription(std::move(request_description));
75 template <
typename T = std::vector<ReplyElem>>
77 return T{begin(), end()};
80 void SetRequestDescription(std::string request_description) {
81 impl_->SetRequestDescription(std::move(request_description));
86 using iterator_category = std::input_iterator_tag;
88 using value_type = ReplyElem;
89 using reference = value_type&;
90 using pointer = value_type*;
92 explicit Iterator(ScanRequest* stream) : stream_(stream) {
93 if (stream_ && !stream_->HasMore()) stream_ =
nullptr;
98 ReplyElemHolder(value_type reply_elem)
99 : reply_elem_(std::move(reply_elem)) {}
101 value_type& operator*() {
return reply_elem_; }
104 value_type reply_elem_;
115 if (!stream_->HasMore()) stream_ =
nullptr;
119 reference operator*() {
return stream_->Current(); }
121 pointer operator->() {
return &**
this; }
123 bool operator==(
const Iterator& rhs)
const {
124 return stream_ == rhs.stream_;
127 bool operator!=(
const Iterator& rhs)
const {
return !(*
this == rhs); }
130 ScanRequest* stream_;
138 using USERVER_NAMESPACE::redis::
Exception::Exception;
142 ReplyElem& Current() {
return impl_->Current(); }
144 ReplyElem Get() {
return impl_->Get(); }
146 bool HasMore() {
return !impl_->Eof(); }
150 std::unique_ptr<RequestScanDataBase<scan_tag>> impl_;
160using RequestExec = Request<ReplyData,
void>;
177using RequestHmset = Request<StatusOk,
void>;
178using RequestHscan = ScanRequest<ScanTag::kHscan>;
191using RequestLtrim = Request<StatusOk,
void>;
193using RequestMset = Request<StatusOk,
void>;
196using RequestPing = Request<StatusPong,
void>;
199using RequestRename = Request<StatusOk,
void>;
204using RequestScan = ScanRequest<ScanTag::kScan>;
206using RequestSet = Request<StatusOk,
void>;
207using RequestSetIfExist = Request<std::optional<StatusOk>,
bool>;
208using RequestSetIfNotExist = Request<std::optional<StatusOk>,
bool>;
210using RequestSetex = Request<StatusOk,
void>;
216using RequestSscan = ScanRequest<ScanTag::kSscan>;
233using RequestZscan = ScanRequest<ScanTag::kZscan>;