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