• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <cinttypes>
20 #include "i_model_info.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     size_t size = eventIds.size();
89     if (size == 0) {
90         return BAD_PARAM;
91     }
92     for (size_t 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     size_t size = eventIds.size();
116     if (size == 0) {
117         return BAD_PARAM;
118     }
119     NativeRdb::RdbPredicates predicates(dbTable_);
120     for (size_t 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     size_t size = eventIds.size();
133     if (size == 0) {
134         return BAD_PARAM;
135     }
136     NativeRdb::RdbPredicates predicates(dbTable_);
137     predicates.BeginWrap();
138     for (size_t 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     if (columnNames.size() > INT32_MAX) {
295         SGLOGE("columnNames size err");
296         return DB_LOAD_ERR;
297     }
298     int32_t columnNamesCount = static_cast<int32_t>(columnNames.size());
299     for (int32_t i = 0; i < columnNamesCount; i++) {
300         std::string columnName = columnNames.at(i);
301         if (columnName == ID) {
302             table.primaryKeyIndex = i;
303         }
304         if (columnName == EVENT_ID) {
305             table.eventIdIndex = i;
306         }
307         if (columnName == VERSION) {
308             table.versionIndex = i;
309         }
310         if (columnName == DATE) {
311             table.dateIndex = i;
312         }
313         if (columnName == CONTENT) {
314             table.contentIndex = i;
315         }
316         if (columnName == USER_ID) {
317             table.userIdIndex = i;
318         }
319         if (columnName == DEVICE_ID) {
320             table.deviceIdIndex = i;
321         }
322     }
323     table.rowCount = rowCount;
324     table.columnCount = columnCount;
325     SGLOGD("info: row=%{public}d col=%{public}d eventIdIdx=%{public}d versionIdx=%{public}d "
326         "dateIdx=%{public}d contentIdx=%{public}d", rowCount, columnCount,
327         table.eventIdIndex, table.versionIndex, table.dateIndex, table.contentIndex);
328     return SUCCESS;
329 }
330 
SetValuesBucket(const SecEvent & event,NativeRdb::ValuesBucket & values)331 void DatabaseHelper::SetValuesBucket(const SecEvent &event, NativeRdb::ValuesBucket &values)
332 {
333     values.PutLong(EVENT_ID, event.eventId);
334     values.PutString(VERSION, event.version);
335     values.PutString(DATE, event.date);
336     values.PutString(CONTENT, event.content);
337     values.PutInt(EVENT_TYPE, event.eventType);
338     values.PutInt(DATA_SENSITIVITY_LEVEL, event.dataSensitivityLevel);
339     values.PutString(OWNER, event.owner);
340     values.PutInt(USER_ID, event.userId);
341     values.PutString(DEVICE_ID, event.deviceId);
342 }
343 
CreateTable()344 std::string DatabaseHelper::CreateTable()
345 {
346     std::string table;
347     table.append("CREATE TABLE IF NOT EXISTS ").append(dbTable_);
348     table.append("(").append(ID).append(" INTEGER PRIMARY KEY AUTOINCREMENT, ");
349     table.append(EVENT_ID).append(" INTEGER NOT NULL, ");
350     table.append(VERSION).append(" TEXT NOT NULL, ");
351     table.append(DATE).append(" TEXT NOT NULL, ");
352     table.append(CONTENT).append(" TEXT NOT NULL, ");
353     table.append(EVENT_TYPE).append(" INTEGER NOT NULL, ");
354     table.append(DATA_SENSITIVITY_LEVEL).append(" INTEGER NOT NULL, ");
355     table.append(OWNER).append(" TEXT NOT NULL, ");
356     table.append(USER_ID).append(" INTEGER NOT NULL, ");
357     table.append(DEVICE_ID).append(" TEXT NOT NULL)");
358     return table;
359 }
360 } // namespace OHOS::Security::SecurityGuard