1 /*
2 * Copyright (C) 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
16 #include "database_helper.h"
17
18 #include <array>
19
20 #include "config_define.h"
21 #include "rdb_event_store_callback.h"
22 #include "security_guard_define.h"
23 #include "security_guard_log.h"
24
25 namespace OHOS::Security::SecurityGuard {
DatabaseHelper(std::string dbTable)26 DatabaseHelper::DatabaseHelper(std::string dbTable)
27 {
28 dbTable_ = dbTable;
29 }
30
Init()31 int DatabaseHelper::Init()
32 {
33 return SUCCESS;
34 }
35
Release()36 void DatabaseHelper::Release()
37 {
38 }
39
InsertEvent(const SecEvent & event)40 int DatabaseHelper::InsertEvent(const SecEvent& event)
41 {
42 NativeRdb::ValuesBucket values;
43 SetValuesBucket(event, values);
44 int64_t rowId;
45 int ret = Insert(rowId, dbTable_, values);
46 if (ret != NativeRdb::E_OK) {
47 SGLOGI("failed to add event, eventId=%{public}" PRId64 ", ret=%{public}d", event.eventId, ret);
48 return DB_OPT_ERR;
49 }
50 return SUCCESS;
51 }
52
QueryAllEvent(std::vector<SecEvent> & events)53 int DatabaseHelper::QueryAllEvent(std::vector<SecEvent> &events)
54 {
55 NativeRdb::RdbPredicates predicates(dbTable_);
56 return QueryEventBase(predicates, events);
57 }
58
QueryRecentEventByEventId(int64_t eventId,SecEvent & event)59 int DatabaseHelper::QueryRecentEventByEventId(int64_t eventId, SecEvent &event)
60 {
61 std::vector<std::string> columns { EVENT_ID, VERSION, DATE, CONTENT };
62 NativeRdb::RdbPredicates predicates(dbTable_);
63 predicates.EqualTo(EVENT_ID, std::to_string(eventId));
64 predicates.OrderByDesc(ID);
65 predicates.Limit(1);
66 std::shared_ptr<NativeRdb::ResultSet> resultSet = Query(predicates, columns);
67 if (resultSet == nullptr) {
68 SGLOGI("failed to get event");
69 return DB_OPT_ERR;
70 }
71 SecEventTableInfo table;
72 int32_t ret = GetResultSetTableInfo(resultSet, table);
73 if (ret != SUCCESS) {
74 return ret;
75 }
76 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
77 resultSet->GetLong(table.eventIdIndex, event.eventId);
78 resultSet->GetString(table.versionIndex, event.version);
79 resultSet->GetString(table.dateIndex, event.date);
80 resultSet->GetString(table.contentIndex, event.content);
81 }
82 resultSet->Close();
83 return SUCCESS;
84 }
85
QueryRecentEventByEventId(const std::vector<int64_t> & eventIds,std::vector<SecEvent> & events)86 int DatabaseHelper::QueryRecentEventByEventId(const std::vector<int64_t> &eventIds, std::vector<SecEvent> &events)
87 {
88 int size = static_cast<int>(eventIds.size());
89 if (size == 0) {
90 return BAD_PARAM;
91 }
92 for (int i = 0; i < size; i++) {
93 SGLOGI("eventId=%{public}" PRId64 "", eventIds[i]);
94 NativeRdb::RdbPredicates predicates(dbTable_);
95 predicates.EqualTo(EVENT_ID, std::to_string(eventIds[i]));
96 predicates.OrderByDesc(ID);
97 predicates.Limit(1);
98 int ret = QueryEventBase(predicates, events);
99 if (ret != SUCCESS) {
100 return ret;
101 }
102 }
103 return SUCCESS;
104 }
105
QueryEventByEventId(int64_t eventId,std::vector<SecEvent> & events)106 int DatabaseHelper::QueryEventByEventId(int64_t eventId, std::vector<SecEvent> &events)
107 {
108 NativeRdb::RdbPredicates predicates(dbTable_);
109 predicates.EqualTo(EVENT_ID, std::to_string(eventId));
110 return QueryEventBase(predicates, events);
111 }
112
QueryEventByEventId(std::vector<int64_t> & eventIds,std::vector<SecEvent> & events)113 int DatabaseHelper::QueryEventByEventId(std::vector<int64_t> &eventIds, std::vector<SecEvent> &events)
114 {
115 int size = static_cast<int>(eventIds.size());
116 if (size == 0) {
117 return BAD_PARAM;
118 }
119 NativeRdb::RdbPredicates predicates(dbTable_);
120 for (int i = 0; i < size; i++) {
121 if (i > 0) {
122 predicates.Or();
123 }
124 predicates.EqualTo(EVENT_ID, std::to_string(eventIds[i]));
125 }
126 return QueryEventBase(predicates, events);
127 }
128
QueryEventByEventIdAndDate(std::vector<int64_t> & eventIds,std::vector<SecEvent> & events,std::string beginTime,std::string endTime)129 int DatabaseHelper::QueryEventByEventIdAndDate(std::vector<int64_t> &eventIds, std::vector<SecEvent> &events,
130 std::string beginTime, std::string endTime)
131 {
132 int size = static_cast<int>(eventIds.size());
133 if (size == 0) {
134 return BAD_PARAM;
135 }
136 NativeRdb::RdbPredicates predicates(dbTable_);
137 predicates.BeginWrap();
138 for (int i = 0; i < size; i++) {
139 if (i > 0) {
140 predicates.Or();
141 }
142 predicates.EqualTo(EVENT_ID, std::to_string(eventIds[i]));
143 }
144 predicates.EndWrap();
145 if (!beginTime.empty()) {
146 predicates.And();
147 predicates.GreaterThanOrEqualTo(DATE, beginTime);
148 }
149 if (!endTime.empty()) {
150 predicates.And();
151 predicates.LessThan(DATE, endTime);
152 }
153 return QueryEventBase(predicates, events);
154 }
155
QueryEventByEventType(int32_t eventType,std::vector<SecEvent> & events)156 int DatabaseHelper::QueryEventByEventType(int32_t eventType, std::vector<SecEvent> &events)
157 {
158 NativeRdb::RdbPredicates predicates(dbTable_);
159 predicates.EqualTo(EVENT_TYPE, std::to_string(eventType));
160 return QueryEventBase(predicates, events);
161 }
162
QueryEventByLevel(int32_t level,std::vector<SecEvent> & events)163 int DatabaseHelper::QueryEventByLevel(int32_t level, std::vector<SecEvent> &events)
164 {
165 NativeRdb::RdbPredicates predicates(dbTable_);
166 predicates.EqualTo(DATA_SENSITIVITY_LEVEL, std::to_string(level));
167 return QueryEventBase(predicates, events);
168 }
169
QueryEventByOwner(std::string owner,std::vector<SecEvent> & events)170 int DatabaseHelper::QueryEventByOwner(std::string owner, std::vector<SecEvent> &events)
171 {
172 NativeRdb::RdbPredicates predicates(dbTable_);
173 predicates.Contains(OWNER, owner);
174 return QueryEventBase(predicates, events);
175 }
176
CountAllEvent()177 int64_t DatabaseHelper::CountAllEvent()
178 {
179 int64_t count;
180 NativeRdb::RdbPredicates predicates(dbTable_);
181 int ret = Count(count, predicates);
182 if (ret != NativeRdb::E_OK) {
183 SGLOGE("failed to count event, ret=%{public}d", ret);
184 }
185 return count;
186 }
187
CountEventByEventId(int64_t eventId)188 int64_t DatabaseHelper::CountEventByEventId(int64_t eventId)
189 {
190 int64_t count;
191 NativeRdb::RdbPredicates predicates(dbTable_);
192 predicates.EqualTo(EVENT_ID, std::to_string(eventId));
193 int ret = Count(count, predicates);
194 if (ret != NativeRdb::E_OK) {
195 SGLOGE("failed to count event, eventId=%{public}" PRId64 ", ret=%{public}d", eventId, ret);
196 }
197 return count;
198 }
199
DeleteOldEventByEventId(int64_t eventId,int64_t count)200 int DatabaseHelper::DeleteOldEventByEventId(int64_t eventId, int64_t count)
201 {
202 NativeRdb::RdbPredicates queryPredicates(dbTable_);
203 queryPredicates.EqualTo(EVENT_ID, std::to_string(eventId));
204 queryPredicates.OrderByAsc(ID);
205 queryPredicates.Limit(count);
206 std::vector<std::string> columns { ID };
207 std::shared_ptr<NativeRdb::ResultSet> resultSet = Query(queryPredicates, columns);
208 if (resultSet == nullptr) {
209 SGLOGI("failed to get event, eventId=%{public}" PRId64 "", eventId);
210 return DB_OPT_ERR;
211 }
212 int64_t primaryKey = -1;
213 std::vector<std::string> primaryKeyVec;
214 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
215 resultSet->GetLong(0, primaryKey);
216 primaryKeyVec.emplace_back(std::to_string(primaryKey));
217 }
218 resultSet->Close();
219 int rowId;
220 NativeRdb::RdbPredicates deletePredicates(dbTable_);
221 deletePredicates.In(ID, primaryKeyVec);
222 deletePredicates.EqualTo(EVENT_ID, std::to_string(eventId));
223 int ret = Delete(rowId, deletePredicates);
224 if (ret != NativeRdb::E_OK) {
225 SGLOGE("failed to delete event, eventId=%{public}" PRId64 ", ret=%{public}d", eventId, ret);
226 return DB_OPT_ERR;
227 }
228 return SUCCESS;
229 }
230
DeleteAllEventByEventId(int64_t eventId)231 int DatabaseHelper::DeleteAllEventByEventId(int64_t eventId)
232 {
233 int rowId;
234 NativeRdb::RdbPredicates predicates(dbTable_);
235 predicates.EqualTo(EVENT_ID, std::to_string(eventId));
236 int ret = Delete(rowId, predicates);
237 if (ret != NativeRdb::E_OK) {
238 SGLOGI("failed to delete event, eventId=%{public}" PRId64 ", ret=%{public}d", eventId, ret);
239 return DB_OPT_ERR;
240 }
241 return SUCCESS;
242 }
243
FlushAllEvent()244 int DatabaseHelper::FlushAllEvent()
245 {
246 return SUCCESS;
247 }
248
QueryEventBase(const NativeRdb::RdbPredicates & predicates,std::vector<SecEvent> & events)249 int DatabaseHelper::QueryEventBase(const NativeRdb::RdbPredicates &predicates, std::vector<SecEvent> &events)
250 {
251 std::vector<std::string> columns { EVENT_ID, VERSION, DATE, CONTENT, USER_ID, DEVICE_ID };
252 std::shared_ptr<NativeRdb::ResultSet> resultSet = Query(predicates, columns);
253 if (resultSet == nullptr) {
254 SGLOGI("failed to get event");
255 return DB_OPT_ERR;
256 }
257 SecEventTableInfo table;
258 table.userIdIndex = INVALID_INDEX;
259 table.deviceIdIndex = INVALID_INDEX;
260 int32_t ret = GetResultSetTableInfo(resultSet, table);
261 if (ret != SUCCESS) {
262 return ret;
263 }
264 SecEvent event;
265 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
266 resultSet->GetLong(table.eventIdIndex, event.eventId);
267 resultSet->GetString(table.versionIndex, event.version);
268 resultSet->GetString(table.dateIndex, event.date);
269 resultSet->GetString(table.contentIndex, event.content);
270 if (table.deviceIdIndex != INVALID_INDEX) {
271 resultSet->GetString(table.deviceIdIndex, event.deviceId);
272 }
273 if (table.userIdIndex != INVALID_INDEX) {
274 resultSet->GetInt(table.userIdIndex, event.userId);
275 }
276 events.emplace_back(event);
277 }
278 resultSet->Close();
279 return SUCCESS;
280 }
281
GetResultSetTableInfo(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,SecEventTableInfo & table)282 int32_t DatabaseHelper::GetResultSetTableInfo(const std::shared_ptr<NativeRdb::ResultSet> &resultSet,
283 SecEventTableInfo &table)
284 {
285 int32_t rowCount = 0;
286 int32_t columnCount = 0;
287 std::vector<std::string> columnNames;
288 if (resultSet->GetRowCount(rowCount) != NativeRdb::E_OK ||
289 resultSet->GetColumnCount(columnCount) != NativeRdb::E_OK ||
290 resultSet->GetAllColumnNames(columnNames) != NativeRdb::E_OK) {
291 SGLOGE("get table info failed");
292 return DB_LOAD_ERR;
293 }
294 int32_t columnNamesCount = static_cast<int32_t>(columnNames.size());
295 for (int32_t i = 0; i < columnNamesCount; i++) {
296 std::string columnName = columnNames.at(i);
297 if (columnName == ID) {
298 table.primaryKeyIndex = i;
299 }
300 if (columnName == EVENT_ID) {
301 table.eventIdIndex = i;
302 }
303 if (columnName == VERSION) {
304 table.versionIndex = i;
305 }
306 if (columnName == DATE) {
307 table.dateIndex = i;
308 }
309 if (columnName == CONTENT) {
310 table.contentIndex = i;
311 }
312 if (columnName == USER_ID) {
313 table.userIdIndex = i;
314 }
315 if (columnName == DEVICE_ID) {
316 table.deviceIdIndex = i;
317 }
318 }
319 table.rowCount = rowCount;
320 table.columnCount = columnCount;
321 SGLOGD("info: row=%{public}d col=%{public}d eventIdIdx=%{public}d versionIdx=%{public}d "
322 "dateIdx=%{public}d contentIdx=%{public}d", rowCount, columnCount,
323 table.eventIdIndex, table.versionIndex, table.dateIndex, table.contentIndex);
324 return SUCCESS;
325 }
326
SetValuesBucket(const SecEvent & event,NativeRdb::ValuesBucket & values)327 void DatabaseHelper::SetValuesBucket(const SecEvent &event, NativeRdb::ValuesBucket &values)
328 {
329 values.PutLong(EVENT_ID, event.eventId);
330 values.PutString(VERSION, event.version);
331 values.PutString(DATE, event.date);
332 values.PutString(CONTENT, event.content);
333 values.PutInt(EVENT_TYPE, event.eventType);
334 values.PutInt(DATA_SENSITIVITY_LEVEL, event.dataSensitivityLevel);
335 values.PutString(OWNER, event.owner);
336 values.PutInt(USER_ID, event.userId);
337 values.PutString(DEVICE_ID, event.deviceId);
338 }
339
CreateTable()340 std::string DatabaseHelper::CreateTable()
341 {
342 std::string table;
343 table.append("CREATE TABLE IF NOT EXISTS ").append(dbTable_);
344 table.append("(").append(ID).append(" INTEGER PRIMARY KEY AUTOINCREMENT, ");
345 table.append(EVENT_ID).append(" INTEGER NOT NULL, ");
346 table.append(VERSION).append(" TEXT NOT NULL, ");
347 table.append(DATE).append(" TEXT NOT NULL, ");
348 table.append(CONTENT).append(" TEXT NOT NULL, ");
349 table.append(EVENT_TYPE).append(" INTEGER NOT NULL, ");
350 table.append(DATA_SENSITIVITY_LEVEL).append(" INTEGER NOT NULL, ");
351 table.append(OWNER).append(" TEXT NOT NULL, ");
352 table.append(USER_ID).append(" INTEGER NOT NULL, ");
353 table.append(DEVICE_ID).append(" TEXT NOT NULL)");
354 return table;
355 }
356 } // namespace OHOS::Security::SecurityGuard