• 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 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     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
295     BeginTransaction();
296     for (const auto& type : dateTypes) {
297         std::string deleteHistorySql = CreateDeleteHistoryRecordsPrepareSqlCmd(type, tokenIDList);
298         auto deleteHistoryStatement = Prepare(deleteHistorySql);
299         if (deleteHistoryStatement.Step() != Statement::State::DONE) {
300             LOGE(PRI_DOMAIN, PRI_TAG, "Rollback transaction.");
301             RollbackTransaction();
302             return FAILURE;
303         }
304     }
305 
306     LOGD(PRI_DOMAIN, PRI_TAG, "Commit transaction.");
307     CommitTransaction();
308 
309     return SUCCESS;
310 }
311 
DeleteExcessiveRecords(DataType type,uint32_t excessiveSize)312 int32_t PermissionUsedRecordDb::DeleteExcessiveRecords(DataType type, uint32_t excessiveSize)
313 {
314     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
315 
316     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
317     std::string deleteExcessiveSql = CreateDeleteExcessiveRecordsPrepareSqlCmd(type, excessiveSize);
318     LOGD(PRI_DOMAIN, PRI_TAG, "DeleteExcessiveRecords sql is %{public}s.", deleteExcessiveSql.c_str());
319     auto deleteExcessiveStatement = Prepare(deleteExcessiveSql);
320     if (deleteExcessiveStatement.Step() != Statement::State::DONE) {
321         return FAILURE;
322     }
323 
324     int64_t endTime = TimeUtil::GetCurrentTimestamp();
325     LOGI(PRI_DOMAIN, PRI_TAG, "DeleteExcessiveRecords cost %{public}" PRId64 ".", endTime - beginTime);
326 
327     return SUCCESS;
328 }
329 
Update(DataType type,const GenericValues & modifyValue,const GenericValues & conditionValue)330 int32_t PermissionUsedRecordDb::Update(DataType type, const GenericValues& modifyValue,
331     const GenericValues& conditionValue)
332 {
333     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
334 
335     std::vector<std::string> modifyNames = modifyValue.GetAllKeys();
336     std::vector<std::string> conditionNames = conditionValue.GetAllKeys();
337 
338     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
339     std::string prepareSql = CreateUpdatePrepareSqlCmd(type, modifyNames, conditionNames);
340     if (prepareSql.empty()) {
341         LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid", type);
342         return FAILURE;
343     }
344     LOGD(PRI_DOMAIN, PRI_TAG, "Update sql is %{public}s.", prepareSql.c_str());
345 
346     auto statement = Prepare(prepareSql);
347 
348     for (const auto& modifyName : modifyNames) {
349         statement.Bind(modifyName, modifyValue.Get(modifyName));
350     }
351 
352     for (const auto& conditionName : conditionNames) {
353         statement.Bind(conditionName, conditionValue.Get(conditionName));
354     }
355 
356     int32_t ret = statement.Step();
357     if (ret != Statement::State::DONE) {
358         LOGE(PRI_DOMAIN, PRI_TAG,
359             "Update table Type %{public}u failed, errCode is %{public}d, errMsg is %{public}s.", type, ret,
360             SpitError().c_str());
361         return FAILURE;
362     }
363 
364     int64_t endTime = TimeUtil::GetCurrentTimestamp();
365     LOGI(PRI_DOMAIN, PRI_TAG, "Update cost %{public}" PRId64 ".", endTime - beginTime);
366 
367     return SUCCESS;
368 }
369 
Query(DataType type,const GenericValues & conditionValue,std::vector<GenericValues> & results)370 int32_t PermissionUsedRecordDb::Query(DataType type, const GenericValues& conditionValue,
371     std::vector<GenericValues>& results)
372 {
373     int64_t beginTime = TimeUtil::GetCurrentTimestamp();
374 
375     std::vector<std::string> conditionColumns = conditionValue.GetAllKeys();
376 
377     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
378     std::string prepareSql = CreateQueryPrepareSqlCmd(type, conditionColumns);
379     if (prepareSql.empty()) {
380         LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid.", type);
381         return FAILURE;
382     }
383     LOGD(PRI_DOMAIN, PRI_TAG, "Query sql is %{public}s.", prepareSql.c_str());
384 
385     auto statement = Prepare(prepareSql);
386     for (const auto& conditionColumn : conditionColumns) {
387         statement.Bind(conditionColumn, conditionValue.Get(conditionColumn));
388     }
389 
390     while (statement.Step() == Statement::State::ROW) {
391         int32_t columnCount = statement.GetColumnCount();
392         GenericValues value;
393 
394         for (int32_t i = 0; i < columnCount; i++) {
395             value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
396         }
397 
398         results.emplace_back(value);
399     }
400 
401     int64_t endTime = TimeUtil::GetCurrentTimestamp();
402     LOGI(PRI_DOMAIN, PRI_TAG, "Query cost %{public}" PRId64 ".", endTime - beginTime);
403 
404     return SUCCESS;
405 }
406 
CreateInsertPrepareSqlCmd(DataType type) const407 std::string PermissionUsedRecordDb::CreateInsertPrepareSqlCmd(DataType type) const
408 {
409     auto it = dataTypeToSqlTable_.find(type);
410     if (it == dataTypeToSqlTable_.end()) {
411         return std::string();
412     }
413     std::string sql = "insert into " + it->second.tableName_ + " values(";
414     int32_t i = 1;
415     for (const auto& name : it->second.tableColumnNames_) {
416         sql.append(":" + name);
417         if (i < static_cast<int32_t>(it->second.tableColumnNames_.size())) {
418             sql.append(",");
419         }
420         i += 1;
421     }
422     sql.append(")");
423     return sql;
424 }
425 
CreateQueryPrepareSqlCmd(DataType type,const std::vector<std::string> & conditionColumns) const426 std::string PermissionUsedRecordDb::CreateQueryPrepareSqlCmd(DataType type,
427     const std::vector<std::string>& conditionColumns) const
428 {
429     auto it = dataTypeToSqlTable_.find(type);
430     if (it == dataTypeToSqlTable_.end()) {
431         return std::string();
432     }
433     std::string sql = "select * from " + it->second.tableName_ + WHERE_1_STR;
434 
435     for (const auto& andColumn : conditionColumns) {
436         sql.append(" and ");
437         sql.append(andColumn + "=:" + andColumn);
438     }
439 
440     return sql;
441 }
442 
CreateDeletePrepareSqlCmd(DataType type,const std::vector<std::string> & columnNames) const443 std::string PermissionUsedRecordDb::CreateDeletePrepareSqlCmd(
444     DataType type, const std::vector<std::string>& columnNames) const
445 {
446     auto it = dataTypeToSqlTable_.find(type);
447     if (it == dataTypeToSqlTable_.end()) {
448         return std::string();
449     }
450     std::string sql = "delete from " + it->second.tableName_ + WHERE_1_STR;
451     for (const auto& name : columnNames) {
452         sql.append(" and ");
453         sql.append(name + "=:" + name);
454     }
455     return sql;
456 }
457 
CreateUpdatePrepareSqlCmd(DataType type,const std::vector<std::string> & modifyColumns,const std::vector<std::string> & conditionColumns) const458 std::string PermissionUsedRecordDb::CreateUpdatePrepareSqlCmd(DataType type,
459     const std::vector<std::string>& modifyColumns, const std::vector<std::string>& conditionColumns) const
460 {
461     if (modifyColumns.empty()) {
462         return std::string();
463     }
464 
465     auto it = dataTypeToSqlTable_.find(type);
466     if (it == dataTypeToSqlTable_.end()) {
467         return std::string();
468     }
469 
470     std::string sql = "update " + it->second.tableName_ + " set ";
471     int32_t i = 1;
472     for (const auto& name : modifyColumns) {
473         sql.append(name + "=:" + name);
474         if (i < static_cast<int32_t>(modifyColumns.size())) {
475             sql.append(",");
476         }
477         i += 1;
478     }
479 
480     if (!conditionColumns.empty()) {
481         sql.append(WHERE_1_STR);
482         for (const auto& columnName : conditionColumns) {
483             sql.append(" and ");
484             sql.append(columnName + "=:" + columnName);
485         }
486     }
487     return sql;
488 }
489 
CreateSelectByConditionPrepareSqlCmd(const int32_t tokenId,DataType type,const std::set<int32_t> & opCodeList,const std::vector<std::string> & andColumns,int32_t databaseQueryCount) const490 std::string PermissionUsedRecordDb::CreateSelectByConditionPrepareSqlCmd(const int32_t tokenId, DataType type,
491     const std::set<int32_t>& opCodeList, const std::vector<std::string>& andColumns, int32_t databaseQueryCount) const
492 {
493     auto it = dataTypeToSqlTable_.find(type);
494     if (it == dataTypeToSqlTable_.end()) {
495         return std::string();
496     }
497 
498     std::string sql = "select * from " + it->second.tableName_ + WHERE_1_STR;
499 
500     for (const auto& andColName : andColumns) {
501         if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
502             sql.append(" and ");
503             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
504             sql.append(" >=:" + andColName);
505         } else if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
506             sql.append(" and ");
507             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
508             sql.append(" <=:" + andColName);
509         } else if (andColName == PrivacyFiledConst::FIELD_TOKEN_ID) {
510             if (tokenId != 0) {
511                 sql.append(" and ");
512                 sql.append(PrivacyFiledConst::FIELD_TOKEN_ID);
513                 sql.append(" =:" + andColName);
514             }
515         } else {
516             sql.append(" and ");
517             sql.append(andColName + "=:" + andColName);
518         }
519     }
520     if (!opCodeList.empty()) {
521         sql.append(" and (");
522         for (const auto& opCode : opCodeList) {
523             if (opCode != Constant::OP_INVALID) {
524                 sql.append(PrivacyFiledConst::FIELD_OP_CODE);
525                 sql.append(+ " = " + std::to_string(opCode));
526                 sql.append(" or ");
527             }
528         }
529         sql.append("0)");
530     }
531     sql.append(" order by timestamp desc");
532     sql.append(" limit " + std::to_string(databaseQueryCount));
533     return sql;
534 }
535 
CreateCountPrepareSqlCmd(DataType type) const536 std::string PermissionUsedRecordDb::CreateCountPrepareSqlCmd(DataType type) const
537 {
538     auto it = dataTypeToSqlTable_.find(type);
539     if (it == dataTypeToSqlTable_.end()) {
540         return std::string();
541     }
542     std::string sql = "select count(*) from " + it->second.tableName_;
543     return sql;
544 }
545 
CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,const std::vector<std::string> & andColumns) const546 std::string PermissionUsedRecordDb::CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,
547     const std::vector<std::string>& andColumns) const
548 {
549     auto it = dataTypeToSqlTable_.find(type);
550     if (it == dataTypeToSqlTable_.end()) {
551         return std::string();
552     }
553     std::string sql = "delete from " + it->second.tableName_ + " where ";
554     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
555     sql.append(" in (select ");
556     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
557     sql.append(" from " + it->second.tableName_ + WHERE_1_STR);
558     for (const auto& name : andColumns) {
559         if (name == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
560             sql.append(" and ");
561             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
562             sql.append(" >=:" + name);
563         } else if (name == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
564             sql.append(" and ");
565             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
566             sql.append(" <=:" + name);
567         } else {
568             sql.append(" and ");
569             sql.append(name + "=:" + name);
570         }
571     }
572     sql.append(" )");
573     return sql;
574 }
575 
CreateDeleteHistoryRecordsPrepareSqlCmd(DataType type,const std::unordered_set<AccessTokenID> & tokenIDList) const576 std::string PermissionUsedRecordDb::CreateDeleteHistoryRecordsPrepareSqlCmd(DataType type,
577     const std::unordered_set<AccessTokenID>& tokenIDList) const
578 {
579     auto it = dataTypeToSqlTable_.find(type);
580     if (it == dataTypeToSqlTable_.end()) {
581         return std::string();
582     }
583     std::string sql = "delete from " + it->second.tableName_ + " where ";
584     sql.append(PrivacyFiledConst::FIELD_TOKEN_ID);
585     sql.append(" in ( ");
586 
587     size_t sqlLen = sql.size();
588     sqlLen += TOKEN_ID_LENGTH * tokenIDList.size();
589     sql.reserve(sqlLen);
590 
591     for (auto token = tokenIDList.begin(); token != tokenIDList.end(); ++token) {
592         sql.append(std::to_string(*token));
593         if (std::next(token) != tokenIDList.end()) {
594             sql.append(", ");
595         }
596     }
597     sql.append(" )");
598     return sql;
599 }
600 
CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,uint32_t excessiveSize) const601 std::string PermissionUsedRecordDb::CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,
602     uint32_t excessiveSize) const
603 {
604     auto it = dataTypeToSqlTable_.find(type);
605     if (it == dataTypeToSqlTable_.end()) {
606         return std::string();
607     }
608     std::string sql = "delete from " + it->second.tableName_ + " where ";
609     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
610     sql.append(" in (select ");
611     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
612     sql.append(" from " + it->second.tableName_ + " order by ");
613     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
614     sql.append(" limit ");
615     sql.append(std::to_string(excessiveSize) + " )");
616     return sql;
617 }
618 
CreatePermissionRecordTable() const619 int32_t PermissionUsedRecordDb::CreatePermissionRecordTable() const
620 {
621     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
622     if (it == dataTypeToSqlTable_.end()) {
623         return FAILURE;
624     }
625     std::string sql = CREATE_TABLE_STR;
626     sql.append(it->second.tableName_ + " (")
627         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
628         .append(INTEGER_STR)
629         .append(PrivacyFiledConst::FIELD_OP_CODE)
630         .append(INTEGER_STR)
631         .append(PrivacyFiledConst::FIELD_STATUS)
632         .append(INTEGER_STR)
633         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
634         .append(INTEGER_STR)
635         .append(PrivacyFiledConst::FIELD_ACCESS_DURATION)
636         .append(INTEGER_STR)
637         .append(PrivacyFiledConst::FIELD_ACCESS_COUNT)
638         .append(INTEGER_STR)
639         .append(PrivacyFiledConst::FIELD_REJECT_COUNT)
640         .append(INTEGER_STR)
641         .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
642         .append(INTEGER_STR)
643         .append(PrivacyFiledConst::FIELD_USED_TYPE)
644         .append(INTEGER_STR)
645         .append("primary key(")
646         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
647         .append(",")
648         .append(PrivacyFiledConst::FIELD_OP_CODE)
649         .append(",")
650         .append(PrivacyFiledConst::FIELD_STATUS)
651         .append(",")
652         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
653         .append(",")
654         .append(PrivacyFiledConst::FIELD_USED_TYPE)
655         .append("))");
656     return ExecuteSql(sql);
657 }
658 
CreatePermissionUsedTypeTable() const659 int32_t PermissionUsedRecordDb::CreatePermissionUsedTypeTable() const
660 {
661     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_USED_TYPE);
662     if (it == dataTypeToSqlTable_.end()) {
663         return FAILURE;
664     }
665     std::string sql = CREATE_TABLE_STR;
666     sql.append(it->second.tableName_ + " (")
667         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
668         .append(INTEGER_STR)
669         .append(PrivacyFiledConst::FIELD_PERMISSION_CODE)
670         .append(INTEGER_STR)
671         .append(PrivacyFiledConst::FIELD_USED_TYPE)
672         .append(INTEGER_STR)
673         .append("primary key(")
674         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
675         .append(",")
676         .append(PrivacyFiledConst::FIELD_PERMISSION_CODE)
677         .append("))");
678     return ExecuteSql(sql);
679 }
680 
CreatePermissionUsedRecordToggleStatusTable() const681 int32_t PermissionUsedRecordDb::CreatePermissionUsedRecordToggleStatusTable() const
682 {
683     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_USED_RECORD_TOGGLE_STATUS);
684     if (it == dataTypeToSqlTable_.end()) {
685         return FAILURE;
686     }
687     std::string sql = CREATE_TABLE_STR;
688     sql.append(it->second.tableName_ + " (")
689         .append(PrivacyFiledConst::FIELD_USER_ID)
690         .append(INTEGER_STR)
691         .append(PrivacyFiledConst::FIELD_STATUS)
692         .append(INTEGER_STR)
693         .append("primary key(")
694         .append(PrivacyFiledConst::FIELD_USER_ID)
695         .append("))");
696     return ExecuteSql(sql);
697 }
698 
InsertLockScreenStatusColumn() const699 int32_t PermissionUsedRecordDb::InsertLockScreenStatusColumn() const
700 {
701     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
702     if (it == dataTypeToSqlTable_.end()) {
703         return FAILURE;
704     }
705     std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
706         PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS + "=" +
707         std::to_string(LockScreenStatusChangeType::PERM_ACTIVE_IN_UNLOCKED);
708     int32_t checkResult = ExecuteSql(checkSql);
709     LOGI(PRI_DOMAIN, PRI_TAG, "Check result:%{public}d", checkResult);
710     if (checkResult != -1) {
711         return SUCCESS;
712     }
713 
714     std::string sql = "alter table ";
715     sql.append(it->second.tableName_ + " add column ")
716         .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
717         .append(" integer default ")
718         .append(std::to_string(LockScreenStatusChangeType::PERM_ACTIVE_IN_UNLOCKED));
719     int32_t insertResult = ExecuteSql(sql);
720     LOGI(PRI_DOMAIN, PRI_TAG, "Insert column result:%{public}d", insertResult);
721     return insertResult;
722 }
723 
InsertPermissionUsedTypeColumn() const724 int32_t PermissionUsedRecordDb::InsertPermissionUsedTypeColumn() const
725 {
726     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
727     if (it == dataTypeToSqlTable_.end()) {
728         return FAILURE;
729     }
730     std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
731         PrivacyFiledConst::FIELD_USED_TYPE + "=" +
732         std::to_string(PermissionUsedType::NORMAL_TYPE);
733     int32_t checkResult = ExecuteSql(checkSql);
734     LOGI(PRI_DOMAIN, PRI_TAG, "Check result:%{public}d", checkResult);
735     if (checkResult != -1) {
736         return SUCCESS;
737     }
738 
739     std::string sql = "alter table ";
740     sql.append(it->second.tableName_ + " add column ")
741         .append(PrivacyFiledConst::FIELD_USED_TYPE)
742         .append(" integer default ")
743         .append(std::to_string(PermissionUsedType::NORMAL_TYPE));
744     int32_t insertResult = ExecuteSql(sql);
745     LOGI(PRI_DOMAIN, PRI_TAG, "Insert column result:%{public}d", insertResult);
746     return insertResult;
747 }
748 
CreateNewPermissionRecordTable(std::string & newTableName,std::string & createNewSql)749 static void CreateNewPermissionRecordTable(std::string& newTableName, std::string& createNewSql)
750 {
751     createNewSql = CREATE_TABLE_STR;
752     createNewSql.append(newTableName + " (")
753         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
754         .append(INTEGER_STR)
755         .append(PrivacyFiledConst::FIELD_OP_CODE)
756         .append(INTEGER_STR)
757         .append(PrivacyFiledConst::FIELD_STATUS)
758         .append(INTEGER_STR)
759         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
760         .append(INTEGER_STR)
761         .append(PrivacyFiledConst::FIELD_ACCESS_DURATION)
762         .append(INTEGER_STR)
763         .append(PrivacyFiledConst::FIELD_ACCESS_COUNT)
764         .append(INTEGER_STR)
765         .append(PrivacyFiledConst::FIELD_REJECT_COUNT)
766         .append(INTEGER_STR)
767         .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
768         .append(INTEGER_STR)
769         .append(PrivacyFiledConst::FIELD_USED_TYPE)
770         .append(INTEGER_STR)
771         .append("primary key(")
772         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
773         .append(",")
774         .append(PrivacyFiledConst::FIELD_OP_CODE)
775         .append(",")
776         .append(PrivacyFiledConst::FIELD_STATUS)
777         .append(",")
778         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
779         .append(",")
780         .append(PrivacyFiledConst::FIELD_USED_TYPE)
781         .append("))");
782 }
783 
UpdatePermissionRecordTablePrimaryKey() const784 int32_t PermissionUsedRecordDb::UpdatePermissionRecordTablePrimaryKey() const
785 {
786     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
787     if (it == dataTypeToSqlTable_.end()) {
788         return FAILURE;
789     }
790 
791     std::string tableName = it->second.tableName_;
792     std::string newTableName = it->second.tableName_ + "_new";
793     std::string createNewSql;
794     CreateNewPermissionRecordTable(newTableName, createNewSql);
795 
796     BeginTransaction();
797 
798     int32_t createNewRes = ExecuteSql(createNewSql); // 1、create new table with new primary key
799     if (createNewRes != 0) {
800         LOGE(PRI_DOMAIN, PRI_TAG, "Create new table failed, errCode is %{public}d, errMsg is %{public}s.",
801             createNewRes, SpitError().c_str());
802         return FAILURE;
803     }
804 
805     std::string copyDataSql = "insert into " + newTableName + " select * from " + tableName;
806     int32_t copyDataRes = ExecuteSql(copyDataSql); // 2、copy data from old table to new table
807     if (copyDataRes != 0) {
808         LOGE(PRI_DOMAIN, PRI_TAG, "Copy data from old table failed, errCode is %{public}d, errMsg is %{public}s.",
809             copyDataRes, SpitError().c_str());
810         RollbackTransaction();
811         return FAILURE;
812     }
813 
814     std::string dropOldSql = "drop table " + tableName;
815     int32_t dropOldRes = ExecuteSql(dropOldSql); // 3、drop old table
816     if (dropOldRes != 0) {
817         LOGE(PRI_DOMAIN, PRI_TAG, "Drop old table failed, errCode is %{public}d, errMsg is %{public}s.",
818             dropOldRes, SpitError().c_str());
819         RollbackTransaction();
820         return FAILURE;
821     }
822 
823     std::string renameSql = "alter table " + newTableName + " rename to " + tableName;
824     int32_t renameRes = ExecuteSql(renameSql); // 4、rename new table to old
825     if (renameRes != 0) {
826         LOGE(PRI_DOMAIN, PRI_TAG, "Rename table failed, errCode is %{public}d, errMsg is %{public}s.",
827             renameRes, SpitError().c_str());
828         RollbackTransaction();
829         return FAILURE;
830     }
831 
832     CommitTransaction();
833 
834     return SUCCESS;
835 }
836 } // namespace AccessToken
837 } // namespace Security
838 } // namespace OHOS
839