1020a203aSopenharmony_ci/*
2020a203aSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4020a203aSopenharmony_ci * you may not use this file except in compliance with the License.
5020a203aSopenharmony_ci * You may obtain a copy of the License at
6020a203aSopenharmony_ci *
7020a203aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8020a203aSopenharmony_ci *
9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12020a203aSopenharmony_ci * See the License for the specific language governing permissions and
13020a203aSopenharmony_ci * limitations under the License.
14020a203aSopenharmony_ci */
15020a203aSopenharmony_ci
16020a203aSopenharmony_ci#include "db_helper.h"
17020a203aSopenharmony_ci
18020a203aSopenharmony_ci#include <regex>
19020a203aSopenharmony_ci#include <map>
20020a203aSopenharmony_ci
21020a203aSopenharmony_ci#include "hiview_logger.h"
22020a203aSopenharmony_ci#include "string_util.h"
23020a203aSopenharmony_ci#include "sys_event_dao.h"
24020a203aSopenharmony_ci
25020a203aSopenharmony_cinamespace OHOS {
26020a203aSopenharmony_cinamespace HiviewDFX {
27020a203aSopenharmony_cinamespace {
28020a203aSopenharmony_ci    static constexpr const char* const EVENT_MSG = "MSG";
29020a203aSopenharmony_ci}
30020a203aSopenharmony_ciDEFINE_LOG_LABEL(0xD002D01, "FreezeDetector");
31020a203aSopenharmony_civoid DBHelper::GetResultMap(const struct WatchParams& watchParams, const FreezeResult& result,
32020a203aSopenharmony_ci    EventStore::ResultSet& set, std::map<std::string, WatchPoint>& resultMap)
33020a203aSopenharmony_ci{
34020a203aSopenharmony_ci    while (set.HasNext()) {
35020a203aSopenharmony_ci        auto record = set.Next();
36020a203aSopenharmony_ci        std::string key = record->domain_ + "-" + record->eventName_;
37020a203aSopenharmony_ci
38020a203aSopenharmony_ci        std::string packageName = record->GetEventValue(FreezeCommon::EVENT_PACKAGE_NAME);
39020a203aSopenharmony_ci        packageName = packageName.empty() ?
40020a203aSopenharmony_ci            record->GetEventValue(FreezeCommon::EVENT_PROCESS_NAME) : packageName;
41020a203aSopenharmony_ci        long pid = record->GetEventIntValue(FreezeCommon::EVENT_PID);
42020a203aSopenharmony_ci        pid = pid ? pid : record->GetPid();
43020a203aSopenharmony_ci        if (result.GetSamePackage() == "true" && (watchParams.packageName != packageName || watchParams.pid != pid)) {
44020a203aSopenharmony_ci            HIVIEW_LOGE("failed to match the same package: %{public}s and %{public}s, the same pid: %{public}lu and "
45020a203aSopenharmony_ci                "%{public}lu", watchParams.packageName.c_str(), packageName.c_str(), watchParams.pid, pid);
46020a203aSopenharmony_ci            continue;
47020a203aSopenharmony_ci        }
48020a203aSopenharmony_ci
49020a203aSopenharmony_ci        long uid = record->GetEventIntValue(FreezeCommon::EVENT_UID);
50020a203aSopenharmony_ci        uid = uid ? uid : record->GetUid();
51020a203aSopenharmony_ci        long tid = std::strtol(record->GetEventValue(EventStore::EventCol::TID).c_str(), nullptr, 0);
52020a203aSopenharmony_ci
53020a203aSopenharmony_ci        WatchPoint watchPoint = WatchPoint::Builder()
54020a203aSopenharmony_ci            .InitSeq(record->GetSeq()).InitDomain(result.GetDomain()).InitStringId(result.GetStringId())
55020a203aSopenharmony_ci            .InitTimestamp(record->happenTime_).InitPid(pid).InitUid(uid).InitTid(tid).InitPackageName(packageName)
56020a203aSopenharmony_ci            .InitProcessName(record->GetEventValue(FreezeCommon::EVENT_PROCESS_NAME))
57020a203aSopenharmony_ci            .InitMsg(StringUtil::ReplaceStr(record->GetEventValue(EVENT_MSG), "\\n", "\n")).Build();
58020a203aSopenharmony_ci
59020a203aSopenharmony_ci        std::string info = record->GetEventValue(EventStore::EventCol::INFO);
60020a203aSopenharmony_ci        std::regex reg("logPath:([^,]+)");
61020a203aSopenharmony_ci        std::smatch smatchResult;
62020a203aSopenharmony_ci        if (std::regex_search(info, smatchResult, reg)) {
63020a203aSopenharmony_ci            watchPoint.SetLogPath(smatchResult[1].str());
64020a203aSopenharmony_ci        }
65020a203aSopenharmony_ci
66020a203aSopenharmony_ci        if (resultMap.find(key) != resultMap.end() && watchPoint.GetTimestamp() > resultMap[key].GetTimestamp()) {
67020a203aSopenharmony_ci            resultMap[key] = watchPoint;
68020a203aSopenharmony_ci        } else {
69020a203aSopenharmony_ci            resultMap.insert(std::pair<std::string, WatchPoint>(key, watchPoint));
70020a203aSopenharmony_ci        }
71020a203aSopenharmony_ci    }
72020a203aSopenharmony_ci}
73020a203aSopenharmony_ci
74020a203aSopenharmony_civoid DBHelper::SelectEventFromDB(unsigned long long start, unsigned long long end, std::vector<WatchPoint>& list,
75020a203aSopenharmony_ci    const struct WatchParams& watchParams, const FreezeResult& result)
76020a203aSopenharmony_ci{
77020a203aSopenharmony_ci    if (freezeCommon_ == nullptr) {
78020a203aSopenharmony_ci        return;
79020a203aSopenharmony_ci    }
80020a203aSopenharmony_ci    if (start > end) {
81020a203aSopenharmony_ci        return;
82020a203aSopenharmony_ci    }
83020a203aSopenharmony_ci
84020a203aSopenharmony_ci    auto eventQuery = EventStore::SysEventDao::BuildQuery(result.GetDomain(), {result.GetStringId()});
85020a203aSopenharmony_ci    std::vector<std::string> selections { EventStore::EventCol::TS };
86020a203aSopenharmony_ci    if (eventQuery) {
87020a203aSopenharmony_ci        eventQuery->Select(selections)
88020a203aSopenharmony_ci            .Where(EventStore::EventCol::TS, EventStore::Op::GE, static_cast<int64_t>(start))
89020a203aSopenharmony_ci            .And(EventStore::EventCol::TS, EventStore::Op::LE, static_cast<int64_t>(end));
90020a203aSopenharmony_ci    } else {
91020a203aSopenharmony_ci        HIVIEW_LOGE("event query selections failed.");
92020a203aSopenharmony_ci        return;
93020a203aSopenharmony_ci    }
94020a203aSopenharmony_ci    EventStore::ResultSet set = eventQuery->Execute();
95020a203aSopenharmony_ci    if (set.GetErrCode() != 0) {
96020a203aSopenharmony_ci        HIVIEW_LOGE("failed to select event from db, error:%{public}d.", set.GetErrCode());
97020a203aSopenharmony_ci        return;
98020a203aSopenharmony_ci    }
99020a203aSopenharmony_ci
100020a203aSopenharmony_ci    std::map<std::string, WatchPoint> resultMap;
101020a203aSopenharmony_ci    GetResultMap(watchParams, result, set, resultMap);
102020a203aSopenharmony_ci
103020a203aSopenharmony_ci    std::map<std::string, WatchPoint>::iterator it;
104020a203aSopenharmony_ci    for (it = resultMap.begin(); it != resultMap.end(); ++it) {
105020a203aSopenharmony_ci        list.push_back(it->second);
106020a203aSopenharmony_ci    }
107020a203aSopenharmony_ci    sort(list.begin(), list.end(), [] (const WatchPoint& frontWatchPoint, const WatchPoint& rearWatchPoint) {
108020a203aSopenharmony_ci        return frontWatchPoint.GetTimestamp() < rearWatchPoint.GetTimestamp();
109020a203aSopenharmony_ci    });
110020a203aSopenharmony_ci
111020a203aSopenharmony_ci    HIVIEW_LOGI("select event from db, size =%{public}zu.", list.size());
112020a203aSopenharmony_ci}
113020a203aSopenharmony_ci} // namespace HiviewDFX
114020a203aSopenharmony_ci} // namespace OHOS
115