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