userver: userver/storages/redis/request.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
request.hpp
1#pragma once
2
3#include <memory>
4#include <optional>
5#include <string>
6#include <unordered_map>
7#include <unordered_set>
8#include <vector>
9
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>
15
16USERVER_NAMESPACE_BEGIN
17
18namespace storages::redis {
19
20template <ScanTag scan_tag>
21class RequestScanData;
22
23template <typename Result, typename ReplyType = Result>
24class [[nodiscard]] Request final {
25 public:
26 using Reply = ReplyType;
27
28 explicit Request(std::unique_ptr<RequestDataBase<ReplyType>>&& impl)
29 : impl_(std::move(impl)) {}
30
31 void Wait() { impl_->Wait(); }
32
33 void IgnoreResult() const {}
34
35 ReplyType Get(const std::string& request_description = {}) {
36 return impl_->Get(request_description);
37 }
38
39 /// @cond
40 /// Internal helper for WaitAny/WaitAll
41 engine::impl::ContextAccessor* TryGetContextAccessor() noexcept {
42 return impl_->TryGetContextAccessor();
43 }
44 /// @endcond
45
46 template <typename T1, typename T2>
47 friend class RequestEval;
48
49 template <typename T1, typename T2>
50 friend class RequestEvalSha;
51
52 template <ScanTag scan_tag>
53 friend class RequestScanData;
54
55 private:
56 ReplyPtr GetRaw() { return impl_->GetRaw(); }
57
58 std::unique_ptr<RequestDataBase<ReplyType>> impl_;
59};
60
61template <ScanTag scan_tag>
62class ScanRequest final {
63 public:
64 using ReplyElem = typename ScanReplyElem<scan_tag>::type;
65
66 explicit ScanRequest(std::unique_ptr<RequestScanDataBase<scan_tag>>&& impl)
67 : impl_(std::move(impl)) {}
68
69 template <typename T = std::vector<ReplyElem>>
70 T GetAll(std::string request_description) {
71 SetRequestDescription(std::move(request_description));
72 return GetAll<T>();
73 }
74
75 template <typename T = std::vector<ReplyElem>>
76 T GetAll() {
77 return T{begin(), end()};
78 }
79
80 void SetRequestDescription(std::string request_description) {
81 impl_->SetRequestDescription(std::move(request_description));
82 }
83
84 class Iterator {
85 public:
86 using iterator_category = std::input_iterator_tag;
88 using value_type = ReplyElem;
89 using reference = value_type&;
90 using pointer = value_type*;
91
92 explicit Iterator(ScanRequest* stream) : stream_(stream) {
93 if (stream_ && !stream_->HasMore()) stream_ = nullptr;
94 }
95
96 class ReplyElemHolder {
97 public:
98 ReplyElemHolder(value_type reply_elem)
99 : reply_elem_(std::move(reply_elem)) {}
100
101 value_type& operator*() { return reply_elem_; }
102
103 private:
104 value_type reply_elem_;
105 };
106
107 ReplyElemHolder operator++(int) {
108 ReplyElemHolder old_value(stream_->Current());
109 ++*this;
110 return old_value;
111 }
112
113 Iterator& operator++() {
114 stream_->Get();
115 if (!stream_->HasMore()) stream_ = nullptr;
116 return *this;
117 }
118
119 reference operator*() { return stream_->Current(); }
120
121 pointer operator->() { return &**this; }
122
123 bool operator==(const Iterator& rhs) const {
124 return stream_ == rhs.stream_;
125 }
126
127 bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
128
129 private:
130 ScanRequest* stream_;
131 };
132
133 Iterator begin() { return Iterator(this); }
134 Iterator end() { return Iterator(nullptr); }
135
136 class GetAfterEofException : public USERVER_NAMESPACE::redis::Exception {
137 public:
138 using USERVER_NAMESPACE::redis::Exception::Exception;
139 };
140
141 private:
142 ReplyElem& Current() { return impl_->Current(); }
143
144 ReplyElem Get() { return impl_->Get(); }
145
146 bool HasMore() { return !impl_->Eof(); }
147
148 friend class Iterator;
149
150 std::unique_ptr<RequestScanDataBase<scan_tag>> impl_;
151};
152
155using RequestDel = Request<size_t>;
160using RequestExec = Request<ReplyData, void>;
168using RequestHdel = Request<size_t>;
173using RequestHincrbyfloat = Request<double>;
175using RequestHlen = Request<size_t>;
177using RequestHmset = Request<StatusOk, void>;
178using RequestHscan = ScanRequest<ScanTag::kHscan>;
180using RequestHsetnx = Request<size_t, bool>;
185using RequestLlen = Request<size_t>;
190using RequestLrem = Request<size_t>;
191using RequestLtrim = Request<StatusOk, void>;
193using RequestMset = Request<StatusOk, void>;
196using RequestPing = Request<StatusPong, void>;
199using RequestRename = Request<StatusOk, void>;
203using RequestSadd = Request<size_t>;
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>;
215using RequestSrem = Request<size_t>;
216using RequestSscan = ScanRequest<ScanTag::kSscan>;
221using RequestZadd = Request<size_t>;
222using RequestZaddIncr = Request<double>;
230using RequestZrem = Request<size_t>;
233using RequestZscan = ScanRequest<ScanTag::kZscan>;
234using RequestZscore = Request<std::optional<double>>;
235
236} // namespace storages::redis
237
238USERVER_NAMESPACE_END