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/impl/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