1 /*
2  * Copyright (C) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define MLOG_TAG "MediaLibraryBackupUtils"
16 
17 #include "backup_database_helper.h"
18 #include "backup_database_utils.h"
19 #include "backup_file_utils.h"
20 #include "media_file_utils.h"
21 #include "media_log.h"
22 
23 namespace OHOS::Media {
Init(int32_t sceneCode,bool shouldIncludeSd,const std::string & prefix)24 void BackupDatabaseHelper::Init(int32_t sceneCode, bool shouldIncludeSd, const std::string &prefix)
25 {
26     if (sceneCode != DUAL_FRAME_CLONE_RESTORE_ID) {
27         return;
28     }
29     std::vector<int32_t> dbTypeList;
30     if (shouldIncludeSd) {
31         dbTypeList = { DbType::PHOTO_CACHE, DbType::VIDEO_CACHE, DbType::PHOTO_SD_CACHE, DbType::VIDEO_SD_CACHE };
32     } else {
33         dbTypeList = { DbType::PHOTO_CACHE, DbType::VIDEO_CACHE };
34     }
35     InitDb(dbTypeList, prefix);
36 }
37 
InitDb(int32_t dbType,const std::string & prefix)38 void BackupDatabaseHelper::InitDb(int32_t dbType, const std::string &prefix)
39 {
40     if (HasDb(dbType)) {
41         MEDIA_WARN_LOG("Db %{public}d already exists", dbType);
42         return;
43     }
44     if (DB_INFO_MAP.count(dbType) == 0) {
45         MEDIA_ERR_LOG("No such db type: %{public}d", dbType);
46         return;
47     }
48     DbInfo dbInfo = DB_INFO_MAP.at(dbType);
49     std::string dbFullPath = prefix + dbInfo.path;
50     if (!MediaFileUtils::IsFileExists(dbFullPath)) {
51         MEDIA_WARN_LOG("Db not exist, type: %{public}d, path: %{public}s", dbType,
52             BackupFileUtils::GarbleFilePath(dbFullPath, DEFAULT_RESTORE_ID).c_str());
53         return;
54     }
55     int32_t errCode = BackupDatabaseUtils::InitDb(dbInfo.rdbStore, dbInfo.name, dbFullPath, BUNDLE_NAME, false);
56     if (dbInfo.rdbStore == nullptr) {
57         MEDIA_ERR_LOG("Init db failed, type: %{public}d, errCode: %{public}d", dbType, errCode);
58         return;
59     }
60     dbInfoMap_[dbType] = dbInfo;
61     MEDIA_INFO_LOG("Init db succeeded, type: %{public}d, current size: %{public}zu", dbType, dbInfoMap_.size());
62 }
63 
InitDb(const std::vector<int32_t> & dbTypeList,const std::string & prefix)64 void BackupDatabaseHelper::InitDb(const std::vector<int32_t> &dbTypeList, const std::string &prefix)
65 {
66     for (auto dbType : dbTypeList) {
67         InitDb(dbType, prefix);
68     }
69 }
70 
AddDb(int32_t dbType,std::shared_ptr<NativeRdb::RdbStore> rdbStore)71 void BackupDatabaseHelper::AddDb(int32_t dbType, std::shared_ptr<NativeRdb::RdbStore> rdbStore)
72 {
73     if (HasDb(dbType)) {
74         MEDIA_WARN_LOG("Db %{public}d already exists", dbType);
75         return;
76     }
77     dbInfoMap_[dbType] = DbInfo(rdbStore);
78     MEDIA_INFO_LOG("Add db succeeded, type: %{public}d, current size: %{public}zu", dbType, dbInfoMap_.size());
79 }
80 
IsFileExist(int32_t sceneCode,const FileInfo & fileInfo,int32_t & dbType,int32_t & dbStatus,int32_t & fileStatus)81 void BackupDatabaseHelper::IsFileExist(int32_t sceneCode, const FileInfo &fileInfo, int32_t &dbType, int32_t &dbStatus,
82     int32_t &fileStatus)
83 {
84     FileQueryInfo fileQueryInfo;
85     GetFileQueryInfo(sceneCode, fileInfo, fileQueryInfo);
86     dbType = fileQueryInfo.dbType;
87     if (!HasDb(fileQueryInfo.dbType)) {
88         dbStatus = E_DB_FAIL;
89         return;
90     }
91     DbInfo dbInfo = dbInfoMap_.at(fileQueryInfo.dbType);
92     std::string querySql = "SELECT count(1) as count FROM " + fileQueryInfo.tableName + " WHERE " +
93         fileQueryInfo.columnName + " = ?";
94     std::vector<std::string> queryArgs = { fileQueryInfo.path };
95     auto resultSet = BackupDatabaseUtils::GetQueryResultSet(dbInfo.rdbStore, querySql, queryArgs);
96     if (resultSet == nullptr || resultSet->GoToFirstRow() != E_OK) {
97         dbStatus = E_HAS_DB_ERROR;
98         return;
99     }
100     dbStatus = E_OK;
101     fileStatus = GetInt32Val(CUSTOM_COUNT, resultSet) > 0 ? E_OK : E_NO_SUCH_FILE;
102 }
103 
HasDb(int32_t dbType)104 bool BackupDatabaseHelper::HasDb(int32_t dbType)
105 {
106     return dbInfoMap_.count(dbType) > 0;
107 }
108 
GetFileQueryInfo(int32_t sceneCode,const FileInfo & fileInfo,FileQueryInfo & fileQueryInfo)109 void BackupDatabaseHelper::GetFileQueryInfo(int32_t sceneCode, const FileInfo &fileInfo, FileQueryInfo &fileQueryInfo)
110 {
111     if (sceneCode == UPGRADE_RESTORE_ID) {
112         fileQueryInfo = FileQueryInfo(DbType::EXTERNAL, "files", "_data", fileInfo.oldPath);
113         return;
114     }
115     int32_t dbType;
116     if (fileInfo.isInternal) {
117         dbType = fileInfo.fileType == DUAL_MEDIA_TYPE::IMAGE_TYPE ? DbType::PHOTO_CACHE : DbType::VIDEO_CACHE;
118     } else {
119         dbType = fileInfo.fileType == DUAL_MEDIA_TYPE::IMAGE_TYPE ? DbType::PHOTO_SD_CACHE : DbType::VIDEO_SD_CACHE;
120     }
121     std::string tableName = fileInfo.fileSize >= TAR_FILE_LIMIT ? "normal_file" : "small_file";
122     fileQueryInfo = FileQueryInfo(dbType, tableName, "filepath", fileInfo.oldPath);
123 }
124 } // namespace OHOS::Media