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