• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }