1 /*
2 * Copyright (c) 2024 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 "sys_event_repeat_db.h"
17
18 #include "hiview_logger.h"
19 #include "rdb_helper.h"
20 #include "sql_util.h"
21 #include "sys_event_database.h"
22
23 namespace OHOS {
24 namespace HiviewDFX {
25 DEFINE_LOG_TAG("HiView-SysEvent-Repeat-Db");
26 namespace {
27 const std::string DB_FILE_NAME = "sys_event_history.db";
28 const std::string TABLE_NAME = "sys_event_history";
29 constexpr int32_t DB_VERSION = 1;
30
31 const std::string COLUMN_DOMAIN = "domain";
32 const std::string COLUMN_NAME = "name";
33 const std::string COLUMN_EVENT_HASH = "eventHash";
34 const std::string COLUMN_HAPPENTIME = "happentime";
35 constexpr int32_t MAX_DB_COUNT = 10000;
36
37 class SysEventRepeatDbCallback : public NativeRdb::RdbOpenCallback {
38 public:
39 int OnCreate(NativeRdb::RdbStore &rdbStore) override;
40 int OnUpgrade(NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) override;
41 };
42
OnCreate(NativeRdb::RdbStore & rdbStore)43 int SysEventRepeatDbCallback::OnCreate(NativeRdb::RdbStore& rdbStore)
44 {
45 HIVIEW_LOGI("create dbStore");
46 return NativeRdb::E_OK;
47 }
48
OnUpgrade(NativeRdb::RdbStore & rdbStore,int oldVersion,int newVersion)49 int SysEventRepeatDbCallback::OnUpgrade(NativeRdb::RdbStore& rdbStore, int oldVersion, int newVersion)
50 {
51 HIVIEW_LOGI("oldVersion=%{public}d, newVersion=%{public}d", oldVersion, newVersion);
52 return NativeRdb::E_OK;
53 }
54 }
55
SysEventRepeatDb()56 SysEventRepeatDb::SysEventRepeatDb()
57 {
58 InitDbStore();
59 RefreshDbCount();
60 }
61
InitDbStore()62 void SysEventRepeatDb::InitDbStore()
63 {
64 auto dbFullName = EventStore::SysEventDatabase::GetInstance().GetDatabaseDir() + DB_FILE_NAME;
65 NativeRdb::RdbStoreConfig config(dbFullName);
66 config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
67 SysEventRepeatDbCallback callback;
68 auto ret = NativeRdb::E_OK;
69 dbStore_ = NativeRdb::RdbHelper::GetRdbStore(config, DB_VERSION, callback, ret);
70 if (ret != NativeRdb::E_OK) {
71 HIVIEW_LOGE("failed to init db store, db store path=%{public}s", dbFullName.c_str());
72 dbStore_ = nullptr;
73 return;
74 }
75 CreateTable();
76 }
77
CreateTable()78 void SysEventRepeatDb::CreateTable()
79 {
80 if (dbStore_ == nullptr) {
81 return;
82 }
83 /**
84 * table: sys_event_history
85 *
86 * describe: store data that app task
87 * |---------|------|-----------|------------|
88 * | domain | name | eventHash | happentime |
89 * |---------|------|-----------|------------|
90 * | TEXT | TEXT | TEXT | INT64 |
91 * |---------|------|-----------|------------|
92 */
93 const std::vector<std::pair<std::string, std::string>> fields = {
94 {COLUMN_DOMAIN, SqlUtil::COLUMN_TYPE_STR},
95 {COLUMN_NAME, SqlUtil::COLUMN_TYPE_STR},
96 {COLUMN_EVENT_HASH, SqlUtil::COLUMN_TYPE_STR},
97 {COLUMN_HAPPENTIME, SqlUtil::COLUMN_TYPE_INT},
98 };
99 std::string sql = SqlUtil::GenerateCreateSql(TABLE_NAME, fields);
100 if (dbStore_->ExecuteSql(sql) != NativeRdb::E_OK) {
101 HIVIEW_LOGE("failed to create table, sql=%{public}s", sql.c_str());
102 return;
103 }
104
105 std::string indexSql = "create index sys_event_his_index1 on ";
106 indexSql.append(TABLE_NAME).append("(").append(COLUMN_DOMAIN).append(", ")
107 .append(COLUMN_NAME).append(",").append(COLUMN_EVENT_HASH).append(");");
108 if (dbStore_->ExecuteSql(indexSql) != NativeRdb::E_OK) {
109 HIVIEW_LOGE("failed to create index1, sql=%{public}s", indexSql.c_str());
110 return;
111 }
112
113 std::string indexHappentimeSql = "create index sys_event_his_index2 on ";
114 indexHappentimeSql.append(TABLE_NAME).append("(").append(COLUMN_HAPPENTIME).append(");");
115 if (dbStore_->ExecuteSql(indexHappentimeSql) != NativeRdb::E_OK) {
116 HIVIEW_LOGE("failed to create index2, sql=%{public}s", indexHappentimeSql.c_str());
117 return;
118 }
119 }
120
CheckAndClearDb(const int64_t happentime)121 void SysEventRepeatDb::CheckAndClearDb(const int64_t happentime)
122 {
123 if (dbCount_ <= MAX_DB_COUNT) {
124 return;
125 }
126 Clear(happentime);
127 }
128
Clear(const int64_t happentime)129 void SysEventRepeatDb::Clear(const int64_t happentime)
130 {
131 ClearHistory(happentime);
132 RefreshDbCount();
133 }
134
Insert(const SysEventHashRecord & sysEventHashRecord)135 bool SysEventRepeatDb::Insert(const SysEventHashRecord &sysEventHashRecord)
136 {
137 if (dbStore_ == nullptr) {
138 return false;
139 }
140 NativeRdb::ValuesBucket bucket;
141 bucket.PutString(COLUMN_DOMAIN, sysEventHashRecord.domain);
142 bucket.PutString(COLUMN_NAME, sysEventHashRecord.name);
143 bucket.PutString(COLUMN_EVENT_HASH, sysEventHashRecord.eventHash);
144 bucket.PutLong(COLUMN_HAPPENTIME, sysEventHashRecord.happentime);
145 int64_t seq = 0;
146 int ret = dbStore_->Insert(seq, TABLE_NAME, bucket);
147 if (ret != NativeRdb::E_OK) {
148 HIVIEW_LOGE("failed to insert app event task, ret=%{public}d", ret);
149 return false;
150 }
151 ++dbCount_;
152 return true;
153 }
154
Update(const SysEventHashRecord & sysEventHashRecord)155 bool SysEventRepeatDb::Update(const SysEventHashRecord &sysEventHashRecord)
156 {
157 if (dbStore_ == nullptr) {
158 return false;
159 }
160 NativeRdb::AbsRdbPredicates predicates(TABLE_NAME);
161 predicates.EqualTo(COLUMN_DOMAIN, sysEventHashRecord.domain);
162 predicates.EqualTo(COLUMN_NAME, sysEventHashRecord.name);
163 predicates.EqualTo(COLUMN_EVENT_HASH, sysEventHashRecord.eventHash);
164 NativeRdb::ValuesBucket bucket;
165 bucket.PutLong(COLUMN_HAPPENTIME, sysEventHashRecord.happentime);
166 int updateRowNum = 0;
167 if (dbStore_->Update(updateRowNum, bucket, predicates) != NativeRdb::E_OK) {
168 HIVIEW_LOGE("failed to update table.");
169 return false;
170 }
171 return true;
172 }
173
ClearHistory(const int64_t happentime)174 void SysEventRepeatDb::ClearHistory(const int64_t happentime)
175 {
176 if (dbStore_ == nullptr) {
177 return;
178 }
179 std::string whereClause = COLUMN_HAPPENTIME;
180 whereClause.append(" < ").append(std::to_string(happentime));
181 int deleteRows = 0;
182 if (dbStore_->Delete(deleteRows, TABLE_NAME, whereClause) != NativeRdb::E_OK) {
183 HIVIEW_LOGE("failed to delete, whereClause=%{public}s", whereClause.c_str());
184 return;
185 }
186 }
187
RefreshDbCount()188 void SysEventRepeatDb::RefreshDbCount()
189 {
190 if (dbStore_ == nullptr) {
191 return;
192 }
193 std::string sql;
194 sql.append("SELECT count(*) from ").append(TABLE_NAME).append(";");
195 std::shared_ptr<NativeRdb::ResultSet> resultSet = dbStore_->QuerySql(sql, std::vector<std::string> {});
196 if (resultSet == nullptr) {
197 HIVIEW_LOGE("failed to query from table %{public}s, db is null", TABLE_NAME.c_str());
198 return;
199 }
200 if (resultSet->GoToNextRow() == NativeRdb::E_OK) {
201 resultSet->GetLong(0, dbCount_);
202 resultSet->Close();
203 return;
204 }
205 resultSet->Close();
206 }
207
QueryHappentime(SysEventHashRecord & sysEventHashRecord)208 int64_t SysEventRepeatDb::QueryHappentime(SysEventHashRecord &sysEventHashRecord)
209 {
210 if (dbStore_ == nullptr) {
211 return 0;
212 }
213 NativeRdb::AbsRdbPredicates predicates(TABLE_NAME);
214 predicates.EqualTo(COLUMN_DOMAIN, sysEventHashRecord.domain);
215 predicates.EqualTo(COLUMN_NAME, sysEventHashRecord.name);
216 predicates.EqualTo(COLUMN_EVENT_HASH, sysEventHashRecord.eventHash);
217 auto resultSet = dbStore_->Query(predicates, {COLUMN_HAPPENTIME});
218 if (resultSet == nullptr) {
219 HIVIEW_LOGE("failed to query from table %{public}s, db is null", TABLE_NAME.c_str());
220 return 0;
221 }
222
223 if (resultSet->GoToNextRow() == NativeRdb::E_OK) {
224 int64_t happentime = 0;
225 resultSet->GetLong(0, happentime); // 0 is result of happentime
226 resultSet->Close();
227 return happentime;
228 }
229 resultSet->Close();
230 return 0;
231 }
232
233 } // HiviewDFX
234 } // OHOS