1 /*
2 * Copyright (c) 2021-2024 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 #include "sys_event_query.h"
16
17 #include <memory>
18 #include <string>
19 #include <utility>
20
21 #include "doc_query.h"
22 #include "sys_event_database.h"
23
24 namespace OHOS {
25 namespace HiviewDFX {
26 namespace EventStore {
27 namespace {
28 constexpr double ESP = 0.0000001;
CompareSeqFuncLess(const Entry & entryA,const Entry & entryB)29 bool CompareSeqFuncLess(const Entry& entryA, const Entry& entryB)
30 {
31 return entryA.id < entryB.id;
32 }
33
CompareSeqFuncGreater(const Entry & entryA,const Entry & entryB)34 bool CompareSeqFuncGreater(const Entry& entryA, const Entry& entryB)
35 {
36 return entryA.id > entryB.id;
37 }
38
CompareTimestampFuncLess(const Entry & entryA,const Entry & entryB)39 bool CompareTimestampFuncLess(const Entry& entryA, const Entry& entryB)
40 {
41 return entryA.ts < entryB.ts;
42 }
43
CompareTimestampFuncGreater(const Entry & entryA,const Entry & entryB)44 bool CompareTimestampFuncGreater(const Entry& entryA, const Entry& entryB)
45 {
46 return entryA.ts > entryB.ts;
47 }
48 }
49
IsNumber() const50 bool FieldValue::IsNumber() const
51 {
52 return (Index() == NUMBER);
53 }
54
IsString() const55 bool FieldValue::IsString() const
56 {
57 return (Index() == STRING);
58 }
59
GetString() const60 std::string FieldValue::GetString() const
61 {
62 if (Index() == NUMBER) {
63 return "";
64 }
65 return std::get<STRING>(val_);
66 }
67
GetFieldNumber() const68 FieldNumber FieldValue::GetFieldNumber() const
69 {
70 if (Index() == STRING) {
71 FieldNumber number(0);
72 return number; // default
73 }
74 return std::get<NUMBER>(val_);
75 }
76
FormatAsString() const77 std::string FieldValue::FormatAsString() const
78 {
79 if (Index() == STRING) {
80 return std::get<STRING>(val_);
81 }
82 return std::get<NUMBER>(val_).FormatAsString();
83 }
84
Index() const85 FieldValue::ValueType FieldValue::Index() const
86 {
87 return FieldValue::ValueType(val_.index());
88 }
89
operator ==(const FieldValue & fieldValue) const90 bool FieldValue::operator==(const FieldValue& fieldValue) const
91 {
92 if (Index() != fieldValue.Index()) {
93 return false;
94 }
95 if (IsNumber()) {
96 return GetFieldNumber() == fieldValue.GetFieldNumber();
97 }
98 if (IsString()) {
99 return GetString() == fieldValue.GetString();
100 }
101 return false;
102 }
103
operator !=(const FieldValue & fieldValue) const104 bool FieldValue::operator!=(const FieldValue& fieldValue) const
105 {
106 if (Index() != fieldValue.Index()) {
107 return false;
108 }
109 if (IsNumber()) {
110 return GetFieldNumber() != fieldValue.GetFieldNumber();
111 }
112 if (IsString()) {
113 return GetString() != fieldValue.GetString();
114 }
115 return false;
116 }
117
operator <(const FieldValue & fieldValue) const118 bool FieldValue::operator<(const FieldValue& fieldValue) const
119 {
120 if (Index() != fieldValue.Index()) {
121 return false;
122 }
123 if (IsNumber()) {
124 return GetFieldNumber() < fieldValue.GetFieldNumber();
125 }
126 if (IsString()) {
127 return GetString() < fieldValue.GetString();
128 }
129 return false;
130 }
131
operator <=(const FieldValue & fieldValue) const132 bool FieldValue::operator<=(const FieldValue& fieldValue) const
133 {
134 if (Index() != fieldValue.Index()) {
135 return false;
136 }
137 if (IsNumber()) {
138 return GetFieldNumber() <= fieldValue.GetFieldNumber();
139 }
140 if (IsString()) {
141 return GetString() <= fieldValue.GetString();
142 }
143 return false;
144 }
145
operator >(const FieldValue & fieldValue) const146 bool FieldValue::operator>(const FieldValue& fieldValue) const
147 {
148 if (Index() != fieldValue.Index()) {
149 return false;
150 }
151 if (IsNumber()) {
152 return GetFieldNumber() > fieldValue.GetFieldNumber();
153 }
154 if (IsString()) {
155 return GetString() > fieldValue.GetString();
156 }
157 return false;
158 }
159
operator >=(const FieldValue & fieldValue) const160 bool FieldValue::operator>=(const FieldValue& fieldValue) const
161 {
162 if (Index() != fieldValue.Index()) {
163 return false;
164 }
165 if (IsNumber()) {
166 return GetFieldNumber() >= fieldValue.GetFieldNumber();
167 }
168 if (IsString()) {
169 return GetString() >= fieldValue.GetString();
170 }
171 return false;
172 }
173
IsStartWith(const FieldValue & fieldValue) const174 bool FieldValue::IsStartWith(const FieldValue& fieldValue) const
175 {
176 if (Index() != fieldValue.Index()) {
177 return false;
178 }
179 if (IsString()) {
180 return GetString().find(fieldValue.GetString()) == 0;
181 }
182 return false;
183 }
184
IsNotStartWith(const FieldValue & fieldValue) const185 bool FieldValue::IsNotStartWith(const FieldValue& fieldValue) const
186 {
187 if (Index() != fieldValue.Index()) {
188 return false;
189 }
190 if (IsString()) {
191 return !(GetString().find(fieldValue.GetString()) == 0);
192 }
193 return false;
194 }
195
operator ==(const FieldNumber & fieldNum) const196 bool FieldNumber::operator==(const FieldNumber& fieldNum) const
197 {
198 if ((Index() == DOUBLE) || (fieldNum.Index() == DOUBLE)) {
199 return abs(GetNumber<double>() - fieldNum.GetNumber<double>()) <= ESP;
200 }
201 if (Index() == fieldNum.Index()) {
202 return (Index() == INT) ? (GetNumber<int64_t>() == fieldNum.GetNumber<int64_t>()) :
203 (GetNumber<uint64_t>() == fieldNum.GetNumber<uint64_t>());
204 }
205 if (Index() == INT) {
206 return (GetNumber<int64_t>() >= 0) && (GetNumber<uint64_t>() == fieldNum.GetNumber<uint64_t>());
207 }
208 return (fieldNum.GetNumber<int64_t>() >= 0) && (fieldNum.GetNumber<uint64_t>() == GetNumber<uint64_t>());
209 }
210
operator !=(const FieldNumber & fieldNum) const211 bool FieldNumber::operator!=(const FieldNumber& fieldNum) const
212 {
213 if ((Index() == DOUBLE) || (fieldNum.Index() == DOUBLE)) {
214 return abs(GetNumber<double>() - fieldNum.GetNumber<double>()) > ESP;
215 }
216 if (Index() == fieldNum.Index()) {
217 return (Index() == INT) ? (GetNumber<int64_t>() != fieldNum.GetNumber<int64_t>()) :
218 (GetNumber<uint64_t>() != fieldNum.GetNumber<uint64_t>());
219 }
220 if (Index() == INT) {
221 return (GetNumber<int64_t>() < 0) || (GetNumber<uint64_t>() != fieldNum.GetNumber<uint64_t>());
222 }
223 return (fieldNum.GetNumber<int64_t>() < 0) || (fieldNum.GetNumber<uint64_t>() != GetNumber<uint64_t>());
224 }
225
operator <(const FieldNumber & fieldNum) const226 bool FieldNumber::operator<(const FieldNumber& fieldNum) const
227 {
228 if ((Index() == DOUBLE) || (fieldNum.Index() == DOUBLE)) {
229 return (abs(GetNumber<double>() - fieldNum.GetNumber<double>()) > ESP) &&
230 (GetNumber<double>() < fieldNum.GetNumber<double>());
231 }
232 if (Index() == fieldNum.Index()) {
233 return (Index() == INT) ? (GetNumber<int64_t>() < fieldNum.GetNumber<int64_t>()) :
234 (GetNumber<uint64_t>() < fieldNum.GetNumber<uint64_t>());
235 }
236 if (Index() == INT) {
237 return (GetNumber<int64_t>() < 0) || (GetNumber<uint64_t>() < fieldNum.GetNumber<uint64_t>());
238 }
239 return (fieldNum.GetNumber<int64_t>() >= 0) && (GetNumber<uint64_t>() < fieldNum.GetNumber<uint64_t>());
240 }
241
operator <=(const FieldNumber & fieldNum) const242 bool FieldNumber::operator<=(const FieldNumber& fieldNum) const
243 {
244 if ((Index() == DOUBLE) || (fieldNum.Index() == DOUBLE)) {
245 return (abs(GetNumber<double>() - fieldNum.GetNumber<double>()) <= ESP) ||
246 (GetNumber<double>() < fieldNum.GetNumber<double>());
247 }
248 if (Index() == fieldNum.Index()) {
249 return (Index() == INT) ? (GetNumber<int64_t>() <= fieldNum.GetNumber<int64_t>()) :
250 (GetNumber<uint64_t>() <= fieldNum.GetNumber<uint64_t>());
251 }
252 if (Index() == INT) {
253 return (GetNumber<int64_t>() < 0) || (GetNumber<uint64_t>() <= fieldNum.GetNumber<uint64_t>());
254 }
255 return (fieldNum.GetNumber<int64_t>() >= 0) && (GetNumber<uint64_t>() <= fieldNum.GetNumber<uint64_t>());
256 }
257
operator >(const FieldNumber & fieldNum) const258 bool FieldNumber::operator>(const FieldNumber& fieldNum) const
259 {
260 if ((Index() == DOUBLE) || (fieldNum.Index() == DOUBLE)) {
261 return (abs(GetNumber<double>() - fieldNum.GetNumber<double>()) > ESP) &&
262 (GetNumber<double>() > fieldNum.GetNumber<double>());
263 }
264 if (Index() == fieldNum.Index()) {
265 return (Index() == INT) ? (GetNumber<int64_t>() > fieldNum.GetNumber<int64_t>()) :
266 (GetNumber<uint64_t>() > fieldNum.GetNumber<uint64_t>());
267 }
268 if (Index() == INT) {
269 return (GetNumber<int64_t>() >= 0) && (GetNumber<uint64_t>() > fieldNum.GetNumber<uint64_t>());
270 }
271 return (fieldNum.GetNumber<int64_t>() < 0) || (GetNumber<uint64_t>() > fieldNum.GetNumber<uint64_t>());
272 }
273
operator >=(const FieldNumber & fieldNum) const274 bool FieldNumber::operator>=(const FieldNumber& fieldNum) const
275 {
276 if ((Index() == DOUBLE) || (fieldNum.Index() == DOUBLE)) {
277 return (abs(GetNumber<double>() - fieldNum.GetNumber<double>()) <= ESP) ||
278 (GetNumber<double>() > fieldNum.GetNumber<double>());
279 }
280 if (Index() == fieldNum.Index()) {
281 return (Index() == INT) ? (GetNumber<int64_t>() >= fieldNum.GetNumber<int64_t>()) :
282 (GetNumber<uint64_t>() >= fieldNum.GetNumber<uint64_t>());
283 }
284 if (Index() == INT) {
285 return (GetNumber<int64_t>() >= 0) && (GetNumber<uint64_t>() >= fieldNum.GetNumber<uint64_t>());
286 }
287 return (fieldNum.GetNumber<int64_t>() < 0) || (GetNumber<uint64_t>() >= fieldNum.GetNumber<uint64_t>());
288 }
289
FormatAsString() const290 std::string FieldNumber::FormatAsString() const
291 {
292 if (Index() == DOUBLE) {
293 return std::to_string(std::get<DOUBLE>(val_));
294 }
295 if (Index() == UINT) {
296 return std::to_string(std::get<UINT>(val_));
297 }
298 return std::to_string(std::get<INT>(val_));
299 }
300
Index() const301 FieldNumber::ValueType FieldNumber::Index() const
302 {
303 return FieldNumber::ValueType(val_.index());
304 }
305
And(const Cond & cond)306 Cond &Cond::And(const Cond &cond)
307 {
308 andConds_.emplace_back(cond);
309 return *this;
310 }
311
IsSimpleCond(const Cond & cond)312 bool Cond::IsSimpleCond(const Cond &cond)
313 {
314 return !cond.col_.empty() && cond.andConds_.empty();
315 }
316
Traval(DocQuery & docQuery,const Cond & cond)317 void Cond::Traval(DocQuery &docQuery, const Cond &cond)
318 {
319 if (!cond.col_.empty()) {
320 docQuery.And(cond);
321 }
322 if (!cond.andConds_.empty()) {
323 for (auto& andCond : cond.andConds_) {
324 if (IsSimpleCond(andCond)) {
325 docQuery.And(andCond);
326 } else {
327 Traval(docQuery, andCond);
328 }
329 }
330 }
331 }
332
ToString() const333 std::string Cond::ToString() const
334 {
335 std::string output;
336 output.append(col_);
337
338 switch (op_) {
339 case EQ:
340 output.append(" == ");
341 break;
342 case NE:
343 output.append(" != ");
344 break;
345 case GT:
346 output.append(" > ");
347 break;
348 case GE:
349 output.append(" >= ");
350 break;
351 case LT:
352 output.append(" < ");
353 break;
354 case LE:
355 output.append(" <= ");
356 break;
357 case SW:
358 output.append(" SW ");
359 break;
360 case NSW:
361 output.append(" NSW ");
362 break;
363 default:
364 return "INVALID COND";
365 }
366
367 output.append(fieldValue_.FormatAsString());
368
369 return output;
370 }
371
ResultSet()372 ResultSet::ResultSet(): iter_(eventRecords_.begin()), code_(0), has_(false)
373 {
374 }
375
~ResultSet()376 ResultSet::~ResultSet()
377 {
378 }
379
ResultSet(ResultSet && result)380 ResultSet::ResultSet(ResultSet &&result)
381 {
382 eventRecords_ = move(result.eventRecords_);
383 code_ = result.code_;
384 has_ = result.has_;
385 iter_ = result.iter_;
386 }
387
operator =(ResultSet && result)388 ResultSet& ResultSet::operator = (ResultSet &&result)
389 {
390 eventRecords_ = move(result.eventRecords_);
391 code_ = result.code_;
392 has_ = result.has_;
393 iter_ = result.iter_;
394 return *this;
395 }
396
GetErrCode() const397 int ResultSet::GetErrCode() const
398 {
399 return code_;
400 }
401
HasNext() const402 bool ResultSet::HasNext() const
403 {
404 return has_;
405 }
406
Next()407 ResultSet::RecordIter ResultSet::Next()
408 {
409 if (!has_) {
410 return eventRecords_.end();
411 }
412
413 auto tempIter = iter_;
414 iter_++;
415 if (iter_ == eventRecords_.end()) {
416 has_ = false;
417 }
418
419 return tempIter;
420 }
421
Set(int code,bool has)422 void ResultSet::Set(int code, bool has)
423 {
424 code_ = code;
425 has_ = has;
426 if (eventRecords_.size() > 0) {
427 iter_ = eventRecords_.begin();
428 }
429 }
430
SysEventQuery(const std::string & domain,const std::vector<std::string> & names)431 SysEventQuery::SysEventQuery(const std::string& domain, const std::vector<std::string>& names)
432 : SysEventQuery(domain, names, 0, INVALID_VALUE_INT, INVALID_VALUE_INT)
433 {}
434
SysEventQuery(const std::string & domain,const std::vector<std::string> & names,uint32_t type,int64_t toSeq,int64_t fromSeq)435 SysEventQuery::SysEventQuery(const std::string& domain, const std::vector<std::string>& names,
436 uint32_t type, int64_t toSeq, int64_t fromSeq) : queryArg_(domain, names, type, toSeq, fromSeq)
437 {}
438
Select(const std::vector<std::string> & eventCols)439 SysEventQuery &SysEventQuery::Select(const std::vector<std::string> &eventCols)
440 {
441 return *this;
442 }
443
Where(const Cond & cond)444 SysEventQuery &SysEventQuery::Where(const Cond &cond)
445 {
446 cond_.And(cond);
447 return *this;
448 }
449
And(const Cond & cond)450 SysEventQuery &SysEventQuery::And(const Cond &cond)
451 {
452 cond_.And(cond);
453 return *this;
454 }
455
Order(const std::string & col,bool isAsc)456 SysEventQuery &SysEventQuery::Order(const std::string &col, bool isAsc)
457 {
458 orderCol_ = std::make_pair<>(col, isAsc);
459 return *this;
460 }
461
BuildDocQuery(DocQuery & docQuery) const462 void SysEventQuery::BuildDocQuery(DocQuery &docQuery) const
463 {
464 Cond::Traval(docQuery, cond_);
465 }
466
CreateCompareFunc() const467 CompareFunc SysEventQuery::CreateCompareFunc() const
468 {
469 if (orderCol_.first == EventCol::TS) {
470 if (orderCol_.second) {
471 return &CompareTimestampFuncGreater;
472 } else {
473 return &CompareTimestampFuncLess;
474 }
475 } else {
476 if (orderCol_.second) {
477 return &CompareSeqFuncGreater;
478 } else {
479 return &CompareSeqFuncLess;
480 }
481 }
482 }
483
Execute(int limit,DbQueryTag tag,QueryProcessInfo callerInfo,DbQueryCallback queryCallback)484 ResultSet SysEventQuery::Execute(int limit, DbQueryTag tag, QueryProcessInfo callerInfo,
485 DbQueryCallback queryCallback)
486 {
487 limit_ = limit;
488
489 // sort query return events
490 EntryQueue entries(CreateCompareFunc());
491 int retCode = SysEventDatabase::GetInstance().Query(*this, entries);
492 ResultSet resultSet;
493 if (retCode != DOC_STORE_SUCCESS) {
494 resultSet.Set(retCode, false);
495 return resultSet;
496 }
497 if (entries.empty()) {
498 resultSet.Set(DOC_STORE_SUCCESS, false);
499 return resultSet;
500 }
501
502 // for an internal query, the number of returned query results need to be limit
503 int resultNum = static_cast<int>(entries.size());
504 if (resultNum > limit && tag.isInnerQuery) {
505 resultNum = limit;
506 }
507 while (!entries.empty() && resultNum >= 0) {
508 auto& entry = entries.top();
509 resultSet.eventRecords_.emplace_back("", nullptr, entry.data, entry.id, entry.sysVersion, entry.patchVersion);
510 entries.pop();
511 resultNum--;
512 }
513 resultSet.Set(DOC_STORE_SUCCESS, true);
514 return resultSet;
515 }
516
ToString() const517 std::string SysEventQuery::ToString() const
518 {
519 std::string output;
520 output.append("domain=[").append(queryArg_.domain).append("], names=[");
521 for (auto& name : queryArg_.names) {
522 output.append(name);
523 if (&name != &queryArg_.names.back()) {
524 output.append(",");
525 }
526 }
527 output.append("], type=[").append(std::to_string(queryArg_.type)).append("], condition=[");
528 DocQuery docQuery;
529 BuildDocQuery(docQuery);
530 output.append(docQuery.ToString()).append("]");
531 return output;
532 }
533 } // EventStore
534 } // namespace HiviewDFX
535 } // namespace OHOS
536