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