/Users/deen/code/yugabyte-db/src/yb/client/table_handle.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #ifndef YB_CLIENT_TABLE_HANDLE_H |
15 | | #define YB_CLIENT_TABLE_HANDLE_H |
16 | | |
17 | | #include <unordered_map> |
18 | | |
19 | | #include <boost/functional/hash.hpp> |
20 | | #include <boost/optional.hpp> |
21 | | |
22 | | #include "yb/client/client_fwd.h" |
23 | | |
24 | | #include "yb/common/column_id.h" |
25 | | #include "yb/common/ql_protocol.pb.h" |
26 | | #include "yb/common/ql_protocol_util.h" |
27 | | #include "yb/common/ql_rowblock.h" |
28 | | #include "yb/common/read_hybrid_time.h" |
29 | | |
30 | | #include "yb/util/async_util.h" |
31 | | #include "yb/util/strongly_typed_bool.h" |
32 | | |
33 | | namespace yb { |
34 | | namespace client { |
35 | | |
36 | | class YBTableName; |
37 | | class YBClient; |
38 | | class YBqlReadOp; |
39 | | class YBqlWriteOp; |
40 | | class YBSchema; |
41 | | class YBSchemaBuilder; |
42 | | |
43 | | class TableIterator; |
44 | | class TableRange; |
45 | | |
46 | | #define TABLE_HANDLE_TYPE_DECLARATIONS_IMPL(name, lname, type) \ |
47 | | void PP_CAT3(Add, name, ColumnValue)( \ |
48 | | QLWriteRequestPB* req, const std::string &column_name, type value) const; \ |
49 | | \ |
50 | | void PP_CAT3(Set, name, Condition)( \ |
51 | | QLConditionPB *const condition, const std::string &column_name, const QLOperator op, \ |
52 | | type value) const; \ |
53 | | void PP_CAT3(Add, name, Condition)( \ |
54 | | QLConditionPB *const condition, const std::string &column_name, const QLOperator op, \ |
55 | | type value) const; \ |
56 | | |
57 | | #define TABLE_HANDLE_TYPE_DECLARATIONS(i, data, entry) TABLE_HANDLE_TYPE_DECLARATIONS_IMPL entry |
58 | | |
59 | | // Utility class for manually filling QL operations. |
60 | | class TableHandle { |
61 | | public: |
62 | | CHECKED_STATUS Create(const YBTableName& table_name, |
63 | | int num_tablets, |
64 | | YBClient* client, |
65 | | YBSchemaBuilder* builder, |
66 | | IndexInfoPB* index_info = nullptr); |
67 | | |
68 | | CHECKED_STATUS Create(const YBTableName& table_name, |
69 | | int num_tablets, |
70 | | const YBSchema& schema, |
71 | | YBClient* client, |
72 | | IndexInfoPB* index_info = nullptr); |
73 | | |
74 | | CHECKED_STATUS Open(const YBTableName& table_name, YBClient* client); |
75 | | |
76 | | CHECKED_STATUS Reopen(); |
77 | | |
78 | | std::shared_ptr<YBqlWriteOp> NewWriteOp(QLWriteRequestPB::QLStmtType type) const; |
79 | | |
80 | 1.80M | std::shared_ptr<YBqlWriteOp> NewInsertOp() const { |
81 | 1.80M | return NewWriteOp(QLWriteRequestPB::QL_STMT_INSERT); |
82 | 1.80M | } |
83 | | |
84 | 83.4k | std::shared_ptr<YBqlWriteOp> NewUpdateOp() const { |
85 | 83.4k | return NewWriteOp(QLWriteRequestPB::QL_STMT_UPDATE); |
86 | 83.4k | } |
87 | | |
88 | 0 | std::shared_ptr<YBqlWriteOp> NewDeleteOp() const { |
89 | 0 | return NewWriteOp(QLWriteRequestPB::QL_STMT_DELETE); |
90 | 0 | } |
91 | | |
92 | | std::shared_ptr<YBqlReadOp> NewReadOp() const; |
93 | | |
94 | 3.73M | int32_t ColumnId(const std::string &column_name) const { |
95 | 3.73M | auto it = column_ids_.find(column_name); |
96 | 18.4E | return it != column_ids_.end()3.73M ? it->second3.73M : -1; |
97 | 3.73M | } |
98 | | |
99 | 1.69k | const std::shared_ptr<QLType>& ColumnType(const std::string &column_name) const { |
100 | 1.69k | static std::shared_ptr<QLType> not_found; |
101 | 1.69k | auto it = column_types_.find(yb::ColumnId(ColumnId(column_name))); |
102 | 1.69k | return it != column_types_.end() ? it->second : not_found0 ; |
103 | 1.69k | } |
104 | | |
105 | | BOOST_PP_SEQ_FOR_EACH(TABLE_HANDLE_TYPE_DECLARATIONS, ~, QL_PROTOCOL_TYPES); |
106 | | |
107 | | // Set a column id without value - for DELETE |
108 | | void SetColumn(QLColumnValuePB *column_value, const std::string &column_name) const; |
109 | | |
110 | | // Add a simple comparison operation under a logical comparison condition. |
111 | | // E.g. Add <EXISTS> under "... AND <EXISTS>". |
112 | | void AddCondition(QLConditionPB *const condition, const QLOperator op) const; |
113 | | |
114 | | void AddColumns(const std::vector<std::string>& columns, QLReadRequestPB* req) const; |
115 | | |
116 | 19.0k | const YBTablePtr& table() const { |
117 | 19.0k | return table_; |
118 | 19.0k | } |
119 | | |
120 | | const YBTableName& name() const; |
121 | | |
122 | | const YBSchema& schema() const; |
123 | | |
124 | 3.63k | YBTable* operator->() const { |
125 | 3.63k | return table_.get(); |
126 | 3.63k | } |
127 | | |
128 | 0 | YBTable* get() const { |
129 | 0 | return table_.get(); |
130 | 0 | } |
131 | | |
132 | 220 | YBClient* client() const { |
133 | 220 | return client_; |
134 | 220 | } |
135 | | |
136 | | std::vector<std::string> AllColumnNames() const; |
137 | | |
138 | | QLValuePB* PrepareColumn(QLWriteRequestPB* req, const string& column_name) const; |
139 | | QLValuePB* PrepareCondition( |
140 | | QLConditionPB* const condition, const string& column_name, const QLOperator op) const; |
141 | | |
142 | | private: |
143 | | typedef std::unordered_map<std::string, yb::ColumnId> ColumnIdsMap; |
144 | | using ColumnTypesMap = std::unordered_map< |
145 | | yb::ColumnId, const std::shared_ptr<QLType>, boost::hash<yb::ColumnId>>; |
146 | | |
147 | | YBClient* client_; |
148 | | YBTablePtr table_; |
149 | | ColumnIdsMap column_ids_; |
150 | | ColumnTypesMap column_types_; |
151 | | }; |
152 | | |
153 | | typedef std::function<void(const TableHandle&, QLConditionPB*)> TableFilter; |
154 | | |
155 | | struct TableIteratorOptions { |
156 | | TableIteratorOptions(); |
157 | | |
158 | | YBConsistencyLevel consistency = YBConsistencyLevel::STRONG; |
159 | | boost::optional<std::vector<std::string>> columns; |
160 | | TableFilter filter; |
161 | | ReadHybridTime read_time; |
162 | | std::string tablet; |
163 | | StatusFunctor error_handler; |
164 | | }; |
165 | | |
166 | | class TableIterator : public std::iterator< |
167 | | std::forward_iterator_tag, QLRow, ptrdiff_t, const QLRow*, const QLRow&> { |
168 | | public: |
169 | | TableIterator(); |
170 | | explicit TableIterator(const TableHandle* table, const TableIteratorOptions& options); |
171 | | |
172 | | bool Equals(const TableIterator& rhs) const; |
173 | | |
174 | | TableIterator& operator++(); |
175 | | |
176 | 0 | TableIterator operator++(int) { |
177 | 0 | TableIterator result = *this; |
178 | 0 | ++*this; |
179 | 0 | return result; |
180 | 0 | } |
181 | | |
182 | | const QLRow& operator*() const; |
183 | | |
184 | 0 | const QLRow* operator->() const { |
185 | 0 | return &**this; |
186 | 0 | } |
187 | | |
188 | | private: |
189 | | bool ExecuteOps(); |
190 | | void Move(); |
191 | | void HandleError(const Status& status); |
192 | | bool IsFlushStatusOkOrHandleErrors(FlushStatus flush_status); |
193 | | |
194 | | const TableHandle* table_; |
195 | | std::vector<YBqlReadOpPtr> ops_; |
196 | | std::vector<std::string> partition_key_ends_; |
197 | | size_t executed_ops_ = 0; |
198 | | size_t ops_index_ = 0; |
199 | | boost::optional<QLRowBlock> current_block_; |
200 | | const QLPagingStatePB* paging_state_ = nullptr; |
201 | | size_t row_index_; |
202 | | YBSessionPtr session_; |
203 | | StatusFunctor error_handler_; |
204 | | }; |
205 | | |
206 | 0 | inline bool operator==(const TableIterator& lhs, const TableIterator& rhs) { |
207 | 0 | return lhs.Equals(rhs); |
208 | 0 | } |
209 | | |
210 | 69.4k | inline bool operator!=(const TableIterator& lhs, const TableIterator& rhs) { |
211 | 69.4k | return !lhs.Equals(rhs); |
212 | 69.4k | } |
213 | | |
214 | | class TableRange { |
215 | | public: |
216 | | typedef TableIterator const_iterator; |
217 | | typedef TableIterator iterator; |
218 | | |
219 | | explicit TableRange(const TableHandle& table, TableIteratorOptions options = {}) |
220 | 218 | : table_(&table), options_(std::move(options)) { |
221 | 218 | if (!options_.columns) { |
222 | 22 | options_.columns = table.AllColumnNames(); |
223 | 22 | } |
224 | 218 | } |
225 | | |
226 | 218 | const_iterator begin() const { |
227 | 218 | return TableIterator(table_, options_); |
228 | 218 | } |
229 | | |
230 | 218 | const_iterator end() const { |
231 | 218 | return TableIterator(); |
232 | 218 | } |
233 | | |
234 | | private: |
235 | | const TableHandle* table_; |
236 | | TableIteratorOptions options_; |
237 | | }; |
238 | | |
239 | | YB_STRONGLY_TYPED_BOOL(Inclusive); |
240 | | |
241 | | template <class T> |
242 | | class FilterBetweenImpl { |
243 | | public: |
244 | | FilterBetweenImpl(const T& lower_bound, Inclusive lower_inclusive, |
245 | | const T& upper_bound, Inclusive upper_inclusive, |
246 | | std::string column = "key") |
247 | | : lower_bound_(lower_bound), lower_inclusive_(lower_inclusive), |
248 | | upper_bound_(upper_bound), upper_inclusive_(upper_inclusive), |
249 | | column_(std::move(column)) {} |
250 | | |
251 | | void operator()(const TableHandle& table, QLConditionPB* condition) const; |
252 | | private: |
253 | | T lower_bound_; |
254 | | Inclusive lower_inclusive_; |
255 | | T upper_bound_; |
256 | | Inclusive upper_inclusive_; |
257 | | std::string column_; |
258 | | }; |
259 | | |
260 | | template <class T> |
261 | | FilterBetweenImpl<T> FilterBetween(const T& lower_bound, Inclusive lower_inclusive, |
262 | | const T& upper_bound, Inclusive upper_inclusive, |
263 | | std::string column = "key") { |
264 | | return FilterBetweenImpl<T>(lower_bound, lower_inclusive, upper_bound, upper_inclusive, column); |
265 | | } |
266 | | |
267 | | class FilterGreater { |
268 | | public: |
269 | | FilterGreater(int32_t bound, Inclusive inclusive, std::string column = "key") |
270 | 0 | : bound_(bound), inclusive_(inclusive), column_(std::move(column)) {} |
271 | | |
272 | | void operator()(const TableHandle& table, QLConditionPB* condition) const; |
273 | | private: |
274 | | int32_t bound_; |
275 | | Inclusive inclusive_; |
276 | | std::string column_; |
277 | | }; |
278 | | |
279 | | class FilterLess { |
280 | | public: |
281 | | FilterLess(int32_t bound, Inclusive inclusive, std::string column = "key") |
282 | 0 | : bound_(bound), inclusive_(inclusive), column_(std::move(column)) {} |
283 | | |
284 | | void operator()(const TableHandle& table, QLConditionPB* condition) const; |
285 | | private: |
286 | | int32_t bound_; |
287 | | Inclusive inclusive_; |
288 | | std::string column_; |
289 | | }; |
290 | | |
291 | | template <class T> |
292 | | class FilterEqualImpl { |
293 | | public: |
294 | | FilterEqualImpl(const T& t, std::string column) |
295 | | : t_(t), column_(std::move(column)) {} |
296 | | |
297 | | void operator()(const TableHandle& table, QLConditionPB* condition) const; |
298 | | private: |
299 | | T t_; |
300 | | std::string column_; |
301 | | }; |
302 | | |
303 | | template <class T> |
304 | | FilterEqualImpl<T> FilterEqual(const T& t, std::string column = "key") { |
305 | | return FilterEqualImpl<T>(t, std::move(column)); |
306 | | } |
307 | | |
308 | | } // namespace client |
309 | | } // namespace yb |
310 | | |
311 | | #endif // YB_CLIENT_TABLE_HANDLE_H |