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/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>
14
15USERVER_NAMESPACE_BEGIN
16
17namespace storages::redis {
18
19template <ScanTag scan_tag>
20class RequestScanData;
21
22template <typename Result, typename ReplyType = Result>
23class [[nodiscard]] Request final {
24 public:
25 using Reply = ReplyType;
26
27 explicit Request(std::unique_ptr<RequestDataBase<ReplyType>>&& impl)
28 : impl_(std::move(impl)) {}
29
30 void Wait() { impl_->Wait(); }
31
32 void IgnoreResult() const {}
33
34 ReplyType Get(const std::string& request_description = {}) {
35 return impl_->Get(request_description);
36 }
37
38 template <typename T1, typename T2>
39 friend class RequestEval;
40
41 template <typename T1, typename T2>
42 friend class RequestEvalSha;
43
44 template <ScanTag scan_tag>
45 friend class RequestScanData;
46
47 private:
48 ReplyPtr GetRaw() { return impl_->GetRaw(); }
49
50 std::unique_ptr<RequestDataBase<ReplyType>> impl_;
51};
52
53template <ScanTag scan_tag>
54class ScanRequest final {
55 public:
56 using ReplyElem = typename ScanReplyElem<scan_tag>::type;
57
58 explicit ScanRequest(std::unique_ptr<RequestScanDataBase<scan_tag>>&& impl)
59 : impl_(std::move(impl)) {}
60
61 template <typename T = std::vector<ReplyElem>>
62 T GetAll(std::string request_description) {
63 SetRequestDescription(std::move(request_description));
64 return GetAll<T>();
65 }
66
67 template <typename T = std::vector<ReplyElem>>
68 T GetAll() {
69 return T{begin(), end()};
70 }
71
72 void SetRequestDescription(std::string request_description) {
73 impl_->SetRequestDescription(std::move(request_description));
74 }
75
76 class Iterator {
77 public:
78 using iterator_category = std::input_iterator_tag;
80 using value_type = ReplyElem;
81 using reference = value_type&;
82 using pointer = value_type*;
83
84 explicit Iterator(ScanRequest* stream) : stream_(stream) {
85 if (stream_ && !stream_->HasMore()) stream_ = nullptr;
86 }
87
88 class ReplyElemHolder {
89 public:
90 ReplyElemHolder(value_type reply_elem)
91 : reply_elem_(std::move(reply_elem)) {}
92
93 value_type& operator*() { return reply_elem_; }
94
95 private:
96 value_type reply_elem_;
97 };
98
99 ReplyElemHolder operator++(int) {
100 ReplyElemHolder old_value(stream_->Current());
101 ++*this;
102 return old_value;
103 }
104
105 Iterator& operator++() {
106 stream_->Get();
107 if (!stream_->HasMore()) stream_ = nullptr;
108 return *this;
109 }
110
111 reference operator*() { return stream_->Current(); }
112
113 pointer operator->() { return &**this; }
114
115 bool operator==(const Iterator& rhs) const {
116 return stream_ == rhs.stream_;
117 }
118
119 bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
120
121 private:
122 ScanRequest* stream_;
123 };
124
125 Iterator begin() { return Iterator(this); }
126 Iterator end() { return Iterator(nullptr); }
127
128 class GetAfterEofException : public USERVER_NAMESPACE::redis::Exception {
129 public:
130 using USERVER_NAMESPACE::redis::Exception::Exception;
131 };
132
133 private:
134 ReplyElem& Current() { return impl_->Current(); }
135
136 ReplyElem Get() { return impl_->Get(); }
137
138 bool HasMore() { return !impl_->Eof(); }
139
140 friend class Iterator;
141
142 std::unique_ptr<RequestScanDataBase<scan_tag>> impl_;
143};
144
147using RequestDel = Request<size_t>;
152using RequestExec = Request<ReplyData, void>;
160using RequestHdel = Request<size_t>;
165using RequestHincrbyfloat = Request<double>;
167using RequestHlen = Request<size_t>;
169using RequestHmset = Request<StatusOk, void>;
170using RequestHscan = ScanRequest<ScanTag::kHscan>;
172using RequestHsetnx = Request<size_t, bool>;
177using RequestLlen = Request<size_t>;
182using RequestLrem = Request<size_t>;
183using RequestLtrim = Request<StatusOk, void>;
185using RequestMset = Request<StatusOk, void>;
188using RequestPing = Request<StatusPong, void>;
191using RequestRename = Request<StatusOk, void>;
195using RequestSadd = Request<size_t>;
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>;
207using RequestSrem = Request<size_t>;
208using RequestSscan = ScanRequest<ScanTag::kSscan>;
213using RequestZadd = Request<size_t>;
214using RequestZaddIncr = Request<double>;
222using RequestZrem = Request<size_t>;
225using RequestZscan = ScanRequest<ScanTag::kZscan>;
226using RequestZscore = Request<std::optional<double>>;
227
228} // namespace storages::redis
229
230USERVER_NAMESPACE_END