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