• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 #include "app_event_store.h"
16 
17 #include <cinttypes>
18 #include <utility>
19 #include <vector>
20 
21 #include "app_event_cache_common.h"
22 #include "app_event_store_callback.h"
23 #include "file_util.h"
24 #include "hiappevent_base.h"
25 #include "hiappevent_config.h"
26 #include "hilog/log.h"
27 #include "rdb_errno.h"
28 #include "rdb_helper.h"
29 #include "sql_util.h"
30 
31 using namespace OHOS::HiviewDFX::AppEventCacheCommon;
32 namespace OHOS {
33 namespace HiviewDFX {
34 namespace {
35 const HiLogLabel LABEL = { LOG_CORE, HIAPPEVENT_DOMAIN, "HiAppEvent_Store" };
36 const char* DATABASE_NAME = "appevent.db";
37 const char* DATABASE_DIR = "databases/";
38 
GetIntFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet,const std::string & colName)39 int GetIntFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet, const std::string& colName)
40 {
41     int value = 0;
42     int colIndex = 0;
43     if (resultSet->GetColumnIndex(colName, colIndex) != NativeRdb::E_OK) {
44         HiLog::Warn(LABEL, "failed to get column index, colName=%{public}s", colName.c_str());
45         return value;
46     }
47     if (resultSet->GetInt(colIndex, value) != NativeRdb::E_OK) {
48         HiLog::Warn(LABEL, "failed to get int value, colName=%{public}s", colName.c_str());
49     }
50     return value;
51 }
52 
GetLongFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet,const std::string & colName)53 int64_t GetLongFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet, const std::string& colName)
54 {
55     int64_t value = 0;
56     int colIndex = 0;
57     if (resultSet->GetColumnIndex(colName, colIndex) != NativeRdb::E_OK) {
58         HiLog::Warn(LABEL, "failed to get column index, colName=%{public}s", colName.c_str());
59         return value;
60     }
61     if (resultSet->GetLong(colIndex, value) != NativeRdb::E_OK) {
62         HiLog::Warn(LABEL, "failed to get long value, colName=%{public}s", colName.c_str());
63     }
64     return value;
65 }
66 
GetStringFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet,const std::string & colName)67 std::string GetStringFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet, const std::string& colName)
68 {
69     std::string value;
70     int colIndex = 0;
71     if (resultSet->GetColumnIndex(colName, colIndex) != NativeRdb::E_OK) {
72         HiLog::Warn(LABEL, "failed to get column index, colName=%{public}s", colName.c_str());
73         return value;
74     }
75     if (resultSet->GetString(colIndex, value) != NativeRdb::E_OK) {
76         HiLog::Warn(LABEL, "failed to get string value, colName=%{public}s", colName.c_str());
77     }
78     return value;
79 }
80 
GetEventFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet)81 std::shared_ptr<AppEventPack> GetEventFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet)
82 {
83     auto event = std::make_shared<AppEventPack>();
84     event->SetSeq(GetLongFromResultSet(resultSet, Events::FIELD_SEQ));
85     event->SetDomain(GetStringFromResultSet(resultSet, Events::FIELD_DOMAIN));
86     event->SetName(GetStringFromResultSet(resultSet, Events::FIELD_NAME));
87     event->SetType(GetIntFromResultSet(resultSet, Events::FIELD_TYPE));
88     event->SetTime(GetLongFromResultSet(resultSet, Events::FIELD_TIME));
89     event->SetTimeZone(GetStringFromResultSet(resultSet, Events::FIELD_TZ));
90     event->SetPid(GetIntFromResultSet(resultSet, Events::FIELD_PID));
91     event->SetTid(GetIntFromResultSet(resultSet, Events::FIELD_TID));
92     event->SetTraceId(GetLongFromResultSet(resultSet, Events::FIELD_TRACE_ID));
93     event->SetSpanId(GetLongFromResultSet(resultSet, Events::FIELD_SPAN_ID));
94     event->SetPspanId(GetLongFromResultSet(resultSet, Events::FIELD_PSPAN_ID));
95     event->SetTraceFlag(GetIntFromResultSet(resultSet, Events::FIELD_TRACE_FLAG));
96     event->SetParamStr(GetStringFromResultSet(resultSet, Events::FIELD_PARAMS));
97     return event;
98 }
99 }
100 
OnCreate(NativeRdb::RdbStore & rdbStore)101 int AppEventStoreCallback::OnCreate(NativeRdb::RdbStore& rdbStore)
102 {
103     HiLog::Debug(LABEL, "OnCreate start to create db");
104     return NativeRdb::E_OK;
105 }
106 
OnUpgrade(NativeRdb::RdbStore & rdbStore,int oldVersion,int newVersion)107 int AppEventStoreCallback::OnUpgrade(NativeRdb::RdbStore& rdbStore, int oldVersion, int newVersion)
108 {
109     HiLog::Debug(LABEL, "OnUpgrade, oldVersion=%{public}d, newVersion=%{public}d", oldVersion, newVersion);
110     return NativeRdb::E_OK;
111 }
112 
AppEventStore()113 AppEventStore::AppEventStore()
114 {
115     (void)InitDbStore();
116 }
117 
~AppEventStore()118 AppEventStore::~AppEventStore()
119 {
120     dbStore_ = nullptr;
121 }
122 
InitDbStore()123 int AppEventStore::InitDbStore()
124 {
125     if (!InitDbStoreDir()) {
126         return DB_FAILED;
127     }
128 
129     int ret = NativeRdb::E_OK;
130     NativeRdb::RdbStoreConfig config(dirPath_ + DATABASE_NAME);
131     config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
132     const int dbVersion = 1;
133     AppEventStoreCallback callback;
134     auto dbStore = NativeRdb::RdbHelper::GetRdbStore(config, dbVersion, callback, ret);
135     if (ret != NativeRdb::E_OK || dbStore == nullptr) {
136         HiLog::Error(LABEL, "failed to create db store, ret=%{pulic}d", ret);
137         return DB_FAILED;
138     }
139 
140     std::lock_guard<std::mutex> lockGuard(dbMutex_);
141     dbStore_ = dbStore;
142     appEventDao_ = std::make_shared<AppEventDao>(dbStore_);
143     appEventObserverDao_ = std::make_shared<AppEventObserverDao>(dbStore_);
144     appEventMappingDao_ = std::make_shared<AppEventMappingDao>(dbStore_);
145     userIdDao_ = std::make_shared<UserIdDao>(dbStore_);
146     userPropertyDao_ = std::make_shared<UserPropertyDao>(dbStore_);
147     HiLog::Info(LABEL, "create db store successfully");
148     return DB_SUCC;
149 }
150 
InitDbStoreDir()151 bool AppEventStore::InitDbStoreDir()
152 {
153     std::string dir = HiAppEventConfig::GetInstance().GetStorageDir();
154     if (dir.empty()) {
155         HiLog::Error(LABEL, "failed to init db dir, path is empty");
156         return false;
157     }
158     dirPath_ = FileUtil::GetFilePathByDir(dir, DATABASE_DIR);
159     if (!FileUtil::IsFileExists(dirPath_) && !FileUtil::ForceCreateDirectory(dirPath_)) {
160         HiLog::Error(LABEL, "failed to create database dir, errno=%{public}d", errno);
161         return false;
162     }
163     return true;
164 }
165 
DestroyDbStore()166 int AppEventStore::DestroyDbStore()
167 {
168     if (dbStore_ == nullptr) {
169         return DB_SUCC;
170     }
171 
172     std::lock_guard<std::mutex> lockGuard(dbMutex_);
173     dbStore_ = nullptr;
174     if (int ret = NativeRdb::RdbHelper::DeleteRdbStore(dirPath_ + DATABASE_NAME); ret != NativeRdb::E_OK) {
175         HiLog::Error(LABEL, "failed to destroy db store, ret=%{pulic}d", ret);
176         return DB_FAILED;
177     }
178     HiLog::Info(LABEL, "destroy db store successfully");
179     return DB_SUCC;
180 }
181 
InsertEvent(std::shared_ptr<AppEventPack> event)182 int64_t AppEventStore::InsertEvent(std::shared_ptr<AppEventPack> event)
183 {
184     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
185         return DB_FAILED;
186     }
187 
188     std::lock_guard<std::mutex> lockGuard(dbMutex_);
189     return appEventDao_->Insert(event);
190 }
191 
InsertObserver(const std::string & observer,int64_t hashCode)192 int64_t AppEventStore::InsertObserver(const std::string& observer, int64_t hashCode)
193 {
194     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
195         return DB_FAILED;
196     }
197 
198     std::lock_guard<std::mutex> lockGuard(dbMutex_);
199     return appEventObserverDao_->Insert(observer, hashCode);
200 }
201 
InsertEventMapping(int64_t eventSeq,int64_t observerSeq)202 int64_t AppEventStore::InsertEventMapping(int64_t eventSeq, int64_t observerSeq)
203 {
204     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
205         return DB_FAILED;
206     }
207 
208     std::lock_guard<std::mutex> lockGuard(dbMutex_);
209     return appEventMappingDao_->Insert(eventSeq, observerSeq);
210 }
211 
InsertUserId(const std::string & name,const std::string & value)212 int64_t AppEventStore::InsertUserId(const std::string& name, const std::string& value)
213 {
214     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
215         return DB_FAILED;
216     }
217 
218     std::lock_guard<std::mutex> lockGuard(dbMutex_);
219     return userIdDao_->Insert(name, value);
220 }
221 
InsertUserProperty(const std::string & name,const std::string & value)222 int64_t AppEventStore::InsertUserProperty(const std::string& name, const std::string& value)
223 {
224     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
225         return DB_FAILED;
226     }
227 
228     std::lock_guard<std::mutex> lockGuard(dbMutex_);
229     return userPropertyDao_->Insert(name, value);
230 }
231 
UpdateUserId(const std::string & name,const std::string & value)232 int64_t AppEventStore::UpdateUserId(const std::string& name, const std::string& value)
233 {
234     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
235         return DB_FAILED;
236     }
237 
238     std::lock_guard<std::mutex> lockGuard(dbMutex_);
239     return userIdDao_->Update(name, value);
240 }
241 
UpdateUserProperty(const std::string & name,const std::string & value)242 int64_t AppEventStore::UpdateUserProperty(const std::string& name, const std::string& value)
243 {
244     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
245         return DB_FAILED;
246     }
247 
248     std::lock_guard<std::mutex> lockGuard(dbMutex_);
249     return userPropertyDao_->Update(name, value);
250 }
251 
DeleteUserId(const std::string & name)252 int AppEventStore::DeleteUserId(const std::string& name)
253 {
254     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
255         return DB_FAILED;
256     }
257 
258     std::lock_guard<std::mutex> lockGuard(dbMutex_);
259     return userIdDao_->Delete(name);
260 }
261 
DeleteUserProperty(const std::string & name)262 int AppEventStore::DeleteUserProperty(const std::string& name)
263 {
264     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
265         return DB_FAILED;
266     }
267 
268     std::lock_guard<std::mutex> lockGuard(dbMutex_);
269     return userPropertyDao_->Delete(name);
270 }
271 
QueryUserIds(std::unordered_map<std::string,std::string> & out)272 int AppEventStore::QueryUserIds(std::unordered_map<std::string, std::string>& out)
273 {
274     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
275         return DB_FAILED;
276     }
277 
278     std::lock_guard<std::mutex> lockGuard(dbMutex_);
279     return userIdDao_->QueryAll(out);
280 }
281 
QueryUserId(const std::string & name,std::string & out)282 int AppEventStore::QueryUserId(const std::string& name, std::string& out)
283 {
284     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
285         return DB_FAILED;
286     }
287 
288     std::lock_guard<std::mutex> lockGuard(dbMutex_);
289     return userIdDao_->Query(name, out);
290 }
291 
QueryUserProperties(std::unordered_map<std::string,std::string> & out)292 int AppEventStore::QueryUserProperties(std::unordered_map<std::string, std::string>& out)
293 {
294     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
295         return DB_FAILED;
296     }
297 
298     std::lock_guard<std::mutex> lockGuard(dbMutex_);
299     return userPropertyDao_->QueryAll(out);
300 }
301 
QueryUserProperty(const std::string & name,std::string & out)302 int AppEventStore::QueryUserProperty(const std::string& name, std::string& out)
303 {
304     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
305         return DB_FAILED;
306     }
307 
308     std::lock_guard<std::mutex> lockGuard(dbMutex_);
309     return userPropertyDao_->Query(name, out);
310 }
311 
TakeEvents(std::vector<std::shared_ptr<AppEventPack>> & events,int64_t observerSeq)312 int AppEventStore::TakeEvents(std::vector<std::shared_ptr<AppEventPack>>& events, int64_t observerSeq)
313 {
314     // query the events of the observer
315     if (int ret = QueryEvents(events, observerSeq); ret != DB_SUCC) {
316         return ret;
317     }
318     // delete the events mapping of the observer
319     std::lock_guard<std::mutex> lockGuard(dbMutex_);
320     if (appEventMappingDao_->Delete(observerSeq, {}) < 0) {
321         HiLog::Warn(LABEL, "failed to delete the events mapping data, observer=%{public}" PRId64, observerSeq);
322         return DB_FAILED;
323     }
324     return DB_SUCC;
325 }
326 
QueryEvents(std::vector<std::shared_ptr<AppEventPack>> & events,int64_t observerSeq)327 int AppEventStore::QueryEvents(std::vector<std::shared_ptr<AppEventPack>>& events, int64_t observerSeq)
328 {
329     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
330         return DB_FAILED;
331     }
332 
333     std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet = nullptr;
334     {
335         std::lock_guard<std::mutex> lockGuard(dbMutex_);
336         const std::string sql = "SELECT " + Events::TABLE + ".* FROM " + AppEventMapping::TABLE + " INNER JOIN "
337             + Events::TABLE + " ON " + AppEventMapping::TABLE + "." + AppEventMapping::FIELD_EVENT_SEQ + "="
338             + Events::TABLE + "." + Events::FIELD_SEQ + " WHERE " + AppEventMapping::FIELD_OBSERVER_SEQ + "=?";
339         resultSet = dbStore_->QuerySql(sql, std::vector<std::string>{std::to_string(observerSeq)});
340     }
341     if (resultSet == nullptr) {
342         HiLog::Warn(LABEL, "result set is null, observer=%{public}" PRId64, observerSeq);
343         return DB_FAILED;
344     }
345     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
346         auto event = GetEventFromResultSet(resultSet);
347         events.emplace_back(event);
348     }
349     resultSet->Close();
350     return DB_SUCC;
351 }
352 
QueryObserverSeq(const std::string & observer,int64_t hashCode)353 int64_t AppEventStore::QueryObserverSeq(const std::string& observer, int64_t hashCode)
354 {
355     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
356         return DB_FAILED;
357     }
358 
359     std::lock_guard<std::mutex> lockGuard(dbMutex_);
360     return appEventObserverDao_->QuerySeq(observer, hashCode);
361 }
362 
QueryObserverSeqs(const std::string & observer,std::vector<int64_t> & observerSeqs)363 int AppEventStore::QueryObserverSeqs(const std::string& observer, std::vector<int64_t>& observerSeqs)
364 {
365     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
366         return DB_FAILED;
367     }
368 
369     std::lock_guard<std::mutex> lockGuard(dbMutex_);
370     return appEventObserverDao_->QuerySeqs(observer, observerSeqs);
371 }
372 
DeleteObserver(int64_t observerSeq)373 int AppEventStore::DeleteObserver(int64_t observerSeq)
374 {
375     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
376         return DB_FAILED;
377     }
378 
379     std::lock_guard<std::mutex> lockGuard(dbMutex_);
380     if (int ret = appEventMappingDao_->Delete(observerSeq, {}); ret < 0) {
381         return ret;
382     }
383     return appEventObserverDao_->Delete(observerSeq);
384 }
385 
DeleteEventMapping(int64_t observerSeq,const std::vector<int64_t> & eventSeqs)386 int AppEventStore::DeleteEventMapping(int64_t observerSeq, const std::vector<int64_t>& eventSeqs)
387 {
388     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
389         return DB_FAILED;
390     }
391 
392     std::lock_guard<std::mutex> lockGuard(dbMutex_);
393     return appEventMappingDao_->Delete(observerSeq, eventSeqs);
394 }
395 
DeleteEvent(int64_t eventSeq)396 int AppEventStore::DeleteEvent(int64_t eventSeq)
397 {
398     if (dbStore_ == nullptr && InitDbStore() != DB_SUCC) {
399         return DB_FAILED;
400     }
401 
402     std::lock_guard<std::mutex> lockGuard(dbMutex_);
403     return appEventDao_->Delete(eventSeq);
404 }
405 } // namespace HiviewDFX
406 } // namespace OHOS
407