1 /*
2 * Copyright (C) 2025 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 #include "clone_restore_analysis_total.h"
16
17 #include "backup_database_utils.h"
18 #include "media_backup_report_data_type.h"
19 #include "media_file_utils.h"
20 #include "media_log.h"
21 #include "result_set_utils.h"
22
23 namespace OHOS::Media {
Init(const std::string & type,int32_t pageSize,std::shared_ptr<NativeRdb::RdbStore> mediaRdb,std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb)24 void CloneRestoreAnalysisTotal::Init(const std::string &type, int32_t pageSize,
25 std::shared_ptr<NativeRdb::RdbStore> mediaRdb, std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb)
26 {
27 type_ = type;
28 pageSize_ = pageSize;
29 mediaRdb_ = mediaRdb;
30 mediaLibraryRdb_ = mediaLibraryRdb;
31 }
32
GetTotalNumber()33 int32_t CloneRestoreAnalysisTotal::GetTotalNumber()
34 {
35 const std::string QUERY_SQL = "SELECT count(1) as count FROM tab_analysis_total";
36 totalCnt_ = BackupDatabaseUtils::QueryInt(mediaRdb_, QUERY_SQL, "count");
37 return totalCnt_;
38 }
39
GetInfos(const std::unordered_map<int32_t,PhotoInfo> & photoInfoMap)40 void CloneRestoreAnalysisTotal::GetInfos(const std::unordered_map<int32_t, PhotoInfo> &photoInfoMap)
41 {
42 analysisTotalInfos_.clear();
43 std::string querySql = "SELECT id, file_id, " + type_ + " FROM tab_analysis_total WHERE id > ? ORDER BY id LIMIT ?";
44 std::vector<NativeRdb::ValueObject> params = { lastId_, pageSize_ };
45 auto resultSet = BackupDatabaseUtils::QuerySql(mediaRdb_, querySql, params);
46 CHECK_AND_RETURN(resultSet != nullptr);
47
48 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
49 int32_t fileIdOld = GetInt32Val("file_id", resultSet);
50 int32_t status = GetInt32Val(type_, resultSet);
51 lastId_ = GetInt32Val("id", resultSet);
52 if (photoInfoMap.count(fileIdOld) == 0) {
53 MEDIA_ERR_LOG("Cannot find %{public}d", fileIdOld);
54 continue;
55 }
56 AnalysisTotalInfo info;
57 info.fileIdOld = fileIdOld;
58 info.fileIdNew = photoInfoMap.at(fileIdOld).fileIdNew;
59 info.status = status;
60 analysisTotalInfos_.emplace_back(info);
61 }
62 resultSet->Close();
63 }
64
SetPlaceHoldersAndParamsByFileIdOld(std::string & placeHolders,std::vector<NativeRdb::ValueObject> & params)65 void CloneRestoreAnalysisTotal::SetPlaceHoldersAndParamsByFileIdOld(std::string &placeHolders,
66 std::vector<NativeRdb::ValueObject> ¶ms)
67 {
68 int32_t count = 0;
69 for (const auto info : analysisTotalInfos_) {
70 CHECK_AND_CONTINUE(info.fileIdOld > 0);
71 placeHolders += (count++ > 0 ? "," : "");
72 placeHolders += "?";
73 params.emplace_back(info.fileIdOld);
74 }
75 }
76
SetPlaceHoldersAndParamsByFileIdNew(std::string & placeHolders,std::vector<NativeRdb::ValueObject> & params)77 void CloneRestoreAnalysisTotal::SetPlaceHoldersAndParamsByFileIdNew(std::string &placeHolders,
78 std::vector<NativeRdb::ValueObject> ¶ms)
79 {
80 int32_t count = 0;
81 for (const auto info : analysisTotalInfos_) {
82 CHECK_AND_CONTINUE(info.fileIdNew > 0);
83 placeHolders += (count++ > 0 ? "," : "");
84 placeHolders += "?";
85 params.emplace_back(info.fileIdNew);
86 }
87 }
88
FindIndexByFileIdOld(int32_t fileIdOld)89 size_t CloneRestoreAnalysisTotal::FindIndexByFileIdOld(int32_t fileIdOld)
90 {
91 auto it = std::find_if(analysisTotalInfos_.begin(), analysisTotalInfos_.end(),
92 [fileIdOld](const AnalysisTotalInfo &analysisTotalInfo) {
93 return analysisTotalInfo.fileIdOld == fileIdOld;
94 });
95 return it != analysisTotalInfos_.end() ? static_cast<size_t>(std::distance(analysisTotalInfos_.begin(), it)) :
96 std::string::npos;
97 }
98
GetFileIdNewByIndex(size_t index)99 int32_t CloneRestoreAnalysisTotal::GetFileIdNewByIndex(size_t index)
100 {
101 CHECK_AND_RETURN_RET(index < analysisTotalInfos_.size(), -1);
102 return analysisTotalInfos_[index].fileIdNew;
103 }
104
UpdateRestoreStatusAsDuplicateByIndex(size_t index)105 void CloneRestoreAnalysisTotal::UpdateRestoreStatusAsDuplicateByIndex(size_t index)
106 {
107 CHECK_AND_RETURN(index < analysisTotalInfos_.size());
108 analysisTotalInfos_[index].restoreStatus = RestoreStatus::DUPLICATE;
109 duplicateCnt_++;
110 }
111
UpdateRestoreStatusAsFailed()112 void CloneRestoreAnalysisTotal::UpdateRestoreStatusAsFailed()
113 {
114 for (auto info : analysisTotalInfos_) {
115 info.restoreStatus = RestoreStatus::FAILED;
116 failedCnt_++;
117 }
118 }
119
UpdateDatabase()120 void CloneRestoreAnalysisTotal::UpdateDatabase()
121 {
122 std::unordered_map<int32_t, std::vector<std::string>> statusFileIdsMap = GetStatusFileIdsMap();
123 for (auto it : statusFileIdsMap) {
124 int32_t updatedRows = UpdateDatabaseByStatus(it.first, it.second);
125 successCnt_ += updatedRows;
126 MEDIA_INFO_LOG("status: %{public}d, size: %{public}zu, updatedRows: %{public}d", it.first,
127 it.second.size(), updatedRows);
128 }
129 }
130
GetStatusFileIdsMap()131 std::unordered_map<int32_t, std::vector<std::string>> CloneRestoreAnalysisTotal::GetStatusFileIdsMap()
132 {
133 std::unordered_map<int32_t, std::vector<std::string>> statusFileIdsMap;
134 for (const auto info : analysisTotalInfos_) {
135 if (info.restoreStatus != RestoreStatus::SUCCESS) {
136 continue;
137 }
138 auto &fileIds = statusFileIdsMap[info.status];
139 fileIds.emplace_back(std::to_string(info.fileIdNew));
140 }
141 return statusFileIdsMap;
142 }
143
UpdateDatabaseByStatus(int32_t status,const std::vector<std::string> & fileIds)144 int32_t CloneRestoreAnalysisTotal::UpdateDatabaseByStatus(int32_t status, const std::vector<std::string> &fileIds)
145 {
146 CHECK_AND_RETURN_RET(!fileIds.empty(), 0);
147
148 int32_t updatedRows = 0;
149 NativeRdb::ValuesBucket valuesBucket;
150 valuesBucket.PutInt(type_, status);
151 std::unique_ptr<NativeRdb::AbsRdbPredicates> updatePredicates =
152 std::make_unique<NativeRdb::AbsRdbPredicates>("tab_analysis_total");
153 updatePredicates->In("file_id", fileIds);
154 int32_t errCode = BackupDatabaseUtils::Update(mediaLibraryRdb_, updatedRows, valuesBucket, updatePredicates);
155 CHECK_AND_PRINT_LOG(errCode == E_OK, "UpdateDatabaseyStatus failed, errCode = %{public}d", errCode);
156 return updatedRows;
157 }
158
SetRestoreTaskInfo(RestoreTaskInfo & info)159 void CloneRestoreAnalysisTotal::SetRestoreTaskInfo(RestoreTaskInfo &info)
160 {
161 info.successCount = successCnt_;
162 info.failedCount = failedCnt_;
163 info.duplicateCount = duplicateCnt_;
164 }
165 }