userver: userver/storages/redis/request.hpp Source File
Loading...
Searching...
No Matches
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 {
25public:
26 using Reply = ReplyType;
27
28 explicit Request(std::unique_ptr<RequestDataBase<ReplyType>>&& impl) : impl_(std::move(impl)) {}
29
30 void Wait() { impl_->Wait(); }
31
32 void IgnoreResult() const {}
33
34 ReplyType Get(const std::string& request_description = {}) { return impl_->Get(request_description); }
35
36 /// @cond
37 /// Internal helper for WaitAny/WaitAll
38 engine::impl::ContextAccessor* TryGetContextAccessor() noexcept { return impl_->TryGetContextAccessor(); }
39 /// @endcond
40
41 template <typename T1, typename T2>
42 friend class RequestEval;
43
44 template <typename T1, typename T2>
45 friend class RequestEvalSha;
46
47 template <ScanTag scan_tag>
48 friend class RequestScanData;
49
50private:
51 ReplyPtr GetRaw() { return impl_->GetRaw(); }
52
53 std::unique_ptr<RequestDataBase<ReplyType>> impl_;
54};
55
56template <ScanTag scan_tag>
57class ScanRequest final {
58public:
59 using ReplyElem = typename ScanReplyElem<scan_tag>::type;
60
61 explicit ScanRequest(std::unique_ptr<RequestScanDataBase<scan_tag>>&& impl) : impl_(std::move(impl)) {}
62
63 template <typename T = std::vector<ReplyElem>>
64 T GetAll(std::string request_description) {
65 SetRequestDescription(std::move(request_description));
66 return GetAll<T>();
67 }
68
69 template <typename T = std::vector<ReplyElem>>
70 T GetAll() {
71 return T{begin(), end()};
72 }
73
74 void SetRequestDescription(std::string request_description) {
75 impl_->SetRequestDescription(std::move(request_description));
76 }
77
78 class Iterator {
79 public:
80 using iterator_category = std::input_iterator_tag;
82 using value_type = ReplyElem;
83 using reference = value_type&;
84 using pointer = value_type*;
85
86 explicit Iterator(ScanRequest* stream) : stream_(stream) {
87 if (stream_ && !stream_->HasMore()) stream_ = nullptr;
88 }
89
90 class ReplyElemHolder {
91 public:
92 ReplyElemHolder(value_type reply_elem) : reply_elem_(std::move(reply_elem)) {}
93
94 value_type& operator*() { return reply_elem_; }
95
96 private:
97 value_type reply_elem_;
98 };
99
100 ReplyElemHolder operator++(int) {
101 ReplyElemHolder old_value(stream_->Current());
102 ++*this;
103 return old_value;
104 }
105
106 Iterator& operator++() {
107 stream_->Get();
108 if (!stream_->HasMore()) stream_ = nullptr;
109 return *this;
110 }
111
112 reference operator*() { return stream_->Current(); }
113
114 pointer operator->() { return &**this; }
115
116 bool operator==(const Iterator& rhs) const { return stream_ == rhs.stream_; }
117
118 bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
119
120 private:
121 ScanRequest* stream_;
122 };
123
124 Iterator begin() { return Iterator(this); }
125 Iterator end() { return Iterator(nullptr); }
126
127 class GetAfterEofException : public USERVER_NAMESPACE::redis::Exception {
128 public:
129 using USERVER_NAMESPACE::redis::Exception::Exception;
130 };
131
132private:
133 ReplyElem& Current() { return impl_->Current(); }
134
135 ReplyElem Get() { return impl_->Get(); }
136
137 bool HasMore() { return !impl_->Eof(); }
138
139 friend class Iterator;
140
141 std::unique_ptr<RequestScanDataBase<scan_tag>> impl_;
142};
143
148using RequestDel = Request<size_t>;
153using RequestExec = Request<ReplyData, void>;
161using RequestHdel = Request<size_t>;
166using RequestHincrbyfloat = Request<double>;
168using RequestHlen = Request<size_t>;
170using RequestHmset = Request<StatusOk, void>;
171using RequestHscan = ScanRequest<ScanTag::kHscan>;
173using RequestHsetnx = Request<size_t, bool>;
178using RequestLlen = Request<size_t>;
183using RequestLrem = Request<size_t>;
184using RequestLtrim = Request<StatusOk, void>;
186using RequestMset = Request<StatusOk, void>;
189using RequestPing = Request<StatusPong, void>;
192using RequestRename = Request<StatusOk, void>;
196using RequestSadd = Request<size_t>;
197using RequestScan = ScanRequest<ScanTag::kScan>;
199using RequestSet = Request<StatusOk, void>;
200using RequestSetIfExist = Request<std::optional<StatusOk>, bool>;
201using RequestSetIfNotExist = Request<std::optional<StatusOk>, bool>;
203using RequestSetex = Request<StatusOk, void>;
208using RequestSrem = Request<size_t>;
209using RequestSscan = ScanRequest<ScanTag::kSscan>;
214using RequestZadd = Request<size_t>;
215using RequestZaddIncr = Request<double>;
223using RequestZrem = Request<size_t>;
226using RequestZscan = ScanRequest<ScanTag::kZscan>;
227using RequestZscore = Request<std::optional<double>>;
228
229} // namespace storages::redis
230
231USERVER_NAMESPACE_END