• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-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 
16 #include "medialibrary_rdb_utils.h"
17 
18 #include <functional>
19 #include <iomanip>
20 #include <sstream>
21 #include <string>
22 
23 #include "datashare_values_bucket.h"
24 #include "media_analysis_helper.h"
25 #include "media_file_uri.h"
26 #include "media_file_utils.h"
27 #include "media_log.h"
28 #include "media_refresh_album_column.h"
29 #include "medialibrary_album_fusion_utils.h"
30 #include "medialibrary_business_record_column.h"
31 #include "medialibrary_data_manager_utils.h"
32 #include "medialibrary_db_const.h"
33 #include "medialibrary_formmap_operations.h"
34 #include "medialibrary_photo_operations.h"
35 #include "medialibrary_rdb_transaction.h"
36 #include "medialibrary_tracer.h"
37 #include "photo_album_column.h"
38 #include "photo_map_column.h"
39 #include "result_set.h"
40 #include "userfile_manager_types.h"
41 #include "vision_album_column.h"
42 #include "vision_column.h"
43 #include "vision_face_tag_column.h"
44 #include "vision_image_face_column.h"
45 #include "vision_photo_map_column.h"
46 #include "vision_total_column.h"
47 #include "location_column.h"
48 #include "search_column.h"
49 #include "story_cover_info_column.h"
50 #include "power_efficiency_manager.h"
51 
52 namespace OHOS::Media {
53 using namespace std;
54 using namespace NativeRdb;
55 
56 constexpr int32_t E_EMPTY_ALBUM_ID = 1;
57 constexpr size_t ALBUM_UPDATE_THRESHOLD = 1000;
58 constexpr int32_t SINGLE_FACE = 1;
59 constexpr double LOCATION_DB_ZERO = 0;
60 constexpr double LOCATION_LATITUDE_MAX = 90.0;
61 constexpr double LOCATION_LATITUDE_MIN = -90.0;
62 constexpr double LOCATION_LONGITUDE_MAX = 180.0;
63 constexpr double LOCATION_LONGITUDE_MIN = -180.0;
64 constexpr int32_t SEARCH_UPDATE_STATUS = 2;
65 constexpr int32_t FACE_RECOGNITION = 1;
66 constexpr int32_t FACE_FEATURE = 2;
67 constexpr int32_t FACE_CLUSTERED = 3;
68 constexpr int32_t CLOUD_POSITION_STATUS = 2;
69 constexpr int32_t UPDATE_ALBUM_TIME_OUT = 1000;
70 mutex MediaLibraryRdbUtils::sRefreshAlbumMutex_;
71 
72 // 注意,端云同步代码仓也有相同常量,添加新相册时,请通知端云同步进行相应修改
73 const std::vector<std::string> ALL_SYS_PHOTO_ALBUM = {
74     std::to_string(PhotoAlbumSubType::FAVORITE),
75     std::to_string(PhotoAlbumSubType::VIDEO),
76     std::to_string(PhotoAlbumSubType::HIDDEN),
77     std::to_string(PhotoAlbumSubType::TRASH),
78     std::to_string(PhotoAlbumSubType::SCREENSHOT),
79     std::to_string(PhotoAlbumSubType::CAMERA),
80     std::to_string(PhotoAlbumSubType::IMAGE),
81     std::to_string(PhotoAlbumSubType::CLOUD_ENHANCEMENT),
82     std::to_string(PhotoAlbumSubType::SOURCE_GENERIC),
83 };
84 
85 // 注意,端云同步代码仓也有相同常量,添加新相册时,请通知端云同步进行相应修改
86 const std::vector<std::string> ALL_ANALYSIS_ALBUM = {
87     std::to_string(PhotoAlbumSubType::CLASSIFY),
88     std::to_string(PhotoAlbumSubType::GEOGRAPHY_LOCATION),
89     std::to_string(PhotoAlbumSubType::GEOGRAPHY_CITY),
90     std::to_string(PhotoAlbumSubType::SHOOTING_MODE),
91     std::to_string(PhotoAlbumSubType::PORTRAIT),
92 };
93 
94 struct BussinessRecordValue {
95     string bussinessType;
96     string key;
97     string value;
98 };
99 
100 enum UpdateAlbumType {
101     UPDATE_SYSTEM_ALBUM = 400,
102     UPDATE_HIDDEN_ALBUM,
103     UPDATE_USER_ALBUM,
104     UPDATE_SOURCE_ALBUM,
105     UPDATE_ANALYSIS_ALBUM,
106 };
107 
108 atomic<bool> MediaLibraryRdbUtils::isNeedRefreshAlbum = false;
109 atomic<bool> MediaLibraryRdbUtils::isInRefreshTask = false;
110 
111 const string ANALYSIS_REFRESH_BUSINESS_TYPE = "ANALYSIS_ALBUM_REFRESH";
112 
GetStringValFromColumn(const shared_ptr<ResultSet> & resultSet,const int index)113 static inline string GetStringValFromColumn(const shared_ptr<ResultSet> &resultSet, const int index)
114 {
115     string value;
116     if (resultSet->GetString(index, value)) {
117         return "";
118     }
119     return value;
120 }
121 
GetIntValFromColumn(const shared_ptr<ResultSet> & resultSet,const int index)122 static inline int32_t GetIntValFromColumn(const shared_ptr<ResultSet> &resultSet, const int index)
123 {
124     int32_t value = 0;
125     if (resultSet->GetInt(index, value)) {
126         return 0;
127     }
128     return value;
129 }
130 
GetStringValFromColumn(const shared_ptr<ResultSet> & resultSet,const string & columnName)131 static inline string GetStringValFromColumn(const shared_ptr<ResultSet> &resultSet, const string &columnName)
132 {
133     int32_t index = 0;
134     if (resultSet->GetColumnIndex(columnName, index)) {
135         return "";
136     }
137 
138     return GetStringValFromColumn(resultSet, index);
139 }
140 
GetIntValFromColumn(const shared_ptr<ResultSet> & resultSet,const string & columnName)141 static inline int32_t GetIntValFromColumn(const shared_ptr<ResultSet> &resultSet, const string &columnName)
142 {
143     int32_t index = 0;
144     if (resultSet->GetColumnIndex(columnName, index)) {
145         return 0;
146     }
147 
148     return GetIntValFromColumn(resultSet, index);
149 }
150 
GetUserAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & userAlbumIds,const vector<string> & columns)151 static inline shared_ptr<ResultSet> GetUserAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,
152     const vector<string> &userAlbumIds, const vector<string> &columns)
153 {
154     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
155     if (userAlbumIds.empty()) {
156         predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::USER_GENERIC));
157     } else {
158         predicates.In(PhotoAlbumColumns::ALBUM_ID, userAlbumIds);
159     }
160     if (rdbStore == nullptr) {
161         return nullptr;
162     }
163     return rdbStore->Query(predicates, columns);
164 }
165 
GetAnalysisAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & analysisAlbumIds,const vector<string> & columns)166 static inline shared_ptr<ResultSet> GetAnalysisAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,
167     const vector<string> &analysisAlbumIds, const vector<string> &columns)
168 {
169     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
170     if (!analysisAlbumIds.empty()) {
171         predicates.In(PhotoAlbumColumns::ALBUM_ID, analysisAlbumIds);
172     }
173     if (rdbStore == nullptr) {
174         return nullptr;
175     }
176     return rdbStore->Query(predicates, columns);
177 }
178 
GetSourceAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & sourceAlbumIds,const vector<string> & columns)179 static inline shared_ptr<ResultSet> GetSourceAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,
180     const vector<string> &sourceAlbumIds, const vector<string> &columns)
181 {
182     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
183     if (!sourceAlbumIds.empty()) {
184         predicates.In(PhotoAlbumColumns::ALBUM_ID, sourceAlbumIds);
185     } else {
186         predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::SOURCE_GENERIC));
187     }
188     if (rdbStore == nullptr) {
189         return nullptr;
190     }
191     return rdbStore->Query(predicates, columns);
192 }
193 
GetAnalysisAlbumBySubtype(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes,const vector<string> & columns)194 static inline shared_ptr<ResultSet> GetAnalysisAlbumBySubtype(const shared_ptr<MediaLibraryRdbStore> rdbStore,
195     const vector<string> &subtypes, const vector<string> &columns)
196 {
197     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
198     if (!subtypes.empty()) {
199         predicates.In(ALBUM_SUBTYPE, subtypes);
200     } else {
201         predicates.In(ALBUM_SUBTYPE, ALL_ANALYSIS_ALBUM);
202     }
203 
204     if (rdbStore == nullptr) {
205         return nullptr;
206     }
207     return rdbStore->Query(predicates, columns);
208 }
209 
GetQueryFilter(const string & tableName)210 static string GetQueryFilter(const string &tableName)
211 {
212     if (tableName == MEDIALIBRARY_TABLE) {
213         return MEDIALIBRARY_TABLE + "." + MEDIA_DATA_DB_SYNC_STATUS + " = " +
214             to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE));
215     }
216     if (tableName == PhotoColumn::PHOTOS_TABLE) {
217         return PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_SYNC_STATUS + " = " +
218             to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)) + " AND " +
219             PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_CLEAN_FLAG + " = " +
220             to_string(static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN));
221     }
222     if (tableName == PhotoAlbumColumns::TABLE) {
223         return PhotoAlbumColumns::TABLE + "." + PhotoAlbumColumns::ALBUM_DIRTY + " != " +
224             to_string(static_cast<int32_t>(DirtyTypes::TYPE_DELETED));
225     }
226     if (tableName == PhotoMap::TABLE) {
227         return PhotoMap::TABLE + "." + PhotoMap::DIRTY + " != " + to_string(static_cast<int32_t>(
228             DirtyTypes::TYPE_DELETED));
229     }
230     return "";
231 }
232 
AddQueryFilter(AbsRdbPredicates & predicates)233 void MediaLibraryRdbUtils::AddQueryFilter(AbsRdbPredicates &predicates)
234 {
235     /* build all-table vector */
236     string tableName = predicates.GetTableName();
237     vector<string> joinTables = predicates.GetJoinTableNames();
238     joinTables.push_back(tableName);
239     /* add filters */
240     string filters;
241     for (auto &t : joinTables) {
242         string filter = GetQueryFilter(t);
243         if (filter.empty()) {
244             continue;
245         }
246         if (filters.empty()) {
247             filters += filter;
248         } else {
249             filters += " AND " + filter;
250         }
251     }
252     if (filters.empty()) {
253         return;
254     }
255 
256     /* rebuild */
257     string queryCondition = predicates.GetWhereClause();
258     queryCondition = queryCondition.empty() ? filters : filters + " AND " + queryCondition;
259     predicates.SetWhereClause(queryCondition);
260 }
261 
QueryGoToFirst(const shared_ptr<MediaLibraryRdbStore> rdbStore,const RdbPredicates & predicates,const vector<string> & columns)262 static shared_ptr<ResultSet> QueryGoToFirst(const shared_ptr<MediaLibraryRdbStore> rdbStore,
263     const RdbPredicates &predicates, const vector<string> &columns)
264 {
265     MediaLibraryTracer tracer;
266     tracer.Start("QueryGoToFirst");
267     auto resultSet = rdbStore->QueryWithFilter(predicates, columns);
268     if (resultSet == nullptr) {
269         return nullptr;
270     }
271 
272     MediaLibraryTracer goToFirst;
273     goToFirst.Start("GoToFirstRow");
274     resultSet->GoToFirstRow();
275     return resultSet;
276 }
277 
ForEachRow(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & resultSet,const bool hiddenState,const function<int32_t (const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,const bool hiddenState,std::shared_ptr<TransactionOperations> trans)> & func)278 static int32_t ForEachRow(const shared_ptr<MediaLibraryRdbStore> rdbStore, const shared_ptr<ResultSet> &resultSet,
279     const bool hiddenState, const function<int32_t(const shared_ptr<MediaLibraryRdbStore> rdbStore,
280     const shared_ptr<ResultSet> &albumResult, const bool hiddenState,
281     std::shared_ptr<TransactionOperations> trans)> &func)
282 {
283     int32_t err = NativeRdb::E_OK;
284     while (resultSet->GoToNextRow() == E_OK) {
285         std::shared_ptr<TransactionOperations> trans = make_shared<TransactionOperations>();
286         std::function<int(void)> transFunc = [&]()->int {
287             // Ignore failure here, try to iterate rows as much as possible.
288             func(rdbStore, resultSet, hiddenState, trans);
289             return err;
290         };
291         err = trans->RetryTrans(transFunc, __func__);
292         if (err != E_OK) {
293             MEDIA_ERR_LOG("ForEachRow: trans retry fail!, ret:%{public}d", err);
294         }
295     }
296     return E_SUCCESS;
297 }
298 
GetFileCount(const shared_ptr<ResultSet> & resultSet)299 static inline int32_t GetFileCount(const shared_ptr<ResultSet> &resultSet)
300 {
301     return GetIntValFromColumn(resultSet, MEDIA_COLUMN_COUNT_1);
302 }
303 
GetPortraitFileCount(const shared_ptr<ResultSet> & resultSet)304 static inline int32_t GetPortraitFileCount(const shared_ptr<ResultSet> &resultSet)
305 {
306     return GetIntValFromColumn(resultSet, MEDIA_COLUMN_COUNT_DISTINCT_FILE_ID);
307 }
308 
GetAlbumCount(const shared_ptr<ResultSet> & resultSet,const string & column)309 static inline int32_t GetAlbumCount(const shared_ptr<ResultSet> &resultSet, const string &column)
310 {
311     return GetIntValFromColumn(resultSet, column);
312 }
313 
GetAlbumCover(const shared_ptr<ResultSet> & resultSet,const string & column)314 static inline string GetAlbumCover(const shared_ptr<ResultSet> &resultSet, const string &column)
315 {
316     return GetStringValFromColumn(resultSet, column);
317 }
318 
GetAlbumId(const shared_ptr<ResultSet> & resultSet)319 static inline int32_t GetAlbumId(const shared_ptr<ResultSet> &resultSet)
320 {
321     return GetIntValFromColumn(resultSet, PhotoAlbumColumns::ALBUM_ID);
322 }
323 
GetAlbumSubType(const shared_ptr<ResultSet> & resultSet)324 static inline int32_t GetAlbumSubType(const shared_ptr<ResultSet> &resultSet)
325 {
326     return GetIntValFromColumn(resultSet, PhotoAlbumColumns::ALBUM_SUBTYPE);
327 }
328 
GetIsCoverSatisfied(const shared_ptr<ResultSet> & resultSet)329 static inline uint8_t GetIsCoverSatisfied(const shared_ptr<ResultSet> &resultSet)
330 {
331     return GetIntValFromColumn(resultSet, IS_COVER_SATISFIED);
332 }
333 
GetFileName(const string & filePath)334 static string GetFileName(const string &filePath)
335 {
336     string fileName;
337 
338     size_t lastSlash = filePath.rfind('/');
339     if (lastSlash == string::npos) {
340         return fileName;
341     }
342     if (filePath.size() > (lastSlash + 1)) {
343         fileName = filePath.substr(lastSlash + 1);
344     }
345     return fileName;
346 }
347 
GetTitleFromDisplayName(const string & displayName)348 static string GetTitleFromDisplayName(const string &displayName)
349 {
350     auto pos = displayName.find_last_of('.');
351     if (pos == string::npos) {
352         return "";
353     }
354     return displayName.substr(0, pos);
355 }
356 
Encode(const string & uri)357 static string Encode(const string &uri)
358 {
359     const unordered_set<char> uriCompentsSet = {
360         ';', ',', '/', '?', ':', '@', '&',
361         '=', '+', '$', '-', '_', '.', '!',
362         '~', '*', '(', ')', '#', '\''
363     };
364     constexpr int32_t encodeLen = 2;
365     ostringstream outPutStream;
366     outPutStream.fill('0');
367     outPutStream << std::hex;
368 
369     for (unsigned char tmpChar : uri) {
370         if (std::isalnum(tmpChar) || uriCompentsSet.find(tmpChar) != uriCompentsSet.end()) {
371             outPutStream << tmpChar;
372         } else {
373             outPutStream << std::uppercase;
374             outPutStream << '%' << std::setw(encodeLen) << static_cast<unsigned int>(tmpChar);
375             outPutStream << std::nouppercase;
376         }
377     }
378 
379     return outPutStream.str();
380 }
381 
GetExtraUri(const string & displayName,const string & path)382 static string GetExtraUri(const string &displayName, const string &path)
383 {
384     string extraUri = "/" + GetTitleFromDisplayName(GetFileName(path)) + "/" + displayName;
385     return Encode(extraUri);
386 }
387 
GetUriByExtrConditions(const string & prefix,const string & fileId,const string & suffix)388 static string GetUriByExtrConditions(const string &prefix, const string &fileId, const string &suffix)
389 {
390     return prefix + fileId + suffix;
391 }
392 
GetCover(const shared_ptr<ResultSet> & resultSet)393 static inline string GetCover(const shared_ptr<ResultSet> &resultSet)
394 {
395     string coverUri;
396     int32_t fileId = GetIntValFromColumn(resultSet, PhotoColumn::MEDIA_ID);
397     if (fileId <= 0) {
398         return coverUri;
399     }
400 
401     string extrUri = GetExtraUri(GetStringValFromColumn(resultSet, PhotoColumn::MEDIA_NAME),
402         GetStringValFromColumn(resultSet, PhotoColumn::MEDIA_FILE_PATH));
403     return GetUriByExtrConditions(PhotoColumn::PHOTO_URI_PREFIX, to_string(fileId), extrUri);
404 }
405 
SetCount(const shared_ptr<ResultSet> & fileResult,const shared_ptr<ResultSet> & albumResult,ValuesBucket & values,const bool hiddenState,PhotoAlbumSubType subtype)406 static int32_t SetCount(const shared_ptr<ResultSet> &fileResult, const shared_ptr<ResultSet> &albumResult,
407     ValuesBucket &values, const bool hiddenState, PhotoAlbumSubType subtype)
408 {
409     const string &targetColumn = hiddenState ? PhotoAlbumColumns::HIDDEN_COUNT : PhotoAlbumColumns::ALBUM_COUNT;
410     int32_t oldCount = GetAlbumCount(albumResult, targetColumn);
411     int32_t newCount;
412     if (subtype == PORTRAIT) {
413         newCount = GetPortraitFileCount(fileResult);
414     } else {
415         newCount = GetFileCount(fileResult);
416     }
417     int32_t id = GetAlbumId(albumResult);
418     if (oldCount != newCount) {
419         MEDIA_INFO_LOG("Album %{public}d Update %{public}s, oldCount: %{public}d, newCount: %{public}d", id,
420             targetColumn.c_str(), oldCount, newCount);
421         values.PutInt(targetColumn, newCount);
422         if (hiddenState) {
423             MEDIA_INFO_LOG("Update album contains hidden: %{public}d", newCount != 0);
424             values.PutInt(PhotoAlbumColumns::CONTAINS_HIDDEN, newCount != 0);
425         }
426     }
427     return newCount;
428 }
429 
SetPortraitCover(const shared_ptr<ResultSet> & fileResult,const shared_ptr<ResultSet> & albumResult,ValuesBucket & values,int newCount)430 static void SetPortraitCover(const shared_ptr<ResultSet> &fileResult, const shared_ptr<ResultSet> &albumResult,
431     ValuesBucket &values, int newCount)
432 {
433     string newCover;
434     if (newCount != 0) {
435         newCover = GetCover(fileResult);
436     }
437     const string &targetColumn = PhotoAlbumColumns::ALBUM_COVER_URI;
438     string oldCover = GetAlbumCover(albumResult, targetColumn);
439     if (oldCover != newCover) {
440         values.PutInt(IS_COVER_SATISFIED, static_cast<uint8_t>(CoverSatisfiedType::DEFAULT_SETTING));
441         values.PutString(targetColumn, newCover);
442         int32_t albumId = GetAlbumId(albumResult);
443         MEDIA_INFO_LOG("Update portrait album %{public}d. oldCover: %{public}s, newCover: %{public}s",
444             albumId, MediaFileUtils::GetUriWithoutDisplayname(oldCover).c_str(),
445             MediaFileUtils::GetUriWithoutDisplayname(newCover).c_str());
446     }
447 }
448 
SetCover(const shared_ptr<ResultSet> & fileResult,const shared_ptr<ResultSet> & albumResult,ValuesBucket & values,const bool hiddenState,PhotoAlbumSubType subtype)449 static void SetCover(const shared_ptr<ResultSet> &fileResult, const shared_ptr<ResultSet> &albumResult,
450     ValuesBucket &values, const bool hiddenState, PhotoAlbumSubType subtype)
451 {
452     string newCover;
453     int32_t newCount = GetFileCount(fileResult);
454     if (newCount != 0) {
455         newCover = GetCover(fileResult);
456     }
457     const string &targetColumn = hiddenState ? PhotoAlbumColumns::HIDDEN_COVER : PhotoAlbumColumns::ALBUM_COVER_URI;
458     string oldCover = GetAlbumCover(albumResult, targetColumn);
459     if (oldCover != newCover) {
460         int32_t id = GetAlbumId(albumResult);
461         MEDIA_INFO_LOG("Update album %{public}d %{public}s. oldCover: %{public}s, newCover: %{public}s",
462             id, targetColumn.c_str(), MediaFileUtils::GetUriWithoutDisplayname(oldCover).c_str(),
463             MediaFileUtils::GetUriWithoutDisplayname(newCover).c_str());
464         values.PutString(targetColumn, newCover);
465     }
466 }
467 
GetAlbumPredicates(PhotoAlbumSubType subtype,const shared_ptr<ResultSet> & albumResult,NativeRdb::RdbPredicates & predicates,const bool hiddenState,const bool isUpdateAlbum=false)468 static void GetAlbumPredicates(PhotoAlbumSubType subtype, const shared_ptr<ResultSet> &albumResult,
469     NativeRdb::RdbPredicates &predicates, const bool hiddenState, const bool isUpdateAlbum = false)
470 {
471     static const string QUERY_ASSETS_FROM_ANALYSIS_ALBUM =
472         PhotoColumn::PHOTO_SYNC_STATUS + " = " + to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)) +
473         " AND " + PhotoColumn::PHOTO_CLEAN_FLAG + " = " + to_string(static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN)) +
474         " AND " + MediaColumn::MEDIA_ID + " IN (SELECT " + PhotoMap::ASSET_ID + " FROM " + ANALYSIS_PHOTO_MAP_TABLE +
475         " WHERE " + PhotoMap::ALBUM_ID + " = ?) AND " + MediaColumn::MEDIA_DATE_TRASHED + " = 0 AND " +
476         MediaColumn::MEDIA_HIDDEN + " = ? AND " + MediaColumn::MEDIA_TIME_PENDING + " = 0 AND " +
477         PhotoColumn::PHOTO_IS_TEMP + " = 0 AND " + PhotoColumn::PHOTO_BURST_COVER_LEVEL + " = " +
478         to_string(static_cast<int32_t>(BurstCoverLevelType::COVER));
479 
480     bool isUserAlbum = !subtype;
481     bool isSourceAlbum = subtype == PhotoAlbumSubType::SOURCE_GENERIC;
482     bool isAnalysisAlbum = subtype >= PhotoAlbumSubType::ANALYSIS_START && subtype <= PhotoAlbumSubType::ANALYSIS_END;
483     if (isUpdateAlbum && isAnalysisAlbum) {
484         predicates.SetWhereClause(QUERY_ASSETS_FROM_ANALYSIS_ALBUM);
485         predicates.SetWhereArgs({ to_string(GetAlbumId(albumResult)), to_string(hiddenState) });
486         return;
487     }
488 
489     if (isUserAlbum) {
490         PhotoAlbumColumns::GetUserAlbumPredicates(GetAlbumId(albumResult), predicates, hiddenState);
491     } else if (subtype == PhotoAlbumSubType::PORTRAIT) {
492         PhotoAlbumColumns::GetPortraitAlbumPredicates(GetAlbumId(albumResult), predicates, hiddenState);
493     } else if (isAnalysisAlbum) {
494         PhotoAlbumColumns::GetAnalysisAlbumPredicates(GetAlbumId(albumResult), predicates, hiddenState);
495     } else if (isSourceAlbum) {
496         PhotoAlbumColumns::GetSourceAlbumPredicates(GetAlbumId(albumResult), predicates, hiddenState);
497     } else {
498         PhotoAlbumColumns::GetSystemAlbumPredicates(subtype, predicates, hiddenState);
499     }
500 }
501 
SetImageVideoCount(int32_t newTotalCount,const shared_ptr<ResultSet> & fileResultVideo,const shared_ptr<ResultSet> & albumResult,ValuesBucket & values)502 static void SetImageVideoCount(int32_t newTotalCount,
503     const shared_ptr<ResultSet> &fileResultVideo, const shared_ptr<ResultSet> &albumResult,
504     ValuesBucket &values)
505 {
506     int32_t oldVideoCount = GetAlbumCount(albumResult, PhotoAlbumColumns::ALBUM_VIDEO_COUNT);
507     int32_t newVideoCount = GetFileCount(fileResultVideo);
508     if (oldVideoCount != newVideoCount) {
509         MEDIA_DEBUG_LOG("Update album %{public}s, oldCount: %{public}d, newCount: %{public}d",
510             PhotoAlbumColumns::ALBUM_VIDEO_COUNT.c_str(), oldVideoCount, newVideoCount);
511         values.PutInt(PhotoAlbumColumns::ALBUM_VIDEO_COUNT, newVideoCount);
512     }
513     int32_t oldImageCount = GetAlbumCount(albumResult, PhotoAlbumColumns::ALBUM_IMAGE_COUNT);
514     int32_t newImageCount = newTotalCount - newVideoCount;
515     if (oldImageCount != newImageCount) {
516         MEDIA_DEBUG_LOG("Update album %{public}s, oldCount: %{public}d, newCount: %{public}d",
517             PhotoAlbumColumns::ALBUM_IMAGE_COUNT.c_str(), oldImageCount, newImageCount);
518         values.PutInt(PhotoAlbumColumns::ALBUM_IMAGE_COUNT, newImageCount);
519     }
520 }
521 
QueryAlbumCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,PhotoAlbumSubType subtype)522 static int32_t QueryAlbumCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,
523     const shared_ptr<ResultSet> &albumResult, PhotoAlbumSubType subtype)
524 {
525     const vector<string> columns = { MEDIA_COLUMN_COUNT_1 };
526     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
527     if (subtype == PhotoAlbumSubType::USER_GENERIC) {
528         GetAlbumPredicates(static_cast<PhotoAlbumSubType>(0), albumResult, predicates, false);
529     } else {
530         GetAlbumPredicates(subtype, albumResult, predicates, false);
531     }
532     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
533     if (fetchResult == nullptr) {
534         return E_HAS_DB_ERROR;
535     }
536     return GetFileCount(fetchResult);
537 }
538 
QueryAlbumVideoCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,PhotoAlbumSubType subtype)539 static int32_t QueryAlbumVideoCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,
540     const shared_ptr<ResultSet> &albumResult, PhotoAlbumSubType subtype)
541 {
542     const vector<string> columns = { MEDIA_COLUMN_COUNT_1 };
543     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
544     if (subtype == PhotoAlbumSubType::USER_GENERIC) {
545         GetAlbumPredicates(static_cast<PhotoAlbumSubType>(0), albumResult, predicates, false);
546     } else {
547         GetAlbumPredicates(subtype, albumResult, predicates, false);
548     }
549     predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_MEDIA_TYPE_INDEX);
550     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO));
551     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
552     if (fetchResult == nullptr) {
553         return E_HAS_DB_ERROR;
554     }
555     return GetFileCount(fetchResult);
556 }
557 
QueryAlbumHiddenCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,PhotoAlbumSubType subtype)558 static int32_t QueryAlbumHiddenCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,
559     const shared_ptr<ResultSet> &albumResult, PhotoAlbumSubType subtype)
560 {
561     const vector<string> columns = { MEDIA_COLUMN_COUNT_1 };
562     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
563     if (subtype == PhotoAlbumSubType::USER_GENERIC) {
564         GetAlbumPredicates(static_cast<PhotoAlbumSubType>(0), albumResult, predicates, true);
565     } else {
566         GetAlbumPredicates(subtype, albumResult, predicates, true);
567     }
568     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
569     if (fetchResult == nullptr) {
570         return E_HAS_DB_ERROR;
571     }
572     return GetFileCount(fetchResult);
573 }
574 
SetAlbumCounts(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,PhotoAlbumSubType subtype,AlbumCounts & albumCounts)575 static int32_t SetAlbumCounts(const shared_ptr<MediaLibraryRdbStore> rdbStore,
576     const shared_ptr<ResultSet> &albumResult, PhotoAlbumSubType subtype, AlbumCounts &albumCounts)
577 {
578     int ret = QueryAlbumCount(rdbStore, albumResult, subtype);
579     if (ret < E_SUCCESS) {
580         MEDIA_ERR_LOG("Failed to QueryAlbumCount, ret:%{public}d", ret);
581         return ret;
582     }
583     albumCounts.count = ret;
584 
585     ret = QueryAlbumVideoCount(rdbStore, albumResult, subtype);
586     if (ret < E_SUCCESS) {
587         MEDIA_ERR_LOG("Failed to QueryAlbumVideoCount, ret:%{public}d", ret);
588         return ret;
589     }
590     albumCounts.videoCount = ret;
591     albumCounts.imageCount = albumCounts.count - albumCounts.videoCount;
592 
593     ret = QueryAlbumHiddenCount(rdbStore, albumResult, subtype);
594     if (ret < E_SUCCESS) {
595         MEDIA_ERR_LOG("Failed to QueryAlbumCount, ret:%{public}d", ret);
596         return ret;
597     }
598     albumCounts.hiddenCount = ret;
599     return E_SUCCESS;
600 }
601 
SetAlbumCoverUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,PhotoAlbumSubType subtype,string & uri)602 static int32_t SetAlbumCoverUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
603     const shared_ptr<ResultSet> &albumResult, PhotoAlbumSubType subtype, string &uri)
604 {
605     const vector<string> columns = {
606         PhotoColumn::MEDIA_ID,
607         PhotoColumn::MEDIA_FILE_PATH,
608         PhotoColumn::MEDIA_NAME
609     };
610     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
611     if (subtype == PhotoAlbumSubType::HIDDEN) {
612         GetAlbumPredicates(subtype, albumResult, predicates, true);
613         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_HIDDEN_TIME_INDEX);
614     } else if (subtype == PhotoAlbumSubType::USER_GENERIC) {
615         GetAlbumPredicates(static_cast<PhotoAlbumSubType>(0), albumResult, predicates, false);
616         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_ADDED_INDEX);
617     } else {
618         GetAlbumPredicates(subtype, albumResult, predicates, false);
619         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_ADDED_INDEX);
620     }
621     predicates.Limit(1);
622 
623     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
624     if (fetchResult == nullptr) {
625         MEDIA_ERR_LOG("QueryGoToFirst failed");
626         return E_HAS_DB_ERROR;
627     }
628     uri = GetCover(fetchResult);
629     return E_SUCCESS;
630 }
631 
SetAlbumCoverHiddenUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,PhotoAlbumSubType subtype,string & uri)632 static int32_t SetAlbumCoverHiddenUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
633     const shared_ptr<ResultSet> &albumResult, PhotoAlbumSubType subtype, string &uri)
634 {
635     const vector<string> columns = {
636         PhotoColumn::MEDIA_ID,
637         PhotoColumn::MEDIA_FILE_PATH,
638         PhotoColumn::MEDIA_NAME
639     };
640     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
641     if (subtype == PhotoAlbumSubType::USER_GENERIC) {
642         GetAlbumPredicates(static_cast<PhotoAlbumSubType>(0), albumResult, predicates, true);
643         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_HIDDEN_TIME_INDEX);
644     } else {
645         GetAlbumPredicates(subtype, albumResult, predicates, true);
646         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_HIDDEN_TIME_INDEX);
647     }
648     predicates.Limit(1);
649     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
650     if (fetchResult == nullptr) {
651         MEDIA_ERR_LOG("QueryGoToFirst failed");
652         return E_HAS_DB_ERROR;
653     }
654     uri = GetCover(fetchResult);
655     return E_SUCCESS;
656 }
657 
FillOneAlbumCountAndCoverUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,PhotoAlbumSubType subtype,string & sql)658 static int32_t FillOneAlbumCountAndCoverUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
659     const shared_ptr<ResultSet> &albumResult, PhotoAlbumSubType subtype, string &sql)
660 {
661     AlbumCounts albumCounts = { 0, 0, 0, 0 };
662     int32_t ret = SetAlbumCounts(rdbStore, albumResult, subtype, albumCounts);
663     if (ret != E_SUCCESS) {
664         return ret;
665     }
666     string coverUri;
667     ret = SetAlbumCoverUri(rdbStore, albumResult, subtype, coverUri);
668     if (ret != E_SUCCESS) {
669         return ret;
670     }
671     string coverHiddenUri;
672     if (albumCounts.hiddenCount != 0) {
673         ret = SetAlbumCoverHiddenUri(rdbStore, albumResult, subtype, coverHiddenUri);
674         if (ret != E_SUCCESS) {
675             return ret;
676         }
677     }
678 
679     int32_t albumId = GetAlbumId(albumResult);
680     if (albumId < 0) {
681         MEDIA_ERR_LOG("Can not get correct albumId, error albumId is %{public}d", albumId);
682         return E_HAS_DB_ERROR;
683     }
684     string coverUriSql = PhotoAlbumColumns::ALBUM_COVER_URI;
685     if (coverUri.empty()) {
686         coverUriSql += " = NULL";
687     } else {
688         coverUriSql += " = '" + coverUri + "'";
689     }
690     string coverHiddenUriSql = PhotoAlbumColumns::HIDDEN_COVER;
691     if (coverHiddenUri.empty()) {
692         coverHiddenUriSql += " = NULL";
693     } else {
694         coverHiddenUriSql += " = '" + coverHiddenUri + "'";
695     }
696 
697     sql = "UPDATE " + PhotoAlbumColumns::TABLE + " SET " +
698         PhotoAlbumColumns::ALBUM_COUNT + " = " + to_string(albumCounts.count) + ", " +
699         PhotoAlbumColumns::ALBUM_IMAGE_COUNT + " = " +  to_string(albumCounts.imageCount) + ", " +
700         PhotoAlbumColumns::ALBUM_VIDEO_COUNT + " = " + to_string(albumCounts.videoCount) + ", " +
701         PhotoAlbumColumns::HIDDEN_COUNT + " = " + to_string(albumCounts.hiddenCount) + ", " +
702         PhotoAlbumColumns::CONTAINS_HIDDEN + " = " + to_string((albumCounts.hiddenCount == 0) ? 0 : 1) + ", " +
703         coverUriSql + ", " + coverHiddenUriSql + " WHERE " +
704         PhotoAlbumColumns::ALBUM_ID + " = " + to_string(albumId) + ";";
705     return E_SUCCESS;
706 }
707 
GetPhotoId(const std::string & uri)708 static std::string GetPhotoId(const std::string &uri)
709 {
710     if (uri.compare(0, PhotoColumn::PHOTO_URI_PREFIX.size(),
711         PhotoColumn::PHOTO_URI_PREFIX) != 0) {
712         return "";
713     }
714     std::string tmp = uri.substr(PhotoColumn::PHOTO_URI_PREFIX.size());
715     return tmp.substr(0, tmp.find_first_of('/'));
716 }
717 
RefreshAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,function<void (PhotoAlbumType,PhotoAlbumSubType,int)> refreshProcessHandler)718 static int32_t RefreshAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
719     const shared_ptr<ResultSet> &albumResult,
720     function<void(PhotoAlbumType, PhotoAlbumSubType, int)> refreshProcessHandler)
721 {
722     while (albumResult->GoToNextRow() == NativeRdb::E_OK) {
723         auto subtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
724         int32_t albumId = GetAlbumId(albumResult);
725         string sql;
726         int32_t ret = FillOneAlbumCountAndCoverUri(rdbStore, albumResult, subtype, sql);
727         if (ret != E_SUCCESS) {
728             return ret;
729         }
730 
731         ret = rdbStore->ExecuteSql(sql);
732         if (ret != NativeRdb::E_OK) {
733             MEDIA_ERR_LOG("Failed to execute sql:%{private}s", sql.c_str());
734             return E_HAS_DB_ERROR;
735         }
736         MEDIA_DEBUG_LOG("Execute sql %{private}s success", sql.c_str());
737         refreshProcessHandler(PhotoAlbumType::SYSTEM, subtype, albumId);
738     }
739     return E_SUCCESS;
740 }
741 
DeleteAllAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore)742 static void DeleteAllAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore)
743 {
744     string updateRefreshTableSql = "DELETE FROM " + ALBUM_REFRESH_TABLE;
745     int32_t ret = rdbStore->ExecuteSql(updateRefreshTableSql);
746     if (ret != NativeRdb::E_OK) {
747         MEDIA_ERR_LOG("Failed to execute sql:%{private}s", updateRefreshTableSql.c_str());
748         return;
749     }
750     MEDIA_INFO_LOG("Delete AlbumRefreshTable success");
751 }
752 
GetAllRefreshAlbumIds(const shared_ptr<MediaLibraryRdbStore> rdbStore,vector<string> & albumIds)753 static int32_t GetAllRefreshAlbumIds(const shared_ptr<MediaLibraryRdbStore> rdbStore,
754     vector<string> &albumIds)
755 {
756     RdbPredicates predicates(ALBUM_REFRESH_TABLE);
757     vector<string> columns = { REFRESHED_ALBUM_ID };
758     auto resultSet = rdbStore->Query(predicates, columns);
759     if (resultSet == nullptr) {
760         MEDIA_ERR_LOG("Can not query ALBUM_REFRESH_TABLE");
761         return E_HAS_DB_ERROR;
762     }
763 
764     int32_t count = 0;
765     int32_t ret = resultSet->GetRowCount(count);
766     if (ret != NativeRdb::E_OK) {
767         MEDIA_ERR_LOG("GetRowCount failed ret:%{public}d", ret);
768         return E_HAS_DB_ERROR;
769     }
770     if (count == 0) {
771         MEDIA_DEBUG_LOG("count is zero, break");
772         return E_SUCCESS;
773     }
774 
775     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
776         int32_t columnIndex = 0;
777         ret = resultSet->GetColumnIndex(REFRESHED_ALBUM_ID, columnIndex);
778         if (ret != NativeRdb::E_OK) {
779             MEDIA_ERR_LOG("GetColumnIndex failed ret:%{public}d", ret);
780             return E_HAS_DB_ERROR;
781         }
782         int32_t refreshAlbumId = 0;
783         ret = resultSet->GetInt(columnIndex, refreshAlbumId);
784         if (ret != NativeRdb::E_OK) {
785             MEDIA_ERR_LOG("GetInt failed ret:%{public}d", ret);
786             return E_HAS_DB_ERROR;
787         }
788         albumIds.push_back(to_string(refreshAlbumId));
789     }
790     DeleteAllAlbumId(rdbStore);
791     return E_SUCCESS;
792 }
793 
QueryAlbumById(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & albumIds)794 shared_ptr<ResultSet> QueryAlbumById(const shared_ptr<MediaLibraryRdbStore> rdbStore,
795     const vector<string> &albumIds)
796 {
797     vector<string> columns = {
798         PhotoAlbumColumns::ALBUM_ID,
799         PhotoAlbumColumns::ALBUM_SUBTYPE
800     };
801     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
802     predicates.In(PhotoAlbumColumns::ALBUM_ID, albumIds);
803     auto resultSet = rdbStore->Query(predicates, columns);
804     if (resultSet == nullptr) {
805         MEDIA_ERR_LOG("Can not Query from rdb");
806         return nullptr;
807     }
808     return resultSet;
809 }
810 
IsNeedRefreshByCheckTable(const shared_ptr<MediaLibraryRdbStore> rdbStore,bool & signal)811 int32_t MediaLibraryRdbUtils::IsNeedRefreshByCheckTable(const shared_ptr<MediaLibraryRdbStore> rdbStore,
812     bool &signal)
813 {
814     if (rdbStore == nullptr) {
815         MEDIA_ERR_LOG("rdb is nullptr");
816         return E_HAS_DB_ERROR;
817     }
818 
819     RdbPredicates predicates(ALBUM_REFRESH_TABLE);
820     vector<string> columns = { REFRESHED_ALBUM_ID };
821     auto resultSet = rdbStore->Query(predicates, columns);
822     if (resultSet == nullptr) {
823         MEDIA_ERR_LOG("Can not query ALBUM_REFRESH_TABLE");
824         return E_HAS_DB_ERROR;
825     }
826 
827     int32_t count = 0;
828     int32_t ret = resultSet->GetRowCount(count);
829     if (ret != NativeRdb::E_OK) {
830         MEDIA_ERR_LOG("GetRowCount failed ret:%{public}d", ret);
831         return E_HAS_DB_ERROR;
832     }
833     if (count == 0) {
834         MEDIA_DEBUG_LOG("count is zero, should not refresh");
835         signal = false;
836     } else {
837         MEDIA_DEBUG_LOG("count is %{public}d, should refresh", count);
838         signal = true;
839     }
840     return E_SUCCESS;
841 }
842 
IsNeedRefreshAlbum()843 bool MediaLibraryRdbUtils::IsNeedRefreshAlbum()
844 {
845     return isNeedRefreshAlbum.load();
846 }
847 
SetNeedRefreshAlbum(bool isNeedRefresh)848 void MediaLibraryRdbUtils::SetNeedRefreshAlbum(bool isNeedRefresh)
849 {
850     isNeedRefreshAlbum = isNeedRefresh;
851 }
852 
IsInRefreshTask()853 bool MediaLibraryRdbUtils::IsInRefreshTask()
854 {
855     return isInRefreshTask.load();
856 }
857 
GetPortraitAlbumCountPredicates(const string & albumId,RdbPredicates & predicates)858 static void GetPortraitAlbumCountPredicates(const string &albumId, RdbPredicates &predicates)
859 {
860     string anaAlbumGroupTag = ANALYSIS_ALBUM_TABLE + "." + GROUP_TAG;
861     string anaAlbumId = ANALYSIS_ALBUM_TABLE + "." + ALBUM_ID;
862     string anaPhotoMapAlbum = ANALYSIS_PHOTO_MAP_TABLE + "." + MAP_ALBUM;
863     string anaPhotoMapAsset = ANALYSIS_PHOTO_MAP_TABLE + "." + MAP_ASSET;
864     string photosDateTrashed = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_DATE_TRASHED;
865     string photosFileId = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID;
866     string photosHidden = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_HIDDEN;
867     string photosTimePending = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_TIME_PENDING;
868     string photosIsTemp = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_IS_TEMP;
869     string photoIsCover = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_BURST_COVER_LEVEL;
870 
871     string clause = anaPhotoMapAsset + " = " + photosFileId;
872     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ clause });
873     clause = anaAlbumId + " = " + anaPhotoMapAlbum;
874     predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On({ clause });
875 
876     clause = "( " + anaAlbumGroupTag + " IN ( SELECT " + GROUP_TAG + " FROM " + ANALYSIS_ALBUM_TABLE +
877         " WHERE " + ALBUM_ID + " = " + albumId + " ))";
878     predicates.SetWhereClause(clause + " AND ");
879     predicates.BeginWrap();
880     predicates.EqualTo(photosDateTrashed, to_string(0));
881     predicates.EqualTo(photosHidden, to_string(0));
882     predicates.EqualTo(photosTimePending, to_string(0));
883     predicates.EqualTo(photosIsTemp, to_string(0));
884     predicates.EqualTo(photoIsCover, to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
885     predicates.EndWrap();
886     predicates.Distinct();
887 }
888 
IsCoverValid(const shared_ptr<MediaLibraryRdbStore> rdbStore,const string & albumId,const string & fileId)889 static bool IsCoverValid(const shared_ptr<MediaLibraryRdbStore> rdbStore, const string &albumId, const string &fileId)
890 {
891     if (fileId.empty()) {
892         MEDIA_WARN_LOG("Invalid cover: empty file_id");
893         return false;
894     }
895     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
896 
897     string anaPhotoMapAsset = ANALYSIS_PHOTO_MAP_TABLE + "." + MAP_ASSET;
898     string photosFileId = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_ID;
899     string clause = anaPhotoMapAsset + " = " + photosFileId;
900     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ clause });
901 
902     string anaAlbumId = ANALYSIS_ALBUM_TABLE + "." + ALBUM_ID;
903     string anaPhotoMapAlbum = ANALYSIS_PHOTO_MAP_TABLE + "." + MAP_ALBUM;
904     clause = anaAlbumId + " = " + anaPhotoMapAlbum;
905     predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On({ clause });
906 
907     string photoSyncStatus = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_SYNC_STATUS;
908     string photoCleanFlag = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_CLEAN_FLAG;
909     string photosDateTrashed = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_DATE_TRASHED;
910     string photosHidden = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_HIDDEN;
911     string photosTimePending = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_TIME_PENDING;
912     string photosIsTemp = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_IS_TEMP;
913     string photoIsCover = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_BURST_COVER_LEVEL;
914 
915     string whereClause = anaAlbumId + " = " + albumId + " AND " + photosFileId + " = " + fileId + " AND " +
916         photoSyncStatus + " = " + to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)) + " AND " +
917         photoCleanFlag + " = " + to_string(static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN)) + " AND " +
918         photosDateTrashed + " = " + to_string(0) + " AND " + photosHidden + " = " + to_string(0) + " AND " +
919         photosTimePending + " = " + to_string(0) + " AND " + photosIsTemp + " = " + to_string(0) + " AND " +
920         photoIsCover + " = " + to_string(static_cast<int32_t>(BurstCoverLevelType::COVER));
921 
922     predicates.SetWhereClause(whereClause);
923     predicates.Limit(1);
924     vector<string> columns;
925     auto resultSet = rdbStore->Query(predicates, columns);
926     if (resultSet == nullptr) {
927         MEDIA_ERR_LOG("Can not query Photos, albumId: %{public}s, fileId: %{public}s", albumId.c_str(), fileId.c_str());
928         return false;
929     }
930     int32_t count = 0;
931     int32_t ret = resultSet->GetRowCount(count);
932     if (ret != NativeRdb::E_OK) {
933         MEDIA_ERR_LOG("GetRowCount failed, albumId: %{public}s, fileId: %{public}s, ret:%{public}d", albumId.c_str(),
934             fileId.c_str(), ret);
935         return false;
936     }
937     if (count == 0) {
938         MEDIA_WARN_LOG("Invalid cover: albumId: %{public}s, fileId: %{public}s not exist", albumId.c_str(),
939             fileId.c_str());
940         return false;
941     }
942     return true;
943 }
944 
ShouldUpdatePortraitAlbumCover(const shared_ptr<MediaLibraryRdbStore> rdbStore,const string & albumId,const string & fileId,const uint8_t isCoverSatisfied)945 static inline bool ShouldUpdatePortraitAlbumCover(const shared_ptr<MediaLibraryRdbStore> rdbStore,
946     const string &albumId, const string &fileId, const uint8_t isCoverSatisfied)
947 {
948     return isCoverSatisfied == static_cast<uint8_t>(CoverSatisfiedType::NO_SETTING) ||
949         !IsCoverValid(rdbStore, albumId, fileId);
950 }
951 
QueryPortraitAlbumCover(const shared_ptr<MediaLibraryRdbStore> rdbStore,const string & albumId)952 static shared_ptr<ResultSet> QueryPortraitAlbumCover(const shared_ptr<MediaLibraryRdbStore> rdbStore,
953     const string &albumId)
954 {
955     MediaLibraryTracer tracer;
956     tracer.Start("QueryPortraitCover");
957 
958     const std::string sql = "\
959         SELECT\
960           Photos.file_id,\
961           Photos.display_name,\
962           Photos.data\
963         FROM\
964           Photos\
965           INNER JOIN AnalysisPhotoMap ON AnalysisPhotoMap.map_asset = Photos.file_id\
966           INNER JOIN AnalysisAlbum ON AnalysisAlbum.album_id = AnalysisPhotoMap.map_album\
967           INNER JOIN tab_analysis_image_face ON tab_analysis_image_face.file_id = Photos.file_id\
968         WHERE\
969           Photos.sync_status = 0\
970           AND Photos.clean_flag = 0\
971           AND Photos.date_trashed = 0\
972           AND Photos.hidden = 0\
973           AND Photos.time_pending = 0\
974           AND Photos.is_temp = 0\
975           AND Photos.burst_cover_level = 1\
976           AND AnalysisAlbum.group_tag = ( SELECT group_tag FROM AnalysisAlbum WHERE album_id = ? LIMIT 1 )\
977           AND AnalysisAlbum.group_tag LIKE '%' || tab_analysis_image_face.tag_id || '%'\
978         ORDER BY\
979           tab_analysis_image_face.is_excluded DESC,\
980           tab_analysis_image_face.aesthetics_score DESC,\
981         CASE\
982             WHEN tab_analysis_image_face.total_faces = 1 THEN\
983             0 ELSE 1\
984           END ASC,\
985           Photos.date_added DESC\
986           LIMIT 1;";
987 
988     const std::vector<ValueObject> bindArgs{ ValueObject(albumId) };
989     auto resultSet = rdbStore->QuerySql(sql, bindArgs);
990     if (resultSet == nullptr) {
991         return nullptr;
992     }
993 
994     resultSet->GoToFirstRow();
995     return resultSet;
996 }
997 
SetPortraitUpdateValues(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,const vector<string> & fileIds,ValuesBucket & values)998 static int32_t SetPortraitUpdateValues(const shared_ptr<MediaLibraryRdbStore> rdbStore,
999     const shared_ptr<ResultSet> &albumResult, const vector<string> &fileIds, ValuesBucket &values)
1000 {
1001     const vector<string> countColumns = {
1002         MEDIA_COLUMN_COUNT_DISTINCT_FILE_ID
1003     };
1004 
1005     string coverUri = GetAlbumCover(albumResult, PhotoAlbumColumns::ALBUM_COVER_URI);
1006     string coverId = GetPhotoId(coverUri);
1007     uint8_t isCoverSatisfied = GetIsCoverSatisfied(albumResult);
1008 
1009     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1010     string albumId = to_string(GetAlbumId(albumResult));
1011     GetPortraitAlbumCountPredicates(albumId, predicates);
1012     shared_ptr<ResultSet> countResult = QueryGoToFirst(rdbStore, predicates, countColumns);
1013     if (countResult == nullptr) {
1014         MEDIA_ERR_LOG("Failed to query Portrait Album Count");
1015         return E_HAS_DB_ERROR;
1016     }
1017     int32_t newCount = SetCount(countResult, albumResult, values, false, PhotoAlbumSubType::PORTRAIT);
1018     if (!ShouldUpdatePortraitAlbumCover(rdbStore, albumId, coverId, isCoverSatisfied)) {
1019         return E_SUCCESS;
1020     }
1021     shared_ptr<ResultSet> coverResult = QueryPortraitAlbumCover(rdbStore, albumId);
1022     if (coverResult == nullptr) {
1023         MEDIA_ERR_LOG("Failed to query Portrait Album Cover");
1024         return E_HAS_DB_ERROR;
1025     }
1026     SetPortraitCover(coverResult, albumResult, values, newCount);
1027     return E_SUCCESS;
1028 }
1029 
RefreshHighlightAlbum(int32_t albumId)1030 static void RefreshHighlightAlbum(int32_t albumId)
1031 {
1032     vector<string> albumIds;
1033     albumIds.push_back(to_string(albumId));
1034     MediaAnalysisHelper::AsyncStartMediaAnalysisService(
1035         static_cast<int32_t>(Media::MediaAnalysisProxy::ActivateServiceType::HIGHLIGHT_COVER_GENERATE), albumIds);
1036 }
1037 
SetUpdateValues(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,ValuesBucket & values,PhotoAlbumSubType subtype,const bool hiddenState)1038 static int32_t SetUpdateValues(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1039     const shared_ptr<ResultSet> &albumResult, ValuesBucket &values, PhotoAlbumSubType subtype, const bool hiddenState)
1040 {
1041     const vector<string> columns = {
1042         MEDIA_COLUMN_COUNT_1,
1043         PhotoColumn::MEDIA_ID,
1044         PhotoColumn::MEDIA_FILE_PATH,
1045         PhotoColumn::MEDIA_NAME
1046     };
1047     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1048     GetAlbumPredicates(subtype, albumResult, predicates, hiddenState, true);
1049     if (subtype == PhotoAlbumSubType::HIDDEN || hiddenState) {
1050         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_HIDDEN_TIME_INDEX);
1051     } else if (subtype == PhotoAlbumSubType::VIDEO || subtype == PhotoAlbumSubType::IMAGE) {
1052         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_MEDIA_TYPE_INDEX);
1053     } else if (subtype == PhotoAlbumSubType::FAVORITE) {
1054         predicates.IndexedBy(PhotoColumn::PHOTO_FAVORITE_INDEX);
1055     } else {
1056         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_ADDED_INDEX);
1057     }
1058     auto fileResult = QueryGoToFirst(rdbStore, predicates, columns);
1059     if (fileResult == nullptr) {
1060         MEDIA_ERR_LOG("Failed to query fileResult");
1061         return E_HAS_DB_ERROR;
1062     }
1063     int32_t newCount = SetCount(fileResult, albumResult, values, hiddenState, subtype);
1064     if (subtype != PhotoAlbumSubType::HIGHLIGHT && subtype != PhotoAlbumSubType::HIGHLIGHT_SUGGESTIONS) {
1065         SetCover(fileResult, albumResult, values, hiddenState, subtype);
1066     } else {
1067         RefreshHighlightAlbum(GetAlbumId(albumResult));
1068     }
1069     if (hiddenState == 0 && (subtype < PhotoAlbumSubType::ANALYSIS_START ||
1070         subtype > PhotoAlbumSubType::ANALYSIS_END)) {
1071         predicates.Clear();
1072         GetAlbumPredicates(subtype, albumResult, predicates, hiddenState, true);
1073         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_MEDIA_TYPE_INDEX);
1074         string queryCondition = predicates.GetWhereClause();
1075         if (queryCondition.empty()) {
1076             predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO));
1077         } else {
1078             predicates.SetWhereClause(
1079                 "(" + queryCondition + ") AND " + MediaColumn::MEDIA_TYPE + " = " + to_string(MEDIA_TYPE_VIDEO));
1080         }
1081         auto fileResultVideo = QueryGoToFirst(rdbStore, predicates, columns);
1082         if (fileResultVideo == nullptr) {
1083             MEDIA_ERR_LOG("Failed to query fileResultVideo");
1084             return E_HAS_DB_ERROR;
1085         }
1086         SetImageVideoCount(newCount, fileResultVideo, albumResult, values);
1087     }
1088     return E_SUCCESS;
1089 }
1090 
QueryAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore,const RdbPredicates predicates,vector<string> & albumId)1091 static void QueryAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore, const RdbPredicates predicates,
1092     vector<string> &albumId)
1093 {
1094     const vector<string> columns = {
1095         "Distinct " + PhotoColumn::PHOTO_OWNER_ALBUM_ID
1096     };
1097     auto resultSet = rdbStore->Query(predicates, columns);
1098     if (resultSet == nullptr) {
1099         MEDIA_WARN_LOG("Failed to Query");
1100         return;
1101     }
1102     while (resultSet->GoToNextRow() == E_OK) {
1103         albumId.push_back(to_string(GetIntValFromColumn(resultSet, 0)));
1104     }
1105 }
1106 
UpdateUserAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,const bool hiddenState,std::shared_ptr<TransactionOperations> trans)1107 static int32_t UpdateUserAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1108     const shared_ptr<ResultSet> &albumResult, const bool hiddenState, std::shared_ptr<TransactionOperations> trans)
1109 {
1110     MediaLibraryTracer tracer;
1111     tracer.Start("UpdateUserAlbumIfNeeded");
1112     if (trans == nullptr) {
1113         MEDIA_ERR_LOG("transactionOprn is null");
1114         return E_HAS_DB_ERROR;
1115     }
1116     ValuesBucket values;
1117     int err = SetUpdateValues(rdbStore, albumResult, values, static_cast<PhotoAlbumSubType>(0), hiddenState);
1118     if (err < 0) {
1119         MEDIA_ERR_LOG(
1120             "Failed to set update values when updating albums, album id: %{public}d, hidden state: %{public}d",
1121             GetAlbumId(albumResult), hiddenState ? 1 : 0);
1122         return err;
1123     }
1124     if (values.IsEmpty()) {
1125         return E_SUCCESS;
1126     }
1127 
1128     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
1129     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(GetAlbumId(albumResult)));
1130     predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::USER_GENERIC));
1131     int32_t changedRows = 0;
1132     err = trans->Update(changedRows, values, predicates);
1133     if (err != NativeRdb::E_OK) {
1134         MEDIA_ERR_LOG("Failed to update album count and cover! album id: %{public}d, hidden state: %{public}d",
1135             GetAlbumId(albumResult), hiddenState ? 1 : 0);
1136         return err;
1137     }
1138     return E_SUCCESS;
1139 }
1140 
UpdatePortraitAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,const vector<string> & fileIds,std::shared_ptr<TransactionOperations> trans)1141 static int32_t UpdatePortraitAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1142     const shared_ptr<ResultSet> &albumResult, const vector<string> &fileIds,
1143     std::shared_ptr<TransactionOperations> trans)
1144 {
1145     MediaLibraryTracer tracer;
1146     tracer.Start("UpdatePortraitAlbumIfNeeded");
1147     if (trans == nullptr) {
1148         MEDIA_ERR_LOG("transactionOprn is null");
1149         return E_HAS_DB_ERROR;
1150     }
1151     auto subtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
1152     if (subtype != PhotoAlbumSubType::PORTRAIT) {
1153         return E_SUCCESS;
1154     }
1155 
1156     ValuesBucket values;
1157     int32_t albumId = GetAlbumId(albumResult);
1158     int setRet = SetPortraitUpdateValues(rdbStore, albumResult, fileIds, values);
1159     if (setRet != E_SUCCESS) {
1160         MEDIA_ERR_LOG("Failed to set portrait album update values! album id: %{public}d, err: %{public}d", albumId,
1161             setRet);
1162         return setRet;
1163     }
1164     if (values.IsEmpty()) {
1165         return E_SUCCESS;
1166     }
1167 
1168     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
1169     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(albumId));
1170     int32_t changedRows = 0;
1171     int updateRet = trans->Update(changedRows, values, predicates);
1172     if (updateRet != NativeRdb::E_OK) {
1173         MEDIA_ERR_LOG("Failed to update album count and cover! album id: %{public}d, err: %{public}d", albumId,
1174             updateRet);
1175         return updateRet;
1176     }
1177     return E_SUCCESS;
1178 }
1179 
UpdateAnalysisAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,const bool hiddenState,std::shared_ptr<TransactionOperations> trans=nullptr)1180 static int32_t UpdateAnalysisAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1181     const shared_ptr<ResultSet> &albumResult, const bool hiddenState,
1182     std::shared_ptr<TransactionOperations> trans = nullptr)
1183 {
1184     MediaLibraryTracer tracer;
1185     tracer.Start("UpdateAnalysisAlbumIfNeeded");
1186     ValuesBucket values;
1187     auto subtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
1188     int err = SetUpdateValues(rdbStore, albumResult, values, subtype, hiddenState);
1189     if (err < 0) {
1190         MEDIA_ERR_LOG(
1191             "Failed to set update values when updating albums, album id: %{public}d, hidden state: %{public}d",
1192             GetAlbumId(albumResult), hiddenState ? 1 : 0);
1193         return err;
1194     }
1195     if (values.IsEmpty()) {
1196         return E_SUCCESS;
1197     }
1198 
1199     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
1200     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(GetAlbumId(albumResult)));
1201     int32_t changedRows = 0;
1202     if (trans == nullptr) {
1203         err = rdbStore->Update(changedRows, values, predicates);
1204     } else {
1205         err = trans->Update(changedRows, values, predicates);
1206     }
1207 
1208     if (err != NativeRdb::E_OK) {
1209         MEDIA_ERR_LOG("Failed to update album count and cover! album id: %{public}d, hidden state: %{public}d",
1210             GetAlbumId(albumResult), hiddenState ? 1 : 0);
1211         return err;
1212     }
1213     return E_SUCCESS;
1214 }
1215 
UpdateSourceAlbumIfNeeded(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,const bool hiddenState,std::shared_ptr<TransactionOperations> trans)1216 static int32_t UpdateSourceAlbumIfNeeded(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,
1217     const shared_ptr<ResultSet> &albumResult, const bool hiddenState, std::shared_ptr<TransactionOperations> trans)
1218 {
1219     if (trans == nullptr) {
1220         MEDIA_ERR_LOG("transactionOprn is null");
1221         return E_HAS_DB_ERROR;
1222     }
1223     MediaLibraryTracer tracer;
1224     tracer.Start("UpdateSourceAlbumIfNeeded");
1225     ValuesBucket values;
1226     auto subtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
1227     int err = SetUpdateValues(rdbStore, albumResult, values, subtype, hiddenState);
1228     if (err < 0) {
1229         MEDIA_ERR_LOG(
1230             "Failed to set update values when updating albums, album id: %{public}d, hidden state: %{public}d",
1231             GetAlbumId(albumResult), hiddenState ? 1 : 0);
1232         return err;
1233     }
1234     if (values.IsEmpty()) {
1235         return E_SUCCESS;
1236     }
1237 
1238     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
1239     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(GetAlbumId(albumResult)));
1240     predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::SOURCE_GENERIC));
1241     int32_t changedRows = 0;
1242     err = trans->Update(changedRows, values, predicates);
1243     if (err != NativeRdb::E_OK) {
1244         MEDIA_ERR_LOG("Failed to update album count and cover! album id: %{public}d, hidden state: %{public}d",
1245             GetAlbumId(albumResult), hiddenState ? 1 : 0);
1246         return err;
1247     }
1248     return E_SUCCESS;
1249 }
1250 
UpdateSysAlbumIfNeeded(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,const bool hiddenState,std::shared_ptr<TransactionOperations> trans)1251 static int32_t UpdateSysAlbumIfNeeded(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,
1252     const shared_ptr<ResultSet> &albumResult, const bool hiddenState, std::shared_ptr<TransactionOperations> trans)
1253 {
1254     if (trans == nullptr) {
1255         MEDIA_ERR_LOG("transactionOprn is null");
1256         return E_HAS_DB_ERROR;
1257     }
1258     ValuesBucket values;
1259     auto subtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
1260     MediaLibraryTracer tracer;
1261     tracer.Start("UpdateSysAlbum: " + to_string(subtype));
1262     int err = SetUpdateValues(rdbStore, albumResult, values, subtype, hiddenState);
1263     if (err < 0) {
1264         MEDIA_ERR_LOG(
1265             "Failed to set update values when updating albums, album id: %{public}d, hidden state: %{public}d",
1266             GetAlbumId(albumResult), hiddenState ? 1 : 0);
1267         return err;
1268     }
1269     if (values.IsEmpty()) {
1270         return E_SUCCESS;
1271     }
1272 
1273     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
1274     predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(subtype));
1275     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(GetAlbumId(albumResult)));
1276     int32_t changedRows = 0;
1277     err = trans->Update(changedRows, values, predicates);
1278     if (err != NativeRdb::E_OK) {
1279         MEDIA_ERR_LOG("Failed to update album count and cover! album id: %{public}d, hidden state: %{public}d",
1280             GetAlbumId(albumResult), hiddenState ? 1 : 0);
1281         return err;
1282     }
1283     return E_SUCCESS;
1284 }
1285 
UpdateUserAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & userAlbumIds={})1286 static void UpdateUserAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1287     const vector<string> &userAlbumIds = {})
1288 {
1289     MediaLibraryTracer tracer;
1290     tracer.Start("UpdateUserAlbumHiddenState");
1291     auto albumResult = GetUserAlbum(rdbStore, userAlbumIds, {
1292         PhotoAlbumColumns::ALBUM_ID,
1293         PhotoAlbumColumns::CONTAINS_HIDDEN,
1294         PhotoAlbumColumns::HIDDEN_COUNT,
1295         PhotoAlbumColumns::HIDDEN_COVER,
1296     });
1297     if (albumResult == nullptr) {
1298         return;
1299     }
1300     ForEachRow(rdbStore, albumResult, true, UpdateUserAlbumIfNeeded);
1301 }
1302 
CopyAssetIfNeed(int32_t fileId,int32_t albumId,const shared_ptr<MediaLibraryRdbStore> rdbStore,vector<int32_t> & updateIds)1303 static bool CopyAssetIfNeed(int32_t fileId, int32_t albumId,
1304     const shared_ptr<MediaLibraryRdbStore> rdbStore, vector<int32_t> &updateIds)
1305 {
1306     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1307     predicates.EqualTo(PhotoColumn::MEDIA_ID, fileId);
1308     vector<string> columns;
1309     shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->Query(predicates, columns);
1310     if (resultSet == nullptr) {
1311         return false;
1312     }
1313     bool needCopy = true;
1314     int64_t newAssetId = -1;
1315     if (resultSet->GoToFirstRow() == NativeRdb::E_OK) {
1316         auto albumIdQuery = GetIntValFromColumn(resultSet, PhotoColumn::PHOTO_OWNER_ALBUM_ID);
1317         if (albumIdQuery == albumId) {
1318             needCopy = false;
1319             updateIds.push_back(fileId);
1320         } else {
1321             needCopy = true;
1322             MEDIA_DEBUG_LOG("add assets: need copy assets id is: %{public}s", to_string(fileId).c_str());
1323             MediaLibraryAlbumFusionUtils::HandleSingleFileCopy(rdbStore, fileId, albumId, newAssetId);
1324             updateIds.push_back(newAssetId);
1325         }
1326     }
1327     return needCopy;
1328 }
1329 
UpdateUserAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris)1330 void MediaLibraryRdbUtils::UpdateUserAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1331     const vector<string> &uris)
1332 {
1333     MediaLibraryTracer tracer;
1334     tracer.Start("UpdateUserAlbumByUri");
1335 
1336     if (uris.size() == 0) {
1337         UpdateUserAlbumInternal(rdbStore);
1338         UpdateUserAlbumHiddenState(rdbStore);
1339     }
1340     vector<string> albumIds;
1341     string idArgs;
1342     for (size_t i = 0; i < uris.size(); i++) {
1343         string fileId = GetPhotoId(uris[i]);
1344         if (fileId.size() > 0) {
1345             idArgs.append("'").append(fileId).append("'").append(",");
1346         }
1347         if ((i == 0 || i % ALBUM_UPDATE_THRESHOLD != 0) && i < uris.size() - 1) {
1348             continue;
1349         }
1350         if (idArgs.size() == 0) {
1351             continue;
1352         }
1353         idArgs = idArgs.substr(0, idArgs.size() - 1);
1354         RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1355         predicates.SetWhereClause(PhotoColumn::MEDIA_ID + " in(" + idArgs + ") and " +
1356             PhotoColumn::PHOTO_OWNER_ALBUM_ID + " in(select " + PhotoAlbumColumns::ALBUM_ID + " from " +
1357             PhotoAlbumColumns::TABLE + " where " + PhotoAlbumColumns::ALBUM_TYPE + " = " +
1358             to_string(PhotoAlbumType::USER) + ")");
1359         QueryAlbumId(rdbStore, predicates, albumIds);
1360         idArgs.clear();
1361     }
1362     if (albumIds.size() > 0) {
1363         UpdateUserAlbumInternal(rdbStore, albumIds);
1364         UpdateUserAlbumHiddenState(rdbStore, albumIds);
1365     }
1366 }
1367 
UpdateUserAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & userAlbumIds)1368 void MediaLibraryRdbUtils::UpdateUserAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1369     const vector<string> &userAlbumIds)
1370 {
1371     MediaLibraryTracer tracer;
1372     tracer.Start("UpdateUserAlbumInternal");
1373 
1374     vector<string> columns = {
1375         PhotoAlbumColumns::ALBUM_ID,
1376         PhotoAlbumColumns::ALBUM_COVER_URI,
1377         PhotoAlbumColumns::ALBUM_COUNT,
1378         PhotoAlbumColumns::ALBUM_IMAGE_COUNT,
1379         PhotoAlbumColumns::ALBUM_VIDEO_COUNT,
1380     };
1381     auto albumResult = GetUserAlbum(rdbStore, userAlbumIds, columns);
1382     if (albumResult == nullptr) {
1383         return;
1384     }
1385     ForEachRow(rdbStore, albumResult, false, UpdateUserAlbumIfNeeded);
1386 }
1387 
GetIntFromResultSet(shared_ptr<ResultSet> resultSet,const string & column,int & value)1388 static int32_t GetIntFromResultSet(shared_ptr<ResultSet> resultSet, const string &column, int &value)
1389 {
1390     if (resultSet == nullptr) {
1391         return E_HAS_DB_ERROR;
1392     }
1393     int index = -1;
1394     resultSet->GetColumnIndex(column, index);
1395     if (index == -1) {
1396         return E_HAS_DB_ERROR;
1397     }
1398     if (resultSet->GetInt(index, value) != NativeRdb::E_OK) {
1399         return E_HAS_DB_ERROR;
1400     }
1401     return E_OK;
1402 }
1403 
GetStringFromResultSet(shared_ptr<ResultSet> resultSet,const string & column,string & value)1404 static int32_t GetStringFromResultSet(shared_ptr<ResultSet> resultSet, const string &column, string &value)
1405 {
1406     if (resultSet == nullptr) {
1407         return E_HAS_DB_ERROR;
1408     }
1409     int index = -1;
1410     resultSet->GetColumnIndex(column, index);
1411     if (index == -1) {
1412         return E_HAS_DB_ERROR;
1413     }
1414     if (resultSet->GetString(index, value) != NativeRdb::E_OK) {
1415         return E_HAS_DB_ERROR;
1416     }
1417     return E_OK;
1418 }
1419 
UpdateTrashedAssetOnAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,RdbPredicates & predicates)1420 int32_t MediaLibraryRdbUtils::UpdateTrashedAssetOnAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1421     RdbPredicates &predicates)
1422 {
1423     vector<string> newWhereIdArgs;
1424     for (auto albumId: predicates.GetWhereArgs()) {
1425         const std::string QUERY_FILE_ASSET_INFO = "SELECT * FROM Photos WHERE owner_album_id = " + albumId +
1426             " AND clean_flag =0 AND hidden =0";
1427         shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->QuerySql(QUERY_FILE_ASSET_INFO);
1428         vector<string> fileAssetsIds, fileAssetsUri;
1429         while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1430             int isHiddenAsset = 0;
1431             GetIntFromResultSet(resultSet, MediaColumn::MEDIA_HIDDEN, isHiddenAsset);
1432             if (isHiddenAsset == 1) {
1433                 continue;
1434             }
1435             int32_t fileId = -1;
1436             string assetData;
1437             GetIntFromResultSet(resultSet, MediaColumn::MEDIA_ID, fileId);
1438             GetStringFromResultSet(resultSet, MediaColumn::MEDIA_FILE_PATH, assetData);
1439             fileAssetsIds.push_back(to_string(fileId));
1440             string uri = MediaLibraryFormMapOperations::GetUriByFileId(fileId, assetData);
1441             fileAssetsUri.push_back(uri);
1442         }
1443         MediaLibraryPhotoOperations::UpdateSourcePath(fileAssetsIds);
1444         RdbPredicates predicatesPhotos(PhotoColumn::PHOTOS_TABLE);
1445         predicatesPhotos.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, albumId);
1446         predicatesPhotos.And()->In(MediaColumn::MEDIA_ID, fileAssetsIds);
1447         ValuesBucket values;
1448         values.Put(MediaColumn::MEDIA_DATE_TRASHED, MediaFileUtils::UTCTimeMilliSeconds());
1449         int32_t updateRow = -1;
1450         rdbStore->Update(updateRow, values, predicatesPhotos);
1451         if (updateRow < 0) {
1452             continue;
1453         }
1454         MediaLibraryRdbUtils::UpdateSystemAlbumInternal(rdbStore, {
1455             to_string(PhotoAlbumSubType::IMAGE), to_string(PhotoAlbumSubType::VIDEO),
1456             to_string(PhotoAlbumSubType::FAVORITE), to_string(PhotoAlbumSubType::TRASH),
1457             to_string(PhotoAlbumSubType::HIDDEN)
1458         });
1459         MediaLibraryRdbUtils::UpdateAnalysisAlbumByUri(rdbStore, fileAssetsUri);
1460         newWhereIdArgs.push_back(albumId);
1461         MediaAnalysisHelper::StartMediaAnalysisServiceAsync(
1462             static_cast<int32_t>(MediaAnalysisProxy::ActivateServiceType::START_UPDATE_INDEX), fileAssetsUri);
1463         MediaLibraryPhotoOperations::TrashPhotosSendNotify(fileAssetsUri);
1464     }
1465     predicates.SetWhereArgs(newWhereIdArgs);
1466     return newWhereIdArgs.size();
1467 }
1468 
UpdateRemoveAsset(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & whereIdArgs)1469 int32_t MediaLibraryRdbUtils::UpdateRemoveAsset(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1470     const vector<string> &whereIdArgs)
1471 {
1472     int32_t updateRows = 0;
1473     vector<string> fileAssetsUri;
1474     MediaLibraryPhotoOperations::UpdateSourcePath(whereIdArgs);
1475     for (auto assetId: whereIdArgs) {
1476         const std::string QUERY_FILE_ASSET_INFO = "SELECT * FROM Photos WHERE file_id = " + assetId;
1477         shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->QuerySql(QUERY_FILE_ASSET_INFO);
1478         if (resultSet->GoToFirstRow() == NativeRdb::E_OK && resultSet != nullptr) {
1479             string assetData;
1480             GetStringFromResultSet(resultSet, MediaColumn::MEDIA_FILE_PATH, assetData);
1481             if (MediaLibraryDataManagerUtils::IsNumber(assetId)) {
1482                 string uri = MediaLibraryFormMapOperations::GetUriByFileId(stoi(assetId), assetData);
1483                 fileAssetsUri.push_back(uri);
1484             }
1485         }
1486     }
1487     RdbPredicates predicatesPhotos(PhotoColumn::PHOTOS_TABLE);
1488     predicatesPhotos.In(MediaColumn::MEDIA_ID, whereIdArgs);
1489     ValuesBucket values;
1490     values.Put(MediaColumn::MEDIA_DATE_TRASHED, MediaFileUtils::UTCTimeMilliSeconds());
1491     rdbStore->Update(updateRows, values, predicatesPhotos);
1492     if (updateRows < 0) {
1493         MEDIA_ERR_LOG("Failed to remove assets");
1494         return E_HAS_DB_ERROR;
1495     }
1496     MediaLibraryRdbUtils::UpdateSystemAlbumInternal(rdbStore, {
1497         to_string(PhotoAlbumSubType::IMAGE), to_string(PhotoAlbumSubType::VIDEO),
1498         to_string(PhotoAlbumSubType::FAVORITE), to_string(PhotoAlbumSubType::TRASH),
1499         to_string(PhotoAlbumSubType::HIDDEN)
1500     });
1501     MediaAnalysisHelper::StartMediaAnalysisServiceAsync(
1502         static_cast<int32_t>(MediaAnalysisProxy::ActivateServiceType::START_UPDATE_INDEX), fileAssetsUri);
1503     MediaLibraryPhotoOperations::TrashPhotosSendNotify(fileAssetsUri);
1504     return updateRows;
1505 }
1506 
UpdateOwnerAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<DataShare::DataShareValuesBucket> & values,vector<int32_t> & updateIds)1507 int32_t MediaLibraryRdbUtils::UpdateOwnerAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1508     const vector<DataShare::DataShareValuesBucket> &values, vector<int32_t> &updateIds)
1509 {
1510     vector<string> whereIdArgs;
1511     int32_t updateRows = 0;
1512     bool isValid = false;
1513     int32_t albumId = values[0].Get(PhotoColumn::PHOTO_OWNER_ALBUM_ID, isValid);
1514     for (const auto &value : values) {
1515         bool isValidNew = false;
1516         std::string assetUri = value.Get(MediaColumn::MEDIA_ID, isValidNew);
1517         if (!MediaFileUtils::StartsWith(assetUri, PhotoColumn::PHOTO_URI_PREFIX)) {
1518             continue;
1519         }
1520         auto photoId = std::stoi(MediaFileUri::GetPhotoId(assetUri));
1521         if (CopyAssetIfNeed(photoId, albumId, rdbStore, updateIds)) {
1522             updateRows++;
1523             continue;
1524         }
1525         whereIdArgs.push_back(MediaFileUri::GetPhotoId(assetUri));
1526     }
1527     if (whereIdArgs.empty()) {
1528         MEDIA_INFO_LOG("add assets: no need copy assets is 0 for update owner album id");
1529         return updateRows;
1530     }
1531     RdbPredicates updatePredicates(PhotoColumn::PHOTOS_TABLE);
1532     updatePredicates.In(MediaColumn::MEDIA_ID, whereIdArgs);
1533     ValuesBucket updateValues;
1534     updateValues.PutString(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
1535     int32_t changedRowsNoNeedCopy = 0;
1536     int err = rdbStore->Update(changedRowsNoNeedCopy, updateValues, updatePredicates);
1537     if (err != NativeRdb::E_OK) {
1538         MEDIA_ERR_LOG("Failed to update owner album id");
1539     }
1540     return updateRows + changedRowsNoNeedCopy;
1541 }
1542 
QueryAnalysisAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore,const RdbPredicates predicates,vector<string> & albumId)1543 static void QueryAnalysisAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore, const RdbPredicates predicates,
1544     vector<string> &albumId)
1545 {
1546     const vector<string> columns = {
1547         "Distinct " + PhotoMap::ALBUM_ID
1548     };
1549     auto resultSet = rdbStore->Query(predicates, columns);
1550     if (resultSet == nullptr) {
1551         MEDIA_WARN_LOG("Failed to Query Analysis Album ID");
1552         return;
1553     }
1554     while (resultSet->GoToNextRow() == E_OK) {
1555         albumId.push_back(to_string(GetIntValFromColumn(resultSet, 0)));
1556     }
1557 }
1558 
UpdateAnalysisAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris)1559 void MediaLibraryRdbUtils::UpdateAnalysisAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1560     const vector<string> &uris)
1561 {
1562     MediaLibraryTracer tracer;
1563     tracer.Start("UpdateAnalysisAlbumByUri");
1564 
1565     if (uris.size() == 0) {
1566         UpdateAnalysisAlbumInternal(rdbStore);
1567     }
1568     vector<string> albumIds;
1569     vector<string> idArgs;
1570     vector<string> fileIds;
1571     for (size_t i = 0; i < uris.size(); i++) {
1572         string fileId = GetPhotoId(uris[i]);
1573         if (fileId.size() > 0) {
1574             idArgs.push_back(fileId);
1575             fileIds.push_back(fileId);
1576         }
1577         if (idArgs.size() == ALBUM_UPDATE_THRESHOLD || i == uris.size() - 1) {
1578             RdbPredicates predicates(ANALYSIS_PHOTO_MAP_TABLE);
1579             predicates.In(PhotoMap::ASSET_ID, idArgs);
1580             QueryAnalysisAlbumId(rdbStore, predicates, albumIds);
1581             idArgs.clear();
1582         }
1583     }
1584     if (albumIds.size() > 0) {
1585         UpdateAnalysisAlbumInternal(rdbStore, albumIds, fileIds);
1586     }
1587 }
1588 
GetAlbumIdsForPortrait(const shared_ptr<MediaLibraryRdbStore> rdbStore,vector<string> & portraitAlbumIds)1589 int32_t MediaLibraryRdbUtils::GetAlbumIdsForPortrait(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1590     vector<string> &portraitAlbumIds)
1591 {
1592     std::stringstream labelIds;
1593     unordered_set<string> resultAlbumIds;
1594     for (size_t i = 0; i < portraitAlbumIds.size(); i++) {
1595         labelIds << portraitAlbumIds[i];
1596         if (i != portraitAlbumIds.size() - 1) {
1597             labelIds << ",";
1598         }
1599         resultAlbumIds.insert(portraitAlbumIds[i]);
1600     }
1601 
1602     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
1603     predicates.SetWhereClause(GROUP_TAG + " IN(SELECT " + GROUP_TAG + " FROM " + ANALYSIS_ALBUM_TABLE +
1604         " WHERE " + ALBUM_ID + " IN (" + labelIds.str() + ") AND " + ALBUM_SUBTYPE + " = " + to_string(PORTRAIT) +")");
1605     vector<string> columns = {
1606         ALBUM_ID,
1607     };
1608     auto resultSet = rdbStore->Query(predicates, columns);
1609     if (resultSet == nullptr) {
1610         return E_HAS_DB_ERROR;
1611     }
1612     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1613         string albumId = to_string(GetIntValFromColumn(resultSet, ALBUM_ID));
1614         if (resultAlbumIds.find(albumId) == resultAlbumIds.end()) {
1615             resultAlbumIds.insert(albumId);
1616             portraitAlbumIds.push_back(albumId);
1617         }
1618     }
1619     return E_OK;
1620 }
1621 
GetAlbumSubtypeArgument(const RdbPredicates & predicates)1622 int32_t MediaLibraryRdbUtils::GetAlbumSubtypeArgument(const RdbPredicates &predicates)
1623 {
1624     string whereClause = predicates.GetWhereClause();
1625     vector<string> whereArgs = predicates.GetWhereArgs();
1626     size_t subtypePos = whereClause.find(PhotoAlbumColumns::ALBUM_SUBTYPE + " = ?");
1627     if (subtypePos == string::npos) {
1628         return E_ERR;
1629     }
1630     size_t argsIndex = 0;
1631     for (size_t i = 0; i < subtypePos; i++) {
1632         if (whereClause[i] == '?') {
1633             argsIndex++;
1634         }
1635     }
1636     if (argsIndex > whereArgs.size() - 1) {
1637         return E_ERR;
1638     }
1639     const string &subtype = whereArgs[argsIndex];
1640     if (subtype.empty() || !MediaLibraryDataManagerUtils::IsNumber(subtype)) {
1641         return E_ERR;
1642     }
1643     return std::stoi(subtype);
1644 }
1645 
UpdateAnalysisAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & anaAlbumAlbumIds,const vector<string> & fileIds)1646 void MediaLibraryRdbUtils::UpdateAnalysisAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1647     const vector<string> &anaAlbumAlbumIds, const vector<string> &fileIds)
1648 {
1649     MediaLibraryTracer tracer;
1650     tracer.Start("UpdateAnalysisAlbumInternal");
1651     vector<string> columns = {
1652         PhotoAlbumColumns::ALBUM_ID,
1653         PhotoAlbumColumns::ALBUM_SUBTYPE,
1654         PhotoAlbumColumns::ALBUM_COVER_URI,
1655         PhotoAlbumColumns::ALBUM_COUNT,
1656         IS_COVER_SATISFIED
1657     };
1658     vector<string> tempAlbumId = anaAlbumAlbumIds;
1659     if (tempAlbumId.size() > 0) {
1660         GetAlbumIdsForPortrait(rdbStore, tempAlbumId);
1661     }
1662     auto albumResult = GetAnalysisAlbum(rdbStore, tempAlbumId, columns);
1663     if (albumResult == nullptr) {
1664         return;
1665     }
1666 
1667     // For each row
1668     int32_t err = NativeRdb::E_OK;
1669     while (albumResult->GoToNextRow() == E_OK) {
1670         int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
1671         std::shared_ptr<TransactionOperations> trans = make_shared<TransactionOperations>();
1672         std::function<int(void)> func = [&]()->int {
1673             auto subtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
1674             if (subtype == PhotoAlbumSubType::PORTRAIT) {
1675                 UpdatePortraitAlbumIfNeeded(rdbStore, albumResult, fileIds, trans);
1676             } else {
1677                 UpdateAnalysisAlbumIfNeeded(rdbStore, albumResult, false, trans);
1678             }
1679             return err;
1680         };
1681         err = trans->RetryTrans(func, __func__);
1682         if (err != E_OK) {
1683             MEDIA_ERR_LOG("UpdateAnalysisAlbumInternal: tans finish fail!, ret:%{public}d", err);
1684         }
1685         int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
1686         if ((end - start) > UPDATE_ALBUM_TIME_OUT) {
1687             MEDIA_INFO_LOG("udpate analysis album: %{public}d cost %{public}ld", GetAlbumId(albumResult),
1688                 static_cast<long>(end - start));
1689         }
1690     }
1691 }
1692 
UpdateAnalysisAlbumByFile(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & fileIds,const vector<int> & albumTypes)1693 void MediaLibraryRdbUtils::UpdateAnalysisAlbumByFile(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1694     const vector<string> &fileIds, const vector<int> &albumTypes)
1695 {
1696     if (fileIds.empty()) {
1697         MEDIA_ERR_LOG("Failed to UpdateAnalysisAlbumByFile cause fileIds empty");
1698         return;
1699     }
1700     MediaLibraryTracer tracer;
1701     tracer.Start("UpdateAnalysisAlbumByFile");
1702     vector<string> columns = {
1703         PhotoMap::ALBUM_ID,
1704         PhotoMap::ASSET_ID,
1705     };
1706     RdbPredicates predicates(ANALYSIS_PHOTO_MAP_TABLE);
1707     if (!albumTypes.empty()) {
1708         std::string files;
1709         for (std::string fileId : fileIds) {
1710             files.append("'").append(fileId).append("'").append(",");
1711         }
1712         files = files.substr(0, files.length() - 1);
1713         std::string subTypes;
1714         for (int subtype : albumTypes) {
1715             subTypes.append(to_string(subtype)).append(",");
1716         }
1717         subTypes = subTypes.substr(0, subTypes.length() - 1);
1718         predicates.SetWhereClause(PhotoMap::ASSET_ID + " in(" + files + ") and " + PhotoMap::ALBUM_ID +
1719             " in(select album_id from AnalysisAlbum where album_subtype in(" + subTypes + "))");
1720     } else {
1721         predicates.In(PhotoMap::ASSET_ID, fileIds);
1722     }
1723     shared_ptr<ResultSet> mapResult = rdbStore->Query(predicates, columns);
1724     if (mapResult == nullptr) {
1725         MEDIA_ERR_LOG("Failed query AnalysisAlbum");
1726         return;
1727     }
1728     vector<string> albumIds;
1729     while (mapResult->GoToNextRow() == E_OK) {
1730         albumIds.push_back(to_string(GetIntValFromColumn(mapResult, PhotoMap::ALBUM_ID)));
1731     }
1732     int err = E_HAS_DB_ERROR;
1733     int32_t deletedRows = 0;
1734     err = rdbStore->Delete(deletedRows, predicates);
1735     if (err != E_OK || deletedRows <= 0) {
1736         MEDIA_ERR_LOG("Failed Delete AnalysisPhotoMap");
1737         return;
1738     }
1739     UpdateAnalysisAlbumInternal(rdbStore, albumIds, fileIds);
1740 }
1741 
UpdateSourceAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & sourceAlbumIds={})1742 static void UpdateSourceAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1743     const vector<string> &sourceAlbumIds = {})
1744 {
1745     MediaLibraryTracer tracer;
1746     tracer.Start("UpdateSourceAlbumHiddenState");
1747 
1748     auto albumResult = GetSourceAlbum(rdbStore, sourceAlbumIds, {
1749         PhotoAlbumColumns::ALBUM_ID,
1750         PhotoAlbumColumns::ALBUM_SUBTYPE,
1751         PhotoAlbumColumns::CONTAINS_HIDDEN,
1752         PhotoAlbumColumns::HIDDEN_COUNT,
1753         PhotoAlbumColumns::HIDDEN_COVER,
1754     });
1755     if (albumResult == nullptr) {
1756         return;
1757     }
1758     ForEachRow(rdbStore, albumResult, true, UpdateSourceAlbumIfNeeded);
1759 }
1760 
UpdateSourceAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris)1761 void MediaLibraryRdbUtils::UpdateSourceAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1762     const vector<string> &uris)
1763 {
1764     MediaLibraryTracer tracer;
1765     tracer.Start("UpdateSourceAlbumByUri");
1766 
1767     if (uris.size() == 0) {
1768         UpdateSourceAlbumInternal(rdbStore);
1769         UpdateSourceAlbumHiddenState(rdbStore);
1770     }
1771     vector<string> albumIds;
1772     string idArgs;
1773     for (size_t i = 0; i < uris.size(); i++) {
1774         string fileId = GetPhotoId(uris[i]);
1775         if (fileId.size() > 0) {
1776             idArgs.append("'").append(fileId).append("'").append(",");
1777         }
1778         if ((i == 0 || i % ALBUM_UPDATE_THRESHOLD != 0) && i < uris.size() - 1) {
1779             continue;
1780         }
1781         if (idArgs.size() == 0) {
1782             continue;
1783         }
1784         idArgs = idArgs.substr(0, idArgs.size() - 1);
1785         RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1786         predicates.SetWhereClause(PhotoColumn::MEDIA_ID + " in(" + idArgs + ") and " +
1787             PhotoColumn::PHOTO_OWNER_ALBUM_ID + " in(select " + PhotoAlbumColumns::ALBUM_ID + " from " +
1788             PhotoAlbumColumns::TABLE + " where " + PhotoAlbumColumns::ALBUM_TYPE + " = " +
1789             to_string(PhotoAlbumType::SOURCE) + ")");
1790         QueryAlbumId(rdbStore, predicates, albumIds);
1791         idArgs.clear();
1792     }
1793     if (albumIds.size() > 0) {
1794         UpdateSourceAlbumInternal(rdbStore, albumIds);
1795         UpdateSourceAlbumHiddenState(rdbStore, albumIds);
1796     }
1797 }
1798 
UpdateSourceAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & sourceAlbumIds)1799 void MediaLibraryRdbUtils::UpdateSourceAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1800     const vector<string> &sourceAlbumIds)
1801 {
1802     MediaLibraryTracer tracer;
1803     tracer.Start("UpdateSourceAlbumInternal");
1804 
1805     vector<string> columns = {
1806         PhotoAlbumColumns::ALBUM_ID,
1807         PhotoAlbumColumns::ALBUM_SUBTYPE,
1808         PhotoAlbumColumns::ALBUM_COVER_URI,
1809         PhotoAlbumColumns::ALBUM_COUNT,
1810         PhotoAlbumColumns::ALBUM_IMAGE_COUNT,
1811         PhotoAlbumColumns::ALBUM_VIDEO_COUNT,
1812     };
1813     auto albumResult = GetSourceAlbum(rdbStore, sourceAlbumIds, columns);
1814     if (albumResult == nullptr) {
1815         return;
1816     }
1817 
1818     ForEachRow(rdbStore, albumResult, false, UpdateSourceAlbumIfNeeded);
1819 }
1820 
GetSystemAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes,const vector<string> & columns)1821 static inline shared_ptr<ResultSet> GetSystemAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1822     const vector<string> &subtypes, const vector<string> &columns)
1823 {
1824     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
1825     if (subtypes.empty()) {
1826         predicates.In(PhotoAlbumColumns::ALBUM_SUBTYPE, ALL_SYS_PHOTO_ALBUM);
1827     } else {
1828         predicates.In(PhotoAlbumColumns::ALBUM_SUBTYPE, subtypes);
1829     }
1830     return rdbStore->QueryWithFilter(predicates, columns);
1831 }
1832 
UpdateSystemAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes)1833 void MediaLibraryRdbUtils::UpdateSystemAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1834     const vector<string> &subtypes)
1835 {
1836     MediaLibraryTracer tracer;
1837     tracer.Start("UpdateSystemAlbumInternal");
1838 
1839     vector<string> columns = {
1840         PhotoAlbumColumns::ALBUM_ID,
1841         PhotoAlbumColumns::ALBUM_SUBTYPE,
1842         PhotoAlbumColumns::ALBUM_COVER_URI,
1843         PhotoAlbumColumns::ALBUM_COUNT,
1844         PhotoAlbumColumns::ALBUM_IMAGE_COUNT,
1845         PhotoAlbumColumns::ALBUM_VIDEO_COUNT,
1846     };
1847     auto albumResult = GetSystemAlbum(rdbStore, subtypes, columns);
1848     if (albumResult == nullptr) {
1849         return;
1850     }
1851     ForEachRow(rdbStore, albumResult, false, UpdateSysAlbumIfNeeded);
1852 }
1853 
UpdateSysAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes)1854 void MediaLibraryRdbUtils::UpdateSysAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1855     const vector<string> &subtypes)
1856 {
1857     MediaLibraryTracer tracer;
1858     tracer.Start("UpdateSysAlbumHiddenState");
1859 
1860     shared_ptr<ResultSet> albumResult = nullptr;
1861 
1862     const vector<string> columns = {
1863         PhotoAlbumColumns::ALBUM_ID,
1864         PhotoAlbumColumns::ALBUM_SUBTYPE,
1865         PhotoAlbumColumns::CONTAINS_HIDDEN,
1866         PhotoAlbumColumns::HIDDEN_COUNT,
1867         PhotoAlbumColumns::HIDDEN_COVER,
1868     };
1869 
1870     if (subtypes.empty()) {
1871         albumResult = GetSystemAlbum(rdbStore, {
1872             to_string(PhotoAlbumSubType::IMAGE),
1873             to_string(PhotoAlbumSubType::VIDEO),
1874             to_string(PhotoAlbumSubType::FAVORITE),
1875             to_string(PhotoAlbumSubType::SCREENSHOT),
1876             to_string(PhotoAlbumSubType::CAMERA),
1877             to_string(PhotoAlbumSubType::CLOUD_ENHANCEMENT),
1878         }, columns);
1879     } else {
1880         albumResult = GetSystemAlbum(rdbStore, subtypes, columns);
1881     }
1882 
1883     if (albumResult == nullptr) {
1884         return;
1885     }
1886     ForEachRow(rdbStore, albumResult, true, UpdateSysAlbumIfNeeded);
1887 }
1888 
UpdateAllAlbums(shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris)1889 void MediaLibraryRdbUtils::UpdateAllAlbums(shared_ptr<MediaLibraryRdbStore> rdbStore, const vector<string> &uris)
1890 {
1891     MediaLibraryTracer tracer;
1892     tracer.Start("UpdateAllAlbums");
1893     if (rdbStore == nullptr) {
1894         MEDIA_ERR_LOG("Failed to get rdbstore, try again!");
1895         rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1896         if (rdbStore == nullptr) {
1897             MEDIA_ERR_LOG("Fatal error! Failed to get rdbstore, new cloud data is not processed!!");
1898             return;
1899         }
1900     }
1901 
1902     vector<string> systemAlbumsExcludeSource = {
1903         to_string(PhotoAlbumSubType::FAVORITE),
1904         to_string(PhotoAlbumSubType::VIDEO),
1905         to_string(PhotoAlbumSubType::HIDDEN),
1906         to_string(PhotoAlbumSubType::TRASH),
1907         to_string(PhotoAlbumSubType::IMAGE),
1908         to_string(PhotoAlbumSubType::CLOUD_ENHANCEMENT),
1909     };
1910     MediaLibraryRdbUtils::UpdateSystemAlbumInternal(rdbStore, systemAlbumsExcludeSource);
1911     MediaLibraryRdbUtils::UpdateSysAlbumHiddenState(rdbStore);
1912     MediaLibraryRdbUtils::UpdateUserAlbumByUri(rdbStore, uris);
1913     MediaLibraryRdbUtils::UpdateSourceAlbumByUri(rdbStore, uris);
1914     MediaLibraryRdbUtils::UpdateAnalysisAlbumByUri(rdbStore, uris);
1915 }
1916 
UpdateAlbumReplacedSignal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & albumIdVector)1917 static int32_t UpdateAlbumReplacedSignal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1918     const vector<string> &albumIdVector)
1919 {
1920     if (albumIdVector.empty()) {
1921         return E_SUCCESS;
1922     }
1923 
1924     ValuesBucket refreshValues;
1925     string insertRefreshTableSql = "INSERT OR IGNORE INTO " + ALBUM_REFRESH_TABLE + " VALUES ";
1926     for (size_t i = 0; i < albumIdVector.size(); ++i) {
1927         if (i != albumIdVector.size() - 1) {
1928             insertRefreshTableSql += "(" + albumIdVector[i] + "), ";
1929         } else {
1930             insertRefreshTableSql += "(" + albumIdVector[i] + ");";
1931         }
1932     }
1933     MEDIA_DEBUG_LOG("output insertRefreshTableSql:%{public}s", insertRefreshTableSql.c_str());
1934 
1935     int32_t ret = rdbStore->ExecuteSql(insertRefreshTableSql);
1936     if (ret != NativeRdb::E_OK) {
1937         MEDIA_ERR_LOG("Can not insert refreshed table, ret:%{public}d", ret);
1938         return E_HAS_DB_ERROR;
1939     }
1940     return E_SUCCESS;
1941 }
1942 
UpdateBussinessRecord(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<BussinessRecordValue> & updateValue)1943 static int32_t UpdateBussinessRecord(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1944     const vector<BussinessRecordValue> &updateValue)
1945 {
1946     if (updateValue.empty()) {
1947         return E_SUCCESS;
1948     }
1949 
1950     ValuesBucket refreshValues;
1951     string insertTableSql = "INSERT OR IGNORE INTO " + MedialibraryBusinessRecordColumn::TABLE + "(" +
1952         MedialibraryBusinessRecordColumn::BUSINESS_TYPE + "," + MedialibraryBusinessRecordColumn::KEY + "," +
1953         MedialibraryBusinessRecordColumn::VALUE + ") VALUES ";
1954     for (size_t i = 0; i < updateValue.size(); ++i) {
1955         if (i != updateValue.size() - 1) {
1956             insertTableSql += "('" + updateValue[i].bussinessType + "', '" + updateValue[i].key + "', '" +
1957                 updateValue[i].value + "'), ";
1958         } else {
1959             insertTableSql += "('" + updateValue[i].bussinessType + "', '" + updateValue[i].key + "', '" +
1960                 updateValue[i].value + "');";
1961         }
1962     }
1963     MEDIA_DEBUG_LOG("output insertTableSql:%{public}s", insertTableSql.c_str());
1964 
1965     int32_t ret = rdbStore->ExecuteSql(insertTableSql);
1966     if (ret != NativeRdb::E_OK) {
1967         MEDIA_ERR_LOG("Can not insert bussinessRecord table, ret:%{public}d", ret);
1968         return E_HAS_DB_ERROR;
1969     }
1970     return E_SUCCESS;
1971 }
1972 
UpdateSystemAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes)1973 void MediaLibraryRdbUtils::UpdateSystemAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1974     const vector<string> &subtypes)
1975 {
1976     // Only use in dfs
1977     MediaLibraryTracer tracer;
1978     tracer.Start("UpdateSystemAlbumCountInternal");
1979 
1980     vector<string> columns = { PhotoAlbumColumns::ALBUM_ID };
1981     auto albumResult = GetSystemAlbum(rdbStore, subtypes, columns);
1982     if (albumResult == nullptr) {
1983         return;
1984     }
1985 
1986     vector<string> replaceSignalAlbumVector;
1987     while (albumResult->GoToNextRow() == NativeRdb::E_OK) {
1988         int32_t ret = GetIntValFromColumn(albumResult, PhotoAlbumColumns::ALBUM_ID);
1989         if (ret <= 0) {
1990             MEDIA_WARN_LOG("Can not get ret:%{public}d", ret);
1991         } else {
1992             replaceSignalAlbumVector.push_back(to_string(ret));
1993         }
1994     }
1995     if (!replaceSignalAlbumVector.empty()) {
1996         int32_t ret = UpdateAlbumReplacedSignal(rdbStore, replaceSignalAlbumVector);
1997         if (ret != E_OK) {
1998             MEDIA_WARN_LOG("Update sysalbum replaced signal failed ret:%{public}d", ret);
1999         }
2000     }
2001     // Do not call SetNeedRefreshAlbum in this function
2002     // This is set by the notification from dfs
2003     // and is set by the media library observer after receiving the notification
2004 }
2005 
UpdateUserAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & userAlbumIds)2006 void MediaLibraryRdbUtils::UpdateUserAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2007     const vector<string> &userAlbumIds)
2008 {
2009     // only use in dfs
2010     MediaLibraryTracer tracer;
2011     tracer.Start("UpdateUserAlbumCountInternal");
2012 
2013     vector<string> columns = { PhotoAlbumColumns::ALBUM_ID };
2014     auto albumResult = GetUserAlbum(rdbStore, userAlbumIds, columns);
2015     if (albumResult == nullptr) {
2016         return;
2017     }
2018 
2019     vector<string> replaceSignalAlbumVector;
2020     while (albumResult->GoToNextRow() == NativeRdb::E_OK) {
2021         int32_t ret = GetIntValFromColumn(albumResult, PhotoAlbumColumns::ALBUM_ID);
2022         if (ret <= 0) {
2023             MEDIA_WARN_LOG("Can not get ret:%{public}d", ret);
2024         } else {
2025             replaceSignalAlbumVector.push_back(to_string(ret));
2026         }
2027     }
2028     if (!replaceSignalAlbumVector.empty()) {
2029         int32_t ret = UpdateAlbumReplacedSignal(rdbStore, replaceSignalAlbumVector);
2030         if (ret != E_OK) {
2031             MEDIA_WARN_LOG("Update user album replaced signal failed ret:%{public}d", ret);
2032             return;
2033         }
2034     }
2035     // Do not call SetNeedRefreshAlbum in this function
2036     // This is set by the notification from dfs
2037     // and is set by the media library observer after receiving the notification
2038 }
2039 
UpdateAnalysisAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes)2040 void MediaLibraryRdbUtils::UpdateAnalysisAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2041     const vector<string> &subtypes)
2042 {
2043     // only use in dfs
2044     MediaLibraryTracer tracer;
2045     tracer.Start("UpdateAnalysisAlbumCountInternal");
2046 
2047     vector<string> columns = { ALBUM_ID, ALBUM_SUBTYPE };
2048     auto albumResult = GetAnalysisAlbumBySubtype(rdbStore, subtypes, columns);
2049     if (albumResult == nullptr) {
2050         return;
2051     }
2052 
2053     vector<BussinessRecordValue> updateAlbumIdList;
2054     while (albumResult->GoToNextRow() == NativeRdb::E_OK) {
2055         int32_t albumId = GetIntValFromColumn(albumResult, ALBUM_ID);
2056         int32_t subtype = GetIntValFromColumn(albumResult, ALBUM_SUBTYPE);
2057         if (albumId <= 0) {
2058             MEDIA_WARN_LOG("Can not get ret:%{public}d", albumId);
2059         } else {
2060             updateAlbumIdList.push_back({ ANALYSIS_REFRESH_BUSINESS_TYPE, to_string(subtype), to_string(albumId) });
2061         }
2062     }
2063     if (!updateAlbumIdList.empty()) {
2064         int32_t ret = UpdateBussinessRecord(rdbStore, updateAlbumIdList);
2065         if (ret != E_OK) {
2066             MEDIA_WARN_LOG("Update sysalbum replaced signal failed ret:%{public}d", ret);
2067         }
2068     }
2069     // Do not call SetNeedRefreshAlbum in this function
2070     // This is set by the notification from dfs
2071     // and is set by the media library observer after receiving the notification
2072 }
2073 
RefreshPhotoAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,function<void (PhotoAlbumType,PhotoAlbumSubType,int)> refreshProcessHandler)2074 int RefreshPhotoAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2075     function<void(PhotoAlbumType, PhotoAlbumSubType, int)> refreshProcessHandler)
2076 {
2077     int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
2078     vector<string> albumIds;
2079     int ret = GetAllRefreshAlbumIds(rdbStore, albumIds);
2080     if (ret != E_SUCCESS) {
2081         MEDIA_ERR_LOG("Failed to get refresh album ids");
2082         return ret;
2083     }
2084     if (albumIds.empty()) {
2085         MEDIA_INFO_LOG("albumIds is empty");
2086         return E_EMPTY_ALBUM_ID;
2087     }
2088     MEDIA_INFO_LOG("Start refresh album task");
2089     auto resultSet = QueryAlbumById(rdbStore, albumIds);
2090     if (resultSet == nullptr) {
2091         MEDIA_ERR_LOG("RefreshPhotoAlbums resultSet is null");
2092         return E_HAS_DB_ERROR;
2093     }
2094     ret = RefreshAlbums(rdbStore, resultSet, refreshProcessHandler);
2095     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
2096     MEDIA_INFO_LOG("%{public}d photo albums update cost %{public}ld", (int)albumIds.size(), (long)(end - start));
2097     return ret;
2098 }
2099 
RefreshAnalysisAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<ResultSet> & albumResult,function<void (PhotoAlbumType,PhotoAlbumSubType,int)> refreshProcessHandler,const vector<string> & subtypes)2100 static int32_t RefreshAnalysisAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2101     const shared_ptr<ResultSet> &albumResult,
2102     function<void(PhotoAlbumType, PhotoAlbumSubType, int)> refreshProcessHandler,
2103     const vector<string> &subtypes)
2104 {
2105     while (albumResult->GoToNextRow() == NativeRdb::E_OK) {
2106         int ret = UpdateAnalysisAlbumIfNeeded(rdbStore, albumResult, false);
2107         if (ret != E_SUCCESS) {
2108             MEDIA_ERR_LOG("UpdateAnalysisAlbumIfNeeded fail");
2109             return E_HAS_DB_ERROR;
2110         }
2111         auto subtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
2112         int32_t albumId = GetAlbumId(albumResult);
2113         refreshProcessHandler(PhotoAlbumType::SMART, subtype, albumId);
2114     }
2115 
2116     string deleteRefreshTableSql = "DELETE FROM " + MedialibraryBusinessRecordColumn::TABLE + " WHERE " +
2117         MedialibraryBusinessRecordColumn::BUSINESS_TYPE + " = '" + ANALYSIS_REFRESH_BUSINESS_TYPE + "'";
2118     int32_t ret = rdbStore->ExecuteSql(deleteRefreshTableSql);
2119     if (ret != NativeRdb::E_OK) {
2120         MEDIA_ERR_LOG("Failed to execute sql:%{private}s", deleteRefreshTableSql.c_str());
2121         return E_HAS_DB_ERROR;
2122     }
2123     MEDIA_DEBUG_LOG("Delete RefreshAnalysisAlbums success");
2124     return E_SUCCESS;
2125 }
2126 
GetRefreshAnalysisAlbumIds(const shared_ptr<MediaLibraryRdbStore> rdbStore,vector<string> & albumIds,const vector<string> & subtypes)2127 static int32_t GetRefreshAnalysisAlbumIds(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2128     vector<string> &albumIds, const vector<string> &subtypes)
2129 {
2130     RdbPredicates predicates(MedialibraryBusinessRecordColumn::TABLE);
2131     if (!subtypes.empty()) {
2132         predicates.In(MedialibraryBusinessRecordColumn::KEY, subtypes);
2133     } else {
2134         predicates.In(MedialibraryBusinessRecordColumn::KEY, ALL_ANALYSIS_ALBUM);
2135     }
2136     predicates.EqualTo(MedialibraryBusinessRecordColumn::BUSINESS_TYPE, ANALYSIS_REFRESH_BUSINESS_TYPE);
2137 
2138     vector<string> columns = { MedialibraryBusinessRecordColumn::VALUE };
2139     auto resultSet = rdbStore->Query(predicates, columns);
2140     if (resultSet == nullptr) {
2141         MEDIA_ERR_LOG("Can not query ALBUM_REFRESH_TABLE");
2142         return E_HAS_DB_ERROR;
2143     }
2144 
2145     int32_t count = 0;
2146     int32_t ret = resultSet->GetRowCount(count);
2147     if (ret != NativeRdb::E_OK) {
2148         MEDIA_ERR_LOG("GetRowCount failed ret:%{public}d", ret);
2149         return E_HAS_DB_ERROR;
2150     }
2151     if (count == 0) {
2152         MEDIA_DEBUG_LOG("count is zero, break");
2153         return E_SUCCESS;
2154     }
2155 
2156     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
2157         int32_t columnIndex = 0;
2158         ret = resultSet->GetColumnIndex(MedialibraryBusinessRecordColumn::VALUE, columnIndex);
2159         if (ret != NativeRdb::E_OK) {
2160             MEDIA_ERR_LOG("GetColumnIndex failed ret:%{public}d", ret);
2161             return E_HAS_DB_ERROR;
2162         }
2163         string refreshAlbumId;
2164         ret = resultSet->GetString(columnIndex, refreshAlbumId);
2165         if (ret != NativeRdb::E_OK) {
2166             MEDIA_ERR_LOG("GetString failed ret:%{public}d", ret);
2167             return E_HAS_DB_ERROR;
2168         }
2169         albumIds.push_back(refreshAlbumId);
2170     }
2171     return E_SUCCESS;
2172 }
2173 
RefreshAnalysisPhotoAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,function<void (PhotoAlbumType,PhotoAlbumSubType,int)> refreshProcessHandler,const vector<string> & subtypes)2174 int RefreshAnalysisPhotoAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2175     function<void(PhotoAlbumType, PhotoAlbumSubType, int)> refreshProcessHandler, const vector<string> &subtypes)
2176 {
2177     int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
2178     vector<string> albumIds;
2179     int ret = GetRefreshAnalysisAlbumIds(rdbStore, albumIds, subtypes);
2180     if (ret != E_SUCCESS) {
2181         return ret;
2182     }
2183     if (albumIds.empty()) {
2184         MEDIA_DEBUG_LOG("albumIds is empty");
2185         return E_EMPTY_ALBUM_ID;
2186     }
2187     vector<string> columns = {
2188         PhotoAlbumColumns::ALBUM_ID,
2189         PhotoAlbumColumns::ALBUM_SUBTYPE,
2190         PhotoAlbumColumns::ALBUM_COVER_URI,
2191         PhotoAlbumColumns::ALBUM_COUNT,
2192     };
2193     auto resultSet = GetAnalysisAlbum(rdbStore, albumIds, columns);
2194     if (resultSet == nullptr) {
2195         ret = E_HAS_DB_ERROR;
2196         return E_HAS_DB_ERROR;
2197     }
2198     ret = RefreshAnalysisAlbums(rdbStore, resultSet, refreshProcessHandler, subtypes);
2199     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
2200     MEDIA_INFO_LOG("%{public}d analysis albums update cost %{public}ld", (int)albumIds.size(), (long)(end - start));
2201     return ret;
2202 }
2203 
IsRefreshAlbumEmpty(const shared_ptr<MediaLibraryRdbStore> rdbStore)2204 static bool IsRefreshAlbumEmpty(const shared_ptr<MediaLibraryRdbStore> rdbStore)
2205 {
2206     RdbPredicates predicates(ALBUM_REFRESH_TABLE);
2207     vector<string> columns = { REFRESHED_ALBUM_ID };
2208     auto resultSet = rdbStore->Query(predicates, columns);
2209     if (resultSet == nullptr) {
2210         MEDIA_ERR_LOG("Can not query ALBUM_REFRESH_TABLE");
2211         return true;
2212     }
2213     int32_t count = -1;
2214     int32_t ret = resultSet->GetRowCount(count);
2215     MEDIA_DEBUG_LOG("RefreshAllAlbuming remain count:%{public}d", count);
2216     return count <= 0;
2217 }
2218 
RefreshAllAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,function<void (PhotoAlbumType,PhotoAlbumSubType,int)> refreshProcessHandler,function<void ()> refreshCallback)2219 int32_t MediaLibraryRdbUtils::RefreshAllAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2220     function<void(PhotoAlbumType, PhotoAlbumSubType, int)> refreshProcessHandler, function<void()> refreshCallback)
2221 {
2222     unique_lock<mutex> lock(sRefreshAlbumMutex_);
2223     if (IsInRefreshTask()) {
2224         lock.unlock();
2225         MEDIA_DEBUG_LOG("RefreshAllAlbuming, quit");
2226         return E_OK;
2227     }
2228     isInRefreshTask = true;
2229     lock.unlock();
2230 
2231     MediaLibraryTracer tracer;
2232     tracer.Start("RefreshAllAlbums");
2233 
2234     if (rdbStore == nullptr) {
2235         MEDIA_ERR_LOG("Can not get rdb");
2236         return E_HAS_DB_ERROR;
2237     }
2238 
2239     int ret = E_SUCCESS;
2240     bool isRefresh = false;
2241     while (IsNeedRefreshAlbum() || !IsRefreshAlbumEmpty(rdbStore)) {
2242         SetNeedRefreshAlbum(false);
2243         ret = RefreshPhotoAlbums(rdbStore, refreshProcessHandler);
2244         if (ret == E_EMPTY_ALBUM_ID) {
2245             ret = E_SUCCESS;
2246             continue;
2247         }
2248         if (ret != E_SUCCESS) {
2249             break;
2250         }
2251         this_thread::sleep_for(chrono::milliseconds(PowerEfficiencyManager::GetAlbumUpdateInterval()));
2252         isRefresh = true;
2253     }
2254 
2255     if (ret != E_SUCCESS) {
2256         // refresh failed and set flag, try to refresh next time
2257         SetNeedRefreshAlbum(true);
2258     } else {
2259         // refresh task is successful
2260         SetNeedRefreshAlbum(false);
2261     }
2262     isInRefreshTask = false;
2263     if (isRefresh) {
2264         refreshCallback();
2265     }
2266 
2267     return ret;
2268 }
2269 
UpdateAllAlbumsForCloud(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2270 void MediaLibraryRdbUtils::UpdateAllAlbumsForCloud(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2271 {
2272     // 注意,端云同步代码仓也有相同函数,添加新相册时,请通知端云同步进行相应修改
2273     MediaLibraryRdbUtils::UpdateSystemAlbumInternal(rdbStore);
2274     MediaLibraryRdbUtils::UpdateUserAlbumInternal(rdbStore);
2275     MediaLibraryRdbUtils::UpdateAnalysisAlbumInternal(rdbStore);
2276 }
2277 
UpdateAllAlbumsCountForCloud(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2278 void MediaLibraryRdbUtils::UpdateAllAlbumsCountForCloud(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2279 {
2280     // 注意,端云同步代码仓也有相同函数,添加新相册时,请通知端云同步进行相应修改
2281     MediaLibraryRdbUtils::UpdateSystemAlbumCountInternal(rdbStore);
2282     MediaLibraryRdbUtils::UpdateUserAlbumCountInternal(rdbStore);
2283     vector<string> subtype = { "4101" };
2284     MediaLibraryRdbUtils::UpdateAnalysisAlbumCountInternal(rdbStore, subtype);
2285 }
2286 
AddQueryIndex(AbsPredicates & predicates,const vector<string> & columns)2287 void MediaLibraryRdbUtils::AddQueryIndex(AbsPredicates& predicates, const vector<string>& columns)
2288 {
2289     auto it = find(columns.begin(), columns.end(), MEDIA_COLUMN_COUNT);
2290     if (it == columns.end()) {
2291         return;
2292     }
2293     const string &group = predicates.GetGroup();
2294     if (group.empty()) {
2295         predicates.GroupBy({ PhotoColumn::PHOTO_DATE_DAY });
2296         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_DAY_INDEX);
2297         return;
2298     }
2299     if (group == PhotoColumn::MEDIA_TYPE) {
2300         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_MEDIA_TYPE_INDEX);
2301         return;
2302     }
2303     if (group == PhotoColumn::PHOTO_DATE_DAY) {
2304         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_DAY_INDEX);
2305         return;
2306     }
2307 }
2308 
AddVirtualColumnsOfDateType(vector<string> & columns)2309 void MediaLibraryRdbUtils::AddVirtualColumnsOfDateType(vector<string>& columns)
2310 {
2311     vector<string> dateTypes = { MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_DATE_TRASHED, MEDIA_DATA_DB_DATE_MODIFIED,
2312             MEDIA_DATA_DB_DATE_TAKEN };
2313     vector<string> dateTypeSeconds = { MEDIA_DATA_DB_DATE_ADDED_TO_SECOND,
2314             MEDIA_DATA_DB_DATE_TRASHED_TO_SECOND, MEDIA_DATA_DB_DATE_MODIFIED_TO_SECOND,
2315             MEDIA_DATA_DB_DATE_TAKEN_TO_SECOND };
2316     for (size_t i = 0; i < dateTypes.size(); i++) {
2317         auto it = find(columns.begin(), columns.end(), dateTypes[i]);
2318         if (it != columns.end()) {
2319             columns.push_back(dateTypeSeconds[i]);
2320         }
2321     }
2322 }
2323 
GetPhotoAndKnowledgeConnection()2324 vector<string> GetPhotoAndKnowledgeConnection()
2325 {
2326     vector<string> clauses;
2327     clauses.push_back(
2328         PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LATITUDE + " = " + GEO_KNOWLEDGE_TABLE + "." + LATITUDE);
2329     clauses.push_back(
2330         PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LONGITUDE + " = " + GEO_KNOWLEDGE_TABLE + "." + LONGITUDE);
2331     return clauses;
2332 }
2333 
QueryCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,const RdbPredicates & predicates)2334 int QueryCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore, const RdbPredicates &predicates)
2335 {
2336     const vector<string> columns = { MEDIA_COLUMN_COUNT_1 };
2337     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
2338     if (fetchResult == nullptr) {
2339         return 0;
2340     }
2341     return GetFileCount(fetchResult);
2342 }
2343 
GetNewKnowledgeDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2344 int GetNewKnowledgeDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2345 {
2346     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
2347     predicates.BeginWrap()->BeginWrap()
2348         ->LessThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LATITUDE, LOCATION_LATITUDE_MAX)
2349         ->And()->GreaterThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LATITUDE, LOCATION_DB_ZERO)
2350         ->EndWrap()->Or()->BeginWrap()
2351         ->LessThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LATITUDE, LOCATION_DB_ZERO)
2352         ->And()->GreaterThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LATITUDE, LOCATION_LATITUDE_MIN)
2353         ->EndWrap()->EndWrap()->And()->BeginWrap()->BeginWrap()
2354         ->LessThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LONGITUDE, LOCATION_LONGITUDE_MAX)->And()
2355         ->GreaterThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LONGITUDE, LOCATION_DB_ZERO)->EndWrap()
2356         ->Or()->BeginWrap()->LessThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LONGITUDE, LOCATION_DB_ZERO)
2357         ->And()->GreaterThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LONGITUDE, LOCATION_LONGITUDE_MIN)
2358         ->EndWrap()->EndWrap();
2359     auto clauses = GetPhotoAndKnowledgeConnection();
2360     predicates.LeftOuterJoin(GEO_KNOWLEDGE_TABLE)->On(clauses);
2361     predicates.And()->BeginWrap()
2362         ->IsNull(GEO_KNOWLEDGE_TABLE + "." + LATITUDE)
2363         ->Or()->IsNull(GEO_KNOWLEDGE_TABLE + "." + LONGITUDE)
2364         ->Or()->IsNull(GEO_KNOWLEDGE_TABLE + "." + LANGUAGE)
2365         ->EndWrap();
2366 
2367     return QueryCount(rdbStore, predicates);
2368 }
2369 
GetUpdateKnowledgeDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2370 int GetUpdateKnowledgeDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2371 {
2372     RdbPredicates predicates(GEO_KNOWLEDGE_TABLE);
2373     predicates.LessThan(GEO_KNOWLEDGE_TABLE + "." + LOCATION_KEY, 0);
2374     return QueryCount(rdbStore, predicates);
2375 }
2376 
GetNewDictionaryDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2377 int GetNewDictionaryDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2378 {
2379     RdbPredicates predicates(GEO_KNOWLEDGE_TABLE);
2380     vector<string> clauses;
2381     clauses.push_back(GEO_KNOWLEDGE_TABLE + "." + CITY_ID + " = " + GEO_DICTIONARY_TABLE + "." + CITY_ID);
2382     clauses.push_back(GEO_KNOWLEDGE_TABLE + "." + LANGUAGE + " = " + GEO_DICTIONARY_TABLE + "." + LANGUAGE);
2383     predicates.LeftOuterJoin(GEO_DICTIONARY_TABLE)->On(clauses);
2384     predicates.BeginWrap()->IsNull(GEO_DICTIONARY_TABLE + "." + CITY_ID)
2385         ->And()->IsNotNull(GEO_KNOWLEDGE_TABLE + "." + COUNTRY)->EndWrap();
2386     vector<string> columns;
2387     auto resultSet = QueryGoToFirst(rdbStore, predicates, columns);
2388     if (resultSet == nullptr) {
2389         return 0;
2390     }
2391     set<string> citySet;
2392     do {
2393         string cityId = GetStringValFromColumn(resultSet, CITY_ID);
2394         string cityName = GetStringValFromColumn(resultSet, CITY_NAME);
2395         if (cityId == "" || cityName == "") {
2396             continue;
2397         }
2398         citySet.insert(cityId);
2399     } while (!resultSet->GoToNextRow());
2400     return citySet.size();
2401 }
2402 
HasLocationData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2403 bool HasLocationData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2404 {
2405     int newDataCount = GetNewKnowledgeDataCount(rdbStore);
2406     int updateDataCount = GetUpdateKnowledgeDataCount(rdbStore);
2407     MEDIA_INFO_LOG("loc newDataCount:%{public}d, updateDataCount:%{public}d", newDataCount, updateDataCount);
2408 
2409     int newDictionaryCount = GetNewDictionaryDataCount(rdbStore);
2410     MEDIA_INFO_LOG("newDictionaryCount:%{public}d", newDictionaryCount);
2411     return (newDataCount + updateDataCount + newDictionaryCount) > 0;
2412 }
2413 
GetCvDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2414 int GetCvDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2415 {
2416     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
2417     vector<string> clauses;
2418     clauses.push_back(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_ID  + " = " +
2419         VISION_TOTAL_TABLE + "." + PhotoColumn::MEDIA_ID);
2420     predicates.InnerJoin(VISION_TOTAL_TABLE)->On(clauses);
2421     predicates.BeginWrap()->EqualTo(VISION_TOTAL_TABLE + "." + STATUS, 0)->And()
2422         ->BeginWrap()->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_TIME_PENDING, 0)->And()
2423         ->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_DATE_TRASHED, 0)->And()
2424         ->BeginWrap()->NotEqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_POSITION, CLOUD_POSITION_STATUS)
2425         ->Or()->BeginWrap()
2426         ->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_POSITION, CLOUD_POSITION_STATUS)->And()
2427         ->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_THUMB_STATUS, 0)
2428         ->EndWrap()->EndWrap()->EndWrap()->EndWrap();
2429     return QueryCount(rdbStore, predicates);
2430 }
2431 
HasCvData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2432 bool HasCvData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2433 {
2434     int count = GetCvDataCount(rdbStore);
2435     MEDIA_INFO_LOG("cv count:%{public}d", count);
2436     return count > 0;
2437 }
2438 
GetSearchBaseCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2439 int GetSearchBaseCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2440 {
2441     RdbPredicates predicates(SEARCH_TOTAL_TABLE);
2442     vector<string> clasues;
2443     clasues.push_back(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_FILE_ID + " = " +
2444         PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_ID);
2445     predicates.InnerJoin(PhotoColumn::PHOTOS_TABLE)->On(clasues);
2446     predicates.EqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_PHOTO_STATUS, 0)
2447         ->And()
2448         ->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_TIME_PENDING, 0)
2449         ->And()
2450         ->GreaterThanOrEqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_FILE_ID, 0);
2451     return QueryCount(rdbStore, predicates);
2452 }
2453 
GetSearchUpdateCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2454 int GetSearchUpdateCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2455 {
2456     RdbPredicates predicates(SEARCH_TOTAL_TABLE);
2457     vector<string> clauses;
2458     clauses.push_back(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_FILE_ID + " = " +
2459         PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_ID);
2460     vector<string> clausesTotal;
2461     clausesTotal.push_back(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_FILE_ID + " = " +
2462         VISION_TOTAL_TABLE + "." + PhotoColumn::MEDIA_ID);
2463     vector<string> clausesGeo;
2464     clausesGeo.push_back(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LATITUDE + " = " + GEO_KNOWLEDGE_TABLE + "." + LATITUDE);
2465     clausesGeo.push_back(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LONGITUDE +
2466         " = " + GEO_KNOWLEDGE_TABLE + "." + LONGITUDE);
2467     predicates.InnerJoin(PhotoColumn::PHOTOS_TABLE)->On(clauses);
2468     predicates.InnerJoin(VISION_TOTAL_TABLE)->On(clausesTotal);
2469     predicates.LeftOuterJoin(GEO_KNOWLEDGE_TABLE)->On(clausesGeo);
2470     predicates.GreaterThanOrEqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_FILE_ID, 0)->And()
2471         ->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_TIME_PENDING, 0)->And()
2472         ->GreaterThan(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_PHOTO_STATUS, 0)->And()
2473         ->BeginWrap()->EqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_PHOTO_STATUS, SEARCH_UPDATE_STATUS)->Or()
2474         ->BeginWrap()->EqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_CV_STATUS, SEARCH_UPDATE_STATUS)->And()
2475         ->EqualTo(VISION_TOTAL_TABLE + "." + FACE, FACE_CLUSTERED)->EndWrap()->Or()
2476         ->BeginWrap()->EqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_CV_STATUS, 0)->And()
2477         ->BeginWrap()->NotEqualTo(VISION_TOTAL_TABLE + "." + OCR, 0)->Or()
2478         ->NotEqualTo(VISION_TOTAL_TABLE + "." + LABEL, 0)->Or()
2479         ->BeginWrap()->NotEqualTo(VISION_TOTAL_TABLE + "." + FACE, 0)->And()
2480         ->NotEqualTo(VISION_TOTAL_TABLE + "." + FACE, FACE_RECOGNITION)->And()
2481         ->NotEqualTo(VISION_TOTAL_TABLE + "." + FACE, FACE_FEATURE)->EndWrap()->EndWrap()->EndWrap()->Or()
2482         ->BeginWrap()->EqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_GEO_STATUS, 0)->And()
2483         ->BeginWrap()->NotEqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LATITUDE, 0)->Or()
2484         ->NotEqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LONGITUDE, 0)->EndWrap()->And()
2485         ->IsNotNull(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LATITUDE)->And()
2486         ->IsNotNull(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LONGITUDE)->And()
2487         ->BeginWrap()->IsNotNull(GEO_KNOWLEDGE_TABLE + "." + LATITUDE)->And()
2488         ->IsNotNull(GEO_KNOWLEDGE_TABLE + "." + LONGITUDE)->EndWrap()->EndWrap()->EndWrap();
2489     return QueryCount(rdbStore, predicates);
2490 }
2491 
HasSearchData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2492 bool HasSearchData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2493 {
2494     int baseCount = GetSearchBaseCount(rdbStore);
2495     int upateCount = GetSearchUpdateCount(rdbStore);
2496     MEDIA_INFO_LOG("baseCount:%{public}d, upateCount:%{public}d", baseCount, upateCount);
2497     return (baseCount + upateCount) > 0;
2498 }
2499 
HasHighLightData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2500 bool HasHighLightData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2501 {
2502     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
2503     vector<string> clauses;
2504     clauses.push_back(ANALYSIS_ALBUM_TABLE + "." + ALBUM_ID + " = " +
2505         HIGHLIGHT_COVER_INFO_TABLE + "." + ALBUM_ID);
2506     predicates.InnerJoin(HIGHLIGHT_COVER_INFO_TABLE)->On(clauses);
2507     predicates.EqualTo(ANALYSIS_ALBUM_TABLE + "." + ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::HIGHLIGHT))->And()
2508         ->NotEqualTo(ANALYSIS_ALBUM_TABLE + "." + PhotoAlbumColumns::ALBUM_COVER_URI,
2509         HIGHLIGHT_COVER_INFO_TABLE + "." + COVER_KEY);
2510     int count = QueryCount(rdbStore, predicates);
2511     MEDIA_INFO_LOG("highligh count:%{public}d", count);
2512     return (count > 0);
2513 }
2514 
HasDataToAnalysis(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2515 bool MediaLibraryRdbUtils::HasDataToAnalysis(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2516 {
2517     if (rdbStore == nullptr) {
2518         MEDIA_ERR_LOG("HasDataToAnalysis rdbstore is null");
2519         return false;
2520     }
2521     bool loc = HasLocationData(rdbStore);
2522     bool cv = HasCvData(rdbStore);
2523     bool search = HasSearchData(rdbStore);
2524     bool highlight = HasHighLightData(rdbStore);
2525     return (loc || cv || search || highlight);
2526 }
2527 } // namespace OHOS::Media
2528