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 #define MLOG_TAG "CloneRestoreClassify"
16
17 #include "clone_restore_classify.h"
18
19 #include "classify_aggregate_types.h"
20 #include "backup_database_utils.h"
21 #include "media_library_db_upgrade.h"
22 #include "medialibrary_unistore_manager.h"
23 #include "media_file_utils.h"
24 #include "media_log.h"
25 #include "result_set_utils.h"
26 #include "upgrade_restore_task_report.h"
27
28 namespace OHOS::Media {
29 const int32_t PAGE_SIZE = 200;
30
31 const string ID = "id";
32 const string FILE_ID = "file_id";
33 const string CATEGORY_ID = "category_id";
34 const string SUB_LABEL = "sub_label";
35 const string PROB = "prob";
36 const string FEATURE = "feature";
37 const string SIM_RESULT = "sim_result";
38 const string LABEL_VERSION = "label_version";
39 const string SALIENCY_SUB_PROB = "saliency_sub_prob";
40 const string ANALYSIS_VERSION = "analysis_version";
41 const string CAPTION_RESULT = "caption_result";
42 const string CAPTION_VERSION = "caption_version";
43
44 const string CONFIDENCE_PROBABILITY = "confidence_probability";
45 const string SUB_CATEGORY = "sub_category";
46 const string SUB_CONFIDENCE_PROB = "sub_confidence_prob";
47 const string SUB_LABEL_PROB = "sub_label_prob";
48 const string SUB_LABEL_TYPE = "sub_label_type";
49 const string TRACKS = "tracks";
50 const string VIDEO_PART_FEATURE = "video_part_feature";
51 const string FILTER_TAG = "filter_tag";
52 const string ALGO_VERSION = "algo_version";
53 const string TRIGGER_GENERATE_THUMBNAIL = "trigger_generate_thumbnail";
54
55 const string ANALYSIS_LABEL_TABLE = "tab_analysis_label";
56 const string ANALYSIS_VIDEO_TABLE = "tab_analysis_video_label";
57 const string FIELD_TYPE_INT = "INT";
58
59 const int32_t CLASSIFY_STATUS_SUCCESS = 1;
60 const int32_t CLASSIFY_TYPE = 4097;
61 const int32_t FRONT_CAMERA = 1;
62
63 const unordered_map<string, unordered_set<string>> COMPARED_COLUMNS_MAP = {
64 { "tab_analysis_label",
65 {
66 "id",
67 "file_id",
68 "category_id",
69 "sub_label",
70 "prob",
71 "feature",
72 "sim_result",
73 "label_version",
74 "saliency_sub_prob",
75 "analysis_version",
76 "caption_result",
77 "caption_version",
78 }
79 },
80 { "tab_analysis_video_label",
81 {
82 "id",
83 "file_id",
84 "category_id",
85 "confidence_probability",
86 "sub_category",
87 "sub_confidence_prob",
88 "sub_label",
89 "sub_label_prob",
90 "sub_label_type",
91 "tracks",
92 "video_part_feature",
93 "filter_tag",
94 "algo_version",
95 "analysis_version",
96 "trigger_generate_thumbnail",
97 }
98 }
99 };
100
101 template<typename Key, typename Value>
GetValueFromMap(const unordered_map<Key,Value> & map,const Key & key,const Value & defaultValue=Value ())102 Value GetValueFromMap(const unordered_map<Key, Value> &map, const Key &key, const Value &defaultValue = Value())
103 {
104 auto it = map.find(key);
105 CHECK_AND_RETURN_RET(it == map.end(), it->second);
106 return defaultValue;
107 }
108
Init(int32_t sceneCode,const std::string & taskId,std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb,std::shared_ptr<NativeRdb::RdbStore> mediaRdb)109 void CloneRestoreClassify::Init(int32_t sceneCode, const std::string &taskId,
110 std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb, std::shared_ptr<NativeRdb::RdbStore> mediaRdb)
111 {
112 sceneCode_ = sceneCode;
113 taskId_ = taskId;
114 mediaLibraryRdb_ = mediaLibraryRdb;
115 mediaRdb_ = mediaRdb;
116 analysisType_ = "label";
117 }
118
Restore(const std::unordered_map<int32_t,PhotoInfo> & photoInfoMap)119 void CloneRestoreClassify::Restore(const std::unordered_map<int32_t, PhotoInfo> &photoInfoMap)
120 {
121 CHECK_AND_RETURN_LOG(mediaRdb_ != nullptr && mediaLibraryRdb_ != nullptr,
122 "ClassifyRestore failed, rdbStore is nullptr");
123
124 int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
125 GetMaxIds();
126 cloneRestoreAnalysisTotal_.Init(analysisType_, PAGE_SIZE, mediaRdb_, mediaLibraryRdb_);
127 int32_t totalNumber = cloneRestoreAnalysisTotal_.GetTotalNumber();
128 for (int32_t offset = 0; offset < totalNumber; offset += PAGE_SIZE) {
129 RestoreBatch(photoInfoMap);
130 }
131 AddSpecialAlbum();
132 int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
133 restoreTimeCost_ = end - start;
134 ReportRestoreTask();
135 MEDIA_INFO_LOG("TimeCost: ClassifyRestore: %{public}" PRId64, end - start);
136 }
137
GetMaxIds()138 void CloneRestoreClassify::GetMaxIds()
139 {
140 maxIdOfLabel_ = BackupDatabaseUtils::QueryMaxId(mediaLibraryRdb_, ANALYSIS_LABEL_TABLE, ID);
141 maxIdOfVideoLabel_ = BackupDatabaseUtils::QueryMaxId(mediaLibraryRdb_, ANALYSIS_VIDEO_TABLE, ID);
142 }
143
RestoreBatch(const std::unordered_map<int32_t,PhotoInfo> & photoInfoMap)144 void CloneRestoreClassify::RestoreBatch(const std::unordered_map<int32_t, PhotoInfo> &photoInfoMap)
145 {
146 int64_t startGet = MediaFileUtils::UTCTimeMilliSeconds();
147 cloneRestoreAnalysisTotal_.GetInfos(photoInfoMap);
148 int64_t startRestoreMaps = MediaFileUtils::UTCTimeMilliSeconds();
149 RestoreMaps();
150 int64_t startRestoreVideoMaps = MediaFileUtils::UTCTimeMilliSeconds();
151 RestoreVideoMaps();
152 int64_t startUpdate = MediaFileUtils::UTCTimeMilliSeconds();
153 cloneRestoreAnalysisTotal_.UpdateDatabase();
154 int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
155 MEDIA_INFO_LOG("TimeCost: GetAnalysisTotalInfos: %{public}" PRId64 ", RestoreMaps: %{public}" PRId64
156 ", RestoreVideoMaps: %{public}" PRId64 ", UpdateDatabase: %{public}" PRId64,
157 startRestoreMaps - startGet, startRestoreVideoMaps - startRestoreMaps, startUpdate - startRestoreVideoMaps,
158 end - startUpdate);
159 }
160
RestoreMaps()161 void CloneRestoreClassify::RestoreMaps()
162 {
163 bool cond = (mediaRdb_ == nullptr || mediaLibraryRdb_ == nullptr);
164 CHECK_AND_RETURN_LOG(!cond, "rdbStore is nullptr");
165
166 MEDIA_INFO_LOG("restore classify albums start.");
167 int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
168 std::vector<ClassifyCloneInfo> classifyInfos;
169 GetClassifyInfos(classifyInfos);
170 int64_t startInsert = MediaFileUtils::UTCTimeMilliSeconds();
171 InsertClassifyAlbums(classifyInfos);
172 int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
173 MEDIA_INFO_LOG("TimeCost: GetClassifyInfos: %{public}" PRId64 ", InsertClassifyAlbums: %{public}" PRId64,
174 startInsert - start, end - startInsert);
175 restoreLabelTimeCost_ += end - start;
176 MEDIA_INFO_LOG("restore classify albums end.");
177 }
178
RestoreVideoMaps()179 void CloneRestoreClassify::RestoreVideoMaps()
180 {
181 bool cond = (mediaRdb_ == nullptr || mediaLibraryRdb_ == nullptr);
182 CHECK_AND_RETURN_LOG(!cond, "rdbStore is nullptr");
183
184 MEDIA_INFO_LOG("restore classify video albums start.");
185 int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
186 std::vector<ClassifyVideoCloneInfo> classifyVideoInfos;
187 GetClassifyVideoInfos(classifyVideoInfos);
188 int64_t startInsert = MediaFileUtils::UTCTimeMilliSeconds();
189 InsertClassifyVideoAlbums(classifyVideoInfos);
190 int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
191 MEDIA_INFO_LOG("TimeCost: GetClassifyVideoInfos: %{public}" PRId64 ", InsertClassifyVideoAlbums: %{public}" PRId64,
192 startInsert - start, end - startInsert);
193 restoreVideoLabelTimeCost_ += end - start;
194 MEDIA_INFO_LOG("restore classify video albums end.");
195 }
196
GetClassifyInfos(std::vector<ClassifyCloneInfo> & classifyInfos)197 void CloneRestoreClassify::GetClassifyInfos(std::vector<ClassifyCloneInfo> &classifyInfos)
198 {
199 std::unordered_map<std::string, std::string> columns;
200 columns[FILE_ID] = FIELD_TYPE_INT;
201 bool hasRequiredColumns = CheckTableColumns(ANALYSIS_LABEL_TABLE, columns);
202 if (!hasRequiredColumns) {
203 MEDIA_ERR_LOG("The tab_analysis_label does not contain the required columns.");
204 ErrorInfo errorInfo(RestoreError::TABLE_LACK_OF_COLUMN, static_cast<int32_t>(columns.size()),
205 "", "The tab_analysis_label does not contain id or file_id");
206 UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
207 return;
208 }
209
210 std::stringstream querySql;
211 std::string placeHolders;
212 std::vector<NativeRdb::ValueObject> params;
213 cloneRestoreAnalysisTotal_.SetPlaceHoldersAndParamsByFileIdOld(placeHolders, params);
214 querySql << "SELECT * FROM " + ANALYSIS_LABEL_TABLE + " WHERE " + FILE_ID + " IN (" << placeHolders << ")";
215
216 auto resultSet = BackupDatabaseUtils::QuerySql(mediaRdb_, querySql.str(), params);
217 CHECK_AND_RETURN_LOG(resultSet != nullptr, "Query resultSql is null.");
218 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
219 ClassifyCloneInfo info;
220 GetClassifyInfo(info, resultSet);
221 classifyInfos.emplace_back(info);
222 }
223 resultSet->Close();
224 MEDIA_INFO_LOG("query tab_analysis_label nums: %{public}zu", classifyInfos.size());
225 }
226
GetClassifyVideoInfos(std::vector<ClassifyVideoCloneInfo> & classifyVideoInfos)227 void CloneRestoreClassify::GetClassifyVideoInfos(std::vector<ClassifyVideoCloneInfo> &classifyVideoInfos)
228 {
229 std::unordered_map<std::string, std::string> columns;
230 columns[FILE_ID] = FIELD_TYPE_INT;
231 bool hasRequiredColumns = CheckTableColumns(ANALYSIS_VIDEO_TABLE, columns);
232 if (!hasRequiredColumns) {
233 MEDIA_ERR_LOG("The tab_analysis_video_label does not contain the required columns.");
234 ErrorInfo errorInfo(RestoreError::TABLE_LACK_OF_COLUMN, static_cast<int32_t>(columns.size()),
235 "", "The tab_analysis_video_label does not contain file_id");
236 UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
237 return;
238 }
239
240 std::stringstream querySql;
241 std::string placeHolders;
242 std::vector<NativeRdb::ValueObject> params;
243 cloneRestoreAnalysisTotal_.SetPlaceHoldersAndParamsByFileIdOld(placeHolders, params);
244 querySql << "SELECT * FROM " + ANALYSIS_VIDEO_TABLE + " WHERE " + FILE_ID + " IN (" << placeHolders << ")";
245
246 auto resultSet = BackupDatabaseUtils::QuerySql(mediaRdb_, querySql.str(), params);
247 CHECK_AND_RETURN_LOG(resultSet != nullptr, "Query resultSql is null.");
248 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
249 ClassifyVideoCloneInfo info;
250 GetClassifyVideoInfo(info, resultSet);
251 classifyVideoInfos.emplace_back(info);
252 }
253 resultSet->Close();
254 MEDIA_INFO_LOG("query tab_analysis_video_label nums: %{public}zu", classifyVideoInfos.size());
255 }
256
DeduplicateClassifyInfos(std::vector<ClassifyCloneInfo> & infos)257 void CloneRestoreClassify::DeduplicateClassifyInfos(std::vector<ClassifyCloneInfo> &infos)
258 {
259 CHECK_AND_RETURN(!infos.empty());
260 std::unordered_set<int32_t> existingFileIds = GetExistingFileIds(ANALYSIS_LABEL_TABLE);
261 RemoveDuplicateClassifyInfos(infos, existingFileIds);
262 MEDIA_INFO_LOG("existing: %{public}zu, after deduplicate: %{public}zu", existingFileIds.size(), infos.size());
263 }
264
DeduplicateClassifyVideoInfos(std::vector<ClassifyVideoCloneInfo> & infos)265 void CloneRestoreClassify::DeduplicateClassifyVideoInfos(std::vector<ClassifyVideoCloneInfo> &infos)
266 {
267 CHECK_AND_RETURN(!infos.empty());
268 std::unordered_set<int32_t> existingFileIds = GetExistingFileIds(ANALYSIS_VIDEO_TABLE);
269 RemoveDuplicateClassifyVideoInfos(infos, existingFileIds);
270 MEDIA_INFO_LOG("existing: %{public}zu, after deduplicate: %{public}zu", existingFileIds.size(), infos.size());
271 }
272
GetExistingFileIds(const std::string & tableName)273 std::unordered_set<int32_t> CloneRestoreClassify::GetExistingFileIds(const std::string &tableName)
274 {
275 std::unordered_set<int32_t> existingFileIds;
276 std::stringstream querySql;
277 std::string placeHolders;
278 std::vector<NativeRdb::ValueObject> params;
279 cloneRestoreAnalysisTotal_.SetPlaceHoldersAndParamsByFileIdNew(placeHolders, params);
280 querySql << "SELECT file_id FROM " + tableName + " WHERE " + FILE_ID + " IN (" << placeHolders << ")";
281
282 auto resultSet = BackupDatabaseUtils::QuerySql(mediaLibraryRdb_, querySql.str(), params);
283 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, existingFileIds, "Query resultSql is null.");
284 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
285 int32_t fileId = GetInt32Val("file_id", resultSet);
286 existingFileIds.insert(fileId);
287 }
288 resultSet->Close();
289 return existingFileIds;
290 }
291
RemoveDuplicateClassifyInfos(std::vector<ClassifyCloneInfo> & infos,const std::unordered_set<int32_t> & existingFileIds)292 void CloneRestoreClassify::RemoveDuplicateClassifyInfos(std::vector<ClassifyCloneInfo> &infos,
293 const std::unordered_set<int32_t> &existingFileIds)
294 {
295 infos.erase(std::remove_if(infos.begin(), infos.end(), [&](ClassifyCloneInfo &info) {
296 if (!info.fileIdOld.has_value()) {
297 return true;
298 }
299
300 size_t index = cloneRestoreAnalysisTotal_.FindIndexByFileIdOld(info.fileIdOld.value());
301 if (index == std::string::npos) {
302 return true;
303 }
304
305 int32_t fileIdNew = cloneRestoreAnalysisTotal_.GetFileIdNewByIndex(index);
306 info.fileIdNew = fileIdNew;
307 if (existingFileIds.count(fileIdNew) == 0) {
308 return false;
309 }
310 cloneRestoreAnalysisTotal_.UpdateRestoreStatusAsDuplicateByIndex(index);
311 duplicateLabelCnt_++;
312 return true;
313 }),
314 infos.end());
315 }
316
RemoveDuplicateClassifyVideoInfos(std::vector<ClassifyVideoCloneInfo> & infos,const std::unordered_set<int32_t> & existingFileIds)317 void CloneRestoreClassify::RemoveDuplicateClassifyVideoInfos(std::vector<ClassifyVideoCloneInfo> &infos,
318 const std::unordered_set<int32_t> &existingFileIds)
319 {
320 infos.erase(std::remove_if(infos.begin(), infos.end(), [&](ClassifyVideoCloneInfo &info) {
321 if (!info.fileIdOld.has_value()) {
322 return true;
323 }
324
325 size_t index = cloneRestoreAnalysisTotal_.FindIndexByFileIdOld(info.fileIdOld.value());
326 if (index == std::string::npos) {
327 return true;
328 }
329
330 int32_t fileIdNew = cloneRestoreAnalysisTotal_.GetFileIdNewByIndex(index);
331 info.fileIdNew = fileIdNew;
332 if (existingFileIds.count(fileIdNew) == 0) {
333 return false;
334 }
335 cloneRestoreAnalysisTotal_.UpdateRestoreStatusAsDuplicateByIndex(index);
336 duplicateVideoLabelCnt_++;
337 return true;
338 }),
339 infos.end());
340 }
341
InsertClassifyAlbums(std::vector<ClassifyCloneInfo> & classifyInfos)342 void CloneRestoreClassify::InsertClassifyAlbums(std::vector<ClassifyCloneInfo> &classifyInfos)
343 {
344 DeduplicateClassifyInfos(classifyInfos);
345 CHECK_AND_RETURN(!classifyInfos.empty());
346
347 std::unordered_set<std::string> intersection = GetCommonColumns(ANALYSIS_LABEL_TABLE);
348 size_t offset = 0;
349 do {
350 std::vector<NativeRdb::ValuesBucket> values;
351 for (size_t index = 0; index < PAGE_SIZE && index + offset < classifyInfos.size(); index++) {
352 CHECK_AND_CONTINUE(classifyInfos[index + offset].fileIdNew.has_value());
353 NativeRdb::ValuesBucket value;
354 GetMapInsertValue(value, classifyInfos[index + offset], intersection);
355 values.emplace_back(value);
356 }
357 MEDIA_INFO_LOG("Insert classify albums, values size: %{public}zu", values.size());
358 int64_t rowNum = 0;
359 int32_t errCode = BatchInsertWithRetry(ANALYSIS_LABEL_TABLE, values, rowNum);
360 if (errCode != E_OK || rowNum != static_cast<int64_t>(values.size())) {
361 int64_t failNums = static_cast<int64_t>(values.size()) - rowNum;
362 MEDIA_ERR_LOG("Insert classify albums fail, num: %{public}" PRId64, failNums);
363 ErrorInfo errorInfo(RestoreError::INSERT_FAILED, static_cast<int32_t>(values.size()),
364 "errCode: " + std::to_string(errCode), "Insert classify albums fail");
365 UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
366 cloneRestoreAnalysisTotal_.UpdateRestoreStatusAsFailed();
367 failInsertLabelCnt_ += failNums;
368 }
369 offset += PAGE_SIZE;
370 successInsertLabelCnt_ += rowNum;
371 } while (offset < classifyInfos.size());
372 }
373
InsertClassifyVideoAlbums(std::vector<ClassifyVideoCloneInfo> & classifyVideoInfos)374 void CloneRestoreClassify::InsertClassifyVideoAlbums(std::vector<ClassifyVideoCloneInfo> &classifyVideoInfos)
375 {
376 DeduplicateClassifyVideoInfos(classifyVideoInfos);
377 CHECK_AND_RETURN(!classifyVideoInfos.empty());
378
379 std::unordered_set<std::string> intersection = GetCommonColumns(ANALYSIS_VIDEO_TABLE);
380 size_t offset = 0;
381 do {
382 std::vector<NativeRdb::ValuesBucket> values;
383 for (size_t index = 0; index < PAGE_SIZE && index + offset < classifyVideoInfos.size(); index++) {
384 CHECK_AND_CONTINUE(classifyVideoInfos[index + offset].fileIdNew.has_value());
385 NativeRdb::ValuesBucket value;
386 GetVideoMapInsertValue(value, classifyVideoInfos[index + offset], intersection);
387 values.emplace_back(value);
388 }
389 MEDIA_INFO_LOG("Insert classify video albums, values size: %{public}zu", values.size());
390 int64_t rowNum = 0;
391 int32_t errCode = BatchInsertWithRetry(ANALYSIS_VIDEO_TABLE, values, rowNum);
392 if (errCode != E_OK || rowNum != static_cast<int64_t>(values.size())) {
393 int64_t failNums = static_cast<int64_t>(values.size()) - rowNum;
394 MEDIA_ERR_LOG("Insert classify video albums fail, num: %{public}" PRId64, failNums);
395 ErrorInfo errorInfo(RestoreError::INSERT_FAILED, static_cast<int32_t>(values.size()),
396 "errCode: " + std::to_string(errCode), "Insert classify video albums fail");
397 UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
398 cloneRestoreAnalysisTotal_.UpdateRestoreStatusAsFailed();
399 failInsertVideoLabelCnt_ += failNums;
400 }
401 offset += PAGE_SIZE;
402 successInsertVideoLabelCnt_ += rowNum;
403 } while (offset < classifyVideoInfos.size());
404 }
405
GetClassifyInfo(ClassifyCloneInfo & info,std::shared_ptr<NativeRdb::ResultSet> resultSet)406 void CloneRestoreClassify::GetClassifyInfo(ClassifyCloneInfo &info,
407 std::shared_ptr<NativeRdb::ResultSet> resultSet)
408 {
409 info.id = BackupDatabaseUtils::GetOptionalValue<int32_t>(resultSet, ID);
410 info.fileIdOld = BackupDatabaseUtils::GetOptionalValue<int32_t>(resultSet, FILE_ID);
411 info.categoryId = BackupDatabaseUtils::GetOptionalValue<int32_t>(resultSet, CATEGORY_ID);
412 info.subLabel = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SUB_LABEL);
413 info.prob = BackupDatabaseUtils::GetOptionalValue<double>(resultSet, PROB);
414 info.feature = BackupDatabaseUtils::GetOptionalValue<std::vector<uint8_t>>(resultSet, FEATURE);
415 info.simResult = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SIM_RESULT);
416 info.labelVersion = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, LABEL_VERSION);
417 info.saliencySubProb = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SALIENCY_SUB_PROB);
418 info.analysisVersion = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, ANALYSIS_VERSION);
419 info.captionResult = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, CAPTION_RESULT);
420 info.captionVersion = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, CAPTION_VERSION);
421 }
422
GetMapInsertValue(NativeRdb::ValuesBucket & value,ClassifyCloneInfo info,const std::unordered_set<std::string> & intersection)423 void CloneRestoreClassify::GetMapInsertValue(NativeRdb::ValuesBucket &value, ClassifyCloneInfo info,
424 const std::unordered_set<std::string> &intersection)
425 {
426 PutIfInIntersection(value, FILE_ID, info.fileIdNew, intersection);
427 PutIfInIntersection(value, CATEGORY_ID, info.categoryId, intersection);
428 PutIfInIntersection(value, SUB_LABEL, info.subLabel, intersection);
429 PutIfInIntersection(value, PROB, info.prob, intersection);
430 PutIfInIntersection(value, FEATURE, info.feature, intersection);
431 PutIfInIntersection(value, SIM_RESULT, info.simResult, intersection);
432 PutIfInIntersection(value, LABEL_VERSION, info.labelVersion, intersection);
433 PutIfInIntersection(value, SALIENCY_SUB_PROB, info.saliencySubProb, intersection);
434 PutIfInIntersection(value, ANALYSIS_VERSION, info.analysisVersion, intersection);
435 PutIfInIntersection(value, CAPTION_RESULT, info.captionResult, intersection);
436 PutIfInIntersection(value, CAPTION_VERSION, info.captionVersion, intersection);
437 }
438
GetClassifyVideoInfo(ClassifyVideoCloneInfo & info,std::shared_ptr<NativeRdb::ResultSet> resultSet)439 void CloneRestoreClassify::GetClassifyVideoInfo(ClassifyVideoCloneInfo &info,
440 std::shared_ptr<NativeRdb::ResultSet> resultSet)
441 {
442 info.id = BackupDatabaseUtils::GetOptionalValue<int32_t>(resultSet, ID);
443 info.fileIdOld = BackupDatabaseUtils::GetOptionalValue<int32_t>(resultSet, FILE_ID);
444 info.categoryId = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, CATEGORY_ID);
445 info.confidenceProbability = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, CONFIDENCE_PROBABILITY);
446 info.subCategory = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SUB_CATEGORY);
447 info.subConfidenceProb = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SUB_CONFIDENCE_PROB);
448 info.subLabel = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SUB_LABEL);
449 info.subLabelProb = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SUB_LABEL_PROB);
450 info.subLabelType = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SUB_LABEL_TYPE);
451 info.tracks = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, TRACKS);
452 info.videoPartFeature = BackupDatabaseUtils::GetOptionalValue<std::vector<uint8_t>>(resultSet, VIDEO_PART_FEATURE);
453 info.filterTag = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, FILTER_TAG);
454 info.algoVersion = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, ALGO_VERSION);
455 info.analysisVersion = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, ANALYSIS_VERSION);
456 info.triggerGenerateThumbnail = BackupDatabaseUtils::GetOptionalValue<int32_t>(resultSet,
457 TRIGGER_GENERATE_THUMBNAIL);
458 }
459
GetVideoMapInsertValue(NativeRdb::ValuesBucket & value,ClassifyVideoCloneInfo info,const std::unordered_set<std::string> & intersection)460 void CloneRestoreClassify::GetVideoMapInsertValue(NativeRdb::ValuesBucket &value, ClassifyVideoCloneInfo info,
461 const std::unordered_set<std::string> &intersection)
462 {
463 PutIfInIntersection(value, FILE_ID, info.fileIdNew, intersection);
464 PutIfInIntersection(value, CATEGORY_ID, info.categoryId, intersection);
465 PutIfInIntersection(value, CONFIDENCE_PROBABILITY, info.confidenceProbability, intersection);
466 PutIfInIntersection(value, SUB_CATEGORY, info.subCategory, intersection);
467 PutIfInIntersection(value, SUB_CONFIDENCE_PROB, info.subConfidenceProb, intersection);
468 PutIfInIntersection(value, SUB_LABEL, info.subLabel, intersection);
469 PutIfInIntersection(value, SUB_LABEL_PROB, info.subLabelProb, intersection);
470 PutIfInIntersection(value, SUB_LABEL_TYPE, info.subLabelType, intersection);
471 PutIfInIntersection(value, TRACKS, info.tracks, intersection);
472 PutIfInIntersection(value, VIDEO_PART_FEATURE, info.videoPartFeature, intersection);
473 PutIfInIntersection(value, FILTER_TAG, info.filterTag, intersection);
474 PutIfInIntersection(value, ALGO_VERSION, info.algoVersion, intersection);
475 PutIfInIntersection(value, ANALYSIS_VERSION, info.analysisVersion, intersection);
476 PutIfInIntersection(value, TRIGGER_GENERATE_THUMBNAIL, info.triggerGenerateThumbnail, intersection);
477 }
478
CheckTableColumns(const std::string & tableName,std::unordered_map<std::string,std::string> & columns)479 bool CloneRestoreClassify::CheckTableColumns(const std::string& tableName,
480 std::unordered_map<std::string, std::string>& columns)
481 {
482 std::unordered_map<std::string, std::string> srcColumnInfoMap =
483 BackupDatabaseUtils::GetColumnInfoMap(mediaRdb_, tableName);
484 for (auto it = columns.begin(); it != columns.end(); ++it) {
485 CHECK_AND_CONTINUE(srcColumnInfoMap.find(it->first) == srcColumnInfoMap.end());
486 return false;
487 }
488 return true;
489 }
490
GetCommonColumns(const string & tableName)491 std::unordered_set<std::string> CloneRestoreClassify::GetCommonColumns(const string &tableName)
492 {
493 std::unordered_map<std::string, std::string> srcColumnInfoMap =
494 BackupDatabaseUtils::GetColumnInfoMap(mediaRdb_, tableName);
495 std::unordered_map<std::string, std::string> dstColumnInfoMap =
496 BackupDatabaseUtils::GetColumnInfoMap(mediaLibraryRdb_, tableName);
497 std::unordered_set<std::string> result;
498 auto comparedColumns = GetValueFromMap(COMPARED_COLUMNS_MAP, tableName);
499 for (auto it = dstColumnInfoMap.begin(); it != dstColumnInfoMap.end(); ++it) {
500 bool cond = srcColumnInfoMap.find(it->first) != srcColumnInfoMap.end() && comparedColumns.count(it->first) > 0;
501 CHECK_AND_EXECUTE(!cond, result.insert(it->first));
502 }
503 return result;
504 }
505
BatchInsertWithRetry(const std::string & tableName,std::vector<NativeRdb::ValuesBucket> & values,int64_t & rowNum)506 int32_t CloneRestoreClassify::BatchInsertWithRetry(const std::string &tableName,
507 std::vector<NativeRdb::ValuesBucket> &values, int64_t &rowNum)
508 {
509 CHECK_AND_RETURN_RET(!values.empty(), E_OK);
510 int32_t errCode = E_ERR;
511 TransactionOperations trans{ __func__ };
512 trans.SetBackupRdbStore(mediaLibraryRdb_);
513 std::function<int(void)> func = [&]()->int {
514 errCode = trans.BatchInsert(rowNum, tableName, values);
515 CHECK_AND_PRINT_LOG(errCode == E_OK, "InsertSql failed, errCode: %{public}d, rowNum: %{public}ld.",
516 errCode, (long)rowNum);
517 return errCode;
518 };
519 errCode = trans.RetryTrans(func, true);
520 CHECK_AND_PRINT_LOG(errCode == E_OK, "BatchInsertWithRetry: tans finish fail!, ret:%{public}d", errCode);
521 return errCode;
522 }
523
ReportRestoreTask()524 void CloneRestoreClassify::ReportRestoreTask()
525 {
526 ReportRestoreTaskOfTotal();
527 ReportRestoreTaskofImage();
528 ReportRestoreTaskofVideo();
529 }
530
ReportRestoreTaskOfTotal()531 void CloneRestoreClassify::ReportRestoreTaskOfTotal()
532 {
533 RestoreTaskInfo info;
534 cloneRestoreAnalysisTotal_.SetRestoreTaskInfo(info);
535 info.type = "CLONE_RESTORE_CLASSIFY_TOTAL";
536 info.errorCode = std::to_string(CLASSIFY_STATUS_SUCCESS);
537 info.errorInfo = "timeCost: " + std::to_string(restoreTimeCost_);
538 UpgradeRestoreTaskReport().SetSceneCode(sceneCode_).SetTaskId(taskId_).Report(info);
539 }
540
ReportRestoreTaskofImage()541 void CloneRestoreClassify::ReportRestoreTaskofImage()
542 {
543 RestoreTaskInfo info;
544 info.type = "CLONE_RESTORE_CLASSIFY_IMAGE";
545 info.errorCode = std::to_string(CLASSIFY_STATUS_SUCCESS);
546 info.errorInfo =
547 "max_id: " + std::to_string(maxIdOfLabel_) +
548 ", timeCost: " + std::to_string(restoreLabelTimeCost_);
549 info.successCount = successInsertLabelCnt_;
550 info.failedCount = failInsertLabelCnt_;
551 info.duplicateCount = duplicateLabelCnt_;
552 UpgradeRestoreTaskReport().SetSceneCode(sceneCode_).SetTaskId(taskId_).Report(info);
553 }
554
ReportRestoreTaskofVideo()555 void CloneRestoreClassify::ReportRestoreTaskofVideo()
556 {
557 RestoreTaskInfo info;
558 info.type = "CLONE_RESTORE_CLASSIFY_VIDEO";
559 info.errorCode = std::to_string(CLASSIFY_STATUS_SUCCESS);
560 info.errorInfo =
561 "max_id: " + std::to_string(maxIdOfVideoLabel_) +
562 ", timeCost: " + std::to_string(restoreVideoLabelTimeCost_);
563 info.successCount = successInsertVideoLabelCnt_;
564 info.failedCount = failInsertVideoLabelCnt_;
565 info.duplicateCount = duplicateVideoLabelCnt_;
566 UpgradeRestoreTaskReport().SetSceneCode(sceneCode_).SetTaskId(taskId_).Report(info);
567 }
568
AddSpecialAlbum()569 void CloneRestoreClassify::AddSpecialAlbum()
570 {
571 MEDIA_INFO_LOG("AddSpecialAlbum start");
572 int64_t startTime = MediaFileUtils::UTCTimeMilliSeconds();
573 AddSelfieAlbum();
574 AddUserCommentAlbum();
575 int64_t endTime = MediaFileUtils::UTCTimeMilliSeconds();
576 MEDIA_INFO_LOG("AddSpecialAlbum end, cost: %{public}" PRId64,
577 endTime - startTime);
578 }
579
AddSelfieAlbum()580 void CloneRestoreClassify::AddSelfieAlbum()
581 {
582 CHECK_AND_RETURN_LOG(mediaLibraryRdb_ != nullptr, "AddSelfieAlbum failed, rdbStore is nullptr");
583 std::string selfieAlbum = std::to_string(static_cast<int32_t>(AggregateType::SELFIE_ALBUM));
584 DataTransfer::MediaLibraryDbUpgrade medialibraryDbUpgrade;
585 bool isExist = medialibraryDbUpgrade.CheckClassifyAlbumExist(selfieAlbum, *this->mediaLibraryRdb_);
586 CHECK_AND_RETURN_INFO_LOG(!isExist, "SelfieAlbum already exist.");
587 std::string querySql = "SELECT count(1) AS count FROM Photos WHERE front_camera = ?;";
588 std::vector<NativeRdb::ValueObject> params;
589 params.push_back(FRONT_CAMERA);
590 auto resultSet = mediaLibraryRdb_->QuerySql(querySql, params);
591 CHECK_AND_RETURN_LOG(resultSet != nullptr, "resultSet is nullptr");
592 if (resultSet->GoToNextRow() == NativeRdb::E_OK && GetInt32Val("count", resultSet) > 0) {
593 resultSet->Close();
594 int32_t ret = medialibraryDbUpgrade.CreateClassifyAlbum(selfieAlbum, *this->mediaLibraryRdb_);
595 CHECK_AND_RETURN_LOG(ret == NativeRdb::E_OK, "AddSelfieAlbum failed");
596 MEDIA_INFO_LOG("AddSelfieAlbum success");
597 return;
598 }
599 resultSet->Close();
600 MEDIA_INFO_LOG("not meet the criteria for AddSelfieAlbum");
601 }
602
AddUserCommentAlbum()603 void CloneRestoreClassify::AddUserCommentAlbum()
604 {
605 CHECK_AND_RETURN_LOG(mediaLibraryRdb_ != nullptr, "AddUserCommentAlbum failed, rdbStore is nullptr");
606 std::string userCommentAlbum = std::to_string(static_cast<int32_t>(AggregateType::USER_COMMENT_ALBUM));
607 DataTransfer::MediaLibraryDbUpgrade medialibraryDbUpgrade;
608 bool isExist = medialibraryDbUpgrade.CheckClassifyAlbumExist(userCommentAlbum, *this->mediaLibraryRdb_);
609 CHECK_AND_RETURN_INFO_LOG(!isExist, "UserCommentAlbum already exist.");
610 std::string querySql = "SELECT count(1) AS count FROM Photos "
611 "WHERE user_comment IS NOT NULL AND user_comment != '';";
612 auto resultSet = mediaLibraryRdb_->QuerySql(querySql);
613 CHECK_AND_RETURN_LOG(resultSet != nullptr, "resultSet is nullptr");
614 if (resultSet->GoToNextRow() == NativeRdb::E_OK && GetInt32Val("count", resultSet) > 0) {
615 resultSet->Close();
616 int32_t ret = medialibraryDbUpgrade.CreateClassifyAlbum(userCommentAlbum, *this->mediaLibraryRdb_);
617 CHECK_AND_RETURN_LOG(ret == NativeRdb::E_OK, "AddUserCommentAlbum failed");
618 MEDIA_INFO_LOG("AddUserCommentAlbum success");
619 return;
620 }
621 resultSet->Close();
622 MEDIA_INFO_LOG("not meet the criteria for AddUserCommentAlbum");
623 }
624 }