• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "permission_used_record_db.h"
17 
18 #include <cinttypes>
19 #include <mutex>
20 
21 #include "accesstoken_common_log.h"
22 #include "active_change_response_info.h"
23 #include "constant.h"
24 #include "permission_used_type.h"
25 #include "privacy_field_const.h"
26 #include "time_util.h"
27 
28 namespace OHOS {
29 namespace Security {
30 namespace AccessToken {
31 namespace {
32 constexpr const char* FIELD_COUNT_NUMBER = "count";
33 constexpr const char* INTEGER_STR = " integer not null,";
34 constexpr const char* CREATE_TABLE_STR = "create table if not exists ";
35 constexpr const char* WHERE_1_STR = " where 1 = 1";
36 constexpr const size_t TOKEN_ID_LENGTH = 11;
37 
38 std::recursive_mutex g_instanceMutex;
39 }
40 
GetInstance()41 PermissionUsedRecordDb& PermissionUsedRecordDb::GetInstance()
42 {
43     static PermissionUsedRecordDb* instance = nullptr;
44     if (instance == nullptr) {
45         std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
46         if (instance == nullptr) {
47             PermissionUsedRecordDb* tmp = new (std::nothrow) PermissionUsedRecordDb();
48             instance = std::move(tmp);
49         }
50     }
51     return *instance;
52 }
53 
~PermissionUsedRecordDb()54 PermissionUsedRecordDb::~PermissionUsedRecordDb()
55 {
56     Close();
57 }
58 
OnCreate()59 void PermissionUsedRecordDb::OnCreate()
60 {
61     LOGI(PRI_DOMAIN, PRI_TAG, "Entry");
62     CreatePermissionRecordTable();
63     CreatePermissionUsedTypeTable();
64     CreatePermissionUsedRecordToggleStatusTable();
65 }
66 
OnUpdate(int32_t version)67 void PermissionUsedRecordDb::OnUpdate(int32_t version)
68 {
69     LOGI(PRI_DOMAIN, PRI_TAG, "Entry");
70     if (version == DataBaseVersion::VERISION_1) {
71         InsertLockScreenStatusColumn();
72         InsertPermissionUsedTypeColumn();
73         CreatePermissionUsedTypeTable();
74         UpdatePermissionRecordTablePrimaryKey();
75         CreatePermissionUsedRecordToggleStatusTable();
76     } else if (version == DataBaseVersion::VERISION_2) {
77         InsertPermissionUsedTypeColumn();
78         CreatePermissionUsedTypeTable();
79         UpdatePermissionRecordTablePrimaryKey();
80         CreatePermissionUsedRecordToggleStatusTable();
81     } else if (version == DataBaseVersion::VERISION_3) {
82         UpdatePermissionRecordTablePrimaryKey();
83         CreatePermissionUsedRecordToggleStatusTable();
84     } else if (version == DataBaseVersion::VERISION_4) {
85         CreatePermissionUsedRecordToggleStatusTable();
86     }
87 }
88 
PermissionUsedRecordDb()89 PermissionUsedRecordDb::PermissionUsedRecordDb() : SqliteHelper(DATABASE_NAME, DATABASE_PATH, DATABASE_VERSION)
90 {
91     SqliteTable permissionRecordTable;
92     permissionRecordTable.tableName_ = PERMISSION_RECORD_TABLE;
93     permissionRecordTable.tableColumnNames_ = {
94         PrivacyFiledConst::FIELD_TOKEN_ID,
95         PrivacyFiledConst::FIELD_OP_CODE,
96         PrivacyFiledConst::FIELD_STATUS,
97         PrivacyFiledConst::FIELD_TIMESTAMP,
98         PrivacyFiledConst::FIELD_ACCESS_DURATION,
99         PrivacyFiledConst::FIELD_ACCESS_COUNT,
100         PrivacyFiledConst::FIELD_REJECT_COUNT,
101         PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS,
102         PrivacyFiledConst::FIELD_USED_TYPE
103     };
104 
105     SqliteTable permissionUsedTypeTable;
106     permissionUsedTypeTable.tableName_ = PERMISSION_USED_TYPE_TABLE;
107     permissionUsedTypeTable.tableColumnNames_ = {
108         PrivacyFiledConst::FIELD_TOKEN_ID,
109         PrivacyFiledConst::FIELD_PERMISSION_CODE,
110         /**
111          * bit operation:
112          * 1 -> 001, NORMAL_TYPE
113          * 2 -> 010, PICKER_TYPE
114          * 3 -> 011, NORMAL_TYPE + PICKER_TYPE
115          * 4 -> 100, SECURITY_COMPONENT_TYPE
116          * 5 -> 101, NORMAL_TYPE + SECURITY_COMPONENT_TYPE
117          * 6 -> 110, PICKER_TYPE + SECURITY_COMPONENT_TYPE
118          * 7 -> 111, NORMAL_TYPE + PICKER_TYPE + SECURITY_COMPONENT_TYPE
119          */
120         PrivacyFiledConst::FIELD_USED_TYPE
121     };
122 
123     SqliteTable permissionUsedRecordToggleStatusTable;
124     permissionUsedRecordToggleStatusTable.tableName_ = PERMISSION_USED_RECORD_TOGGLE_STATUS_TABLE;
125     permissionUsedRecordToggleStatusTable.tableColumnNames_ = {
126         PrivacyFiledConst::FIELD_USER_ID,
127         PrivacyFiledConst::FIELD_STATUS
128     };
129 
130     dataTypeToSqlTable_ = {
131         {PERMISSION_RECORD, permissionRecordTable},
132         {PERMISSION_USED_TYPE, permissionUsedTypeTable},
133         {PERMISSION_USED_RECORD_TOGGLE_STATUS, permissionUsedRecordToggleStatusTable},
134     };
135     Open();
136 }
137 
Add(DataType type,const std::vector<GenericValues> & values)138 int32_t PermissionUsedRecordDb::Add(DataType type, const std::vector<GenericValues>& values)
139 {
140     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
141 
142     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
143     std::string prepareSql = CreateInsertPrepareSqlCmd(type);
144     if (prepareSql.empty()) {
145         LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid", type);
146         return FAILURE;
147     }
148     LOGD(PRI_DOMAIN, PRI_TAG, "Add sql is %{public}s.", prepareSql.c_str());
149 
150     auto statement = Prepare(prepareSql);
151     BeginTransaction();
152     bool isAddSuccessfully = true;
153     for (const auto& value : values) {
154         std::vector<std::string> columnNames = value.GetAllKeys();
155         for (const auto& name : columnNames) {
156             statement.Bind(name, value.Get(name));
157         }
158         int32_t ret = statement.Step();
159         if (ret != Statement::State::DONE) {
160             LOGE(PRI_DOMAIN, PRI_TAG, "Failed, errorMsg: %{public}s", SpitError().c_str());
161             isAddSuccessfully = false;
162         }
163         statement.Reset();
164     }
165     if (!isAddSuccessfully) {
166         LOGE(PRI_DOMAIN, PRI_TAG, "Rollback transaction.");
167         RollbackTransaction();
168         return FAILURE;
169     }
170     LOGD(PRI_DOMAIN, PRI_TAG, "Commit transaction.");
171     CommitTransaction();
172 
173     int64_t endTime = TimeUtil::GetCurrentTimestamp();
174     LOGI(PRI_DOMAIN, PRI_TAG, "Add cost %{public}" PRId64 ".", endTime - beginTime);
175 
176     return SUCCESS;
177 }
178 
Remove(DataType type,const GenericValues & conditions)179 int32_t PermissionUsedRecordDb::Remove(DataType type, const GenericValues& conditions)
180 {
181     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
182 
183     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
184     std::vector<std::string> columnNames = conditions.GetAllKeys();
185     std::string prepareSql = CreateDeletePrepareSqlCmd(type, columnNames);
186     if (prepareSql.empty()) {
187         LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid", type);
188         return FAILURE;
189     }
190     LOGD(PRI_DOMAIN, PRI_TAG, "Remove sql is %{public}s.", prepareSql.c_str());
191 
192     auto statement = Prepare(prepareSql);
193     for (const auto& columnName : columnNames) {
194         statement.Bind(columnName, conditions.Get(columnName));
195     }
196     int32_t ret = statement.Step();
197 
198     int64_t endTime = TimeUtil::GetCurrentTimestamp();
199     LOGI(PRI_DOMAIN, PRI_TAG, "Remove cost %{public}" PRId64 ".", endTime - beginTime);
200 
201     return (ret == Statement::State::DONE) ? SUCCESS : FAILURE;
202 }
203 
FindByConditions(DataType type,const std::set<int32_t> & opCodeList,const GenericValues & andConditions,std::vector<GenericValues> & results,int32_t databaseQueryCount)204 int32_t PermissionUsedRecordDb::FindByConditions(DataType type, const std::set<int32_t>& opCodeList,
205     const GenericValues& andConditions, std::vector<GenericValues>& results, int32_t databaseQueryCount)
206 {
207     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
208 
209     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
210     std::vector<std::string> andColumns = andConditions.GetAllKeys();
211     int32_t tokenId = andConditions.GetInt(PrivacyFiledConst::FIELD_TOKEN_ID);
212     std::string prepareSql = CreateSelectByConditionPrepareSqlCmd(tokenId, type, opCodeList, andColumns,
213         databaseQueryCount);
214     if (prepareSql.empty()) {
215         LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid", type);
216         return FAILURE;
217     }
218     LOGD(PRI_DOMAIN, PRI_TAG, "FindByConditions sql is %{public}s.", prepareSql.c_str());
219 
220     auto statement = Prepare(prepareSql);
221 
222     for (const auto& columnName : andColumns) {
223         statement.Bind(columnName, andConditions.Get(columnName));
224     }
225 
226     while (statement.Step() == Statement::State::ROW) {
227         int32_t columnCount = statement.GetColumnCount();
228         GenericValues value;
229         for (int32_t i = 0; i < columnCount; i++) {
230             if ((statement.GetColumnName(i) == PrivacyFiledConst::FIELD_TIMESTAMP) ||
231                 (statement.GetColumnName(i) == PrivacyFiledConst::FIELD_ACCESS_DURATION)) {
232                 value.Put(statement.GetColumnName(i), statement.GetValue(i, true));
233             } else {
234                 value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
235             }
236         }
237         results.emplace_back(value);
238     }
239 
240     int64_t endTime = TimeUtil::GetCurrentTimestamp();
241     LOGI(PRI_DOMAIN, PRI_TAG, "FindByConditions cost %{public}" PRId64 ".", endTime - beginTime);
242 
243     return SUCCESS;
244 }
245 
Count(DataType type)246 int32_t PermissionUsedRecordDb::Count(DataType type)
247 {
248     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
249 
250     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
251     GenericValues countValue;
252     std::string countSql = CreateCountPrepareSqlCmd(type);
253     LOGD(PRI_DOMAIN, PRI_TAG, "Count sql is %{public}s.", countSql.c_str());
254     auto countStatement = Prepare(countSql);
255     if (countStatement.Step() == Statement::State::ROW) {
256         int32_t column = 0;
257         countValue.Put(FIELD_COUNT_NUMBER, countStatement.GetValue(column, false));
258     }
259 
260     int64_t endTime = TimeUtil::GetCurrentTimestamp();
261     LOGI(PRI_DOMAIN, PRI_TAG, "Count cost %{public}" PRId64 ".", endTime - beginTime);
262 
263     return countValue.GetInt(FIELD_COUNT_NUMBER);
264 }
265 
DeleteExpireRecords(DataType type,const GenericValues & andConditions)266 int32_t PermissionUsedRecordDb::DeleteExpireRecords(DataType type,
267     const GenericValues& andConditions)
268 {
269     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
270 
271     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
272     std::vector<std::string> andColumns = andConditions.GetAllKeys();
273     if (!andColumns.empty()) {
274         std::string deleteExpireSql = CreateDeleteExpireRecordsPrepareSqlCmd(type, andColumns);
275         LOGD(PRI_DOMAIN, PRI_TAG, "DeleteExpireRecords sql is %{public}s.", deleteExpireSql.c_str());
276         auto deleteExpireStatement = Prepare(deleteExpireSql);
277         for (const auto& columnName : andColumns) {
278             deleteExpireStatement.Bind(columnName, andConditions.Get(columnName));
279         }
280         if (deleteExpireStatement.Step() != Statement::State::DONE) {
281             return FAILURE;
282         }
283     }
284 
285     int64_t endTime = TimeUtil::GetCurrentTimestamp();
286     LOGI(PRI_DOMAIN, PRI_TAG, "DeleteExpireRecords cost %{public}" PRId64 ".", endTime - beginTime);
287 
288     return SUCCESS;
289 }
290 
DeleteHistoryRecordsInTables(std::vector<DataType> dateTypes,const std::unordered_set<AccessTokenID> & tokenIDList)291 int32_t PermissionUsedRecordDb::DeleteHistoryRecordsInTables(std::vector<DataType> dateTypes,
292     const std::unordered_set<AccessTokenID>& tokenIDList)
293 {
294     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
295 
296     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
297     BeginTransaction();
298     for (const auto& type : dateTypes) {
299         std::string deleteHistorySql = CreateDeleteHistoryRecordsPrepareSqlCmd(type, tokenIDList);
300         LOGD(PRI_DOMAIN, PRI_TAG, "DeleteHistoryRecordsInTables sql is %{public}s.", deleteHistorySql.c_str());
301         auto deleteHistoryStatement = Prepare(deleteHistorySql);
302         if (deleteHistoryStatement.Step() != Statement::State::DONE) {
303             LOGE(PRI_DOMAIN, PRI_TAG, "Rollback transaction.");
304             RollbackTransaction();
305             return FAILURE;
306         }
307     }
308 
309     LOGD(PRI_DOMAIN, PRI_TAG, "Commit transaction.");
310     CommitTransaction();
311 
312     int64_t endTime = TimeUtil::GetCurrentTimestamp();
313     LOGI(PRI_DOMAIN, PRI_TAG, "DeleteHistoryRecordsInTables cost %{public}" PRId64 ".", endTime - beginTime);
314 
315     return SUCCESS;
316 }
317 
DeleteExcessiveRecords(DataType type,uint32_t excessiveSize)318 int32_t PermissionUsedRecordDb::DeleteExcessiveRecords(DataType type, uint32_t excessiveSize)
319 {
320     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
321 
322     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
323     std::string deleteExcessiveSql = CreateDeleteExcessiveRecordsPrepareSqlCmd(type, excessiveSize);
324     LOGD(PRI_DOMAIN, PRI_TAG, "DeleteExcessiveRecords sql is %{public}s.", deleteExcessiveSql.c_str());
325     auto deleteExcessiveStatement = Prepare(deleteExcessiveSql);
326     if (deleteExcessiveStatement.Step() != Statement::State::DONE) {
327         return FAILURE;
328     }
329 
330     int64_t endTime = TimeUtil::GetCurrentTimestamp();
331     LOGI(PRI_DOMAIN, PRI_TAG, "DeleteExcessiveRecords cost %{public}" PRId64 ".", endTime - beginTime);
332 
333     return SUCCESS;
334 }
335 
Update(DataType type,const GenericValues & modifyValue,const GenericValues & conditionValue)336 int32_t PermissionUsedRecordDb::Update(DataType type, const GenericValues& modifyValue,
337     const GenericValues& conditionValue)
338 {
339     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
340 
341     std::vector<std::string> modifyNames = modifyValue.GetAllKeys();
342     std::vector<std::string> conditionNames = conditionValue.GetAllKeys();
343 
344     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
345     std::string prepareSql = CreateUpdatePrepareSqlCmd(type, modifyNames, conditionNames);
346     if (prepareSql.empty()) {
347         LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid", type);
348         return FAILURE;
349     }
350     LOGD(PRI_DOMAIN, PRI_TAG, "Update sql is %{public}s.", prepareSql.c_str());
351 
352     auto statement = Prepare(prepareSql);
353 
354     for (const auto& modifyName : modifyNames) {
355         statement.Bind(modifyName, modifyValue.Get(modifyName));
356     }
357 
358     for (const auto& conditionName : conditionNames) {
359         statement.Bind(conditionName, conditionValue.Get(conditionName));
360     }
361 
362     int32_t ret = statement.Step();
363     if (ret != Statement::State::DONE) {
364         LOGE(PRI_DOMAIN, PRI_TAG,
365             "Update table Type %{public}u failed, errCode is %{public}d, errMsg is %{public}s.", type, ret,
366             SpitError().c_str());
367         return FAILURE;
368     }
369 
370     int64_t endTime = TimeUtil::GetCurrentTimestamp();
371     LOGI(PRI_DOMAIN, PRI_TAG, "Update cost %{public}" PRId64 ".", endTime - beginTime);
372 
373     return SUCCESS;
374 }
375 
Query(DataType type,const GenericValues & conditionValue,std::vector<GenericValues> & results)376 int32_t PermissionUsedRecordDb::Query(DataType type, const GenericValues& conditionValue,
377     std::vector<GenericValues>& results)
378 {
379     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
380 
381     std::vector<std::string> conditionColumns = conditionValue.GetAllKeys();
382 
383     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
384     std::string prepareSql = CreateQueryPrepareSqlCmd(type, conditionColumns);
385     if (prepareSql.empty()) {
386         LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid.", type);
387         return FAILURE;
388     }
389     LOGD(PRI_DOMAIN, PRI_TAG, "Query sql is %{public}s.", prepareSql.c_str());
390 
391     auto statement = Prepare(prepareSql);
392     for (const auto& conditionColumn : conditionColumns) {
393         statement.Bind(conditionColumn, conditionValue.Get(conditionColumn));
394     }
395 
396     while (statement.Step() == Statement::State::ROW) {
397         int32_t columnCount = statement.GetColumnCount();
398         GenericValues value;
399 
400         for (int32_t i = 0; i < columnCount; i++) {
401             value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
402         }
403 
404         results.emplace_back(value);
405     }
406 
407     int64_t endTime = TimeUtil::GetCurrentTimestamp();
408     LOGI(PRI_DOMAIN, PRI_TAG, "Query cost %{public}" PRId64 ".", endTime - beginTime);
409 
410     return SUCCESS;
411 }
412 
CreateInsertPrepareSqlCmd(DataType type) const413 std::string PermissionUsedRecordDb::CreateInsertPrepareSqlCmd(DataType type) const
414 {
415     auto it = dataTypeToSqlTable_.find(type);
416     if (it == dataTypeToSqlTable_.end()) {
417         return std::string();
418     }
419     std::string sql = "insert into " + it->second.tableName_ + " values(";
420     int32_t i = 1;
421     for (const auto& name : it->second.tableColumnNames_) {
422         sql.append(":" + name);
423         if (i < static_cast<int32_t>(it->second.tableColumnNames_.size())) {
424             sql.append(",");
425         }
426         i += 1;
427     }
428     sql.append(")");
429     return sql;
430 }
431 
CreateQueryPrepareSqlCmd(DataType type,const std::vector<std::string> & conditionColumns) const432 std::string PermissionUsedRecordDb::CreateQueryPrepareSqlCmd(DataType type,
433     const std::vector<std::string>& conditionColumns) const
434 {
435     auto it = dataTypeToSqlTable_.find(type);
436     if (it == dataTypeToSqlTable_.end()) {
437         return std::string();
438     }
439     std::string sql = "select * from " + it->second.tableName_ + WHERE_1_STR;
440 
441     for (const auto& andColumn : conditionColumns) {
442         sql.append(" and ");
443         sql.append(andColumn + "=:" + andColumn);
444     }
445 
446     return sql;
447 }
448 
CreateDeletePrepareSqlCmd(DataType type,const std::vector<std::string> & columnNames) const449 std::string PermissionUsedRecordDb::CreateDeletePrepareSqlCmd(
450     DataType type, const std::vector<std::string>& columnNames) const
451 {
452     auto it = dataTypeToSqlTable_.find(type);
453     if (it == dataTypeToSqlTable_.end()) {
454         return std::string();
455     }
456     std::string sql = "delete from " + it->second.tableName_ + WHERE_1_STR;
457     for (const auto& name : columnNames) {
458         sql.append(" and ");
459         sql.append(name + "=:" + name);
460     }
461     return sql;
462 }
463 
CreateUpdatePrepareSqlCmd(DataType type,const std::vector<std::string> & modifyColumns,const std::vector<std::string> & conditionColumns) const464 std::string PermissionUsedRecordDb::CreateUpdatePrepareSqlCmd(DataType type,
465     const std::vector<std::string>& modifyColumns, const std::vector<std::string>& conditionColumns) const
466 {
467     if (modifyColumns.empty()) {
468         return std::string();
469     }
470 
471     auto it = dataTypeToSqlTable_.find(type);
472     if (it == dataTypeToSqlTable_.end()) {
473         return std::string();
474     }
475 
476     std::string sql = "update " + it->second.tableName_ + " set ";
477     int32_t i = 1;
478     for (const auto& name : modifyColumns) {
479         sql.append(name + "=:" + name);
480         if (i < static_cast<int32_t>(modifyColumns.size())) {
481             sql.append(",");
482         }
483         i += 1;
484     }
485 
486     if (!conditionColumns.empty()) {
487         sql.append(WHERE_1_STR);
488         for (const auto& columnName : conditionColumns) {
489             sql.append(" and ");
490             sql.append(columnName + "=:" + columnName);
491         }
492     }
493     return sql;
494 }
495 
CreateSelectByConditionPrepareSqlCmd(const int32_t tokenId,DataType type,const std::set<int32_t> & opCodeList,const std::vector<std::string> & andColumns,int32_t databaseQueryCount) const496 std::string PermissionUsedRecordDb::CreateSelectByConditionPrepareSqlCmd(const int32_t tokenId, DataType type,
497     const std::set<int32_t>& opCodeList, const std::vector<std::string>& andColumns, int32_t databaseQueryCount) const
498 {
499     auto it = dataTypeToSqlTable_.find(type);
500     if (it == dataTypeToSqlTable_.end()) {
501         return std::string();
502     }
503 
504     std::string sql = "select * from " + it->second.tableName_ + WHERE_1_STR;
505 
506     for (const auto& andColName : andColumns) {
507         if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
508             sql.append(" and ");
509             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
510             sql.append(" >=:" + andColName);
511         } else if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
512             sql.append(" and ");
513             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
514             sql.append(" <=:" + andColName);
515         } else if (andColName == PrivacyFiledConst::FIELD_TOKEN_ID) {
516             if (tokenId != 0) {
517                 sql.append(" and ");
518                 sql.append(PrivacyFiledConst::FIELD_TOKEN_ID);
519                 sql.append(" =:" + andColName);
520             }
521         } else {
522             sql.append(" and ");
523             sql.append(andColName + "=:" + andColName);
524         }
525     }
526     if (!opCodeList.empty()) {
527         sql.append(" and (");
528         for (const auto& opCode : opCodeList) {
529             if (opCode != Constant::OP_INVALID) {
530                 sql.append(PrivacyFiledConst::FIELD_OP_CODE);
531                 sql.append(+ " = " + std::to_string(opCode));
532                 sql.append(" or ");
533             }
534         }
535         sql.append("0)");
536     }
537     sql.append(" order by timestamp desc");
538     sql.append(" limit " + std::to_string(databaseQueryCount));
539     return sql;
540 }
541 
CreateCountPrepareSqlCmd(DataType type) const542 std::string PermissionUsedRecordDb::CreateCountPrepareSqlCmd(DataType type) const
543 {
544     auto it = dataTypeToSqlTable_.find(type);
545     if (it == dataTypeToSqlTable_.end()) {
546         return std::string();
547     }
548     std::string sql = "select count(*) from " + it->second.tableName_;
549     return sql;
550 }
551 
CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,const std::vector<std::string> & andColumns) const552 std::string PermissionUsedRecordDb::CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,
553     const std::vector<std::string>& andColumns) const
554 {
555     auto it = dataTypeToSqlTable_.find(type);
556     if (it == dataTypeToSqlTable_.end()) {
557         return std::string();
558     }
559     std::string sql = "delete from " + it->second.tableName_ + " where ";
560     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
561     sql.append(" in (select ");
562     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
563     sql.append(" from " + it->second.tableName_ + WHERE_1_STR);
564     for (const auto& name : andColumns) {
565         if (name == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
566             sql.append(" and ");
567             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
568             sql.append(" >=:" + name);
569         } else if (name == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
570             sql.append(" and ");
571             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
572             sql.append(" <=:" + name);
573         } else {
574             sql.append(" and ");
575             sql.append(name + "=:" + name);
576         }
577     }
578     sql.append(" )");
579     return sql;
580 }
581 
CreateDeleteHistoryRecordsPrepareSqlCmd(DataType type,const std::unordered_set<AccessTokenID> & tokenIDList) const582 std::string PermissionUsedRecordDb::CreateDeleteHistoryRecordsPrepareSqlCmd(DataType type,
583     const std::unordered_set<AccessTokenID>& tokenIDList) const
584 {
585     auto it = dataTypeToSqlTable_.find(type);
586     if (it == dataTypeToSqlTable_.end()) {
587         return std::string();
588     }
589     std::string sql = "delete from " + it->second.tableName_ + " where ";
590     sql.append(PrivacyFiledConst::FIELD_TOKEN_ID);
591     sql.append(" in ( ");
592 
593     size_t sqlLen = sql.size();
594     sqlLen += TOKEN_ID_LENGTH * tokenIDList.size();
595     sql.reserve(sqlLen);
596 
597     for (auto token = tokenIDList.begin(); token != tokenIDList.end(); ++token) {
598         sql.append(std::to_string(*token));
599         if (std::next(token) != tokenIDList.end()) {
600             sql.append(", ");
601         }
602     }
603     sql.append(" )");
604     return sql;
605 }
606 
CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,uint32_t excessiveSize) const607 std::string PermissionUsedRecordDb::CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,
608     uint32_t excessiveSize) const
609 {
610     auto it = dataTypeToSqlTable_.find(type);
611     if (it == dataTypeToSqlTable_.end()) {
612         return std::string();
613     }
614     std::string sql = "delete from " + it->second.tableName_ + " where ";
615     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
616     sql.append(" in (select ");
617     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
618     sql.append(" from " + it->second.tableName_ + " order by ");
619     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
620     sql.append(" limit ");
621     sql.append(std::to_string(excessiveSize) + " )");
622     return sql;
623 }
624 
CreatePermissionRecordTable() const625 int32_t PermissionUsedRecordDb::CreatePermissionRecordTable() const
626 {
627     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
628     if (it == dataTypeToSqlTable_.end()) {
629         return FAILURE;
630     }
631     std::string sql = CREATE_TABLE_STR;
632     sql.append(it->second.tableName_ + " (")
633         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
634         .append(INTEGER_STR)
635         .append(PrivacyFiledConst::FIELD_OP_CODE)
636         .append(INTEGER_STR)
637         .append(PrivacyFiledConst::FIELD_STATUS)
638         .append(INTEGER_STR)
639         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
640         .append(INTEGER_STR)
641         .append(PrivacyFiledConst::FIELD_ACCESS_DURATION)
642         .append(INTEGER_STR)
643         .append(PrivacyFiledConst::FIELD_ACCESS_COUNT)
644         .append(INTEGER_STR)
645         .append(PrivacyFiledConst::FIELD_REJECT_COUNT)
646         .append(INTEGER_STR)
647         .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
648         .append(INTEGER_STR)
649         .append(PrivacyFiledConst::FIELD_USED_TYPE)
650         .append(INTEGER_STR)
651         .append("primary key(")
652         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
653         .append(",")
654         .append(PrivacyFiledConst::FIELD_OP_CODE)
655         .append(",")
656         .append(PrivacyFiledConst::FIELD_STATUS)
657         .append(",")
658         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
659         .append(",")
660         .append(PrivacyFiledConst::FIELD_USED_TYPE)
661         .append("))");
662     return ExecuteSql(sql);
663 }
664 
CreatePermissionUsedTypeTable() const665 int32_t PermissionUsedRecordDb::CreatePermissionUsedTypeTable() const
666 {
667     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_USED_TYPE);
668     if (it == dataTypeToSqlTable_.end()) {
669         return FAILURE;
670     }
671     std::string sql = CREATE_TABLE_STR;
672     sql.append(it->second.tableName_ + " (")
673         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
674         .append(INTEGER_STR)
675         .append(PrivacyFiledConst::FIELD_PERMISSION_CODE)
676         .append(INTEGER_STR)
677         .append(PrivacyFiledConst::FIELD_USED_TYPE)
678         .append(INTEGER_STR)
679         .append("primary key(")
680         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
681         .append(",")
682         .append(PrivacyFiledConst::FIELD_PERMISSION_CODE)
683         .append("))");
684     return ExecuteSql(sql);
685 }
686 
CreatePermissionUsedRecordToggleStatusTable() const687 int32_t PermissionUsedRecordDb::CreatePermissionUsedRecordToggleStatusTable() const
688 {
689     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_USED_RECORD_TOGGLE_STATUS);
690     if (it == dataTypeToSqlTable_.end()) {
691         return FAILURE;
692     }
693     std::string sql = CREATE_TABLE_STR;
694     sql.append(it->second.tableName_ + " (")
695         .append(PrivacyFiledConst::FIELD_USER_ID)
696         .append(INTEGER_STR)
697         .append(PrivacyFiledConst::FIELD_STATUS)
698         .append(INTEGER_STR)
699         .append("primary key(")
700         .append(PrivacyFiledConst::FIELD_USER_ID)
701         .append("))");
702     return ExecuteSql(sql);
703 }
704 
InsertLockScreenStatusColumn() const705 int32_t PermissionUsedRecordDb::InsertLockScreenStatusColumn() const
706 {
707     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
708     if (it == dataTypeToSqlTable_.end()) {
709         return FAILURE;
710     }
711     std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
712         PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS + "=" +
713         std::to_string(LockScreenStatusChangeType::PERM_ACTIVE_IN_UNLOCKED);
714     int32_t checkResult = ExecuteSql(checkSql);
715     LOGI(PRI_DOMAIN, PRI_TAG, "Check result:%{public}d", checkResult);
716     if (checkResult != -1) {
717         return SUCCESS;
718     }
719 
720     std::string sql = "alter table ";
721     sql.append(it->second.tableName_ + " add column ")
722         .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
723         .append(" integer default ")
724         .append(std::to_string(LockScreenStatusChangeType::PERM_ACTIVE_IN_UNLOCKED));
725     int32_t insertResult = ExecuteSql(sql);
726     LOGI(PRI_DOMAIN, PRI_TAG, "Insert column result:%{public}d", insertResult);
727     return insertResult;
728 }
729 
InsertPermissionUsedTypeColumn() const730 int32_t PermissionUsedRecordDb::InsertPermissionUsedTypeColumn() const
731 {
732     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
733     if (it == dataTypeToSqlTable_.end()) {
734         return FAILURE;
735     }
736     std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
737         PrivacyFiledConst::FIELD_USED_TYPE + "=" +
738         std::to_string(PermissionUsedType::NORMAL_TYPE);
739     int32_t checkResult = ExecuteSql(checkSql);
740     LOGI(PRI_DOMAIN, PRI_TAG, "Check result:%{public}d", checkResult);
741     if (checkResult != -1) {
742         return SUCCESS;
743     }
744 
745     std::string sql = "alter table ";
746     sql.append(it->second.tableName_ + " add column ")
747         .append(PrivacyFiledConst::FIELD_USED_TYPE)
748         .append(" integer default ")
749         .append(std::to_string(PermissionUsedType::NORMAL_TYPE));
750     int32_t insertResult = ExecuteSql(sql);
751     LOGI(PRI_DOMAIN, PRI_TAG, "Insert column result:%{public}d", insertResult);
752     return insertResult;
753 }
754 
CreateNewPermissionRecordTable(std::string & newTableName,std::string & createNewSql)755 static void CreateNewPermissionRecordTable(std::string& newTableName, std::string& createNewSql)
756 {
757     createNewSql = CREATE_TABLE_STR;
758     createNewSql.append(newTableName + " (")
759         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
760         .append(INTEGER_STR)
761         .append(PrivacyFiledConst::FIELD_OP_CODE)
762         .append(INTEGER_STR)
763         .append(PrivacyFiledConst::FIELD_STATUS)
764         .append(INTEGER_STR)
765         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
766         .append(INTEGER_STR)
767         .append(PrivacyFiledConst::FIELD_ACCESS_DURATION)
768         .append(INTEGER_STR)
769         .append(PrivacyFiledConst::FIELD_ACCESS_COUNT)
770         .append(INTEGER_STR)
771         .append(PrivacyFiledConst::FIELD_REJECT_COUNT)
772         .append(INTEGER_STR)
773         .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
774         .append(INTEGER_STR)
775         .append(PrivacyFiledConst::FIELD_USED_TYPE)
776         .append(INTEGER_STR)
777         .append("primary key(")
778         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
779         .append(",")
780         .append(PrivacyFiledConst::FIELD_OP_CODE)
781         .append(",")
782         .append(PrivacyFiledConst::FIELD_STATUS)
783         .append(",")
784         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
785         .append(",")
786         .append(PrivacyFiledConst::FIELD_USED_TYPE)
787         .append("))");
788 }
789 
UpdatePermissionRecordTablePrimaryKey() const790 int32_t PermissionUsedRecordDb::UpdatePermissionRecordTablePrimaryKey() const
791 {
792     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
793     if (it == dataTypeToSqlTable_.end()) {
794         return FAILURE;
795     }
796 
797     std::string tableName = it->second.tableName_;
798     std::string newTableName = it->second.tableName_ + "_new";
799     std::string createNewSql;
800     CreateNewPermissionRecordTable(newTableName, createNewSql);
801 
802     BeginTransaction();
803 
804     int32_t createNewRes = ExecuteSql(createNewSql); // 1、create new table with new primary key
805     if (createNewRes != 0) {
806         LOGE(PRI_DOMAIN, PRI_TAG, "Create new table failed, errCode is %{public}d, errMsg is %{public}s.",
807             createNewRes, SpitError().c_str());
808         return FAILURE;
809     }
810 
811     std::string copyDataSql = "insert into " + newTableName + " select * from " + tableName;
812     int32_t copyDataRes = ExecuteSql(copyDataSql); // 2、copy data from old table to new table
813     if (copyDataRes != 0) {
814         LOGE(PRI_DOMAIN, PRI_TAG, "Copy data from old table failed, errCode is %{public}d, errMsg is %{public}s.",
815             copyDataRes, SpitError().c_str());
816         RollbackTransaction();
817         return FAILURE;
818     }
819 
820     std::string dropOldSql = "drop table " + tableName;
821     int32_t dropOldRes = ExecuteSql(dropOldSql); // 3、drop old table
822     if (dropOldRes != 0) {
823         LOGE(PRI_DOMAIN, PRI_TAG, "Drop old table failed, errCode is %{public}d, errMsg is %{public}s.",
824             dropOldRes, SpitError().c_str());
825         RollbackTransaction();
826         return FAILURE;
827     }
828 
829     std::string renameSql = "alter table " + newTableName + " rename to " + tableName;
830     int32_t renameRes = ExecuteSql(renameSql); // 4、rename new table to old
831     if (renameRes != 0) {
832         LOGE(PRI_DOMAIN, PRI_TAG, "Rename table failed, errCode is %{public}d, errMsg is %{public}s.",
833             renameRes, SpitError().c_str());
834         RollbackTransaction();
835         return FAILURE;
836     }
837 
838     CommitTransaction();
839 
840     return SUCCESS;
841 }
842 } // namespace AccessToken
843 } // namespace Security
844 } // namespace OHOS
845