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 "asset_value.h"
19 #include "log_print.h"
20 #include "utils/anonymous.h"
21 #include "value_proxy.h"
22 namespace OHOS::DistributedRdb {
23 using namespace DistributedData;
IsEqual(uint64_t tid)24 bool RdbQuery::IsEqual(uint64_t tid)
25 {
26 return tid == TYPE_ID;
27 }
28
GetTables()29 std::vector<std::string> RdbQuery::GetTables()
30 {
31 return tables_;
32 }
33
MakeRemoteQuery(const std::string & devices,const std::string & sql,Values && args)34 void RdbQuery::MakeRemoteQuery(const std::string &devices, const std::string &sql, Values &&args)
35 {
36 isRemote_ = true;
37 devices_ = { devices };
38 sql_ = sql;
39 args_ = std::move(args);
40 }
41
GetQuery() const42 DistributedDB::Query RdbQuery::GetQuery() const
43 {
44 return query_;
45 }
46
GetDevices() const47 std::vector<std::string> RdbQuery::GetDevices() const
48 {
49 return devices_;
50 }
51
MakeQuery(const PredicatesMemo & predicates)52 void RdbQuery::MakeQuery(const PredicatesMemo &predicates)
53 {
54 ZLOGD("table size:%{public}zu, device size:%{public}zu, op size:%{public}zu", predicates.tables_.size(),
55 predicates.devices_.size(), predicates.operations_.size());
56 query_ = predicates.tables_.size() == 1 ? DistributedDB::Query::Select(*predicates.tables_.begin())
57 : DistributedDB::Query::Select();
58 if (predicates.tables_.size() > 1) {
59 query_.FromTable(predicates.tables_);
60 }
61 if (!predicates.tables_.empty()) {
62 predicates_ = std::make_shared<Predicates>(*predicates.tables_.begin());
63 }
64 for (const auto &operation : predicates.operations_) {
65 if (operation.operator_ >= 0 && operation.operator_ < OPERATOR_MAX) {
66 (this->*HANDLES[operation.operator_])(operation);
67 }
68 }
69 devices_ = predicates.devices_;
70 tables_ = predicates.tables_;
71 }
72
MakeQuery(const std::string & table)73 void RdbQuery::MakeQuery(const std::string &table)
74 {
75 query_ = DistributedDB::Query::Select(table);
76 }
77
MakeCloudQuery(const PredicatesMemo & predicates)78 void RdbQuery::MakeCloudQuery(const PredicatesMemo& predicates)
79 {
80 ZLOGD("table size:%{public}zu, device size:%{public}zu, op size:%{public}zu", predicates.tables_.size(),
81 predicates.devices_.size(), predicates.operations_.size());
82 devices_ = predicates.devices_;
83 tables_ = predicates.tables_;
84 if (predicates.operations_.empty() || predicates.tables_.size() != 1) {
85 query_ = DistributedDB::Query::Select();
86 if (!predicates.tables_.empty()) {
87 query_.FromTable(predicates.tables_);
88 }
89 return;
90 }
91 predicates_ = std::make_shared<Predicates>(*predicates.tables_.begin());
92 query_ = DistributedDB::Query::Select().From(*predicates.tables_.begin());
93 isPriority_ = true;
94 for (const auto& operation : predicates.operations_) {
95 if (operation.operator_ >= 0 && operation.operator_ < OPERATOR_MAX) {
96 (this->*HANDLES[operation.operator_])(operation);
97 }
98 }
99 }
100
IsRemoteQuery()101 bool RdbQuery::IsRemoteQuery()
102 {
103 return isRemote_;
104 }
105
GetRemoteCondition() const106 DistributedDB::RemoteCondition RdbQuery::GetRemoteCondition() const
107 {
108 auto args = args_;
109 std::vector<std::string> bindArgs = ValueProxy::Convert(std::move(args));
110 return { sql_, bindArgs };
111 }
112
GetStatement() const113 std::string RdbQuery::GetStatement() const
114 {
115 return predicates_ != nullptr ? predicates_->GetStatement() : "";
116 }
117
GetBindArgs() const118 DistributedData::Values RdbQuery::GetBindArgs() const
119 {
120 return predicates_ != nullptr ? ValueProxy::Convert(predicates_->GetBindArgs()) : DistributedData::Values();
121 }
122
SetQueryNodes(const std::string & tableName,QueryNodes && nodes)123 void RdbQuery::SetQueryNodes(const std::string& tableName, QueryNodes&& nodes)
124 {
125 tables_ = { tableName };
126 queryNodes_ = std::move(nodes);
127 }
128
GetQueryNodes(const std::string & tableName)129 DistributedData::QueryNodes RdbQuery::GetQueryNodes(const std::string& tableName)
130 {
131 return queryNodes_;
132 }
133
EqualTo(const RdbPredicateOperation & operation)134 void RdbQuery::EqualTo(const RdbPredicateOperation &operation)
135 {
136 if (operation.values_.empty()) {
137 return;
138 }
139 query_.EqualTo(operation.field_, operation.values_[0]);
140 predicates_->EqualTo(operation.field_, operation.values_[0]);
141 }
142
NotEqualTo(const RdbPredicateOperation & operation)143 void RdbQuery::NotEqualTo(const RdbPredicateOperation &operation)
144 {
145 if (operation.values_.empty()) {
146 return;
147 }
148 query_.NotEqualTo(operation.field_, operation.values_[0]);
149 predicates_->NotEqualTo(operation.field_, operation.values_[0]);
150 }
151
And(const RdbPredicateOperation & operation)152 void RdbQuery::And(const RdbPredicateOperation &operation)
153 {
154 query_.And();
155 predicates_->And();
156 }
157
Or(const RdbPredicateOperation & operation)158 void RdbQuery::Or(const RdbPredicateOperation &operation)
159 {
160 query_.Or();
161 predicates_->Or();
162 }
163
OrderBy(const RdbPredicateOperation & operation)164 void RdbQuery::OrderBy(const RdbPredicateOperation &operation)
165 {
166 if (operation.values_.empty()) {
167 return;
168 }
169 bool isAsc = operation.values_[0] == "true";
170 query_.OrderBy(operation.field_, isAsc);
171 isAsc ? predicates_->OrderByAsc(operation.field_) : predicates_->OrderByDesc(operation.field_);
172 }
173
Limit(const RdbPredicateOperation & operation)174 void RdbQuery::Limit(const RdbPredicateOperation &operation)
175 {
176 char *end = nullptr;
177 int limit = static_cast<int>(strtol(operation.field_.c_str(), &end, DECIMAL_BASE));
178 int offset = static_cast<int>(strtol(operation.values_[0].c_str(), &end, DECIMAL_BASE));
179 if (limit < 0) {
180 limit = 0;
181 }
182 if (offset < 0) {
183 offset = 0;
184 }
185 query_.Limit(limit, offset);
186 predicates_->Limit(limit, offset);
187 }
188
In(const RdbPredicateOperation & operation)189 void RdbQuery::In(const RdbPredicateOperation& operation)
190 {
191 query_.In(operation.field_, operation.values_);
192 predicates_->In(operation.field_, operation.values_);
193 }
194
BeginGroup(const RdbPredicateOperation & operation)195 void RdbQuery::BeginGroup(const RdbPredicateOperation& operation)
196 {
197 query_.BeginGroup();
198 predicates_->BeginWrap();
199 }
200
EndGroup(const RdbPredicateOperation & operation)201 void RdbQuery::EndGroup(const RdbPredicateOperation& operation)
202 {
203 query_.EndGroup();
204 predicates_->EndWrap();
205 }
206
NotIn(const RdbPredicateOperation & operation)207 void RdbQuery::NotIn(const RdbPredicateOperation& operation)
208 {
209 query_.NotIn(operation.field_, operation.values_);
210 predicates_->NotIn(operation.field_, operation.values_);
211 }
212
Contain(const RdbPredicateOperation & operation)213 void RdbQuery::Contain(const RdbPredicateOperation& operation)
214 {
215 if (operation.values_.empty()) {
216 return;
217 }
218 query_.Like(operation.field_, "%" + operation.values_[0] + "%");
219 predicates_->Contains(operation.field_, operation.values_[0]);
220 }
221
BeginWith(const RdbPredicateOperation & operation)222 void RdbQuery::BeginWith(const RdbPredicateOperation& operation)
223 {
224 if (operation.values_.empty()) {
225 return;
226 }
227 query_.Like(operation.field_, operation.values_[0] + "%");
228 predicates_->BeginsWith(operation.field_, operation.values_[0]);
229 }
230
EndWith(const RdbPredicateOperation & operation)231 void RdbQuery::EndWith(const RdbPredicateOperation& operation)
232 {
233 if (operation.values_.empty()) {
234 return;
235 }
236 query_.Like(operation.field_, "%" + operation.values_[0]);
237 predicates_->EndsWith(operation.field_, operation.values_[0]);
238 }
239
IsNull(const RdbPredicateOperation & operation)240 void RdbQuery::IsNull(const RdbPredicateOperation& operation)
241 {
242 query_.IsNull(operation.field_);
243 predicates_->IsNull(operation.field_);
244 }
245
IsNotNull(const RdbPredicateOperation & operation)246 void RdbQuery::IsNotNull(const RdbPredicateOperation& operation)
247 {
248 query_.IsNotNull(operation.field_);
249 predicates_->IsNotNull(operation.field_);
250 }
251
Like(const RdbPredicateOperation & operation)252 void RdbQuery::Like(const RdbPredicateOperation& operation)
253 {
254 if (operation.values_.empty()) {
255 return;
256 }
257 query_.Like(operation.field_, operation.values_[0]);
258 predicates_->Like(operation.field_, operation.values_[0]);
259 }
260
Glob(const RdbPredicateOperation & operation)261 void RdbQuery::Glob(const RdbPredicateOperation& operation)
262 {
263 if (operation.values_.empty()) {
264 return;
265 }
266 predicates_->Glob(operation.field_, operation.values_[0]);
267 }
268
Between(const RdbPredicateOperation & operation)269 void RdbQuery::Between(const RdbPredicateOperation& operation)
270 {
271 if (operation.values_.size() != 2) { // between a and b 2 args
272 return;
273 }
274 predicates_->Between(operation.field_, operation.values_[0], operation.values_[1]);
275 }
276
NotBetween(const RdbPredicateOperation & operation)277 void RdbQuery::NotBetween(const RdbPredicateOperation& operation)
278 {
279 if (operation.values_.size() != 2) { // not between a and b 2 args
280 return;
281 }
282 predicates_->NotBetween(operation.field_, operation.values_[0], operation.values_[1]);
283 }
284
GreaterThan(const RdbPredicateOperation & operation)285 void RdbQuery::GreaterThan(const RdbPredicateOperation& operation)
286 {
287 if (operation.values_.empty()) {
288 return;
289 }
290 query_.GreaterThan(operation.field_, operation.field_[0]);
291 predicates_->GreaterThan(operation.field_, operation.field_[0]);
292 }
293
GreaterThanOrEqual(const RdbPredicateOperation & operation)294 void RdbQuery::GreaterThanOrEqual(const RdbPredicateOperation& operation)
295 {
296 if (operation.values_.empty()) {
297 return;
298 }
299 query_.GreaterThanOrEqualTo(operation.field_, operation.field_[0]);
300 predicates_->GreaterThanOrEqualTo(operation.field_, operation.field_[0]);
301 }
302
LessThan(const RdbPredicateOperation & operation)303 void RdbQuery::LessThan(const RdbPredicateOperation& operation)
304 {
305 if (operation.values_.empty()) {
306 return;
307 }
308 query_.LessThan(operation.field_, operation.field_[0]);
309 predicates_->LessThan(operation.field_, operation.field_[0]);
310 }
311
LessThanOrEqual(const RdbPredicateOperation & operation)312 void RdbQuery::LessThanOrEqual(const RdbPredicateOperation& operation)
313 {
314 if (operation.values_.empty()) {
315 return;
316 }
317 query_.LessThanOrEqualTo(operation.field_, operation.field_[0]);
318 predicates_->LessThanOrEqualTo(operation.field_, operation.field_[0]);
319 }
320
Distinct(const RdbPredicateOperation & operation)321 void RdbQuery::Distinct(const RdbPredicateOperation& operation)
322 {
323 predicates_->Distinct();
324 }
325
IndexedBy(const RdbPredicateOperation & operation)326 void RdbQuery::IndexedBy(const RdbPredicateOperation& operation)
327 {
328 predicates_->IndexedBy(operation.field_);
329 query_.SuggestIndex(operation.field_);
330 }
331
IsPriority()332 bool RdbQuery::IsPriority()
333 {
334 return isPriority_;
335 }
336
SetColumns(std::vector<std::string> && columns)337 void RdbQuery::SetColumns(std::vector<std::string> &&columns)
338 {
339 columns_ = std::move(columns);
340 }
341
SetColumns(const std::vector<std::string> & columns)342 void RdbQuery::SetColumns(const std::vector<std::string> &columns)
343 {
344 columns_ = columns;
345 }
346
GetColumns() const347 std::vector<std::string> RdbQuery::GetColumns() const
348 {
349 return columns_;
350 }
351
NotContains(const RdbPredicateOperation & operation)352 void RdbQuery::NotContains(const RdbPredicateOperation &operation)
353 {
354 return;
355 }
356
NotLike(const RdbPredicateOperation & operation)357 void RdbQuery::NotLike(const RdbPredicateOperation &operation)
358 {
359 if (operation.values_.empty()) {
360 return;
361 }
362 query_.NotLike(operation.field_, operation.values_[0]);
363 predicates_->NotLike(operation.field_, operation.values_[0]);
364 }
365
AssetsOnly(const RdbPredicateOperation & operation)366 void RdbQuery::AssetsOnly(const RdbPredicateOperation &operation)
367 {
368 if (operation.values_.empty()) {
369 return;
370 }
371 DistributedDB::AssetsMap assetsMap;
372 std::vector<NativeRdb::AssetValue> assets;
373 std::set<std::string> names;
374 for (const auto &value : operation.values_) {
375 names.insert(value);
376 NativeRdb::AssetValue asset{ .name = value };
377 assets.push_back(std::move(asset));
378 }
379 NativeRdb::ValueObject object(assets);
380 assetsMap[operation.field_] = names;
381 query_.AssetsOnly(assetsMap);
382 predicates_->EqualTo(operation.field_, object);
383 }
384 } // namespace OHOS::DistributedRdb