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_classify.h"
16
17 #include "backup_database_utils.h"
18 #include "medialibrary_data_manager_utils.h"
19 #include "medialibrary_unistore_manager.h"
20 #include "media_file_utils.h"
21 #include "media_log.h"
22 #include "result_set_utils.h"
23 #include "upgrade_restore_task_report.h"
24
25 namespace OHOS::Media {
26 const int32_t PAGE_SIZE = 200;
27
28 const string ID = "id";
29 const string FILE_ID = "file_id";
30 const string CATEGORY_ID = "category_id";
31 const string SUB_LABEL = "sub_label";
32 const string PROB = "prob";
33 const string FEATURE = "feature";
34 const string SIM_RESULT = "sim_result";
35 const string LABEL_VERSION = "label_version";
36 const string SALIENCY_SUB_PROB = "saliency_sub_prob";
37 const string ANALYSIS_VERSION = "analysis_version";
38
39 const string CONFIDENCE_PROBABILITY = "confidence_probability";
40 const string SUB_CATEGORY = "sub_category";
41 const string SUB_CONFIDENCE_PROB = "sub_confidence_prob";
42 const string SUB_LABEL_PROB = "sub_label_prob";
43 const string SUB_LABEL_TYPE = "sub_label_type";
44 const string TRACKS = "tracks";
45 const string VIDEO_PART_FEATURE = "video_part_feature";
46 const string FILTER_TAG = "filter_tag";
47 const string ALGO_VERSION = "algo_version";
48 const string TRIGGER_GENERATE_THUMBNAIL = "trigger_generate_thumbnail";
49
50 const string ANALYSIS_LABEL_TABLE = "tab_analysis_label";
51 const string ANALYSIS_VIDEO_TABLE = "tab_analysis_video_label";
52 const string FIELD_TYPE_INT = "INT";
53 const string FIELD_NAME_DATA = "data";
54
55 const int32_t CLASSIFY_STATUS_SUCCESS = 1;
56 const int32_t CLASSIFY_TYPE = 4097;
57
58 const unordered_map<string, unordered_set<string>> COMPARED_COLUMNS_MAP = {
59 { "tab_analysis_label",
60 {
61 "id",
62 "file_id",
63 "category_id",
64 "sub_label",
65 "prob",
66 "feature",
67 "sim_result",
68 "label_version",
69 "saliency_sub_prob",
70 "analysis_version",
71 }
72 },
73 { "tab_analysis_video_label",
74 {
75 "id",
76 "file_id",
77 "category_id",
78 "confidence_probability",
79 "sub_category",
80 "sub_confidence_prob",
81 "sub_label",
82 "sub_label_prob",
83 "sub_label_type",
84 "tracks",
85 "video_part_feature",
86 "filter_tag",
87 "algo_version",
88 "analysis_version",
89 "trigger_generate_thumbnail",
90 }
91 }
92 };
93
94 template<typename Key, typename Value>
GetValueFromMap(const unordered_map<Key,Value> & map,const Key & key,const Value & defaultValue=Value ())95 Value GetValueFromMap(const unordered_map<Key, Value> &map, const Key &key, const Value &defaultValue = Value())
96 {
97 auto it = map.find(key);
98 CHECK_AND_RETURN_RET(it == map.end(), it->second);
99 return defaultValue;
100 }
101
Init(int32_t sceneCode,const std::string & taskId,std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb,std::shared_ptr<NativeRdb::RdbStore> mediaRdb)102 void CloneRestoreClassify::Init(int32_t sceneCode, const std::string &taskId,
103 std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb, std::shared_ptr<NativeRdb::RdbStore> mediaRdb)
104 {
105 sceneCode_ = sceneCode;
106 taskId_ = taskId;
107 mediaLibraryRdb_ = mediaLibraryRdb;
108 mediaRdb_ = mediaRdb;
109 successInsertLabelCnt_ = 0;
110 successInsertVideoLabelCnt_ = 0;
111 failInsertLabelCnt_ = 0;
112 failInsertVideoLabelCnt_ = 0;
113 }
114
RestoreMaps(std::vector<FileInfo> & fileInfos)115 void CloneRestoreClassify::RestoreMaps(std::vector<FileInfo> &fileInfos)
116 {
117 bool cond = (mediaRdb_ == nullptr || mediaLibraryRdb_ == nullptr);
118 CHECK_AND_RETURN_LOG(!cond, "rdbStore is nullptr");
119
120 MEDIA_INFO_LOG("restore classify albums start.");
121 for (size_t offset = 0; offset < fileInfos.size(); offset += PAGE_SIZE) {
122 std::vector<ClassifyCloneInfo> classifyInfos;
123 GetClassifyInfos(classifyInfos, fileInfos, offset);
124 InsertClassifyAlbums(classifyInfos, fileInfos);
125 }
126 MEDIA_INFO_LOG("restore classify albums end.");
127 }
128
RestoreVideoMaps(std::vector<FileInfo> & fileInfos)129 void CloneRestoreClassify::RestoreVideoMaps(std::vector<FileInfo> &fileInfos)
130 {
131 bool cond = (mediaRdb_ == nullptr || mediaLibraryRdb_ == nullptr);
132 CHECK_AND_RETURN_LOG(!cond, "rdbStore is nullptr");
133
134 MEDIA_INFO_LOG("restore classify video albums start.");
135 for (size_t offset = 0; offset < fileInfos.size(); offset += PAGE_SIZE) {
136 std::vector<ClassifyVideoCloneInfo> classifyVideoInfos;
137 GetClassifyVideoInfos(classifyVideoInfos, fileInfos, offset);
138 InsertClassifyVideoAlbums(classifyVideoInfos, fileInfos);
139 }
140 MEDIA_INFO_LOG("restore classify video albums end.");
141 }
142
GetClassifyInfos(std::vector<ClassifyCloneInfo> & classifyInfo,std::vector<FileInfo> & fileInfos,int32_t offset)143 void CloneRestoreClassify::GetClassifyInfos(std::vector<ClassifyCloneInfo> &classifyInfo,
144 std::vector<FileInfo> &fileInfos, int32_t offset)
145 {
146 std::unordered_map<std::string, std::string> columns;
147 columns[FILE_ID] = FIELD_TYPE_INT;
148 bool hasRequiredColumns = CheckTableColumns(ANALYSIS_LABEL_TABLE, columns);
149 if (!hasRequiredColumns) {
150 MEDIA_ERR_LOG("The tab_analysis_label does not contain the required columns.");
151 ErrorInfo errorInfo(RestoreError::TABLE_LACK_OF_COLUMN, static_cast<int32_t>(columns.size()),
152 "", "The tab_analysis_label does not contain id or file_id");
153 UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
154 return;
155 }
156 int32_t count = 0;
157 std::stringstream querySql;
158 querySql << "SELECT * FROM " + ANALYSIS_LABEL_TABLE + " WHERE " + FILE_ID + " IN (";
159 std::vector<NativeRdb::ValueObject> params;
160 for (size_t index = 0; index < PAGE_SIZE && index + offset < fileInfos.size(); index++) {
161 auto fileInfo = fileInfos[index + offset];
162 if (fileInfo.fileIdOld > 0) {
163 querySql << (count++ > 0 ? "," : "");
164 querySql << "?";
165 params.emplace_back(fileInfo.fileIdOld);
166 }
167 }
168 querySql << ")";
169
170 auto resultSet = BackupDatabaseUtils::QuerySql(mediaRdb_, querySql.str(), params);
171 CHECK_AND_RETURN_LOG(resultSet != nullptr, "Query resultSql is null.");
172 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
173 ClassifyCloneInfo info;
174 GetClassifyInfo(info, resultSet);
175 classifyInfo.emplace_back(info);
176 }
177 resultSet->Close();
178 MEDIA_INFO_LOG("query tab_analysis_label nums: %{public}zu", classifyInfo.size());
179 }
180
GetClassifyVideoInfos(std::vector<ClassifyVideoCloneInfo> & classifyVideoInfo,std::vector<FileInfo> & fileInfos,int32_t offset)181 void CloneRestoreClassify::GetClassifyVideoInfos(std::vector<ClassifyVideoCloneInfo> &classifyVideoInfo,
182 std::vector<FileInfo> &fileInfos, int32_t offset)
183 {
184 std::unordered_map<std::string, std::string> columns;
185 columns[FILE_ID] = FIELD_TYPE_INT;
186 bool hasRequiredColumns = CheckTableColumns(ANALYSIS_VIDEO_TABLE, columns);
187 if (!hasRequiredColumns) {
188 MEDIA_ERR_LOG("The tab_analysis_video_label does not contain the required columns.");
189 ErrorInfo errorInfo(RestoreError::TABLE_LACK_OF_COLUMN, static_cast<int32_t>(columns.size()),
190 "", "The tab_analysis_video_label does not contain file_id");
191 UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
192 return;
193 }
194 int32_t count = 0;
195 std::stringstream querySql;
196 querySql << "SELECT * FROM " + ANALYSIS_VIDEO_TABLE + " WHERE " + FILE_ID + " IN (";
197 std::vector<NativeRdb::ValueObject> params;
198 for (size_t index = 0; index < PAGE_SIZE && index + offset < fileInfos.size(); index++) {
199 auto fileInfo = fileInfos[index + offset];
200 if (fileInfo.fileIdOld > 0) {
201 querySql << (count++ > 0 ? "," : "");
202 querySql << "?";
203 params.emplace_back(fileInfo.fileIdOld);
204 }
205 }
206 querySql << ")";
207
208 auto resultSet = BackupDatabaseUtils::QuerySql(mediaRdb_, querySql.str(), params);
209 CHECK_AND_RETURN_LOG(resultSet != nullptr, "Query resultSql is null.");
210 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
211 ClassifyVideoCloneInfo info;
212 GetClassifyVideoInfo(info, resultSet);
213 classifyVideoInfo.emplace_back(info);
214 }
215 resultSet->Close();
216 MEDIA_INFO_LOG("query tab_analysis_video_label nums: %{public}zu", classifyVideoInfo.size());
217 }
218
DeduplicateClassifyInfos(std::vector<ClassifyCloneInfo> & classifyInfos,std::vector<FileInfo> & fileInfos)219 void CloneRestoreClassify::DeduplicateClassifyInfos(std::vector<ClassifyCloneInfo> &classifyInfos,
220 std::vector<FileInfo> &fileInfos)
221 {
222 for (auto &classifyInfo : classifyInfos) {
223 auto it = std::find_if(fileInfos.begin(), fileInfos.end(),
224 [classifyInfo](const FileInfo &fileInfo) {
225 return classifyInfo.fileIdOld == fileInfo.fileIdOld;
226 });
227 if (it != fileInfos.end()) {
228 classifyInfo.fileIdNew = it->fileIdNew;
229 }
230 }
231 auto itr = classifyInfos.begin();
232 while (itr != classifyInfos.end()) {
233 if (!itr->fileIdNew.has_value()) {
234 ++itr;
235 continue;
236 }
237 std::vector<NativeRdb::ValueObject> params { itr->fileIdNew.value() };
238 const std::string querySql = "SELECT * FROM " + ANALYSIS_LABEL_TABLE + " WHERE " + FILE_ID + " = ?";
239 auto resultSet = BackupDatabaseUtils::QuerySql(mediaLibraryRdb_, querySql, params);
240 if (resultSet == nullptr) {
241 MEDIA_ERR_LOG("Query resultSql is null.");
242 break;
243 }
244 if (resultSet->GoToNextRow() == NativeRdb::E_OK) {
245 itr = classifyInfos.erase(itr);
246 } else {
247 ++itr;
248 }
249 resultSet->Close();
250 }
251 }
252
DeduplicateClassifyVideoInfos(std::vector<ClassifyVideoCloneInfo> & classifyVideoInfos,std::vector<FileInfo> & fileInfos)253 void CloneRestoreClassify::DeduplicateClassifyVideoInfos(std::vector<ClassifyVideoCloneInfo> &classifyVideoInfos,
254 std::vector<FileInfo> &fileInfos)
255 {
256 for (auto &classifyVideoInfo : classifyVideoInfos) {
257 auto it = std::find_if(fileInfos.begin(), fileInfos.end(),
258 [classifyVideoInfo](const FileInfo &fileInfo) {
259 return classifyVideoInfo.fileIdOld == fileInfo.fileIdOld;
260 });
261 if (it != fileInfos.end()) {
262 classifyVideoInfo.fileIdNew = it->fileIdNew;
263 }
264 }
265 auto itr = classifyVideoInfos.begin();
266 while (itr != classifyVideoInfos.end()) {
267 if (!itr->fileIdNew.has_value()) {
268 ++itr;
269 continue;
270 }
271 std::vector<NativeRdb::ValueObject> params { itr->fileIdNew.value() };
272 const std::string querySql = "SELECT * FROM " + ANALYSIS_VIDEO_TABLE + " WHERE " + FILE_ID + " = ?";
273 auto resultSet = BackupDatabaseUtils::QuerySql(mediaLibraryRdb_, querySql, params);
274 if (resultSet == nullptr) {
275 MEDIA_ERR_LOG("Query resultSql is null.");
276 break;
277 }
278 if (resultSet->GoToNextRow() == NativeRdb::E_OK) {
279 itr = classifyVideoInfos.erase(itr);
280 } else {
281 ++itr;
282 }
283 resultSet->Close();
284 }
285 }
286
InsertClassifyAlbums(std::vector<ClassifyCloneInfo> & classifyInfos,std::vector<FileInfo> & fileInfos)287 void CloneRestoreClassify::InsertClassifyAlbums(std::vector<ClassifyCloneInfo> &classifyInfos,
288 std::vector<FileInfo> &fileInfos)
289 {
290 DeduplicateClassifyInfos(classifyInfos, fileInfos);
291 std::unordered_set<std::string> intersection = GetCommonColumns(ANALYSIS_LABEL_TABLE);
292 size_t offset = 0;
293 do {
294 std::vector<NativeRdb::ValuesBucket> values;
295 for (size_t index = 0; index < PAGE_SIZE && index + offset < classifyInfos.size(); index++) {
296 if (!classifyInfos[index + offset].fileIdNew.has_value()) {
297 continue;
298 }
299 NativeRdb::ValuesBucket value;
300 GetMapInsertValue(value, classifyInfos[index + offset], intersection);
301 values.emplace_back(value);
302 }
303 MEDIA_INFO_LOG("Insert classify albums, values size: %{public}zu", values.size());
304 int64_t rowNum = 0;
305 int32_t errCode = BatchInsertWithRetry(ANALYSIS_LABEL_TABLE, values, rowNum);
306 if (errCode != E_OK || rowNum != static_cast<int64_t>(values.size())) {
307 int64_t failNums = static_cast<int64_t>(values.size()) - rowNum;
308 MEDIA_ERR_LOG("Insert classify albums fail, num: %{public}" PRId64, failNums);
309 ErrorInfo errorInfo(RestoreError::INSERT_FAILED, static_cast<int32_t>(values.size()),
310 "errCode: " + std::to_string(errCode), "Insert classify albums fail");
311 UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
312 failInsertLabelCnt_ += failNums;
313 }
314 offset += PAGE_SIZE;
315 successInsertLabelCnt_ += rowNum;
316 } while (offset < classifyInfos.size());
317 }
318
InsertClassifyVideoAlbums(std::vector<ClassifyVideoCloneInfo> & classifyVideoInfos,std::vector<FileInfo> & fileInfos)319 void CloneRestoreClassify::InsertClassifyVideoAlbums(std::vector<ClassifyVideoCloneInfo> &classifyVideoInfos,
320 std::vector<FileInfo> &fileInfos)
321 {
322 DeduplicateClassifyVideoInfos(classifyVideoInfos, fileInfos);
323 std::unordered_set<std::string> intersection = GetCommonColumns(ANALYSIS_VIDEO_TABLE);
324 size_t offset = 0;
325 do {
326 std::vector<NativeRdb::ValuesBucket> values;
327 for (size_t index = 0; index < PAGE_SIZE && index + offset < classifyVideoInfos.size(); index++) {
328 if (!classifyVideoInfos[index + offset].fileIdNew.has_value()) {
329 continue;
330 }
331 NativeRdb::ValuesBucket value;
332 GetVideoMapInsertValue(value, classifyVideoInfos[index + offset], intersection);
333 values.emplace_back(value);
334 }
335 MEDIA_INFO_LOG("Insert classify video albums, values size: %{public}zu", values.size());
336 int64_t rowNum = 0;
337 int32_t errCode = BatchInsertWithRetry(ANALYSIS_VIDEO_TABLE, values, rowNum);
338 if (errCode != E_OK || rowNum != static_cast<int64_t>(values.size())) {
339 int64_t failNums = static_cast<int64_t>(values.size()) - rowNum;
340 MEDIA_ERR_LOG("Insert classify video albums fail, num: %{public}" PRId64, failNums);
341 ErrorInfo errorInfo(RestoreError::INSERT_FAILED, static_cast<int32_t>(values.size()),
342 "errCode: " + std::to_string(errCode), "Insert classify video albums fail");
343 UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
344 failInsertVideoLabelCnt_ += failNums;
345 }
346 offset += PAGE_SIZE;
347 successInsertVideoLabelCnt_ += rowNum;
348 } while (offset < classifyVideoInfos.size());
349 }
350
GetClassifyInfo(ClassifyCloneInfo & info,std::shared_ptr<NativeRdb::ResultSet> resultSet)351 void CloneRestoreClassify::GetClassifyInfo(ClassifyCloneInfo &info,
352 std::shared_ptr<NativeRdb::ResultSet> resultSet)
353 {
354 info.id = BackupDatabaseUtils::GetOptionalValue<int64_t>(resultSet, ID);
355 info.fileIdOld = BackupDatabaseUtils::GetOptionalValue<int64_t>(resultSet, FILE_ID);
356 info.categoryId = BackupDatabaseUtils::GetOptionalValue<int64_t>(resultSet, CATEGORY_ID);
357 info.subLabel = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SUB_LABEL);
358 info.prob = BackupDatabaseUtils::GetOptionalValue<double>(resultSet, PROB);
359 info.feature = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, FEATURE);
360 info.simResult = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SIM_RESULT);
361 info.labelVersion = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, LABEL_VERSION);
362 info.saliencySubProb = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SALIENCY_SUB_PROB);
363 info.analysisVersion = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, ANALYSIS_VERSION);
364 }
365
GetMapInsertValue(NativeRdb::ValuesBucket & value,ClassifyCloneInfo info,const std::unordered_set<std::string> & intersection)366 void CloneRestoreClassify::GetMapInsertValue(NativeRdb::ValuesBucket &value, ClassifyCloneInfo info,
367 const std::unordered_set<std::string> &intersection)
368 {
369 PutIfInIntersection(value, FILE_ID, info.fileIdNew, intersection);
370 PutIfInIntersection(value, CATEGORY_ID, info.categoryId, intersection);
371 PutIfInIntersection(value, SUB_LABEL, info.subLabel, intersection);
372 PutIfInIntersection(value, PROB, info.prob, intersection);
373 PutIfInIntersection(value, FEATURE, info.feature, intersection);
374 PutIfInIntersection(value, SIM_RESULT, info.simResult, intersection);
375 PutIfInIntersection(value, LABEL_VERSION, info.labelVersion, intersection);
376 PutIfInIntersection(value, SALIENCY_SUB_PROB, info.saliencySubProb, intersection);
377 PutIfInIntersection(value, ANALYSIS_VERSION, info.analysisVersion, intersection);
378 }
379
GetClassifyVideoInfo(ClassifyVideoCloneInfo & info,std::shared_ptr<NativeRdb::ResultSet> resultSet)380 void CloneRestoreClassify::GetClassifyVideoInfo(ClassifyVideoCloneInfo &info,
381 std::shared_ptr<NativeRdb::ResultSet> resultSet)
382 {
383 info.id = BackupDatabaseUtils::GetOptionalValue<int64_t>(resultSet, ID);
384 info.fileIdOld = BackupDatabaseUtils::GetOptionalValue<int64_t>(resultSet, FILE_ID);
385 info.categoryId = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, CATEGORY_ID);
386 info.confidenceProbability = BackupDatabaseUtils::GetOptionalValue<double>(resultSet, CONFIDENCE_PROBABILITY);
387 info.subCategory = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SUB_CATEGORY);
388 info.subConfidenceProb = BackupDatabaseUtils::GetOptionalValue<double>(resultSet, SUB_CONFIDENCE_PROB);
389 info.subLabel = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, SUB_LABEL);
390 info.subLabelProb = BackupDatabaseUtils::GetOptionalValue<double>(resultSet, SUB_LABEL_PROB);
391 info.subLabelType = BackupDatabaseUtils::GetOptionalValue<int64_t>(resultSet, SUB_LABEL_TYPE);
392 info.tracks = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, TRACKS);
393 info.videoPartFeature = BackupDatabaseUtils::GetOptionalValue<std::vector<uint8_t>>(resultSet, VIDEO_PART_FEATURE);
394 info.filterTag = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, FILTER_TAG);
395 info.algoVersion = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, ALGO_VERSION);
396 info.analysisVersion = BackupDatabaseUtils::GetOptionalValue<std::string>(resultSet, ANALYSIS_VERSION);
397 info.triggerGenerateThumbnail = BackupDatabaseUtils::GetOptionalValue<int64_t>(resultSet,
398 TRIGGER_GENERATE_THUMBNAIL);
399 }
400
GetVideoMapInsertValue(NativeRdb::ValuesBucket & value,ClassifyVideoCloneInfo info,const std::unordered_set<std::string> & intersection)401 void CloneRestoreClassify::GetVideoMapInsertValue(NativeRdb::ValuesBucket &value, ClassifyVideoCloneInfo info,
402 const std::unordered_set<std::string> &intersection)
403 {
404 PutIfInIntersection(value, FILE_ID, info.fileIdNew, intersection);
405 PutIfInIntersection(value, CATEGORY_ID, info.categoryId, intersection);
406 PutIfInIntersection(value, CONFIDENCE_PROBABILITY, info.confidenceProbability, intersection);
407 PutIfInIntersection(value, SUB_CATEGORY, info.subCategory, intersection);
408 PutIfInIntersection(value, SUB_CONFIDENCE_PROB, info.subConfidenceProb, intersection);
409 PutIfInIntersection(value, SUB_LABEL, info.subLabel, intersection);
410 PutIfInIntersection(value, SUB_LABEL_PROB, info.subLabelProb, intersection);
411 PutIfInIntersection(value, SUB_LABEL_TYPE, info.subLabelType, intersection);
412 PutIfInIntersection(value, TRACKS, info.tracks, intersection);
413 PutIfInIntersection(value, VIDEO_PART_FEATURE, info.videoPartFeature, intersection);
414 PutIfInIntersection(value, FILTER_TAG, info.filterTag, intersection);
415 PutIfInIntersection(value, ALGO_VERSION, info.algoVersion, intersection);
416 PutIfInIntersection(value, ANALYSIS_VERSION, info.analysisVersion, intersection);
417 PutIfInIntersection(value, TRIGGER_GENERATE_THUMBNAIL, info.triggerGenerateThumbnail, intersection);
418 }
419
CheckTableColumns(const std::string & tableName,std::unordered_map<std::string,std::string> & columns)420 bool CloneRestoreClassify::CheckTableColumns(const std::string& tableName,
421 std::unordered_map<std::string, std::string>& columns)
422 {
423 std::unordered_map<std::string, std::string> srcColumnInfoMap =
424 BackupDatabaseUtils::GetColumnInfoMap(mediaRdb_, tableName);
425 for (auto it = columns.begin(); it != columns.end(); ++it) {
426 if (srcColumnInfoMap.find(it->first) != srcColumnInfoMap.end()) {
427 continue;
428 }
429 return false;
430 }
431 return true;
432 }
433
GetCommonColumns(const string & tableName)434 std::unordered_set<std::string> CloneRestoreClassify::GetCommonColumns(const string &tableName)
435 {
436 std::unordered_map<std::string, std::string> srcColumnInfoMap =
437 BackupDatabaseUtils::GetColumnInfoMap(mediaRdb_, tableName);
438 std::unordered_map<std::string, std::string> dstColumnInfoMap =
439 BackupDatabaseUtils::GetColumnInfoMap(mediaLibraryRdb_, tableName);
440 std::unordered_set<std::string> result;
441 auto comparedColumns = GetValueFromMap(COMPARED_COLUMNS_MAP, tableName);
442 for (auto it = dstColumnInfoMap.begin(); it != dstColumnInfoMap.end(); ++it) {
443 if (srcColumnInfoMap.find(it->first) != srcColumnInfoMap.end() && comparedColumns.count(it->first) > 0) {
444 result.insert(it->first);
445 }
446 }
447 return result;
448 }
449
BatchInsertWithRetry(const std::string & tableName,std::vector<NativeRdb::ValuesBucket> & values,int64_t & rowNum)450 int32_t CloneRestoreClassify::BatchInsertWithRetry(const std::string &tableName,
451 std::vector<NativeRdb::ValuesBucket> &values, int64_t &rowNum)
452 {
453 CHECK_AND_RETURN_RET(!values.empty(), E_OK);
454 int32_t errCode = E_ERR;
455 TransactionOperations trans{ __func__ };
456 trans.SetBackupRdbStore(mediaLibraryRdb_);
457 std::function<int(void)> func = [&]()->int {
458 errCode = trans.BatchInsert(rowNum, tableName, values);
459 CHECK_AND_PRINT_LOG(errCode == E_OK, "InsertSql failed, errCode: %{public}d, rowNum: %{public}ld.",
460 errCode, (long)rowNum);
461 return errCode;
462 };
463 errCode = trans.RetryTrans(func, true);
464 CHECK_AND_PRINT_LOG(errCode == E_OK, "BatchInsertWithRetry: tans finish fail!, ret:%{public}d", errCode);
465 return errCode;
466 }
467
ReportClassifyRestoreTask()468 void CloneRestoreClassify::ReportClassifyRestoreTask()
469 {
470 MEDIA_INFO_LOG("Classify label insert successInsertCnt_: %{public}d, failInsertCnt_: %{public}d",
471 successInsertLabelCnt_.load(), failInsertLabelCnt_.load());
472 UpgradeRestoreTaskReport().SetSceneCode(sceneCode_).SetTaskId(taskId_)
473 .Report("Classify label restore", std::to_string(CLASSIFY_STATUS_SUCCESS),
474 "successInsertCnt_: " + std::to_string(successInsertLabelCnt_) +
475 ", failInsertCnt_: " + std::to_string(failInsertLabelCnt_));
476
477 MEDIA_INFO_LOG("Classify video label insert successInsertCnt_: %{public}d, failInsertCnt_: %{public}d",
478 successInsertVideoLabelCnt_.load(), failInsertVideoLabelCnt_.load());
479 UpgradeRestoreTaskReport().SetSceneCode(sceneCode_).SetTaskId(taskId_)
480 .Report("Classify video label restore", std::to_string(CLASSIFY_STATUS_SUCCESS),
481 "successInsertCnt_: " + std::to_string(successInsertVideoLabelCnt_) +
482 ", failInsertCnt_: " + std::to_string(failInsertVideoLabelCnt_));
483 }
484 }