• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
16 #include "event_query_wrapper_builder.h"
17 
18 #include <algorithm>
19 #include <cinttypes>
20 
21 #include "common_utils.h"
22 #include "hilog/log.h"
23 #include "ipc_skeleton.h"
24 #include "ret_code.h"
25 #include "string_ex.h"
26 
27 namespace OHOS {
28 namespace HiviewDFX {
29 namespace {
30 constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002D10, "HiView-SysEventQueryBuilder" };
31 constexpr char DOMAIN_[] = "domain_";
32 constexpr char NAME_[] = "name_";
33 constexpr char SEQ_[] = "seq_";
34 constexpr char LOGIC_AND_COND[] = "and";
35 constexpr char LOGIC_OR_COND[] = "or";
36 constexpr int64_t INVALID_SEQ = -1;
37 constexpr int64_t TRANS_DEFAULT_CNT = 0;
38 constexpr int32_t IGNORED_DEFAULT_CNT = 0;
39 constexpr int MAX_QUERY_EVENTS = 1000; // The maximum number of queries is 1000 at one time
40 constexpr int MAX_TRANS_BUF = 1024 * 768;  // Maximum transmission 768K at one time
41 const std::vector<int> EVENT_TYPES = {1, 2, 3, 4}; // FAULT = 1, STATISTIC = 2 SECURITY = 3, BEHAVIOR = 4
42 
GetCallingProcessInfo()43 EventStore::QueryProcessInfo GetCallingProcessInfo()
44 {
45     std::string processName = CommonUtils::GetProcNameByPid(IPCSkeleton::GetCallingPid());
46     processName = processName.empty() ? "unknown" : processName;
47     return std::make_pair(IPCSkeleton::GetCallingPid(), processName);
48 }
49 }
50 
ParseCondition(const std::string & condStr,EventStore::Cond & condition)51 bool ConditionParser::ParseCondition(const std::string& condStr, EventStore::Cond& condition)
52 {
53     if (extraInfoCondCache.empty() || extraInfoCondCache.find(condStr) == extraInfoCondCache.end()) {
54         EventStore::Cond cond;
55         if (ParseQueryCondition(condStr, cond)) {
56             extraInfoCondCache[condStr] = cond;
57         }
58     }
59     auto iter = extraInfoCondCache.find(condStr);
60     if (iter != extraInfoCondCache.end()) {
61         condition = iter->second;
62         return true;
63     }
64     return false;
65 }
66 
ParseJsonString(const Json::Value & root,const std::string & key,std::string & value)67 bool ConditionParser::ParseJsonString(const Json::Value& root, const std::string& key, std::string& value)
68 {
69     if (!root.isMember(key.c_str()) || !root[key.c_str()].isString()) {
70         return false;
71     }
72     value = root[key].asString();
73     return true;
74 }
75 
GetOpEnum(const std::string & op)76 EventStore::Op ConditionParser::GetOpEnum(const std::string& op)
77 {
78     const std::unordered_map<std::string, EventStore::Op> opMap = {
79         { "=", EventStore::Op::EQ },
80         { "<", EventStore::Op::LT },
81         { ">", EventStore::Op::GT },
82         { "<=", EventStore::Op::LE },
83         { ">=", EventStore::Op::GE },
84     };
85     return opMap.find(op) == opMap.end() ? EventStore::Op::NONE : opMap.at(op);
86 }
87 
SpliceConditionByLogic(EventStore::Cond & condition,const EventStore::Cond & subCond,const std::string & logic)88 void ConditionParser::SpliceConditionByLogic(EventStore::Cond& condition, const EventStore::Cond& subCond,
89     const std::string& logic)
90 {
91     if (logic == LOGIC_OR_COND) {
92         condition.Or(subCond);
93     } else {
94         condition.And(subCond);
95     }
96 }
97 
ParseLogicCondition(const Json::Value & root,const std::string & logic,EventStore::Cond & condition)98 bool ConditionParser::ParseLogicCondition(const Json::Value& root, const std::string& logic,
99     EventStore::Cond& condition)
100 {
101     if (!root.isMember(logic) || !root[logic].isArray()) {
102         HiLog::Error(LABEL, "ParseLogicCondition err1.");
103         return false;
104     }
105 
106     EventStore::Cond subCondition;
107     for (size_t i = 0; i < root[logic].size(); ++i) {
108         auto cond = root[logic][static_cast<int>(i)];
109         std::string param;
110         if (!ParseJsonString(cond, "param", param) || param.empty()) {
111             return false;
112         }
113         std::string op;
114         if (!ParseJsonString(cond, "op", op) || GetOpEnum(op) == EventStore::Op::NONE) {
115             return false;
116         }
117         const char valueKey[] = "value";
118         if (!cond.isMember(valueKey)) {
119             return false;
120         }
121         if (cond[valueKey].isString()) {
122             std::string value = cond[valueKey].asString();
123             SpliceConditionByLogic(subCondition, EventStore::Cond(param, GetOpEnum(op), value), logic);
124         } else if (cond[valueKey].isInt64()) {
125             int64_t value = cond[valueKey].asInt64();
126             SpliceConditionByLogic(subCondition, EventStore::Cond(param, GetOpEnum(op), value), logic);
127         } else {
128             return false;
129         }
130     }
131     condition.And(subCondition);
132     return true;
133 }
134 
ParseOrCondition(const Json::Value & root,EventStore::Cond & condition)135 bool ConditionParser::ParseOrCondition(const Json::Value& root, EventStore::Cond& condition)
136 {
137     return ParseLogicCondition(root, LOGIC_OR_COND, condition);
138 }
139 
ParseAndCondition(const Json::Value & root,EventStore::Cond & condition)140 bool ConditionParser::ParseAndCondition(const Json::Value& root, EventStore::Cond& condition)
141 {
142     return ParseLogicCondition(root, LOGIC_AND_COND, condition);
143 }
144 
ParseQueryConditionJson(const Json::Value & root,EventStore::Cond & condition)145 bool ConditionParser::ParseQueryConditionJson(const Json::Value& root, EventStore::Cond& condition)
146 {
147     const char condKey[] = "condition";
148     if (!root.isMember(condKey) || !root[condKey].isObject()) {
149         return false;
150     }
151     bool res = false;
152     if (ParseOrCondition(root[condKey], condition)) {
153         res = true;
154     }
155     if (ParseAndCondition(root[condKey], condition)) {
156         res = true;
157     }
158     return res;
159 }
160 
ParseQueryCondition(const std::string & condStr,EventStore::Cond & condition)161 bool ConditionParser::ParseQueryCondition(const std::string& condStr, EventStore::Cond& condition)
162 {
163     if (condStr.empty()) {
164         return false;
165     }
166     Json::Value root;
167     Json::CharReaderBuilder jsonRBuilder;
168     Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
169     std::unique_ptr<Json::CharReader> const reader(jsonRBuilder.newCharReader());
170     JSONCPP_STRING errs;
171     if (!reader->parse(condStr.data(), condStr.data() + condStr.size(), &root, &errs)) {
172         HiLog::Error(LABEL, "failed to parse condition string: %{public}s.", condStr.c_str());
173         return false;
174     }
175     std::string version;
176     if (!ParseJsonString(root, "version", version)) {
177         HiLog::Error(LABEL, "failed to parser version.");
178         return false;
179     }
180     const std::set<std::string> versionSet = { "V1" }; // set is used for future expansion
181     if (versionSet.find(version) == versionSet.end()) {
182         HiLog::Error(LABEL, "version is invalid.");
183         return false;
184     }
185     if (!ParseQueryConditionJson(root, condition)) {
186         HiLog::Error(LABEL, "condition is invalid.");
187         return false;
188     }
189     return true;
190 }
191 
HandleCurrentQueryDone(OHOS::sptr<OHOS::HiviewDFX::IQuerySysEventCallback> callback,int32_t & queryResult)192 void BaseEventQueryWrapper::HandleCurrentQueryDone(OHOS::sptr<OHOS::HiviewDFX::IQuerySysEventCallback> callback,
193     int32_t& queryResult)
194 {
195     if (callback == nullptr) {
196         return;
197     }
198     if (IsQueryComplete()) { // all queries have finished, call OnComplete directly
199         callback->OnComplete(queryResult, totalEventCnt, maxSeq);
200         return;
201     }
202     if (query != nullptr && !NeedStartNextQuery()) { // keep current query
203         Query(callback, queryResult);
204         return;
205     }
206     if (HasNext()) { // start next query
207         Next()->SetMaxSequence(maxSeq);
208         Next()->SetEventTotalCount(totalEventCnt);
209         Next()->Query(callback, queryResult);
210         return;
211     }
212     callback->OnComplete(queryResult, totalEventCnt, maxSeq);
213 }
214 
Query(OHOS::sptr<OHOS::HiviewDFX::IQuerySysEventCallback> eventQueryCallback,int32_t & queryResult)215 void BaseEventQueryWrapper::Query(OHOS::sptr<OHOS::HiviewDFX::IQuerySysEventCallback> eventQueryCallback,
216     int32_t& queryResult)
217 {
218     if (eventQueryCallback == nullptr) {
219         queryResult = ERR_LISTENER_NOT_EXIST;
220         return;
221     }
222     if (query == nullptr) {
223         HiLog::Debug(LABEL, "current query is null.");
224         HandleCurrentQueryDone(eventQueryCallback, queryResult);
225         return;
226     }
227     BuildQuery(query);
228     EventStore::Cond domainNameConds;
229     if (BuildConditonByDomainNameExtraInfo(domainNameConds)) {
230         query->And(domainNameConds);
231     }
232     Order();
233     HiLog::Debug(LABEL, "eventType[%{public}u] execute query: beginTime=%{public}" PRId64
234         ", endTime=%{public}" PRId64 ", maxEvents=%{public}d, fromSeq=%{public}" PRId64
235         ", toSeq=%{public}" PRId64 ", queryLimit=%{public}d.", eventType, argument.beginTime, argument.endTime,
236         argument.maxEvents, argument.fromSeq, argument.toSeq, queryLimit);
237     if (isFirstPartialQuery) {
238         HiLog::Debug(LABEL, "current query is first partial query.");
239     }
240     auto resultSet = query->Execute(queryLimit, { false, isFirstPartialQuery }, GetCallingProcessInfo(),
241         [&queryResult] (EventStore::DbQueryStatus status) {
242             std::unordered_map<EventStore::DbQueryStatus, int32_t> statusToCode {
243                 { EventStore::DbQueryStatus::CONCURRENT, ERR_TOO_MANY_CONCURRENT_QUERIES },
244                 { EventStore::DbQueryStatus::OVER_TIME, ERR_QUERY_OVER_TIME },
245                 { EventStore::DbQueryStatus::OVER_LIMIT, ERR_QUERY_OVER_LIMIT },
246                 { EventStore::DbQueryStatus::TOO_FREQENTLY, ERR_QUERY_TOO_FREQUENTLY },
247             };
248             queryResult = statusToCode[status];
249         });
250     if (queryResult != IPC_CALL_SUCCEED) {
251         eventQueryCallback->OnComplete(queryResult, totalEventCnt, maxSeq);
252         return;
253     }
254     auto details = std::make_pair(TRANS_DEFAULT_CNT, IGNORED_DEFAULT_CNT);
255     TransportSysEvent(resultSet, eventQueryCallback, details);
256     transportedEventCnt = details.first;
257     totalEventCnt += transportedEventCnt;
258     ignoredEventCnt += details.second;
259     SetIsFirstPartialQuery(false);
260     if (HasNext()) {
261         Next()->SetIsFirstPartialQuery(false);
262     }
263     argument.maxEvents -= transportedEventCnt;
264     HandleCurrentQueryDone(eventQueryCallback, queryResult);
265 }
266 
TransportSysEvent(OHOS::HiviewDFX::EventStore::ResultSet & result,const OHOS::sptr<OHOS::HiviewDFX::IQuerySysEventCallback> callback,std::pair<int64_t,int32_t> & details)267 void BaseEventQueryWrapper::TransportSysEvent(OHOS::HiviewDFX::EventStore::ResultSet& result,
268     const OHOS::sptr<OHOS::HiviewDFX::IQuerySysEventCallback> callback, std::pair<int64_t, int32_t>& details)
269 {
270     std::vector<std::u16string> events;
271     std::vector<int64_t> seqs;
272     OHOS::HiviewDFX::EventStore::ResultSet::RecordIter iter;
273     int32_t transTotalJsonSize = 0;
274     while (result.HasNext()) {
275         iter = result.Next();
276         std::u16string curJson = Str8ToStr16(iter->jsonExtraInfo_);
277         int32_t eventJsonSize = static_cast<int32_t>((curJson.size() + 1) * sizeof(std::u16string));
278         if (eventJsonSize > MAX_TRANS_BUF) { // too large events, drop
279             details.second++;
280             continue;
281         }
282         if (eventJsonSize + transTotalJsonSize > MAX_TRANS_BUF) {
283             callback->OnQuery(events, seqs);
284             events.clear();
285             seqs.clear();
286             transTotalJsonSize = 0;
287         }
288         events.push_back(curJson);
289         seqs.push_back(iter->GetSeq());
290         details.first++;
291         transTotalJsonSize += eventJsonSize;
292         SyncQueryArgument(iter);
293     }
294     if (!events.empty()) {
295         callback->OnQuery(events, seqs);
296     }
297 }
298 
BuildConditonByDomainNameExtraInfo(EventStore::Cond & domainNameConds)299 bool BaseEventQueryWrapper::BuildConditonByDomainNameExtraInfo(EventStore::Cond& domainNameConds)
300 {
301     auto hasDomainNameCond = false;
302     for_each(domainNameExtraInfos.cbegin(), domainNameExtraInfos.cend(),
303         [this, &hasDomainNameCond, &domainNameConds] (const auto& item) {
304             if (this->HasDomainNameExtraConditon(domainNameConds, item)) {
305                 hasDomainNameCond = true;
306             }
307         });
308     return hasDomainNameCond;
309 }
310 
HasDomainNameExtraConditon(EventStore::Cond & domainNameConds,const DomainNameExtraInfoMap::value_type & domainNameExtraInfo)311 bool BaseEventQueryWrapper::HasDomainNameExtraConditon(EventStore::Cond& domainNameConds,
312     const DomainNameExtraInfoMap::value_type& domainNameExtraInfo)
313 {
314     auto isDomainCondsEmpty = true;
315     auto isNameCondsEmpty = true;
316     EventStore::Cond domainConds;
317     if (!domainNameExtraInfo.first.empty()) {
318         isDomainCondsEmpty = false;
319         domainConds = EventStore::Cond(DOMAIN_, EventStore::Op::EQ, domainNameExtraInfo.first);
320     }
321     EventStore::Cond nameConds;
322     for_each(domainNameExtraInfo.second.cbegin(), domainNameExtraInfo.second.cend(),
323         [this, &nameConds, &isNameCondsEmpty] (const auto& item) {
324             if (item.first.empty() && item.second.empty()) {
325                 return;
326             }
327             EventStore::Cond nameCond(NAME_, EventStore::Op::EQ, item.first);
328             EventStore::Cond extraCond;
329             if (!item.second.empty() &&
330                 (this->parser).ParseCondition(item.second, extraCond)) {
331                 nameCond.And(extraCond);
332             }
333             nameConds.Or(nameCond);
334             isNameCondsEmpty = false;
335         });
336     if (isDomainCondsEmpty && isNameCondsEmpty) {
337         return false;
338     }
339     if (!isDomainCondsEmpty && !isNameCondsEmpty) {
340         domainConds.And(nameConds);
341     } else if (isDomainCondsEmpty) {
342         domainConds = nameConds;
343     }
344     domainNameConds.Or(domainConds);
345     return true;
346 }
347 
SetQueryArgument(QueryArgument argument)348 void BaseEventQueryWrapper::SetQueryArgument(QueryArgument argument)
349 {
350     HiLog::Debug(LABEL, "eventType[%{public}u] set argument: beginTime=%{public} " PRId64
351         ", endTime=%{public} " PRId64 ", maxEvents=%{public}d, fromSeq=%{public} " PRId64
352         ", toSeq=%{public} " PRId64 ".", eventType, argument.beginTime, argument.endTime,
353         argument.maxEvents, argument.fromSeq, argument.toSeq);
354     this->argument = argument;
355 }
356 
GetQueryArgument()357 QueryArgument& BaseEventQueryWrapper::GetQueryArgument()
358 {
359     return argument;
360 }
361 
SetIsFirstPartialQuery(bool isFirstPartialQuery)362 void BaseEventQueryWrapper::SetIsFirstPartialQuery(bool isFirstPartialQuery)
363 {
364     this->isFirstPartialQuery = isFirstPartialQuery;
365 }
366 
GetDomainNameExtraInfoMap()367 DomainNameExtraInfoMap& BaseEventQueryWrapper::GetDomainNameExtraInfoMap()
368 {
369     return domainNameExtraInfos;
370 }
371 
GetMaxSequence() const372 int64_t BaseEventQueryWrapper::GetMaxSequence() const
373 {
374     return maxSeq;
375 }
376 
GetEventTotalCount() const377 int64_t BaseEventQueryWrapper::GetEventTotalCount() const
378 {
379     return totalEventCnt;
380 }
381 
IsValid() const382 bool BaseEventQueryWrapper::IsValid() const
383 {
384     return query != nullptr;
385 }
386 
SetSysEventQuery(std::shared_ptr<EventStore::SysEventQuery> query)387 void BaseEventQueryWrapper::SetSysEventQuery(std::shared_ptr<EventStore::SysEventQuery> query)
388 {
389     this->query = query;
390 }
391 
SetNext(std::shared_ptr<BaseEventQueryWrapper> next)392 void BaseEventQueryWrapper::SetNext(std::shared_ptr<BaseEventQueryWrapper> next)
393 {
394     this->next = next;
395 }
396 
HasNext() const397 bool BaseEventQueryWrapper::HasNext() const
398 {
399     return next != nullptr;
400 }
401 
Next() const402 std::shared_ptr<BaseEventQueryWrapper> BaseEventQueryWrapper::Next() const
403 {
404     return next;
405 }
406 
GetEventType() const407 uint32_t BaseEventQueryWrapper::GetEventType() const
408 {
409     return eventType;
410 }
411 
IsQueryComplete() const412 bool BaseEventQueryWrapper::IsQueryComplete() const
413 {
414     return argument.maxEvents <= 0;
415 }
416 
SetEventTotalCount(int64_t totalCount)417 void BaseEventQueryWrapper::SetEventTotalCount(int64_t totalCount)
418 {
419     HiLog::Debug(LABEL, "eventType[%{public}u] SetEventTotalCount: %{public}" PRId64 ".", eventType, totalCount);
420     totalEventCnt = totalCount;
421 }
422 
BuildQuery(std::shared_ptr<EventStore::SysEventQuery> query)423 void TimeStampEventQueryWrapper::BuildQuery(std::shared_ptr<EventStore::SysEventQuery> query)
424 {
425     if (query == nullptr) {
426         HiLog::Debug(LABEL, "query is null");
427         return;
428     }
429     argument.beginTime = argument.beginTime < 0 ? 0 : argument.beginTime;
430     argument.endTime = argument.endTime < 0 ? std::numeric_limits<int64_t>::max() : argument.endTime;
431     argument.maxEvents = argument.maxEvents < 0 ? std::numeric_limits<int32_t>::max() : argument.maxEvents;
432     queryLimit = argument.maxEvents < MAX_QUERY_EVENTS ? argument.maxEvents : MAX_QUERY_EVENTS;
433     EventStore::Cond whereCond;
434     whereCond.And(EventStore::EventCol::TS, EventStore::Op::GE, argument.beginTime)
435         .And(EventStore::EventCol::TS, EventStore::Op::LT, argument.endTime);
436     query->Where(whereCond);
437 }
438 
SyncQueryArgument(const EventStore::ResultSet::RecordIter iter)439 void TimeStampEventQueryWrapper::SyncQueryArgument(const EventStore::ResultSet::RecordIter iter)
440 {
441     argument.beginTime = static_cast<int64_t>(iter->happenTime_);
442 }
443 
SetMaxSequence(int64_t maxSeq)444 void TimeStampEventQueryWrapper::SetMaxSequence(int64_t maxSeq)
445 {
446     this->maxSeq = maxSeq;
447 }
448 
NeedStartNextQuery()449 bool TimeStampEventQueryWrapper::NeedStartNextQuery()
450 {
451     argument.beginTime++;
452     if (((transportedEventCnt + ignoredEventCnt) < queryLimit || argument.beginTime >= argument.endTime)) {
453         if (HasNext()) {
454             argument.beginTime = Next()->GetQueryArgument().beginTime;
455             argument.endTime = Next()->GetQueryArgument().endTime;
456             Next()->SetQueryArgument(argument);
457         }
458         return true;
459     }
460     return false;
461 }
462 
Order()463 void TimeStampEventQueryWrapper::Order()
464 {
465     if (query == nullptr) {
466         return;
467     }
468     query->Order(EventStore::EventCol::TS, true);
469 }
470 
BuildQuery(std::shared_ptr<EventStore::SysEventQuery> query)471 void SeqEventQueryWrapper::BuildQuery(std::shared_ptr<EventStore::SysEventQuery> query)
472 {
473     if (query == nullptr) {
474         HiLog::Debug(LABEL, "query is null");
475         return;
476     }
477     auto offset = static_cast<int32_t>(argument.toSeq - argument.fromSeq);
478     queryLimit = offset < MAX_QUERY_EVENTS ? offset : MAX_QUERY_EVENTS;
479     EventStore::Cond whereCond;
480     whereCond.And(SEQ_, EventStore::Op::GE, argument.fromSeq)
481             .And(SEQ_, EventStore::Op::LT, argument.toSeq);
482     query->Where(whereCond);
483 }
484 
SyncQueryArgument(const EventStore::ResultSet::RecordIter iter)485 void SeqEventQueryWrapper::SyncQueryArgument(const EventStore::ResultSet::RecordIter iter)
486 {
487     argument.fromSeq = iter->GetEventSeq();
488 }
489 
SetMaxSequence(int64_t maxSeq)490 void SeqEventQueryWrapper::SetMaxSequence(int64_t maxSeq)
491 {
492     this->maxSeq = maxSeq;
493     HiLog::Debug(LABEL, "argument.toSeq is %{public}" PRId64 ", maxSeq is %{public}" PRId64 ".",
494         argument.toSeq, maxSeq);
495     argument.toSeq = std::min(argument.toSeq, maxSeq);
496 }
497 
NeedStartNextQuery()498 bool SeqEventQueryWrapper::NeedStartNextQuery()
499 {
500     argument.fromSeq++;
501     if (((transportedEventCnt + ignoredEventCnt) < queryLimit || argument.fromSeq >= argument.toSeq)) {
502         if (HasNext()) {
503             argument.fromSeq = Next()->GetQueryArgument().fromSeq;
504             argument.toSeq = Next()->GetQueryArgument().toSeq;
505             Next()->SetQueryArgument(argument);
506         }
507         return true;
508     }
509     return false;
510 }
511 
Order()512 void SeqEventQueryWrapper::Order()
513 {
514     if (query == nullptr) {
515         return;
516     }
517     query->Order(SEQ_, true);
518 }
519 
Append(uint32_t eventType)520 EventQueryWrapperBuilder& EventQueryWrapperBuilder::Append(uint32_t eventType)
521 {
522     HiLog::Debug(LABEL, "append eventType: %{public}u.", eventType);
523     auto queryWrapper = Find(eventType);
524     if (queryWrapper != nullptr && !queryWrapper->IsValid()) {
525         queryWrapper->SetSysEventQuery(
526             EventStore::SysEventDao::BuildQuery(static_cast<EventStore::StoreType>(eventType)));
527     }
528     return *shared_from_this();
529 }
530 
Append(const std::string & domain,const std::string & eventName,uint32_t eventType,const std::string & extraInfo)531 EventQueryWrapperBuilder& EventQueryWrapperBuilder::Append(const std::string& domain, const std::string& eventName,
532     uint32_t eventType, const std::string& extraInfo)
533 {
534     HiLog::Debug(LABEL, "builder append domain=%{public}s, event name=%{public}s, event type=%{public}u,"
535         "extra condition=%{public}s.", domain.c_str(), eventName.c_str(), eventType, extraInfo.c_str());
536     auto queryWrapper = Find(eventType);
537     if (queryWrapper == nullptr) {
538         return *shared_from_this();
539     }
540     if (!queryWrapper->IsValid()) {
541         queryWrapper->SetSysEventQuery(
542             EventStore::SysEventDao::BuildQuery(static_cast<EventStore::StoreType>(eventType)));
543     }
544     auto eventNameWithExtraInfo = std::make_pair(eventName, extraInfo);
545     auto& domainNameExtraInfos = queryWrapper->GetDomainNameExtraInfoMap();
546     if (domainNameExtraInfos.empty()) {
547         domainNameExtraInfos[domain] = { eventNameWithExtraInfo };
548         return *shared_from_this();
549     }
550     auto domainNameExtraInfosIter = domainNameExtraInfos.find(domain);
551     if (domainNameExtraInfosIter == domainNameExtraInfos.end()) {
552         domainNameExtraInfos[domain] = { eventNameWithExtraInfo };
553         return *shared_from_this();
554     }
555     auto& nameExtraInfos = domainNameExtraInfosIter->second;
556     if (any_of(nameExtraInfos.begin(), nameExtraInfos.end(), [] (auto& nameExtraInfo) {
557         return nameExtraInfo.first.empty() && nameExtraInfo.second.empty();
558     })) {
559         return *shared_from_this();
560     }
561     if (eventName.empty() && extraInfo.empty()) {
562         nameExtraInfos.clear();
563         nameExtraInfos.emplace(eventName, extraInfo);
564         return *shared_from_this();
565     }
566     if (nameExtraInfos.find(eventName) == nameExtraInfos.end()) {
567         nameExtraInfos.emplace(eventName, extraInfo);
568         return *shared_from_this();
569     }
570     nameExtraInfos[eventName] = extraInfo;
571     return *shared_from_this();
572 }
573 
IsValid() const574 bool EventQueryWrapperBuilder::IsValid() const
575 {
576     auto queryWrapper = Build();
577     if (queryWrapper == nullptr) {
578         return false;
579     }
580     while (queryWrapper != nullptr) {
581         if (queryWrapper->IsValid()) {
582             return true;
583         }
584         queryWrapper = queryWrapper->Next();
585     }
586     return false;
587 }
588 
Build() const589 std::shared_ptr<BaseEventQueryWrapper> EventQueryWrapperBuilder::Build() const
590 {
591     return queryWrapper;
592 }
593 
CreateQueryWrapperByArgument(const QueryArgument & argument,uint32_t eventType,std::shared_ptr<EventStore::SysEventQuery> query)594 std::shared_ptr<BaseEventQueryWrapper> EventQueryWrapperBuilder::CreateQueryWrapperByArgument(
595     const QueryArgument& argument, uint32_t eventType, std::shared_ptr<EventStore::SysEventQuery> query)
596 {
597     if (argument.fromSeq != INVALID_SEQ && argument.toSeq != INVALID_SEQ && argument.fromSeq < argument.toSeq) {
598         return std::make_shared<SeqEventQueryWrapper>(eventType, query);
599     }
600     return std::make_shared<TimeStampEventQueryWrapper>(eventType, query);
601 }
602 
InitQueryWrappers(const QueryArgument & argument)603 void EventQueryWrapperBuilder::InitQueryWrappers(const QueryArgument& argument)
604 {
605     HiLog::Debug(LABEL, "init link list of query wrapper with argument: beginTime=%{public} " PRId64
606         ", endTime=%{public} " PRId64 ", maxEvents=%{public}d, fromSeq=%{public} " PRId64
607         ", toSeq=%{public} " PRId64 ".", argument.beginTime, argument.endTime,
608         argument.maxEvents, argument.fromSeq, argument.toSeq);
609     std::shared_ptr<BaseEventQueryWrapper> queryWrapper = nullptr;
610     for (auto& eventType : EVENT_TYPES) {
611         if (queryWrapper == nullptr) {
612             queryWrapper = CreateQueryWrapperByArgument(argument, eventType, nullptr);
613             queryWrapper->SetQueryArgument(argument);
614             this->queryWrapper = queryWrapper;
615             continue;
616         }
617         queryWrapper->SetNext(CreateQueryWrapperByArgument(argument, eventType, nullptr));
618         queryWrapper = queryWrapper->Next();
619         queryWrapper->SetQueryArgument(argument);
620     }
621 }
622 
Find(uint32_t eventType)623 std::shared_ptr<BaseEventQueryWrapper> EventQueryWrapperBuilder::Find(uint32_t eventType)
624 {
625     auto queryWrapper = Build();
626     if (eventType == 0) {
627         return queryWrapper;
628     }
629     while (queryWrapper != nullptr && queryWrapper->GetEventType() != eventType) {
630         queryWrapper = queryWrapper->Next();
631     }
632     if (queryWrapper != nullptr && queryWrapper->GetEventType() == eventType) {
633         return queryWrapper;
634     }
635     return nullptr;
636 }
637 } // namespace HiviewDFX
638 } // namespace OHOS
639