1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #define LOG_TAG "RdbQuery"
16 #include "rdb_query.h"
17
18 #include "log_print.h"
19 #include "utils/anonymous.h"
20 #include "value_proxy.h"
21 namespace OHOS::DistributedRdb {
22 using namespace DistributedData;
IsEqual(uint64_t tid)23 bool RdbQuery::IsEqual(uint64_t tid)
24 {
25 return tid == TYPE_ID;
26 }
27
GetTables()28 std::vector<std::string> RdbQuery::GetTables()
29 {
30 return tables_;
31 }
32
MakeRemoteQuery(const std::string &devices, const std::string &sql, Values &&args)33 void RdbQuery::MakeRemoteQuery(const std::string &devices, const std::string &sql, Values &&args)
34 {
35 isRemote_ = true;
36 devices_ = { devices };
37 sql_ = sql;
38 args_ = std::move(args);
39 }
40
GetQuery() const41 DistributedDB::Query RdbQuery::GetQuery() const
42 {
43 return query_;
44 }
45
GetDevices() const46 std::vector<std::string> RdbQuery::GetDevices() const
47 {
48 return devices_;
49 }
50
MakeQuery(const PredicatesMemo &predicates)51 void RdbQuery::MakeQuery(const PredicatesMemo &predicates)
52 {
53 ZLOGD("table size:%{public}zu, device size:%{public}zu, op size:%{public}zu", predicates.tables_.size(),
54 predicates.devices_.size(), predicates.operations_.size());
55 query_ = predicates.tables_.size() == 1 ? DistributedDB::Query::Select(*predicates.tables_.begin())
56 : DistributedDB::Query::Select();
57 if (predicates.tables_.size() > 1) {
58 query_.FromTable(predicates.tables_);
59 }
60 if (!predicates.tables_.empty()) {
61 predicates_ = std::make_shared<Predicates>(*predicates.tables_.begin());
62 }
63 for (const auto &operation : predicates.operations_) {
64 if (operation.operator_ >= 0 && operation.operator_ < OPERATOR_MAX) {
65 (this->*HANDLES[operation.operator_])(operation);
66 }
67 }
68 devices_ = predicates.devices_;
69 tables_ = predicates.tables_;
70 }
71
MakeCloudQuery(const PredicatesMemo& predicates)72 void RdbQuery::MakeCloudQuery(const PredicatesMemo& predicates)
73 {
74 ZLOGD("table size:%{public}zu, device size:%{public}zu, op size:%{public}zu", predicates.tables_.size(),
75 predicates.devices_.size(), predicates.operations_.size());
76 devices_ = predicates.devices_;
77 tables_ = predicates.tables_;
78 if (predicates.operations_.empty() || predicates.tables_.size() != 1) {
79 query_ = DistributedDB::Query::Select();
80 if (!predicates.tables_.empty()) {
81 query_.FromTable(predicates.tables_);
82 }
83 return;
84 }
85 predicates_ = std::make_shared<Predicates>(*predicates.tables_.begin());
86 query_ = DistributedDB::Query::Select().From(*predicates.tables_.begin());
87 isPriority_ = true;
88 for (const auto& operation : predicates.operations_) {
89 if (operation.operator_ >= 0 && operation.operator_ < OPERATOR_MAX) {
90 (this->*HANDLES[operation.operator_])(operation);
91 }
92 }
93 }
94
IsRemoteQuery()95 bool RdbQuery::IsRemoteQuery()
96 {
97 return isRemote_;
98 }
99
GetRemoteCondition() const100 DistributedDB::RemoteCondition RdbQuery::GetRemoteCondition() const
101 {
102 auto args = args_;
103 std::vector<std::string> bindArgs = ValueProxy::Convert(std::move(args));
104 return { sql_, bindArgs };
105 }
106
GetStatement() const107 std::string RdbQuery::GetStatement() const
108 {
109 return predicates_ != nullptr ? predicates_->GetStatement() : "";
110 }
111
GetBindArgs() const112 DistributedData::Values RdbQuery::GetBindArgs() const
113 {
114 return predicates_ != nullptr ? ValueProxy::Convert(predicates_->GetBindArgs()) : DistributedData::Values();
115 }
116
SetQueryNodes(const std::string& tableName, QueryNodes&& nodes)117 void RdbQuery::SetQueryNodes(const std::string& tableName, QueryNodes&& nodes)
118 {
119 tables_ = { tableName };
120 queryNodes_ = std::move(nodes);
121 }
122
GetQueryNodes(const std::string& tableName)123 DistributedData::QueryNodes RdbQuery::GetQueryNodes(const std::string& tableName)
124 {
125 return queryNodes_;
126 }
127
EqualTo(const RdbPredicateOperation &operation)128 void RdbQuery::EqualTo(const RdbPredicateOperation &operation)
129 {
130 if (operation.values_.empty()) {
131 return;
132 }
133 query_.EqualTo(operation.field_, operation.values_[0]);
134 predicates_->EqualTo(operation.field_, operation.values_[0]);
135 }
136
NotEqualTo(const RdbPredicateOperation &operation)137 void RdbQuery::NotEqualTo(const RdbPredicateOperation &operation)
138 {
139 if (operation.values_.empty()) {
140 return;
141 }
142 query_.NotEqualTo(operation.field_, operation.values_[0]);
143 predicates_->NotEqualTo(operation.field_, operation.values_[0]);
144 }
145
And(const RdbPredicateOperation &operation)146 void RdbQuery::And(const RdbPredicateOperation &operation)
147 {
148 query_.And();
149 predicates_->And();
150 }
151
Or(const RdbPredicateOperation &operation)152 void RdbQuery::Or(const RdbPredicateOperation &operation)
153 {
154 query_.Or();
155 predicates_->Or();
156 }
157
OrderBy(const RdbPredicateOperation &operation)158 void RdbQuery::OrderBy(const RdbPredicateOperation &operation)
159 {
160 if (operation.values_.empty()) {
161 return;
162 }
163 bool isAsc = operation.values_[0] == "true";
164 query_.OrderBy(operation.field_, isAsc);
165 isAsc ? predicates_->OrderByAsc(operation.field_) : predicates_->OrderByDesc(operation.field_);
166 }
167
Limit(const RdbPredicateOperation &operation)168 void RdbQuery::Limit(const RdbPredicateOperation &operation)
169 {
170 char *end = nullptr;
171 int limit = static_cast<int>(strtol(operation.field_.c_str(), &end, DECIMAL_BASE));
172 int offset = static_cast<int>(strtol(operation.values_[0].c_str(), &end, DECIMAL_BASE));
173 if (limit < 0) {
174 limit = 0;
175 }
176 if (offset < 0) {
177 offset = 0;
178 }
179 query_.Limit(limit, offset);
180 predicates_->Limit(limit, offset);
181 }
182
In(const RdbPredicateOperation& operation)183 void RdbQuery::In(const RdbPredicateOperation& operation)
184 {
185 query_.In(operation.field_, operation.values_);
186 predicates_->In(operation.field_, operation.values_);
187 }
188
BeginGroup(const RdbPredicateOperation& operation)189 void RdbQuery::BeginGroup(const RdbPredicateOperation& operation)
190 {
191 query_.BeginGroup();
192 predicates_->BeginWrap();
193 }
194
EndGroup(const RdbPredicateOperation& operation)195 void RdbQuery::EndGroup(const RdbPredicateOperation& operation)
196 {
197 query_.EndGroup();
198 predicates_->EndWrap();
199 }
200
NotIn(const RdbPredicateOperation& operation)201 void RdbQuery::NotIn(const RdbPredicateOperation& operation)
202 {
203 query_.NotIn(operation.field_, operation.values_);
204 predicates_->NotIn(operation.field_, operation.values_);
205 }
206
Contain(const RdbPredicateOperation& operation)207 void RdbQuery::Contain(const RdbPredicateOperation& operation)
208 {
209 if (operation.values_.empty()) {
210 return;
211 }
212 query_.Like(operation.field_, "%" + operation.values_[0] + "%");
213 predicates_->Contains(operation.field_, operation.values_[0]);
214 }
215
BeginWith(const RdbPredicateOperation& operation)216 void RdbQuery::BeginWith(const RdbPredicateOperation& operation)
217 {
218 if (operation.values_.empty()) {
219 return;
220 }
221 query_.Like(operation.field_, operation.values_[0] + "%");
222 predicates_->BeginsWith(operation.field_, operation.values_[0]);
223 }
224
EndWith(const RdbPredicateOperation& operation)225 void RdbQuery::EndWith(const RdbPredicateOperation& operation)
226 {
227 if (operation.values_.empty()) {
228 return;
229 }
230 query_.Like(operation.field_, "%" + operation.values_[0]);
231 predicates_->EndsWith(operation.field_, operation.values_[0]);
232 }
233
IsNull(const RdbPredicateOperation& operation)234 void RdbQuery::IsNull(const RdbPredicateOperation& operation)
235 {
236 query_.IsNull(operation.field_);
237 predicates_->IsNull(operation.field_);
238 }
239
IsNotNull(const RdbPredicateOperation& operation)240 void RdbQuery::IsNotNull(const RdbPredicateOperation& operation)
241 {
242 query_.IsNotNull(operation.field_);
243 predicates_->IsNotNull(operation.field_);
244 }
245
Like(const RdbPredicateOperation& operation)246 void RdbQuery::Like(const RdbPredicateOperation& operation)
247 {
248 if (operation.values_.empty()) {
249 return;
250 }
251 query_.Like(operation.field_, operation.values_[0]);
252 predicates_->Like(operation.field_, operation.values_[0]);
253 }
254
Glob(const RdbPredicateOperation& operation)255 void RdbQuery::Glob(const RdbPredicateOperation& operation)
256 {
257 if (operation.values_.empty()) {
258 return;
259 }
260 predicates_->Glob(operation.field_, operation.values_[0]);
261 }
262
Between(const RdbPredicateOperation& operation)263 void RdbQuery::Between(const RdbPredicateOperation& operation)
264 {
265 if (operation.values_.size() != 2) { // between a and b 2 args
266 return;
267 }
268 predicates_->Between(operation.field_, operation.values_[0], operation.values_[1]);
269 }
270
NotBetween(const RdbPredicateOperation& operation)271 void RdbQuery::NotBetween(const RdbPredicateOperation& operation)
272 {
273 if (operation.values_.size() != 2) { // not between a and b 2 args
274 return;
275 }
276 predicates_->NotBetween(operation.field_, operation.values_[0], operation.values_[1]);
277 }
278
GreaterThan(const RdbPredicateOperation& operation)279 void RdbQuery::GreaterThan(const RdbPredicateOperation& operation)
280 {
281 if (operation.values_.empty()) {
282 return;
283 }
284 query_.GreaterThan(operation.field_, operation.field_[0]);
285 predicates_->GreaterThan(operation.field_, operation.field_[0]);
286 }
287
GreaterThanOrEqual(const RdbPredicateOperation& operation)288 void RdbQuery::GreaterThanOrEqual(const RdbPredicateOperation& operation)
289 {
290 if (operation.values_.empty()) {
291 return;
292 }
293 query_.GreaterThanOrEqualTo(operation.field_, operation.field_[0]);
294 predicates_->GreaterThanOrEqualTo(operation.field_, operation.field_[0]);
295 }
296
LessThan(const RdbPredicateOperation& operation)297 void RdbQuery::LessThan(const RdbPredicateOperation& operation)
298 {
299 if (operation.values_.empty()) {
300 return;
301 }
302 query_.LessThan(operation.field_, operation.field_[0]);
303 predicates_->LessThan(operation.field_, operation.field_[0]);
304 }
305
LessThanOrEqual(const RdbPredicateOperation& operation)306 void RdbQuery::LessThanOrEqual(const RdbPredicateOperation& operation)
307 {
308 if (operation.values_.empty()) {
309 return;
310 }
311 query_.LessThanOrEqualTo(operation.field_, operation.field_[0]);
312 predicates_->LessThanOrEqualTo(operation.field_, operation.field_[0]);
313 }
314
Distinct(const RdbPredicateOperation& operation)315 void RdbQuery::Distinct(const RdbPredicateOperation& operation)
316 {
317 predicates_->Distinct();
318 }
319
IndexedBy(const RdbPredicateOperation& operation)320 void RdbQuery::IndexedBy(const RdbPredicateOperation& operation)
321 {
322 predicates_->IndexedBy(operation.field_);
323 query_.SuggestIndex(operation.field_);
324 }
325
IsPriority()326 bool RdbQuery::IsPriority()
327 {
328 return isPriority_;
329 }
330
SetColumns(std::vector<std::string> &&columns)331 void RdbQuery::SetColumns(std::vector<std::string> &&columns)
332 {
333 columns_ = std::move(columns);
334 }
335
SetColumns(const std::vector<std::string> &columns)336 void RdbQuery::SetColumns(const std::vector<std::string> &columns)
337 {
338 columns_ = columns;
339 }
340
GetColumns() const341 std::vector<std::string> RdbQuery::GetColumns() const
342 {
343 return columns_;
344 }
345 } // namespace OHOS::DistributedRdb
346