• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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_app_uri_permission_column.h"
26 #include "media_column.h"
27 #include "media_file_uri.h"
28 #include "media_file_utils.h"
29 #include "media_log.h"
30 #include "media_refresh_album_column.h"
31 #include "medialibrary_album_helper.h"
32 #include "medialibrary_album_fusion_utils.h"
33 #include "medialibrary_async_worker.h"
34 #include "medialibrary_business_record_column.h"
35 #include "medialibrary_data_manager_utils.h"
36 #include "medialibrary_db_const.h"
37 #include "medialibrary_formmap_operations.h"
38 #include "medialibrary_notify.h"
39 #include "medialibrary_photo_operations.h"
40 #include "medialibrary_rdb_transaction.h"
41 #include "medialibrary_tracer.h"
42 #include "permission_utils.h"
43 #include "photo_album_column.h"
44 #include "photo_map_column.h"
45 #include "result_set.h"
46 #include "result_set_utils.h"
47 #include "userfile_manager_types.h"
48 #include "vision_album_column.h"
49 #include "vision_column.h"
50 #include "vision_face_tag_column.h"
51 #include "vision_image_face_column.h"
52 #include "vision_photo_map_column.h"
53 #include "vision_total_column.h"
54 #include "location_column.h"
55 #include "search_column.h"
56 #include "story_cover_info_column.h"
57 #include "story_play_info_column.h"
58 #include "shooting_mode_column.h"
59 #include "photo_query_filter.h"
60 #include "power_efficiency_manager.h"
61 #include "rdb_sql_utils.h"
62 #include "medialibrary_restore.h"
63 #include "album_accurate_refresh_manager.h"
64 #include "refresh_business_name.h"
65 
66 namespace OHOS::Media {
67 using namespace std;
68 using namespace NativeRdb;
69 
70 constexpr int32_t E_EMPTY_ALBUM_ID = 1;
71 constexpr size_t ALBUM_UPDATE_THRESHOLD = 1000;
72 constexpr int32_t SINGLE_FACE = 1;
73 constexpr double LOCATION_DB_ZERO = 0;
74 constexpr double LOCATION_LATITUDE_MAX = 90.0;
75 constexpr double LOCATION_LATITUDE_MIN = -90.0;
76 constexpr double LOCATION_LONGITUDE_MAX = 180.0;
77 constexpr double LOCATION_LONGITUDE_MIN = -180.0;
78 constexpr int32_t SEARCH_UPDATE_STATUS = 2;
79 constexpr int32_t FACE_RECOGNITION = 1;
80 constexpr int32_t FACE_FEATURE = 2;
81 constexpr int32_t FACE_CLUSTERED = 3;
82 constexpr int32_t CLOUD_POSITION_STATUS = 2;
83 constexpr int32_t UPDATE_ALBUM_TIME_OUT = 1000;
84 constexpr int32_t PERSIST_READ_IMAGEVIDEO = 1;
85 constexpr int32_t PERSIST_READWRITE_IMAGEVIDEO = 4;
86 
87 const string INTEGRITY_CHECK_COLUMN = "quick_check";
88 const std::string DB_INTEGRITY_CHECK = "ok";
89 mutex MediaLibraryRdbUtils::sRefreshAlbumMutex_;
90 std::map<PhotoAlbumSubType, int32_t> MediaLibraryRdbUtils::subType2AlbumIdMap;
91 
92 // 注意,端云同步代码仓也有相同常量,添加新相册时,请通知端云同步进行相应修改
93 const std::vector<std::string> ALL_SYS_PHOTO_ALBUM = {
94     std::to_string(PhotoAlbumSubType::FAVORITE),
95     std::to_string(PhotoAlbumSubType::VIDEO),
96     std::to_string(PhotoAlbumSubType::HIDDEN),
97     std::to_string(PhotoAlbumSubType::TRASH),
98     std::to_string(PhotoAlbumSubType::SCREENSHOT),
99     std::to_string(PhotoAlbumSubType::CAMERA),
100     std::to_string(PhotoAlbumSubType::IMAGE),
101     std::to_string(PhotoAlbumSubType::CLOUD_ENHANCEMENT),
102     std::to_string(PhotoAlbumSubType::SOURCE_GENERIC),
103 };
104 
105 // 注意,端云同步代码仓也有相同常量,添加新相册时,请通知端云同步进行相应修改
106 const vector<string> ALL_ANALYSIS_ALBUM = {
107     to_string(PhotoAlbumSubType::CLASSIFY),
108     to_string(PhotoAlbumSubType::GEOGRAPHY_LOCATION),
109     to_string(PhotoAlbumSubType::GEOGRAPHY_CITY),
110     to_string(PhotoAlbumSubType::SHOOTING_MODE),
111     to_string(PhotoAlbumSubType::PORTRAIT),
112 };
113 
114 const vector<string> PHOTO_ALBUM_INFO_COLUMNS = {
115     PhotoAlbumColumns::ALBUM_ID,
116     PhotoAlbumColumns::ALBUM_SUBTYPE,
117     PhotoAlbumColumns::ALBUM_COVER_URI,
118     PhotoAlbumColumns::ALBUM_COUNT,
119     PhotoAlbumColumns::ALBUM_IMAGE_COUNT,
120     PhotoAlbumColumns::ALBUM_VIDEO_COUNT,
121     PhotoAlbumColumns::COVER_DATE_TIME,
122 };
123 
124 const vector<string> PHOTO_ALBUM_HIDDEN_INFO_COLUMNS = {
125     PhotoAlbumColumns::ALBUM_ID,
126     PhotoAlbumColumns::ALBUM_SUBTYPE,
127     PhotoAlbumColumns::HIDDEN_COUNT,
128     PhotoAlbumColumns::HIDDEN_COVER,
129     PhotoAlbumColumns::HIDDEN_COVER_DATE_TIME,
130 };
131 
132 const vector<string> SYSTEM_ALBUMS = {
133     to_string(PhotoAlbumSubType::FAVORITE),
134     to_string(PhotoAlbumSubType::VIDEO),
135     to_string(PhotoAlbumSubType::HIDDEN),
136     to_string(PhotoAlbumSubType::TRASH),
137     to_string(PhotoAlbumSubType::IMAGE),
138     to_string(PhotoAlbumSubType::CLOUD_ENHANCEMENT),
139 };
140 
141 struct BussinessRecordValue {
142     string bussinessType;
143     string key;
144     string value;
145 };
146 
147 struct RefreshAlbumData {
148     int32_t albumId;
149     int32_t albumSubtype;
150 };
151 
152 struct UpdateAlbumDataWithCache {
153     int32_t albumCount;
154     string albumCoverUri;
155 };
156 
157 enum UpdateAlbumType {
158     UPDATE_SYSTEM_ALBUM = 400,
159     UPDATE_HIDDEN_ALBUM,
160     UPDATE_USER_ALBUM,
161     UPDATE_SOURCE_ALBUM,
162     UPDATE_ANALYSIS_ALBUM,
163 };
164 
165 using UpdateHandler = std::function<int32_t(
166     const shared_ptr<MediaLibraryRdbStore> &rdbStore,
167     UpdateAlbumData &data,
168     const bool hiddenState,
169     AccurateRefresh::AlbumAccurateRefresh &albumRefresh)>;
170 
171 atomic<bool> MediaLibraryRdbUtils::isNeedRefreshAlbum = false;
172 atomic<bool> MediaLibraryRdbUtils::isInRefreshTask = false;
173 
174 const string ANALYSIS_REFRESH_BUSINESS_TYPE = "ANALYSIS_ALBUM_REFRESH";
175 const std::string MEDIA_COLUMN_COUNT_DISTINCT_FILE_ID = "count(distinct file_id)";
176 
GetStringValFromColumn(const shared_ptr<ResultSet> & resultSet,const int index)177 static inline string GetStringValFromColumn(const shared_ptr<ResultSet> &resultSet, const int index)
178 {
179     string value;
180     if (resultSet->GetString(index, value)) {
181         return "";
182     }
183     return value;
184 }
185 
GetIntValFromColumn(const shared_ptr<ResultSet> & resultSet,const int index)186 static inline int32_t GetIntValFromColumn(const shared_ptr<ResultSet> &resultSet, const int index)
187 {
188     int32_t value = 0;
189     if (resultSet->GetInt(index, value)) {
190         return 0;
191     }
192     return value;
193 }
194 
GetInt64ValFromColumn(const shared_ptr<ResultSet> & resultSet,const int index)195 static inline int64_t GetInt64ValFromColumn(const shared_ptr<ResultSet> &resultSet, const int index)
196 {
197     int64_t value = 0;
198     if (resultSet->GetLong(index, value)) {
199         return 0;
200     }
201     return value;
202 }
203 
GetStringValFromColumn(const shared_ptr<ResultSet> & resultSet,const string & columnName)204 static inline string GetStringValFromColumn(const shared_ptr<ResultSet> &resultSet, const string &columnName)
205 {
206     int32_t index = 0;
207     if (resultSet->GetColumnIndex(columnName, index)) {
208         return "";
209     }
210 
211     return GetStringValFromColumn(resultSet, index);
212 }
213 
GetIntValFromColumn(const shared_ptr<ResultSet> & resultSet,const string & columnName)214 static inline int32_t GetIntValFromColumn(const shared_ptr<ResultSet> &resultSet, const string &columnName)
215 {
216     int32_t index = 0;
217     if (resultSet->GetColumnIndex(columnName, index)) {
218         return 0;
219     }
220 
221     return GetIntValFromColumn(resultSet, index);
222 }
223 
GetLongValFromColumn(const shared_ptr<ResultSet> & resultSet,const string & columnName)224 static inline int64_t GetLongValFromColumn(const shared_ptr<ResultSet> &resultSet, const string &columnName)
225 {
226     int32_t index = 0;
227     if (resultSet->GetColumnIndex(columnName, index)) {
228         return 0;
229     }
230 
231     int64_t integer64Val;
232     if (resultSet->GetLong(index, integer64Val)) {
233         return 0;
234     }
235     return integer64Val;
236 }
237 
GetInt64ValFromColumn(const shared_ptr<ResultSet> & resultSet,const string & columnName)238 static inline int64_t GetInt64ValFromColumn(const shared_ptr<ResultSet> &resultSet, const string &columnName)
239 {
240     int32_t index = 0;
241     if (resultSet->GetColumnIndex(columnName, index)) {
242         return 0;
243     }
244 
245     return GetInt64ValFromColumn(resultSet, index);
246 }
247 
GetTypeFromCountVariation(UpdateAlbumData & data)248 static NotifyType GetTypeFromCountVariation(UpdateAlbumData &data)
249 {
250     int oldCount = data.albumVideoCount + data.albumImageCount;
251     int newCount = data.newTotalCount;
252     if (oldCount < newCount) {
253         return NOTIFY_ALBUM_ADD_ASSET;
254     } else if (oldCount > newCount) {
255         return NOTIFY_ALBUM_REMOVE_ASSET;
256     } else {
257         return NOTIFY_UPDATE;
258     }
259 }
260 
SendAlbumIdNotify(UpdateAlbumData & data)261 static void SendAlbumIdNotify(UpdateAlbumData &data)
262 {
263     auto watch = MediaLibraryNotify::GetInstance();
264     if (watch != nullptr && data.shouldNotify && data.hasChanged && data.albumSubtype != PhotoAlbumSubType::TRASH &&
265         data.albumSubtype != PhotoAlbumSubType::HIDDEN) {
266         NotifyType type = GetTypeFromCountVariation(data);
267         watch->Notify(PhotoColumn::PHOTO_URI_PREFIX, type, data.albumId);
268         MEDIA_INFO_LOG("send notification albumId: %{public}d, type:%{public}d", data.albumId, type);
269     }
270 }
271 
GetUserAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & userAlbumIds,const vector<string> & columns)272 static inline shared_ptr<ResultSet> GetUserAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,
273     const vector<string> &userAlbumIds, const vector<string> &columns)
274 {
275     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
276     if (userAlbumIds.empty()) {
277         predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::USER_GENERIC));
278     } else {
279         predicates.In(PhotoAlbumColumns::ALBUM_ID, userAlbumIds);
280     }
281     CHECK_AND_RETURN_RET(rdbStore != nullptr, nullptr);
282     return rdbStore->Query(predicates, columns);
283 }
284 
GetAnalysisAlbum(const shared_ptr<MediaLibraryRdbStore> & rdbStore,const vector<string> & analysisAlbumIds,const vector<string> & columns)285 static inline shared_ptr<ResultSet> GetAnalysisAlbum(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
286     const vector<string> &analysisAlbumIds, const vector<string> &columns)
287 {
288     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
289     if (!analysisAlbumIds.empty()) {
290         predicates.In(PhotoAlbumColumns::ALBUM_ID, analysisAlbumIds);
291     }
292     CHECK_AND_RETURN_RET(rdbStore != nullptr, nullptr);
293     return rdbStore->Query(predicates, columns);
294 }
295 
GetSourceAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & sourceAlbumIds,const vector<string> & columns)296 static inline shared_ptr<ResultSet> GetSourceAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,
297     const vector<string> &sourceAlbumIds, const vector<string> &columns)
298 {
299     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
300     if (!sourceAlbumIds.empty()) {
301         predicates.In(PhotoAlbumColumns::ALBUM_ID, sourceAlbumIds);
302     } else {
303         predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::SOURCE_GENERIC));
304     }
305     CHECK_AND_RETURN_RET(rdbStore != nullptr, nullptr);
306     return rdbStore->Query(predicates, columns);
307 }
308 
GetCommonAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & albumIds,const vector<string> & columns)309 static shared_ptr<ResultSet> GetCommonAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,
310     const vector<string> &albumIds, const vector<string> &columns)
311 {
312     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
313     if (!albumIds.empty()) {
314         predicates.In(PhotoAlbumColumns::ALBUM_ID, albumIds);
315     } else {
316         predicates.BeginWrap();
317         predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::SOURCE_GENERIC));
318         predicates.Or();
319         predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::USER_GENERIC));
320         predicates.EndWrap();
321     }
322     CHECK_AND_RETURN_RET(rdbStore != nullptr, nullptr);
323     return rdbStore->Query(predicates, columns);
324 }
325 
GetAnalysisAlbumBySubtype(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes,const vector<string> & columns)326 static inline shared_ptr<ResultSet> GetAnalysisAlbumBySubtype(const shared_ptr<MediaLibraryRdbStore> rdbStore,
327     const vector<string> &subtypes, const vector<string> &columns)
328 {
329     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
330     if (!subtypes.empty()) {
331         predicates.In(ALBUM_SUBTYPE, subtypes);
332     } else {
333         predicates.In(ALBUM_SUBTYPE, ALL_ANALYSIS_ALBUM);
334     }
335 
336     CHECK_AND_RETURN_RET(rdbStore != nullptr, nullptr);
337     return rdbStore->Query(predicates, columns);
338 }
339 
GetQueryFilter(const string & tableName)340 static string GetQueryFilter(const string &tableName)
341 {
342     if (tableName == MEDIALIBRARY_TABLE) {
343         return MEDIALIBRARY_TABLE + "." + MEDIA_DATA_DB_SYNC_STATUS + " = " +
344             to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE));
345     }
346     if (tableName == PhotoColumn::PHOTOS_TABLE) {
347         return PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_SYNC_STATUS + " = " +
348             to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)) + " AND " +
349             PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_CLEAN_FLAG + " = " +
350             to_string(static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN));
351     }
352     if (tableName == PhotoAlbumColumns::TABLE) {
353         return PhotoAlbumColumns::TABLE + "." + PhotoAlbumColumns::ALBUM_DIRTY + " != " +
354             to_string(static_cast<int32_t>(DirtyTypes::TYPE_DELETED));
355     }
356     if (tableName == PhotoMap::TABLE) {
357         return PhotoMap::TABLE + "." + PhotoMap::DIRTY + " != " + to_string(static_cast<int32_t>(
358             DirtyTypes::TYPE_DELETED));
359     }
360     return "";
361 }
362 
AddQueryFilter(AbsRdbPredicates & predicates)363 void MediaLibraryRdbUtils::AddQueryFilter(AbsRdbPredicates &predicates)
364 {
365     /* build all-table vector */
366     string tableName = predicates.GetTableName();
367     vector<string> joinTables = predicates.GetJoinTableNames();
368     joinTables.push_back(tableName);
369     /* add filters */
370     string filters;
371     for (auto &t : joinTables) {
372         string filter = GetQueryFilter(t);
373         if (filter.empty()) {
374             continue;
375         }
376         if (filters.empty()) {
377             filters += filter;
378         } else {
379             filters += " AND " + filter;
380         }
381     }
382     if (filters.empty()) {
383         return;
384     }
385 
386     /* rebuild */
387     string queryCondition = predicates.GetWhereClause();
388     queryCondition = queryCondition.empty() ? filters : filters + " AND " + queryCondition;
389     predicates.SetWhereClause(queryCondition);
390 }
391 
QueryGoToFirst(const shared_ptr<MediaLibraryRdbStore> & rdbStore,const RdbPredicates & predicates,const vector<string> & columns)392 static shared_ptr<ResultSet> QueryGoToFirst(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
393     const RdbPredicates &predicates, const vector<string> &columns)
394 {
395     MediaLibraryTracer tracer;
396     tracer.Start("QueryGoToFirst");
397     auto resultSet = rdbStore->StepQueryWithoutCheck(predicates, columns);
398     CHECK_AND_RETURN_RET(resultSet != nullptr, nullptr);
399 
400     MediaLibraryTracer goToFirst;
401     goToFirst.Start("GoToFirstRow");
402     int32_t err = resultSet->GoToFirstRow();
403     MediaLibraryRestore::GetInstance().CheckRestore(err);
404     return resultSet;
405 }
406 
ForEachRow(const shared_ptr<MediaLibraryRdbStore> rdbStore,std::vector<UpdateAlbumData> & datas,const bool hiddenState,const UpdateHandler & func)407 static int32_t ForEachRow(const shared_ptr<MediaLibraryRdbStore> rdbStore, std::vector<UpdateAlbumData> &datas,
408     const bool hiddenState, const UpdateHandler &func)
409 {
410     int32_t err = NativeRdb::E_OK;
411     for (auto data : datas) {
412         std::shared_ptr<TransactionOperations> trans = make_shared<TransactionOperations>(__func__);
413         AccurateRefresh::AlbumAccurateRefresh albumRefresh(AccurateRefresh::COMMIT_EDITE_ASSET_BUSSINESS_NAME, trans);
414         std::function<int(void)> transFunc = [&]()->int {
415             // Ignore failure here, try to iterate rows as much as possible.
416             func(rdbStore, data, hiddenState, albumRefresh);
417             return err;
418         };
419         err = trans->RetryTrans(transFunc);
420         CHECK_AND_PRINT_LOG(err == E_OK, "ForEachRow: trans retry fail!, ret:%{public}d", err);
421         SendAlbumIdNotify(data);
422         if (data.hasChanged) {
423             albumRefresh.Notify();
424         }
425     }
426     return E_SUCCESS;
427 }
428 
GetFileCount(const shared_ptr<ResultSet> & resultSet)429 static inline int32_t GetFileCount(const shared_ptr<ResultSet> &resultSet)
430 {
431     return GetIntValFromColumn(resultSet, MEDIA_COLUMN_COUNT_1);
432 }
433 
GetPortraitFileCount(const shared_ptr<ResultSet> & resultSet)434 static inline int32_t GetPortraitFileCount(const shared_ptr<ResultSet> &resultSet)
435 {
436     return GetIntValFromColumn(resultSet, MEDIA_COLUMN_COUNT_DISTINCT_FILE_ID);
437 }
438 
GetGroupPhotoFileCount(const shared_ptr<ResultSet> & resultSet)439 static inline int32_t GetGroupPhotoFileCount(const shared_ptr<ResultSet> &resultSet)
440 {
441     return GetIntValFromColumn(resultSet, MEDIA_COLUMN_COUNT_DISTINCT_FILE_ID);
442 }
443 
GetAlbumCount(const shared_ptr<ResultSet> & resultSet,const string & column)444 static inline int32_t GetAlbumCount(const shared_ptr<ResultSet> &resultSet, const string &column)
445 {
446     return GetIntValFromColumn(resultSet, column);
447 }
448 
GetAlbumCover(const shared_ptr<ResultSet> & resultSet,const string & column)449 static inline string GetAlbumCover(const shared_ptr<ResultSet> &resultSet, const string &column)
450 {
451     return GetStringValFromColumn(resultSet, column);
452 }
453 
GetAlbumId(const shared_ptr<ResultSet> & resultSet)454 static inline int32_t GetAlbumId(const shared_ptr<ResultSet> &resultSet)
455 {
456     return GetIntValFromColumn(resultSet, PhotoAlbumColumns::ALBUM_ID);
457 }
458 
GetAlbumSubType(const shared_ptr<ResultSet> & resultSet)459 static inline int32_t GetAlbumSubType(const shared_ptr<ResultSet> &resultSet)
460 {
461     return GetIntValFromColumn(resultSet, PhotoAlbumColumns::ALBUM_SUBTYPE);
462 }
463 
GetIsCoverSatisfied(const shared_ptr<ResultSet> & resultSet)464 static inline uint8_t GetIsCoverSatisfied(const shared_ptr<ResultSet> &resultSet)
465 {
466     return GetIntValFromColumn(resultSet, IS_COVER_SATISFIED);
467 }
468 
GetCoverDateTime(const shared_ptr<ResultSet> & resultSet)469 static inline int64_t GetCoverDateTime(const shared_ptr<ResultSet> &resultSet)
470 {
471     return GetInt64ValFromColumn(resultSet, PhotoAlbumColumns::COVER_DATE_TIME);
472 }
473 
GetHiddenCoverDateTime(const shared_ptr<ResultSet> & resultSet)474 static inline int64_t GetHiddenCoverDateTime(const shared_ptr<ResultSet> &resultSet)
475 {
476     return GetInt64ValFromColumn(resultSet, PhotoAlbumColumns::HIDDEN_COVER_DATE_TIME);
477 }
478 
GetPhotosDateTaken(const shared_ptr<ResultSet> & resultSet)479 static inline int64_t GetPhotosDateTaken(const shared_ptr<ResultSet> &resultSet)
480 {
481     return GetInt64ValFromColumn(resultSet, PhotoColumn::MEDIA_DATE_TAKEN);
482 }
483 
GetPhotosDateAdded(const shared_ptr<ResultSet> & resultSet)484 static inline int64_t GetPhotosDateAdded(const shared_ptr<ResultSet> &resultSet)
485 {
486     return GetInt64ValFromColumn(resultSet, PhotoColumn::MEDIA_DATE_ADDED);
487 }
488 
GetPhotosHiddenTime(const shared_ptr<ResultSet> & resultSet)489 static inline int64_t GetPhotosHiddenTime(const shared_ptr<ResultSet> &resultSet)
490 {
491     return GetInt64ValFromColumn(resultSet, PhotoColumn::PHOTO_HIDDEN_TIME);
492 }
493 
GetFileName(const string & filePath)494 static string GetFileName(const string &filePath)
495 {
496     string fileName;
497 
498     size_t lastSlash = filePath.rfind('/');
499     if (lastSlash == string::npos) {
500         return fileName;
501     }
502     if (filePath.size() > (lastSlash + 1)) {
503         fileName = filePath.substr(lastSlash + 1);
504     }
505     return fileName;
506 }
507 
GetTitleFromDisplayName(const string & displayName)508 static string GetTitleFromDisplayName(const string &displayName)
509 {
510     auto pos = displayName.find_last_of('.');
511     if (pos == string::npos) {
512         return "";
513     }
514     return displayName.substr(0, pos);
515 }
516 
GetExtraUri(const string & displayName,const string & path)517 static string GetExtraUri(const string &displayName, const string &path)
518 {
519     string extraUri = "/" + GetTitleFromDisplayName(GetFileName(path)) + "/" + displayName;
520     return MediaFileUtils::Encode(extraUri);
521 }
522 
GetUriByExtrConditions(const string & prefix,const string & fileId,const string & suffix)523 static string GetUriByExtrConditions(const string &prefix, const string &fileId, const string &suffix)
524 {
525     return prefix + fileId + suffix;
526 }
527 
GetCover(const shared_ptr<ResultSet> & resultSet)528 static inline string GetCover(const shared_ptr<ResultSet> &resultSet)
529 {
530     string coverUri;
531     int32_t fileId = GetIntValFromColumn(resultSet, PhotoColumn::MEDIA_ID);
532     if (fileId <= 0) {
533         return coverUri;
534     }
535 
536     string extrUri = GetExtraUri(GetStringValFromColumn(resultSet, PhotoColumn::MEDIA_NAME),
537         GetStringValFromColumn(resultSet, PhotoColumn::MEDIA_FILE_PATH));
538     return GetUriByExtrConditions(PhotoColumn::PHOTO_URI_PREFIX, to_string(fileId), extrUri);
539 }
540 
SetCount(const shared_ptr<ResultSet> & fileResult,const UpdateAlbumData & data,ValuesBucket & values,const bool hiddenState,PhotoAlbumSubType subtype)541 static int32_t SetCount(const shared_ptr<ResultSet> &fileResult, const UpdateAlbumData &data,
542     ValuesBucket &values, const bool hiddenState, PhotoAlbumSubType subtype)
543 {
544     const string &targetColumn = hiddenState ? PhotoAlbumColumns::HIDDEN_COUNT : PhotoAlbumColumns::ALBUM_COUNT;
545     int32_t oldCount = hiddenState ? data.hiddenCount : data.albumCount;
546     int32_t newCount;
547     if (subtype == PORTRAIT) {
548         newCount = GetPortraitFileCount(fileResult);
549     } else if (subtype == GROUP_PHOTO) {
550         newCount = GetGroupPhotoFileCount(fileResult);
551     } else {
552         newCount = GetFileCount(fileResult);
553     }
554     int32_t id = data.albumId;
555     if (oldCount != newCount) {
556         MEDIA_INFO_LOG("AccurateRefresh Album %{public}d Update %{public}s, oldCount: %{public}d, newCount: %{public}d",
557             id, targetColumn.c_str(), oldCount, newCount);
558         values.PutInt(targetColumn, newCount);
559         bool isHiddenInfoChange = hiddenState || data.albumSubtype == static_cast<int32_t>(PhotoAlbumSubType::HIDDEN);
560         if (isHiddenInfoChange) {
561             MEDIA_INFO_LOG("AccurateRefresh Update album contains hidden: %{public}d", newCount != 0);
562             values.PutInt(PhotoAlbumColumns::CONTAINS_HIDDEN, newCount != 0);
563         }
564         if (data.albumSubtype == static_cast<int32_t>(PhotoAlbumSubType::HIDDEN)) {
565             const string &otherColumn = hiddenState ? PhotoAlbumColumns::ALBUM_COUNT : PhotoAlbumColumns::HIDDEN_COUNT;
566             values.PutInt(otherColumn, newCount);
567             MEDIA_INFO_LOG("AccurateRefresh Update album other count");
568         }
569     }
570     return newCount;
571 }
572 
SetPortraitCover(const shared_ptr<ResultSet> & fileResult,const UpdateAlbumData & data,ValuesBucket & values,int newCount)573 static void SetPortraitCover(const shared_ptr<ResultSet> &fileResult, const UpdateAlbumData &data,
574     ValuesBucket &values, int newCount)
575 {
576     string newCover;
577     if (newCount != 0) {
578         newCover = GetCover(fileResult);
579     }
580     string oldCover = data.albumCoverUri;
581     if (oldCover != newCover) {
582         values.PutInt(IS_COVER_SATISFIED, static_cast<uint8_t>(CoverSatisfiedType::DEFAULT_SETTING));
583         values.PutString(PhotoAlbumColumns::ALBUM_COVER_URI, newCover);
584         int32_t albumId = data.albumId;
585         MEDIA_INFO_LOG("Update portrait album %{public}d. oldCover: %{public}s, newCover: %{public}s",
586             albumId, MediaFileUtils::GetUriWithoutDisplayname(oldCover).c_str(),
587             MediaFileUtils::GetUriWithoutDisplayname(newCover).c_str());
588     }
589 }
590 
SetGroupPhotoCover(const shared_ptr<ResultSet> & fileResult,const UpdateAlbumData & data,ValuesBucket & values,int newCount)591 static void SetGroupPhotoCover(const shared_ptr<ResultSet> &fileResult, const UpdateAlbumData &data,
592     ValuesBucket &values, int newCount)
593 {
594     SetPortraitCover(fileResult, data, values, newCount);
595 }
596 
SetCoverDateTime(const shared_ptr<ResultSet> & fileResult,const UpdateAlbumData & data,ValuesBucket & values,const bool hiddenState)597 static void SetCoverDateTime(const shared_ptr<ResultSet> &fileResult, const UpdateAlbumData &data,
598     ValuesBucket &values, const bool hiddenState)
599 {
600     bool isUserAlbum = data.albumSubtype == PhotoAlbumSubType::USER_GENERIC;
601     bool isSourceAlbum = data.albumSubtype == PhotoAlbumSubType::SOURCE_GENERIC;
602     bool isSystemAlbum = data.albumSubtype >= PhotoAlbumSubType::SYSTEM_START &&
603         data.albumSubtype <= PhotoAlbumSubType::SYSTEM_END;
604     bool isPhotoAlbum = isUserAlbum || isSourceAlbum || isSystemAlbum;
605     if (!isPhotoAlbum) {
606         MEDIA_INFO_LOG("AccurateRefresh Update album[%{public}d] subType[%{public}d]", data.albumId, data.albumSubtype);
607         return;
608     }
609     if (data.albumSubtype == PhotoAlbumSubType::HIDDEN) {
610         int64_t oldCoverDateTime = data.coverDateTime;
611         int64_t coverDateTime = GetPhotosHiddenTime(fileResult);
612         if (coverDateTime != oldCoverDateTime) {
613             values.PutLong(PhotoAlbumColumns::COVER_DATE_TIME, coverDateTime);
614             values.PutLong(PhotoAlbumColumns::HIDDEN_COVER_DATE_TIME, coverDateTime);
615         }
616         MEDIA_INFO_LOG("AccurateRefresh Update album %{public}d, old coverDateTime(%{public}" PRId64 ")," \
617             "cover/hiddenCoverDateTime(%{public}" PRId64 ")", data.albumId, oldCoverDateTime, coverDateTime);
618         return;
619     }
620     if (hiddenState) {
621         int64_t oldHiddenCoverDateTime = data.hiddenCoverDateTime;
622         int64_t hiddenCoverDateTime = GetPhotosHiddenTime(fileResult);
623         if (oldHiddenCoverDateTime != hiddenCoverDateTime) {
624             values.PutLong(PhotoAlbumColumns::HIDDEN_COVER_DATE_TIME, hiddenCoverDateTime);
625         }
626         MEDIA_INFO_LOG("AccurateRefresh Update album %{public}d, old hiddenCoverDateTime(%{public}" PRId64 "), \
627             hiddenCoverDateTime(%{public}" PRId64 ")", data.albumId, oldHiddenCoverDateTime, hiddenCoverDateTime);
628     } else {
629         int64_t oldCoverDateTime = data.coverDateTime;
630         int64_t coverDateTime;
631         if (data.albumSubtype == PhotoAlbumSubType::VIDEO || data.albumSubtype == PhotoAlbumSubType::IMAGE) {
632             coverDateTime = GetPhotosDateAdded(fileResult);
633         } else {
634             coverDateTime = GetPhotosDateTaken(fileResult);
635         }
636         if (coverDateTime != oldCoverDateTime) {
637             values.PutLong(PhotoAlbumColumns::COVER_DATE_TIME, coverDateTime);
638         }
639         MEDIA_INFO_LOG("AccurateRefresh Update album %{public}d, old coverDateTime(%{public}" PRId64 ")," \
640             "coverDateTime(%{public}" PRId64 ")", data.albumId, oldCoverDateTime, coverDateTime);
641     }
642 }
643 
SetCover(const shared_ptr<ResultSet> & fileResult,const UpdateAlbumData & data,ValuesBucket & values,const bool hiddenState)644 static void SetCover(const shared_ptr<ResultSet> &fileResult, const UpdateAlbumData &data,
645     ValuesBucket &values, const bool hiddenState)
646 {
647     string newCover;
648     int32_t newCount = GetFileCount(fileResult);
649     if (newCount != 0) {
650         newCover = GetCover(fileResult);
651     }
652     const string &targetColumn = hiddenState ? PhotoAlbumColumns::HIDDEN_COVER : PhotoAlbumColumns::ALBUM_COVER_URI;
653     string oldCover = hiddenState ? data.hiddenCover : data.albumCoverUri;
654     if (oldCover != newCover) {
655         int32_t id = data.albumId;
656         MEDIA_INFO_LOG("AccurateRefresh Update album %{public}d %{public}s. oldCover: %{public}s, newCover: %{public}s",
657             id, targetColumn.c_str(), MediaFileUtils::GetUriWithoutDisplayname(oldCover).c_str(),
658             MediaFileUtils::GetUriWithoutDisplayname(newCover).c_str());
659         values.PutString(targetColumn, newCover);
660         SetCoverDateTime(fileResult, data, values, hiddenState);
661         if (data.albumSubtype == static_cast<int32_t>(PhotoAlbumSubType::HIDDEN)) {
662             const string &otherColumn = hiddenState ? PhotoAlbumColumns::ALBUM_COVER_URI :
663                 PhotoAlbumColumns::HIDDEN_COVER;
664             values.PutString(otherColumn, newCover);
665             MEDIA_INFO_LOG("AccurateRefresh Update album other cover");
666         }
667     }
668 }
669 
GetTrashAlbumHiddenPredicates(RdbPredicates & predicates)670 static void GetTrashAlbumHiddenPredicates(RdbPredicates &predicates)
671 {
672     PhotoQueryFilter::Config config {};
673     config.hiddenConfig = PhotoQueryFilter::ConfigType::INCLUDE;
674     config.trashedConfig = PhotoQueryFilter::ConfigType::INCLUDE;
675     PhotoQueryFilter::ModifyPredicate(config, predicates);
676     MEDIA_DEBUG_LOG("Query hidden asset in trash album, predicates statement is %{public}s",
677         predicates.GetStatement().c_str());
678 }
679 
GetAlbumCountAndCoverPredicates(const UpdateAlbumData & albumInfo,NativeRdb::RdbPredicates & predicates,const bool hiddenState,const bool isUpdateAlbum=false)680 static void GetAlbumCountAndCoverPredicates(const UpdateAlbumData& albumInfo,
681     NativeRdb::RdbPredicates &predicates, const bool hiddenState, const bool isUpdateAlbum = false)
682 {
683     const PhotoAlbumSubType subtype = static_cast<PhotoAlbumSubType>(albumInfo.albumSubtype);
684     const string albumName = albumInfo.albumName;
685     const int32_t albumId = albumInfo.albumId;
686     static const string QUERY_ASSETS_FROM_ANALYSIS_ALBUM =
687         PhotoColumn::PHOTO_SYNC_STATUS + " = " + to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)) +
688         " AND " + PhotoColumn::PHOTO_CLEAN_FLAG + " = " + to_string(static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN)) +
689         " AND " + MediaColumn::MEDIA_ID + " IN (SELECT " + PhotoMap::ASSET_ID + " FROM " + ANALYSIS_PHOTO_MAP_TABLE +
690         " WHERE " + PhotoMap::ALBUM_ID + " = ?) AND " + MediaColumn::MEDIA_DATE_TRASHED + " = 0 AND " +
691         MediaColumn::MEDIA_HIDDEN + " = ? AND " + MediaColumn::MEDIA_TIME_PENDING + " = 0 AND " +
692         PhotoColumn::PHOTO_IS_TEMP + " = 0 AND " + PhotoColumn::PHOTO_BURST_COVER_LEVEL + " = " +
693         to_string(static_cast<int32_t>(BurstCoverLevelType::COVER));
694 
695     bool isUserAlbum = subtype == PhotoAlbumSubType::USER_GENERIC;
696     bool isSourceAlbum = subtype == PhotoAlbumSubType::SOURCE_GENERIC;
697     bool isAnalysisAlbum = subtype >= PhotoAlbumSubType::ANALYSIS_START && subtype <= PhotoAlbumSubType::ANALYSIS_END;
698     bool isSystemAlbum = subtype >= PhotoAlbumSubType::SYSTEM_START && subtype <= PhotoAlbumSubType::SYSTEM_END;
699     if (isUpdateAlbum && isAnalysisAlbum &&
700         subtype != PhotoAlbumSubType::PORTRAIT && subtype != PhotoAlbumSubType::SHOOTING_MODE) {
701         predicates.SetWhereClause(QUERY_ASSETS_FROM_ANALYSIS_ALBUM);
702         predicates.SetWhereArgs({ to_string(albumId), to_string(hiddenState) });
703         return;
704     }
705 
706     if (isUserAlbum) {
707         PhotoAlbumColumns::GetUserAlbumPredicates(albumId, predicates, hiddenState);
708     } else if (isAnalysisAlbum) {
709         MediaLibraryAlbumHelper::GetAnalysisAlbumPredicates(albumId, subtype, albumName, predicates, hiddenState);
710     } else if (isSourceAlbum) {
711         PhotoAlbumColumns::GetSourceAlbumPredicates(albumId, predicates, hiddenState);
712     } else if (isSystemAlbum) {
713         if (hiddenState && subtype == PhotoAlbumSubType::TRASH) {
714             GetTrashAlbumHiddenPredicates(predicates);
715             return;
716         }
717         PhotoAlbumColumns::GetSystemAlbumPredicates(subtype, predicates, hiddenState);
718     } else {
719         MEDIA_ERR_LOG("Invalid album subtype %{public}d, will return nothing", subtype);
720         predicates.EqualTo(PhotoColumn::MEDIA_ID, to_string(0));
721     }
722 }
723 
SetImageVideoCount(int32_t newTotalCount,const shared_ptr<ResultSet> & fileResultVideo,const UpdateAlbumData & data,ValuesBucket & values)724 static void SetImageVideoCount(int32_t newTotalCount, const shared_ptr<ResultSet> &fileResultVideo,
725     const UpdateAlbumData &data, ValuesBucket &values)
726 {
727     int32_t oldVideoCount = data.albumVideoCount;
728     int32_t newVideoCount = GetFileCount(fileResultVideo);
729     if (oldVideoCount != newVideoCount) {
730         MEDIA_DEBUG_LOG("Update album %{public}s, oldCount: %{public}d, newCount: %{public}d",
731             PhotoAlbumColumns::ALBUM_VIDEO_COUNT.c_str(), oldVideoCount, newVideoCount);
732         values.PutInt(PhotoAlbumColumns::ALBUM_VIDEO_COUNT, newVideoCount);
733     }
734     int32_t oldImageCount = data.albumImageCount;
735     int32_t newImageCount = newTotalCount - newVideoCount;
736     if (oldImageCount != newImageCount) {
737         MEDIA_DEBUG_LOG("Update album %{public}s, oldCount: %{public}d, newCount: %{public}d",
738             PhotoAlbumColumns::ALBUM_IMAGE_COUNT.c_str(), oldImageCount, newImageCount);
739         values.PutInt(PhotoAlbumColumns::ALBUM_IMAGE_COUNT, newImageCount);
740     }
741 }
742 
QueryAlbumCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,int32_t albumId,PhotoAlbumSubType subtype)743 static int32_t QueryAlbumCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,
744     int32_t albumId, PhotoAlbumSubType subtype)
745 {
746     const vector<string> columns = { MEDIA_COLUMN_COUNT_1 };
747     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
748     UpdateAlbumData albumInfo;
749     albumInfo.albumId = albumId;
750     albumInfo.albumSubtype = static_cast<int32_t>(subtype);
751     GetAlbumCountAndCoverPredicates(albumInfo, predicates, false);
752     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
753     CHECK_AND_RETURN_RET(fetchResult != nullptr, E_HAS_DB_ERROR);
754     return GetFileCount(fetchResult);
755 }
756 
QueryAlbumVideoCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,int32_t albumId,PhotoAlbumSubType subtype)757 static int32_t QueryAlbumVideoCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,
758     int32_t albumId, PhotoAlbumSubType subtype)
759 {
760     const vector<string> columns = { MEDIA_COLUMN_COUNT_1 };
761     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
762     UpdateAlbumData albumInfo;
763     albumInfo.albumId = albumId;
764     albumInfo.albumSubtype = static_cast<int32_t>(subtype);
765     GetAlbumCountAndCoverPredicates(albumInfo, predicates, false);
766     predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_MEDIA_TYPE_INDEX);
767     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO));
768     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
769     CHECK_AND_RETURN_RET(fetchResult != nullptr, E_HAS_DB_ERROR);
770     return GetFileCount(fetchResult);
771 }
772 
QueryAlbumHiddenCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,int32_t albumId,PhotoAlbumSubType subtype)773 static int32_t QueryAlbumHiddenCount(const shared_ptr<MediaLibraryRdbStore> rdbStore,
774     int32_t albumId, PhotoAlbumSubType subtype)
775 {
776     const vector<string> columns = { MEDIA_COLUMN_COUNT_1 };
777     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
778     UpdateAlbumData albumInfo;
779     albumInfo.albumId = albumId;
780     albumInfo.albumSubtype = static_cast<int32_t>(subtype);
781     GetAlbumCountAndCoverPredicates(albumInfo, predicates, true);
782     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
783     CHECK_AND_RETURN_RET(fetchResult != nullptr, E_HAS_DB_ERROR);
784     return GetFileCount(fetchResult);
785 }
786 
SetAlbumCounts(const shared_ptr<MediaLibraryRdbStore> rdbStore,int32_t albumId,PhotoAlbumSubType subtype,AlbumCounts & albumCounts)787 static int32_t SetAlbumCounts(const shared_ptr<MediaLibraryRdbStore> rdbStore,
788     int32_t albumId, PhotoAlbumSubType subtype, AlbumCounts &albumCounts)
789 {
790     int ret = QueryAlbumCount(rdbStore, albumId, subtype);
791     CHECK_AND_RETURN_RET_LOG(ret >= E_SUCCESS, ret,
792         "Failed to QueryAlbumCount, ret:%{public}d", ret);
793     albumCounts.count = ret;
794 
795     ret = QueryAlbumVideoCount(rdbStore, albumId, subtype);
796     CHECK_AND_RETURN_RET_LOG(ret >= E_SUCCESS, ret,
797         "Failed to QueryAlbumVideoCount, ret:%{public}d", ret);
798     albumCounts.videoCount = ret;
799     albumCounts.imageCount = albumCounts.count - albumCounts.videoCount;
800 
801     ret = QueryAlbumHiddenCount(rdbStore, albumId, subtype);
802     CHECK_AND_RETURN_RET_LOG(ret >= E_SUCCESS, ret,
803         "Failed to QueryAlbumCount, ret:%{public}d", ret);
804     albumCounts.hiddenCount = ret;
805     return E_SUCCESS;
806 }
807 
IsManualCover(const shared_ptr<MediaLibraryRdbStore> rdbStore,int32_t albumId,string & uri)808 static bool IsManualCover(const shared_ptr<MediaLibraryRdbStore> rdbStore, int32_t albumId, string &uri)
809 {
810     MEDIA_DEBUG_LOG("IsManualCover: albumId:%{public}d, coverUri:%{public}s", albumId, uri.c_str());
811 
812     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
813     string updateCondition = PhotoAlbumColumns::ALBUM_ID + "=" + to_string(albumId);
814     predicates.SetWhereClause(updateCondition);
815 
816     vector<string> columns = {PhotoAlbumColumns::ALBUM_COVER_URI, PhotoAlbumColumns::COVER_URI_SOURCE };
817     auto resultSet = rdbStore->Query(predicates, columns);
818     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "failed to acquire result from visitor query.");
819     if (resultSet->GoToNextRow() == NativeRdb::E_OK) {
820         int32_t coverUriSource = GetIntValFromColumn(resultSet, PhotoAlbumColumns::COVER_URI_SOURCE);
821         if (coverUriSource == static_cast<int32_t>(CoverUriSource::MANUAL_CLOUD_COVER)) {
822             uri = GetStringValFromColumn(resultSet, PhotoAlbumColumns::ALBUM_COVER_URI);
823             MEDIA_INFO_LOG("IsManualCover: albumId:%{public}d, coverUri:%{public}s", albumId, uri.c_str());
824             return true;
825         }
826     }
827     return false;
828 }
829 
SetAlbumCoverUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,int32_t albumId,PhotoAlbumSubType subtype,string & uri)830 static int32_t SetAlbumCoverUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
831     int32_t albumId, PhotoAlbumSubType subtype, string &uri)
832 {
833     if (IsManualCover(rdbStore, albumId, uri)) {
834         return E_SUCCESS;
835     }
836     const vector<string> columns = {
837         PhotoColumn::MEDIA_ID,
838         PhotoColumn::MEDIA_FILE_PATH,
839         PhotoColumn::MEDIA_NAME
840     };
841     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
842     UpdateAlbumData albumInfo;
843     albumInfo.albumId = albumId;
844     albumInfo.albumSubtype = static_cast<int32_t>(subtype);
845     GetAlbumCountAndCoverPredicates(albumInfo, predicates, false);
846     if (subtype == PhotoAlbumSubType::HIDDEN) {
847         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_HIDDEN_TIME_INDEX);
848     } else if (subtype == PhotoAlbumSubType::VIDEO || subtype == PhotoAlbumSubType::IMAGE) {
849         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_MEDIA_TYPE_INDEX);
850     } else if (subtype == PhotoAlbumSubType::FAVORITE) {
851         predicates.IndexedBy(PhotoColumn::PHOTO_FAVORITE_INDEX);
852     } else if (subtype == PhotoAlbumSubType::CLOUD_ENHANCEMENT) {
853         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_CLOUD_ENHANCEMENT_ALBUM_INDEX);
854     } else if (subtype == PhotoAlbumSubType::USER_GENERIC || subtype == PhotoAlbumSubType::SOURCE_GENERIC) {
855         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_ALBUM_INDEX);
856     } else {
857         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_ADDED_INDEX);
858     }
859     predicates.Limit(1);
860 
861     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
862     CHECK_AND_RETURN_RET_LOG(fetchResult != nullptr, E_HAS_DB_ERROR, "QueryGoToFirst failed");
863     uri = GetCover(fetchResult);
864     return E_SUCCESS;
865 }
866 
SetAlbumCoverHiddenUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,int32_t albumId,PhotoAlbumSubType subtype,string & uri)867 static int32_t SetAlbumCoverHiddenUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
868     int32_t albumId, PhotoAlbumSubType subtype, string &uri)
869 {
870     const vector<string> columns = {
871         PhotoColumn::MEDIA_ID,
872         PhotoColumn::MEDIA_FILE_PATH,
873         PhotoColumn::MEDIA_NAME
874     };
875     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
876     UpdateAlbumData albumInfo;
877     albumInfo.albumId = albumId;
878     albumInfo.albumSubtype = static_cast<int32_t>(subtype);
879     GetAlbumCountAndCoverPredicates(albumInfo, predicates, true);
880     predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_HIDDEN_TIME_INDEX);
881     predicates.Limit(1);
882 
883     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
884     CHECK_AND_RETURN_RET_LOG(fetchResult != nullptr, E_HAS_DB_ERROR, "QueryGoToFirst failed");
885     uri = GetCover(fetchResult);
886     return E_SUCCESS;
887 }
888 
FillOneAlbumCountAndCoverUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,int32_t albumId,PhotoAlbumSubType subtype,string & sql)889 int32_t MediaLibraryRdbUtils::FillOneAlbumCountAndCoverUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
890     int32_t albumId, PhotoAlbumSubType subtype, string &sql)
891 {
892     AlbumCounts albumCounts = { 0, 0, 0, 0 };
893     int32_t ret = SetAlbumCounts(rdbStore, albumId, subtype, albumCounts);
894     CHECK_AND_RETURN_RET(ret == E_SUCCESS, ret);
895     string coverUri;
896     ret = SetAlbumCoverUri(rdbStore, albumId, subtype, coverUri);
897     CHECK_AND_RETURN_RET(ret == E_SUCCESS, ret);
898     string coverHiddenUri;
899     if (albumCounts.hiddenCount != 0) {
900         ret = SetAlbumCoverHiddenUri(rdbStore, albumId, subtype, coverHiddenUri);
901         CHECK_AND_RETURN_RET(ret == E_SUCCESS, ret);
902     }
903 
904     CHECK_AND_RETURN_RET_LOG(albumId >= 0, E_HAS_DB_ERROR,
905         "Can not get correct albumId, error albumId is %{public}d", albumId);
906     string coverUriSql = PhotoAlbumColumns::ALBUM_COVER_URI;
907     if (coverUri.empty()) {
908         coverUriSql += " = NULL";
909     } else {
910         coverUriSql += " = '" + coverUri + "'";
911     }
912     string coverHiddenUriSql = PhotoAlbumColumns::HIDDEN_COVER;
913     if (coverHiddenUri.empty()) {
914         coverHiddenUriSql += " = NULL";
915     } else {
916         coverHiddenUriSql += " = '" + coverHiddenUri + "'";
917     }
918 
919     sql = "UPDATE " + PhotoAlbumColumns::TABLE + " SET " +
920         PhotoAlbumColumns::ALBUM_COUNT + " = " + to_string(albumCounts.count) + ", " +
921         PhotoAlbumColumns::ALBUM_IMAGE_COUNT + " = " +  to_string(albumCounts.imageCount) + ", " +
922         PhotoAlbumColumns::ALBUM_VIDEO_COUNT + " = " + to_string(albumCounts.videoCount) + ", " +
923         PhotoAlbumColumns::HIDDEN_COUNT + " = " + to_string(albumCounts.hiddenCount) + ", " +
924         PhotoAlbumColumns::CONTAINS_HIDDEN + " = " + to_string((albumCounts.hiddenCount == 0) ? 0 : 1) + ", " +
925         coverUriSql + ", " + coverHiddenUriSql + " WHERE " +
926         PhotoAlbumColumns::ALBUM_ID + " = " + to_string(albumId) + ";";
927     return E_SUCCESS;
928 }
929 
GetPhotoId(const std::string & uri)930 static std::string GetPhotoId(const std::string &uri)
931 {
932     if (uri.compare(0, PhotoColumn::PHOTO_URI_PREFIX.size(),
933         PhotoColumn::PHOTO_URI_PREFIX) != 0) {
934         return "";
935     }
936     std::string tmp = uri.substr(PhotoColumn::PHOTO_URI_PREFIX.size());
937     return tmp.substr(0, tmp.find_first_of('/'));
938 }
939 
RefreshAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,const std::vector<RefreshAlbumData> & datas,function<void (PhotoAlbumType,PhotoAlbumSubType,int)> refreshProcessHandler)940 static int32_t RefreshAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
941     const std::vector<RefreshAlbumData> &datas,
942     function<void(PhotoAlbumType, PhotoAlbumSubType, int)> refreshProcessHandler)
943 {
944     for (auto data : datas) {
945         auto subtype = static_cast<PhotoAlbumSubType>(data.albumSubtype);
946         int32_t albumId = data.albumId;
947         string sql;
948         int32_t ret = MediaLibraryRdbUtils::FillOneAlbumCountAndCoverUri(rdbStore, albumId, subtype, sql);
949         CHECK_AND_RETURN_RET(ret == E_SUCCESS, ret);
950 
951         ret = rdbStore->ExecuteSql(sql);
952         CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_HAS_DB_ERROR,
953             "Failed to execute sql:%{private}s", sql.c_str());
954         MEDIA_DEBUG_LOG("Execute sql %{private}s success", sql.c_str());
955         refreshProcessHandler(PhotoAlbumType::SYSTEM, subtype, albumId);
956     }
957     return E_SUCCESS;
958 }
959 
DeleteAllAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore)960 static void DeleteAllAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore)
961 {
962     string updateRefreshTableSql = "DELETE FROM " + ALBUM_REFRESH_TABLE;
963     int32_t ret = rdbStore->ExecuteSql(updateRefreshTableSql);
964     CHECK_AND_RETURN_LOG(ret == NativeRdb::E_OK,
965         "Failed to execute sql:%{private}s", updateRefreshTableSql.c_str());
966     MEDIA_INFO_LOG("Delete AlbumRefreshTable success");
967 }
968 
GetSystemRefreshAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,std::vector<RefreshAlbumData> & systemAlbums)969 static int32_t GetSystemRefreshAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
970     std::vector<RefreshAlbumData> &systemAlbums)
971 {
972     vector<string> columns = { PhotoAlbumColumns::ALBUM_ID, PhotoAlbumColumns::ALBUM_SUBTYPE };
973     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
974     predicates.SetWhereClause(PhotoAlbumColumns::ALBUM_ID + " IN (SELECT " + REFRESH_ALBUM_ID + " FROM " +
975         ALBUM_REFRESH_TABLE + ")");
976     auto resultSet = rdbStore->Query(predicates, columns);
977     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "Can not query ALBUM_REFRESH_TABLE");
978     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
979         RefreshAlbumData data;
980         data.albumId = GetAlbumId(resultSet);
981         data.albumSubtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(resultSet));
982         systemAlbums.push_back(data);
983     }
984     resultSet->Close();
985     return E_SUCCESS;
986 }
987 
GetIsUpdateAllAnalysis(const shared_ptr<MediaLibraryRdbStore> rdbStore,bool & isUpdateAllAnalysis)988 static int32_t GetIsUpdateAllAnalysis(const shared_ptr<MediaLibraryRdbStore> rdbStore, bool &isUpdateAllAnalysis)
989 {
990     vector<string> columns = { REFRESH_ALBUM_ID };
991     NativeRdb::RdbPredicates predicates(ALBUM_REFRESH_TABLE);
992     predicates.EqualTo(REFRESH_ALBUM_ID, -1);
993     shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->Query(predicates, columns);
994     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "Failed query RefreshAlbum.");
995     if (resultSet->GoToFirstRow() == NativeRdb::E_OK) {
996         isUpdateAllAnalysis = true;
997         MEDIA_INFO_LOG("isUpdateAllAnalysis is true.");
998     }
999     resultSet->Close();
1000     return E_SUCCESS;
1001 }
1002 
GetAnalysisRefreshAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,vector<RefreshAlbumData> & analysisAlbums,bool & isUpdateAllAnalysis)1003 static int32_t GetAnalysisRefreshAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1004     vector<RefreshAlbumData> &analysisAlbums, bool &isUpdateAllAnalysis)
1005 {
1006     int ret = GetIsUpdateAllAnalysis(rdbStore, isUpdateAllAnalysis);
1007     if (ret == E_HAS_DB_ERROR) {
1008         return E_HAS_DB_ERROR;
1009     } else if (isUpdateAllAnalysis) {
1010         MEDIA_INFO_LOG("UpdateAllAnalysis.");
1011         return E_SUCCESS;
1012     }
1013 
1014     vector<string> columns = { PhotoAlbumColumns::ALBUM_ID, PhotoAlbumColumns::ALBUM_SUBTYPE };
1015     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
1016     predicates.SetWhereClause(PhotoAlbumColumns::ALBUM_ID + " IN (SELECT " + REFRESH_ALBUM_ID +
1017         " - 100000000 FROM " + ALBUM_REFRESH_TABLE + " WHERE refresh_album_id > 100000000)");
1018     auto resultSet = rdbStore->Query(predicates, columns);
1019     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "Can not query ALBUM_REFRESH_TABLE");
1020     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1021         RefreshAlbumData data;
1022         data.albumId = GetAlbumId(resultSet);
1023         data.albumSubtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(resultSet));
1024         analysisAlbums.push_back(data);
1025     }
1026     resultSet->Close();
1027     return E_SUCCESS;
1028 }
1029 
QueryAlbumById(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & albumIds)1030 shared_ptr<ResultSet> QueryAlbumById(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1031     const vector<string> &albumIds)
1032 {
1033     vector<string> columns = {
1034         PhotoAlbumColumns::ALBUM_ID,
1035         PhotoAlbumColumns::ALBUM_SUBTYPE
1036     };
1037     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
1038     predicates.In(PhotoAlbumColumns::ALBUM_ID, albumIds);
1039     auto resultSet = rdbStore->Query(predicates, columns);
1040     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, nullptr, "Can not Query from rdb");
1041     return resultSet;
1042 }
1043 
IsNeedRefreshByCheckTable(const shared_ptr<MediaLibraryRdbStore> rdbStore,bool & signal)1044 int32_t MediaLibraryRdbUtils::IsNeedRefreshByCheckTable(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1045     bool &signal)
1046 {
1047     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_HAS_DB_ERROR, "rdb is nullptr");
1048 
1049     RdbPredicates predicates(ALBUM_REFRESH_TABLE);
1050     vector<string> columns = { REFRESH_ALBUM_ID };
1051     auto resultSet = rdbStore->Query(predicates, columns);
1052     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "Can not query ALBUM_REFRESH_TABLE");
1053 
1054     int32_t count = 0;
1055     int32_t ret = resultSet->GetRowCount(count);
1056     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_HAS_DB_ERROR,
1057         "GetRowCount failed ret:%{public}d", ret);
1058     if (count == 0) {
1059         MEDIA_DEBUG_LOG("count is zero, should not refresh");
1060         signal = false;
1061     } else {
1062         MEDIA_DEBUG_LOG("count is %{public}d, should refresh", count);
1063         signal = true;
1064     }
1065     return E_SUCCESS;
1066 }
1067 
IsNeedRefreshAlbum()1068 bool MediaLibraryRdbUtils::IsNeedRefreshAlbum()
1069 {
1070     return isNeedRefreshAlbum.load();
1071 }
1072 
SetNeedRefreshAlbum(bool isNeedRefresh)1073 void MediaLibraryRdbUtils::SetNeedRefreshAlbum(bool isNeedRefresh)
1074 {
1075     isNeedRefreshAlbum = isNeedRefresh;
1076 }
1077 
IsInRefreshTask()1078 bool MediaLibraryRdbUtils::IsInRefreshTask()
1079 {
1080     return isInRefreshTask.load();
1081 }
1082 
GetPortraitAlbumCountPredicates(const string & albumId,RdbPredicates & predicates)1083 static void GetPortraitAlbumCountPredicates(const string &albumId, RdbPredicates &predicates)
1084 {
1085     string anaAlbumGroupTag = ANALYSIS_ALBUM_TABLE + "." + GROUP_TAG;
1086     string anaAlbumId = ANALYSIS_ALBUM_TABLE + "." + ALBUM_ID;
1087     string anaPhotoMapAlbum = ANALYSIS_PHOTO_MAP_TABLE + "." + MAP_ALBUM;
1088     string anaPhotoMapAsset = ANALYSIS_PHOTO_MAP_TABLE + "." + MAP_ASSET;
1089     string photosDateTrashed = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_DATE_TRASHED;
1090     string photosFileId = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID;
1091     string photosHidden = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_HIDDEN;
1092     string photosTimePending = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_TIME_PENDING;
1093     string photosIsTemp = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_IS_TEMP;
1094     string photoIsCover = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_BURST_COVER_LEVEL;
1095 
1096     string clause = anaPhotoMapAsset + " = " + photosFileId;
1097     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ clause });
1098     clause = anaAlbumId + " = " + anaPhotoMapAlbum;
1099     predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On({ clause });
1100 
1101     clause = "( AnalysisAlbum.album_id IN (SELECT album_id FROM AnalysisAlbum where "
1102         + anaAlbumGroupTag + " IN ( SELECT "+ GROUP_TAG + " FROM " + ANALYSIS_ALBUM_TABLE +
1103         " WHERE " + ALBUM_ID + " = " + albumId + " )))";
1104     predicates.SetWhereClause(clause + " AND ");
1105     predicates.BeginWrap();
1106     predicates.EqualTo(photosDateTrashed, to_string(0));
1107     predicates.EqualTo(photosHidden, to_string(0));
1108     predicates.EqualTo(photosTimePending, to_string(0));
1109     predicates.EqualTo(photosIsTemp, to_string(0));
1110     predicates.EqualTo(photoIsCover, to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
1111     predicates.EndWrap();
1112     predicates.Distinct();
1113 }
1114 
GetGroupPhotoAlbumCountPredicates(const string & albumId,RdbPredicates & predicates)1115 static void GetGroupPhotoAlbumCountPredicates(const string &albumId, RdbPredicates &predicates)
1116 {
1117     GetPortraitAlbumCountPredicates(albumId, predicates);
1118 }
1119 
IsCoverValid(const shared_ptr<MediaLibraryRdbStore> & rdbStore,const string & albumId,const string & fileId)1120 static bool IsCoverValid(const shared_ptr<MediaLibraryRdbStore>& rdbStore, const string &albumId, const string &fileId)
1121 {
1122     if (fileId.empty()) {
1123         MEDIA_WARN_LOG("Invalid cover: empty file_id");
1124         return false;
1125     }
1126     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1127 
1128     string anaPhotoMapAsset = ANALYSIS_PHOTO_MAP_TABLE + "." + MAP_ASSET;
1129     string photosFileId = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_ID;
1130     string clause = anaPhotoMapAsset + " = " + photosFileId;
1131     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ clause });
1132 
1133     string anaAlbumId = ANALYSIS_ALBUM_TABLE + "." + ALBUM_ID;
1134     string anaPhotoMapAlbum = ANALYSIS_PHOTO_MAP_TABLE + "." + MAP_ALBUM;
1135     clause = anaAlbumId + " = " + anaPhotoMapAlbum;
1136     predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On({ clause });
1137 
1138     string photoSyncStatus = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_SYNC_STATUS;
1139     string photoCleanFlag = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_CLEAN_FLAG;
1140     string photosDateTrashed = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_DATE_TRASHED;
1141     string photosHidden = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_HIDDEN;
1142     string photosTimePending = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_TIME_PENDING;
1143     string photosIsTemp = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_IS_TEMP;
1144     string photoIsCover = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_BURST_COVER_LEVEL;
1145 
1146     string whereClause = "group_tag = (SELECT group_tag FROM AnalysisAlbum WHERE album_id = " + albumId + ") AND " +
1147         photosFileId + " = " + fileId + " AND " +
1148         photoSyncStatus + " = " + to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)) + " AND " +
1149         photoCleanFlag + " = " + to_string(static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN)) + " AND " +
1150         photosDateTrashed + " = " + to_string(0) + " AND " + photosHidden + " = " + to_string(0) + " AND " +
1151         photosTimePending + " = " + to_string(0) + " AND " + photosIsTemp + " = " + to_string(0) + " AND " +
1152         photoIsCover + " = " + to_string(static_cast<int32_t>(BurstCoverLevelType::COVER));
1153 
1154     predicates.SetWhereClause(whereClause);
1155     predicates.Limit(1);
1156     vector<string> columns;
1157     auto resultSet = rdbStore->Query(predicates, columns);
1158     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, false,
1159         "Can not query Photos, albumId: %{public}s, fileId: %{public}s", albumId.c_str(), fileId.c_str());
1160     int32_t count = 0;
1161     int32_t ret = resultSet->GetRowCount(count);
1162     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, false,
1163         "GetRowCount failed, albumId: %{public}s, fileId: %{public}s, ret:%{public}d", albumId.c_str(),
1164         fileId.c_str(), ret);
1165     if (count == 0) {
1166         MEDIA_WARN_LOG("Invalid cover: albumId: %{public}s, fileId: %{public}s not exist", albumId.c_str(),
1167             fileId.c_str());
1168         return false;
1169     }
1170     return true;
1171 }
1172 
ShouldUpdatePortraitAlbumCover(const shared_ptr<MediaLibraryRdbStore> & rdbStore,const string & albumId,const string & fileId,const uint8_t isCoverSatisfied)1173 static inline bool ShouldUpdatePortraitAlbumCover(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
1174     const string &albumId, const string &fileId, const uint8_t isCoverSatisfied)
1175 {
1176     return isCoverSatisfied == static_cast<uint8_t>(CoverSatisfiedType::NO_SETTING) ||
1177         !IsCoverValid(rdbStore, albumId, fileId);
1178 }
1179 
ShouldUpdateGroupPhotoAlbumCover(const shared_ptr<MediaLibraryRdbStore> rdbStore,const string & albumId,const string & fileId,const uint8_t isCoverSatisfied)1180 static inline bool ShouldUpdateGroupPhotoAlbumCover(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1181     const string &albumId, const string &fileId, const uint8_t isCoverSatisfied)
1182 {
1183     return isCoverSatisfied == static_cast<uint8_t>(CoverSatisfiedType::NO_SETTING) ||
1184         !IsCoverValid(rdbStore, albumId, fileId);
1185 }
1186 
QueryPortraitAlbumCover(const shared_ptr<MediaLibraryRdbStore> & rdbStore,const string & albumId)1187 static shared_ptr<ResultSet> QueryPortraitAlbumCover(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
1188     const string &albumId)
1189 {
1190     MediaLibraryTracer tracer;
1191     tracer.Start("QueryPortraitCover");
1192     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1193 
1194     // INNER JOIN AnalysisPhotoMap ON AnalysisPhotoMap.map_asset = Photos.file_id
1195     string anaPhotoMapAsset = ANALYSIS_PHOTO_MAP_TABLE + "." + MAP_ASSET;
1196     string photosFileId = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID;
1197     string clause = anaPhotoMapAsset + " = " + photosFileId;
1198     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ clause });
1199 
1200     // INNER JOIN AnalysisAlbum ON AnalysisAlbum.album_id = AnalysisPhotoMap.map_album
1201     string anaAlbumId = ANALYSIS_ALBUM_TABLE + "." + ALBUM_ID;
1202     string anaPhotoMapAlbum = ANALYSIS_PHOTO_MAP_TABLE + "." + MAP_ALBUM;
1203     clause = anaAlbumId + " = " + anaPhotoMapAlbum;
1204     predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On({ clause });
1205 
1206     // INNER JOIN tab_analysis_image_face ON tab_analysis_image_face.file_id = Photos.file_id
1207     string anaImageFaceFileId = VISION_IMAGE_FACE_TABLE + "." + MediaColumn::MEDIA_ID;
1208     clause = anaImageFaceFileId + "=" + photosFileId;
1209     predicates.InnerJoin(VISION_IMAGE_FACE_TABLE)->On({ clause });
1210 
1211     clause = "Photos.sync_status = 0 "
1212         "AND Photos.clean_flag = 0 "
1213         "AND Photos.date_trashed = 0 "
1214         "AND Photos.hidden = 0 "
1215         "AND Photos.time_pending = 0 "
1216         "AND Photos.is_temp = 0 "
1217         "AND Photos.burst_cover_level = 1 "
1218         "AND AnalysisAlbum.album_id IN (SELECT album_id FROM AnalysisAlbum where AnalysisAlbum.group_tag "
1219         "IN (SELECT group_tag FROM AnalysisAlbum WHERE album_id = " +
1220         albumId +
1221         " LIMIT 1))";
1222     predicates.SetWhereClause(clause);
1223 
1224     predicates.OrderByAsc(
1225         "CASE WHEN AnalysisAlbum.group_tag LIKE '%' || tab_analysis_image_face.tag_id || '%' THEN 0 ELSE 1 END");
1226     predicates.OrderByDesc(VISION_IMAGE_FACE_TABLE + "." + IS_EXCLUDED);
1227     predicates.OrderByDesc(VISION_IMAGE_FACE_TABLE + "." + FACE_AESTHETICS_SCORE);
1228     predicates.OrderByAsc("CASE WHEN tab_analysis_image_face.total_faces = 1 THEN 0 ELSE 1 END");
1229     predicates.OrderByDesc(PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_DATE_ADDED);
1230     predicates.Limit(1);
1231     const string columnFileId = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_ID;
1232     const string columnDisplayName = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_NAME;
1233     const string columnData = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_FILE_PATH;
1234     const vector<string> columns = { columnFileId, columnDisplayName, columnData };
1235     auto resultSet = rdbStore->StepQueryWithoutCheck(predicates, columns);
1236     string sql = RdbSqlUtils::BuildQueryString(predicates, columns);
1237     CHECK_AND_RETURN_RET(resultSet != nullptr, nullptr);
1238     int32_t err = resultSet->GoToFirstRow();
1239     MediaLibraryRestore::GetInstance().CheckRestore(err);
1240     return resultSet;
1241 }
1242 
QueryGroupPhotoAlbumCover(const shared_ptr<MediaLibraryRdbStore> rdbStore,const string & albumId)1243 static shared_ptr<ResultSet> QueryGroupPhotoAlbumCover(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1244     const string &albumId)
1245 {
1246     return QueryPortraitAlbumCover(rdbStore, albumId);
1247 }
1248 
SetPortraitValuesWithCache(shared_ptr<UpdateAlbumDataWithCache> portraitData,const UpdateAlbumData & data,ValuesBucket & values)1249 static void SetPortraitValuesWithCache(shared_ptr<UpdateAlbumDataWithCache> portraitData,
1250     const UpdateAlbumData &data, ValuesBucket &values)
1251 {
1252     if (data.albumCount != portraitData->albumCount) {
1253         MEDIA_INFO_LOG("Update with cache: Portrait album %{public}d. oldCount: %{public}d, newCount: %{public}d",
1254                        data.albumId, data.albumCount, portraitData->albumCount);
1255         values.PutInt(PhotoAlbumColumns::ALBUM_COUNT, portraitData->albumCount);
1256     }
1257     if (data.albumCoverUri != portraitData->albumCoverUri) {
1258         values.PutInt(IS_COVER_SATISFIED, static_cast<uint8_t>(CoverSatisfiedType::DEFAULT_SETTING));
1259         values.PutString(PhotoAlbumColumns::ALBUM_COVER_URI, portraitData->albumCoverUri);
1260         MEDIA_INFO_LOG("Update with cache: Portrait album %{public}d. oldCover: %{public}s, newCover: %{public}s",
1261                        data.albumId, MediaFileUtils::GetUriWithoutDisplayname(data.albumCoverUri).c_str(),
1262                        MediaFileUtils::GetUriWithoutDisplayname(portraitData->albumCoverUri).c_str());
1263     }
1264 }
1265 
SetGroupPhotoValuesWithCache(shared_ptr<UpdateAlbumDataWithCache> portraitData,const UpdateAlbumData & data,ValuesBucket & values)1266 static void SetGroupPhotoValuesWithCache(shared_ptr<UpdateAlbumDataWithCache> portraitData,
1267     const UpdateAlbumData &data, ValuesBucket &values)
1268 {
1269     SetPortraitValuesWithCache(portraitData, data, values);
1270 }
1271 
UpdatePortraitCache(const shared_ptr<MediaLibraryRdbStore> rdbStore,const ValuesBucket & values,const UpdateAlbumData & data,map<int32_t,shared_ptr<UpdateAlbumDataWithCache>> & portraitCacheMap)1272 static void UpdatePortraitCache(const shared_ptr<MediaLibraryRdbStore> rdbStore, const ValuesBucket &values,
1273     const UpdateAlbumData &data, map<int32_t, shared_ptr<UpdateAlbumDataWithCache>> &portraitCacheMap)
1274 {
1275     // get update data
1276     auto portraitData = make_shared<UpdateAlbumDataWithCache>();
1277     portraitData->albumCount = data.albumCount;
1278     portraitData->albumCoverUri = data.albumCoverUri;
1279     ValueObject valueObject;
1280     if (values.GetObject(PhotoAlbumColumns::ALBUM_COUNT, valueObject)) {
1281         valueObject.GetInt(portraitData->albumCount);
1282     }
1283     if (values.GetObject(PhotoAlbumColumns::ALBUM_COVER_URI, valueObject)) {
1284         valueObject.GetString(portraitData->albumCoverUri);
1285     }
1286     // select all albumId
1287     string albumId = to_string(data.albumId);
1288     string clause = "group_tag IN (SELECT group_tag FROM AnalysisAlbum WHERE album_id = " + albumId + ")";
1289     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
1290     predicates.SetWhereClause(clause);
1291     auto resultSet = rdbStore->Query(predicates,  { PhotoAlbumColumns::ALBUM_ID });
1292     CHECK_AND_RETURN_LOG(resultSet != nullptr, "Failed to get Analysis Album Ids");
1293     // update cache map
1294     while (resultSet->GoToNextRow() == E_OK) {
1295         int32_t albumId = GetAlbumId(resultSet);
1296         portraitCacheMap[albumId] = portraitData;
1297     }
1298     resultSet->Close();
1299 }
1300 
UpdateGroupPhotoCache(const shared_ptr<MediaLibraryRdbStore> rdbStore,const ValuesBucket & values,const UpdateAlbumData & data,map<int32_t,shared_ptr<UpdateAlbumDataWithCache>> & portraitCacheMap)1301 static void UpdateGroupPhotoCache(const shared_ptr<MediaLibraryRdbStore> rdbStore, const ValuesBucket &values,
1302     const UpdateAlbumData &data, map<int32_t, shared_ptr<UpdateAlbumDataWithCache>> &portraitCacheMap)
1303 {
1304     UpdatePortraitCache(rdbStore, values, data, portraitCacheMap);
1305 }
1306 
SetPortraitUpdateValues(const shared_ptr<MediaLibraryRdbStore> & rdbStore,const UpdateAlbumData & data,ValuesBucket & values)1307 static int32_t SetPortraitUpdateValues(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
1308     const UpdateAlbumData &data, ValuesBucket &values)
1309 {
1310     const vector<string> countColumns = {
1311         MEDIA_COLUMN_COUNT_DISTINCT_FILE_ID
1312     };
1313 
1314     string coverUri = data.albumCoverUri;
1315     string coverId = GetPhotoId(coverUri);
1316     uint8_t isCoverSatisfied = data.isCoverSatisfied;
1317 
1318     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1319     string albumId = to_string(data.albumId);
1320     GetPortraitAlbumCountPredicates(albumId, predicates);
1321     shared_ptr<ResultSet> countResult = QueryGoToFirst(rdbStore, predicates, countColumns);
1322     CHECK_AND_RETURN_RET_LOG(countResult != nullptr, E_HAS_DB_ERROR, "Failed to query Portrait Album Count");
1323 
1324     int32_t newCount = SetCount(countResult, data, values, false, PhotoAlbumSubType::PORTRAIT);
1325     if (!ShouldUpdatePortraitAlbumCover(rdbStore, albumId, coverId, isCoverSatisfied)) {
1326         return E_SUCCESS;
1327     }
1328     shared_ptr<ResultSet> coverResult = QueryPortraitAlbumCover(rdbStore, albumId);
1329     CHECK_AND_RETURN_RET_LOG(coverResult != nullptr, E_HAS_DB_ERROR,
1330         "Failed to query Portrait Album Cover");
1331     SetPortraitCover(coverResult, data, values, newCount);
1332     return E_SUCCESS;
1333 }
1334 
SetGroupPhotoUpdateValues(const shared_ptr<MediaLibraryRdbStore> rdbStore,const UpdateAlbumData & data,ValuesBucket & values)1335 static int32_t SetGroupPhotoUpdateValues(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1336     const UpdateAlbumData &data, ValuesBucket &values)
1337 {
1338     const vector<string> countColumns = {
1339         MEDIA_COLUMN_COUNT_DISTINCT_FILE_ID
1340     };
1341 
1342     string coverUri = data.albumCoverUri;
1343     string coverId = GetPhotoId(coverUri);
1344     uint8_t isCoverSatisfied = data.isCoverSatisfied;
1345 
1346     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1347     string albumId = to_string(data.albumId);
1348     GetGroupPhotoAlbumCountPredicates(albumId, predicates);
1349     shared_ptr<ResultSet> countResult = QueryGoToFirst(rdbStore, predicates, countColumns);
1350     CHECK_AND_RETURN_RET_LOG(countResult != nullptr, E_HAS_DB_ERROR, "Failed to query GroupPhoto Album Count");
1351 
1352     int32_t newCount = SetCount(countResult, data, values, false, PhotoAlbumSubType::PORTRAIT);
1353     if (!ShouldUpdateGroupPhotoAlbumCover(rdbStore, albumId, coverId, isCoverSatisfied)) {
1354         return E_SUCCESS;
1355     }
1356     shared_ptr<ResultSet> coverResult = QueryGroupPhotoAlbumCover(rdbStore, albumId);
1357     CHECK_AND_RETURN_RET_LOG(coverResult != nullptr, E_HAS_DB_ERROR,
1358         "Failed to query GroupPhoto Album Cover");
1359     SetGroupPhotoCover(coverResult, data, values, newCount);
1360     return E_SUCCESS;
1361 }
1362 
RefreshHighlightAlbum(int32_t albumId)1363 static void RefreshHighlightAlbum(int32_t albumId)
1364 {
1365     vector<string> albumIds;
1366     albumIds.push_back(to_string(albumId));
1367     MediaAnalysisHelper::AsyncStartMediaAnalysisService(
1368         static_cast<int32_t>(Media::MediaAnalysisProxy::ActivateServiceType::HIGHLIGHT_COVER_GENERATE), albumIds);
1369 }
1370 
IsInSystemAlbum(std::shared_ptr<MediaLibraryRdbStore> & rdbStore,RdbPredicates & predicates,PhotoAlbumSubType subtype)1371 static bool IsInSystemAlbum(std::shared_ptr<MediaLibraryRdbStore> &rdbStore,
1372     RdbPredicates &predicates, PhotoAlbumSubType subtype)
1373 {
1374     vector<string> columns = {PhotoColumn::MEDIA_IS_FAV, PhotoColumn::MEDIA_TYPE, PhotoColumn::MEDIA_DATE_TRASHED,
1375     PhotoColumn::PHOTO_STRONG_ASSOCIATION};
1376     auto resultSet = rdbStore->Query(predicates, columns);
1377     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "failed to acquire result from visitor query.");
1378     bool ret = false;
1379     if (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1380         switch (subtype) {
1381             case PhotoAlbumSubType::FAVORITE:
1382                 ret = GetIntValFromColumn(resultSet, PhotoColumn::MEDIA_IS_FAV) == 1;
1383                 break;
1384             case PhotoAlbumSubType::VIDEO:
1385                 ret = GetIntValFromColumn(resultSet, PhotoColumn::MEDIA_TYPE) == MediaType::MEDIA_TYPE_VIDEO;
1386                 break;
1387             case PhotoAlbumSubType::IMAGE:
1388                 ret = GetIntValFromColumn(resultSet, PhotoColumn::MEDIA_TYPE) == MediaType::MEDIA_TYPE_IMAGE;
1389                 break;
1390             case PhotoAlbumSubType::TRASH:
1391                 ret = GetLongValFromColumn(resultSet, PhotoColumn::MEDIA_DATE_TRASHED) == 0;
1392                 break;
1393             case PhotoAlbumSubType::CLOUD_ENHANCEMENT:
1394                 ret = GetIntValFromColumn(resultSet, PhotoColumn::PHOTO_STRONG_ASSOCIATION) ==
1395                     static_cast<int32_t>(StrongAssociationType::CLOUD_ENHANCEMENT);
1396                 break;
1397             default:
1398                 MEDIA_ERR_LOG("albumSubtype is invalid: %{public}d", subtype);
1399                 break;
1400         }
1401     } else {
1402         MEDIA_ERR_LOG("resultSet GoToNextRow failed");
1403     }
1404     return ret;
1405 }
1406 
UpdateCoverUriSourceToDefault(int32_t albumId)1407 int32_t UpdateCoverUriSourceToDefault(int32_t albumId)
1408 {
1409     MEDIA_DEBUG_LOG("UpdateCoverUriSourceToDefault enter, albumId:%{public}d", albumId);
1410     RdbPredicates newPredicates(PhotoAlbumColumns::TABLE);
1411     ValuesBucket values;
1412     values.PutLong(PhotoAlbumColumns::ALBUM_DATE_MODIFIED, MediaFileUtils::UTCTimeMilliSeconds());
1413     values.PutInt(PhotoAlbumColumns::COVER_URI_SOURCE, CoverUriSource::DEFAULT_COVER);
1414 
1415     string UPDATE_CONDITION = PhotoAlbumColumns::ALBUM_ID + " = " + to_string(albumId) + " AND " +
1416         PhotoAlbumColumns::COVER_URI_SOURCE + " > " + to_string(CoverUriSource::DEFAULT_COVER);
1417 
1418     newPredicates.SetWhereClause(UPDATE_CONDITION);
1419 
1420     int32_t changedRows = OHOS::Media::MediaLibraryRdbStore::UpdateWithDateTime(values, newPredicates);
1421     CHECK_AND_PRINT_LOG(changedRows >= 0, "Update photo album failed: %{public}d", changedRows);
1422 
1423     return changedRows;
1424 }
1425 
IsNeedSetCover(UpdateAlbumData & data,PhotoAlbumSubType subtype)1426 static bool IsNeedSetCover(UpdateAlbumData &data, PhotoAlbumSubType subtype)
1427 {
1428     MEDIA_DEBUG_LOG(
1429         "IsNeedSetCover enter, albumId:%{public}d, coverUri:%{public}s, subtype:%{public}d, coverUriSource:%{public}d",
1430         data.albumId, data.albumCoverUri.c_str(), static_cast<int32_t>(subtype), data.coverUriSource);
1431     // manual cover and cover in the album
1432     if (data.coverUriSource == static_cast<int32_t>(CoverUriSource::DEFAULT_COVER) ||
1433         data.albumCoverUri.empty()) { // first pull
1434         return true;
1435     }
1436     string &coverUri = data.albumCoverUri;
1437     string fileId = MediaLibraryDataManagerUtils::GetFileIdFromPhotoUri(coverUri);
1438 
1439     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1440     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_HAS_DB_ERROR, "Failed to get rdbStore when query owner_album_id");
1441     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1442 
1443     string checkCoverValid = MediaColumn::MEDIA_ID + " = " + fileId + " AND " +
1444         MediaColumn::MEDIA_DATE_TRASHED + " = 0 AND " + MediaColumn::MEDIA_HIDDEN + " = 0 AND " +
1445         MediaColumn::MEDIA_TIME_PENDING + " = 0 AND " + PhotoColumn::PHOTO_IS_TEMP + " = 0 AND " +
1446         PhotoColumn::PHOTO_BURST_COVER_LEVEL + " = " +
1447         to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)) +
1448         " AND " + PhotoColumn::PHOTO_SYNC_STATUS + " = 0 AND " + PhotoColumn::PHOTO_CLEAN_FLAG + " = 0";
1449     predicates.SetWhereClause(checkCoverValid);
1450     if (subtype == PhotoAlbumSubType::USER_GENERIC || subtype == PhotoAlbumSubType::SOURCE_GENERIC) {
1451         vector<string> columns = { PhotoColumn::PHOTO_OWNER_ALBUM_ID };
1452         auto resultSet = rdbStore->Query(predicates, columns);
1453         CHECK_AND_RETURN_RET_INFO_LOG(resultSet != nullptr, E_HAS_DB_ERROR,
1454             "failed to acquire result from visitor query.");
1455         int32_t ownerAlbumId = -1;
1456         if (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1457             ownerAlbumId = GetIntValFromColumn(resultSet, PhotoColumn::PHOTO_OWNER_ALBUM_ID);
1458         } else {
1459             MEDIA_ERR_LOG("resultSet GoToNextRow failed, fileId:%{public}s", fileId.c_str());
1460         }
1461         auto isInAlbum = ownerAlbumId == data.albumId;
1462         if (!isInAlbum) {
1463             UpdateCoverUriSourceToDefault(data.albumId);
1464         }
1465         MEDIA_DEBUG_LOG("IsNeedSetCover: ownerAlbumId:%{public}d", ownerAlbumId);
1466         return !isInAlbum;
1467     }
1468     auto isInAlbum = IsInSystemAlbum(rdbStore, predicates, subtype);
1469     if (!isInAlbum) {
1470         UpdateCoverUriSourceToDefault(data.albumId);
1471     }
1472     return !isInAlbum;
1473 }
1474 
SetShootingModeAlbumQueryOrder(RdbPredicates & predicates,const string & albumName,vector<string> & columns)1475 static int32_t SetShootingModeAlbumQueryOrder(RdbPredicates& predicates, const string& albumName,
1476     vector<string>& columns)
1477 {
1478     columns.push_back("max(date_taken)");
1479     ShootingModeAlbumType type {};
1480     if (!ShootingModeAlbum::AlbumNameToShootingModeAlbumType(albumName, type)) {
1481         MEDIA_ERR_LOG("Invalid shooting mode album name: %{public}s", albumName.c_str());
1482         predicates.EqualTo(PhotoColumn::MEDIA_ID, to_string(0));
1483         return E_INVALID_ARGUMENTS;
1484     }
1485     if (type != ShootingModeAlbumType::MOVING_PICTURE) {
1486         predicates.IndexedBy(ShootingModeAlbum::GetQueryAssetsIndex(type));
1487     }
1488     return E_SUCCESS;
1489 }
1490 
DetermineQueryOrder(RdbPredicates & predicates,const UpdateAlbumData & data,bool hiddenState,vector<string> & columns)1491 static void DetermineQueryOrder(RdbPredicates& predicates, const UpdateAlbumData& data, bool hiddenState,
1492     vector<string>& columns)
1493 {
1494     PhotoAlbumSubType subtype = static_cast<PhotoAlbumSubType>(data.albumSubtype);
1495     if (subtype == PhotoAlbumSubType::HIDDEN || hiddenState) {
1496         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_HIDDEN_TIME_INDEX);
1497     } else if (subtype == PhotoAlbumSubType::VIDEO || subtype == PhotoAlbumSubType::IMAGE) {
1498         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_MEDIA_TYPE_INDEX);
1499     } else if (subtype == PhotoAlbumSubType::FAVORITE) {
1500         predicates.IndexedBy(PhotoColumn::PHOTO_FAVORITE_INDEX);
1501     } else if (subtype == PhotoAlbumSubType::CLOUD_ENHANCEMENT) {
1502         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_CLOUD_ENHANCEMENT_ALBUM_INDEX);
1503     } else if (subtype == PhotoAlbumSubType::USER_GENERIC || subtype == PhotoAlbumSubType::SOURCE_GENERIC) {
1504         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_ALBUM_INDEX);
1505     } else if (subtype == PhotoAlbumSubType::SHOOTING_MODE) {
1506         SetShootingModeAlbumQueryOrder(predicates, data.albumName, columns);
1507     } else {
1508         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_ADDED_INDEX);
1509     }
1510 }
1511 
SetUpdateValues(const shared_ptr<MediaLibraryRdbStore> & rdbStore,UpdateAlbumData & data,ValuesBucket & values,const bool hiddenState)1512 static int32_t SetUpdateValues(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
1513     UpdateAlbumData &data, ValuesBucket &values, const bool hiddenState)
1514 {
1515     PhotoAlbumSubType subtype = static_cast<PhotoAlbumSubType>(data.albumSubtype);
1516     vector<string> columns = {
1517         MEDIA_COLUMN_COUNT_1, PhotoColumn::MEDIA_ID,
1518         PhotoColumn::MEDIA_FILE_PATH, PhotoColumn::MEDIA_NAME,
1519         PhotoColumn::PHOTO_HIDDEN_TIME,
1520         PhotoColumn::MEDIA_DATE_ADDED,
1521         PhotoColumn::MEDIA_DATE_TAKEN
1522     };
1523     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1524     GetAlbumCountAndCoverPredicates(data, predicates, hiddenState, true);
1525     DetermineQueryOrder(predicates, data, hiddenState, columns);
1526     auto fileResult = QueryGoToFirst(rdbStore, predicates, columns);
1527     CHECK_AND_RETURN_RET_LOG(fileResult != nullptr, E_HAS_DB_ERROR, "Failed to query fileResult");
1528     int32_t newCount = SetCount(fileResult, data, values, hiddenState, subtype);
1529     data.newTotalCount = newCount;
1530 
1531     if (subtype != PhotoAlbumSubType::HIGHLIGHT && subtype != PhotoAlbumSubType::HIGHLIGHT_SUGGESTIONS &&
1532         IsNeedSetCover(data, subtype)) {
1533         SetCover(fileResult, data, values, hiddenState);
1534     }
1535     if (hiddenState == 0 && (subtype < PhotoAlbumSubType::ANALYSIS_START ||
1536         subtype > PhotoAlbumSubType::ANALYSIS_END)) {
1537         predicates.Clear();
1538         GetAlbumCountAndCoverPredicates(data, predicates, hiddenState, true);
1539         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_MEDIA_TYPE_INDEX);
1540         string queryCondition = predicates.GetWhereClause();
1541         if (queryCondition.empty()) {
1542             predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO));
1543         } else {
1544             predicates.SetWhereClause(
1545                 "(" + queryCondition + ") AND " + MediaColumn::MEDIA_TYPE + " = " + to_string(MEDIA_TYPE_VIDEO));
1546         }
1547         auto fileResultVideo = QueryGoToFirst(rdbStore, predicates, columns);
1548         CHECK_AND_RETURN_RET_LOG(fileResultVideo != nullptr, E_HAS_DB_ERROR, "Failed to query fileResultVideo");
1549         SetImageVideoCount(newCount, fileResultVideo, data, values);
1550     }
1551 
1552     // album datemodified can be update only when the number of user and source album is updated.
1553     if (data.shouldUpdateDateModified) {
1554         values.PutLong(PhotoAlbumColumns::ALBUM_DATE_MODIFIED, MediaFileUtils::UTCTimeMilliSeconds());
1555     }
1556     return E_SUCCESS;
1557 }
1558 
QueryAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris,PhotoAlbumType photoAlbumType)1559 static vector<string> QueryAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore, const vector<string> &uris,
1560     PhotoAlbumType photoAlbumType)
1561 {
1562     vector<string> albumIds;
1563     string idArgs;
1564     for (size_t i = 0; i < uris.size(); i++) {
1565         string fileId = GetPhotoId(uris[i]);
1566         CHECK_AND_EXECUTE(fileId.size() <= 0, idArgs.append("'").append(fileId).append("'").append(","));
1567         bool cond = ((i == 0 || i % ALBUM_UPDATE_THRESHOLD != 0) && i < uris.size() - 1);
1568         CHECK_AND_CONTINUE(!cond);
1569         CHECK_AND_CONTINUE(idArgs.size() != 0);
1570 
1571         idArgs = idArgs.substr(0, idArgs.size() - 1);
1572         const string sql = ""
1573             "WITH PhotoAlbumIds AS ( SELECT album_id FROM PhotoAlbum WHERE album_type = " +
1574             to_string(photoAlbumType) +
1575             " ) "
1576             "SELECT DISTINCT "
1577             "owner_album_id "
1578             "FROM"
1579             "  Photos"
1580             "  INNER JOIN PhotoAlbumIds ON Photos.owner_album_id = PhotoAlbumIds.album_id "
1581             "WHERE"
1582             "  file_id IN ( " +
1583             idArgs + " );";
1584         auto resultSet = rdbStore->QueryByStep(sql);
1585         CHECK_AND_CONTINUE_ERR_LOG(resultSet != nullptr, "Failed to Query AlbumId");
1586         while (resultSet->GoToNextRow() == E_OK) {
1587             albumIds.push_back(to_string(GetIntValFromColumn(resultSet, 0)));
1588         }
1589         resultSet->Close();
1590         idArgs.clear();
1591     }
1592     return albumIds;
1593 }
1594 
QueryAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris)1595 static vector<string> QueryAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore, const vector<string> &uris)
1596 {
1597     vector<string> albumIds;
1598     string idArgs;
1599     for (size_t i = 0; i < uris.size(); i++) {
1600         string fileId = GetPhotoId(uris[i]);
1601         if (fileId.size() > 0) {
1602             idArgs.append("'").append(fileId).append("'").append(",");
1603         }
1604         bool cond = ((i == 0 || i % ALBUM_UPDATE_THRESHOLD != 0) && i < uris.size() - 1);
1605         CHECK_AND_CONTINUE(!cond);
1606         CHECK_AND_CONTINUE(idArgs.size() != 0);
1607 
1608         idArgs = idArgs.substr(0, idArgs.size() - 1);
1609         const string sql = ""
1610             "SELECT DISTINCT owner_album_id FROM Photos WHERE "
1611             "file_id IN ( " + idArgs + " ); ";
1612         auto resultSet = rdbStore->QueryByStep(sql);
1613         CHECK_AND_CONTINUE_ERR_LOG(resultSet != nullptr, "Failed to Query AlbumId");
1614         while (resultSet->GoToNextRow() == E_OK) {
1615             albumIds.push_back(to_string(GetIntValFromColumn(resultSet, 0)));
1616         }
1617         resultSet->Close();
1618         idArgs.clear();
1619     }
1620     return albumIds;
1621 }
1622 
UpdateUserAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore> rdbStore,UpdateAlbumData & data,const bool hiddenState,AccurateRefresh::AlbumAccurateRefresh & albumRefresh)1623 static int32_t UpdateUserAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore> rdbStore, UpdateAlbumData &data,
1624     const bool hiddenState, AccurateRefresh::AlbumAccurateRefresh &albumRefresh)
1625 {
1626     AccurateRefresh::AlbumRefreshTimestampRecord refreshRecord(data.albumId, hiddenState);
1627     MediaLibraryTracer tracer;
1628     tracer.Start("UpdateUserAlbumIfNeeded");
1629 
1630     ValuesBucket values;
1631     int err = SetUpdateValues(rdbStore, data, values, hiddenState);
1632     CHECK_AND_RETURN_RET_LOG(err >= 0, err,
1633         "Failed to set update values when updating albums, album id: %{public}d, hidden state: %{public}d",
1634         data.albumId, hiddenState ? 1 : 0);
1635     if (values.IsEmpty()) {
1636         refreshRecord.ClearRecord();
1637         return E_SUCCESS;
1638     }
1639 
1640     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
1641     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(data.albumId));
1642     predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::USER_GENERIC));
1643     int32_t changedRows = 0;
1644     err = albumRefresh.Update(changedRows, values, predicates);
1645     CHECK_AND_RETURN_RET_LOG(err == NativeRdb::E_OK, err,
1646         "Failed to update album count and cover! album id: %{public}d, hidden state: %{public}d",
1647             data.albumId, hiddenState ? 1 : 0);
1648     data.hasChanged = true;
1649     refreshRecord.RefreshAlbumEnd();
1650     return E_SUCCESS;
1651 }
1652 
UpdatePortraitAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore> & rdbStore,const UpdateAlbumData & data,std::shared_ptr<TransactionOperations> trans,map<int32_t,shared_ptr<UpdateAlbumDataWithCache>> & portraitCacheMap)1653 static int32_t UpdatePortraitAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
1654     const UpdateAlbumData &data, std::shared_ptr<TransactionOperations> trans,
1655     map<int32_t, shared_ptr<UpdateAlbumDataWithCache>> &portraitCacheMap)
1656 {
1657     MediaLibraryTracer tracer;
1658     tracer.Start("UpdatePortraitAlbumIfNeeded");
1659     CHECK_AND_RETURN_RET_LOG(trans != nullptr, E_HAS_DB_ERROR, "transactionOprn is null");
1660     auto subtype = static_cast<PhotoAlbumSubType>(data.albumSubtype);
1661     CHECK_AND_RETURN_RET(subtype == PhotoAlbumSubType::PORTRAIT, E_SUCCESS);
1662 
1663     ValuesBucket values;
1664     int32_t albumId = data.albumId;
1665     auto it = portraitCacheMap.find(data.albumId);
1666     if (it != portraitCacheMap.end()) {
1667         SetPortraitValuesWithCache(it->second, data, values);
1668     } else {
1669         int setRet = SetPortraitUpdateValues(rdbStore, data, values);
1670         if (setRet != E_SUCCESS) {
1671             MEDIA_ERR_LOG("Failed to set portrait album update values! album id: %{public}d, err: %{public}d", albumId,
1672                           setRet);
1673             return setRet;
1674         }
1675         UpdatePortraitCache(rdbStore, values, data, portraitCacheMap);
1676     }
1677     if (values.IsEmpty()) {
1678         return E_SUCCESS;
1679     }
1680 
1681     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
1682     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(albumId));
1683     int32_t changedRows = 0;
1684     int updateRet = trans->Update(changedRows, values, predicates);
1685     CHECK_AND_RETURN_RET_LOG(updateRet == NativeRdb::E_OK, updateRet,
1686         "Failed to update album count and cover! album id: %{public}d, err: %{public}d", albumId, updateRet);
1687     return E_SUCCESS;
1688 }
1689 
UpdateGroupPhotoAlbumIfNeed(const shared_ptr<MediaLibraryRdbStore> & rdbStore,const UpdateAlbumData & data,std::shared_ptr<TransactionOperations> trans,map<int32_t,shared_ptr<UpdateAlbumDataWithCache>> & pgroupPhotoCacheMap)1690 static int32_t UpdateGroupPhotoAlbumIfNeed(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
1691     const UpdateAlbumData &data, std::shared_ptr<TransactionOperations> trans,
1692     map<int32_t, shared_ptr<UpdateAlbumDataWithCache>> &pgroupPhotoCacheMap)
1693 {
1694     MediaLibraryTracer tracer;
1695     tracer.Start("UpdateGroupPhotoAlbumIfNeed");
1696     CHECK_AND_RETURN_RET_LOG(trans != nullptr, E_HAS_DB_ERROR, "transactionOprn is null");
1697     auto subtype = static_cast<PhotoAlbumSubType>(data.albumSubtype);
1698     CHECK_AND_RETURN_RET(subtype == PhotoAlbumSubType::GROUP_PHOTO, E_SUCCESS);
1699     ValuesBucket values;
1700     int32_t albumId = data.albumId;
1701     auto it = pgroupPhotoCacheMap.find(data.albumId);
1702     if (it != pgroupPhotoCacheMap.end()) {
1703         SetGroupPhotoValuesWithCache(it->second, data, values);
1704     } else {
1705         int setRet = SetGroupPhotoUpdateValues(rdbStore, data, values);
1706         if (setRet != E_SUCCESS) {
1707             MEDIA_ERR_LOG("Failed to set group Photo album update values! album id: %{public}d, err: %{public}d",
1708                 albumId, setRet);
1709             return setRet;
1710         }
1711         UpdateGroupPhotoCache(rdbStore, values, data, pgroupPhotoCacheMap);
1712     }
1713     if (values.IsEmpty()) {
1714         return E_SUCCESS;
1715     }
1716 
1717     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
1718     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(albumId));
1719     int32_t changedRows = 0;
1720     int updateRet = trans->Update(changedRows, values, predicates);
1721     CHECK_AND_RETURN_RET_LOG(updateRet == NativeRdb::E_OK, updateRet,
1722         "Failed to update album count and cover! album id: %{public}d, err: %{public}d", albumId, updateRet);
1723     return E_SUCCESS;
1724 }
1725 
UpdateAnalysisAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore> & rdbStore,UpdateAlbumData & data,const bool hiddenState,std::shared_ptr<TransactionOperations> trans=nullptr)1726 static int32_t UpdateAnalysisAlbumIfNeeded(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
1727     UpdateAlbumData &data, const bool hiddenState, std::shared_ptr<TransactionOperations> trans = nullptr)
1728 {
1729     MediaLibraryTracer tracer;
1730     tracer.Start("UpdateAnalysisAlbumIfNeeded");
1731     ValuesBucket values;
1732     int err = SetUpdateValues(rdbStore, data, values, hiddenState);
1733     CHECK_AND_RETURN_RET_LOG(err >= 0, err,
1734         "Failed to set update values when updating albums, album id: %{public}d, hidden state: %{public}d",
1735         data.albumId, hiddenState ? 1 : 0);
1736     if (values.IsEmpty()) {
1737         return E_SUCCESS;
1738     }
1739 
1740     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
1741     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(data.albumId));
1742     int32_t changedRows = 0;
1743     if (trans == nullptr) {
1744         err = rdbStore->Update(changedRows, values, predicates);
1745     } else {
1746         err = trans->Update(changedRows, values, predicates);
1747     }
1748 
1749     CHECK_AND_RETURN_RET_LOG(err == NativeRdb::E_OK, err,
1750         "Failed to update album count and cover! album id: %{public}d, hidden state: %{public}d",
1751         data.albumId, hiddenState ? 1 : 0);
1752     data.hasChanged = true;
1753     return E_SUCCESS;
1754 }
1755 
UpdateCommonAlbumIfNeeded(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,UpdateAlbumData & data,const bool hiddenState,AccurateRefresh::AlbumAccurateRefresh & albumRefresh)1756 static int32_t UpdateCommonAlbumIfNeeded(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,
1757     UpdateAlbumData &data, const bool hiddenState, AccurateRefresh::AlbumAccurateRefresh &albumRefresh)
1758 {
1759     MediaLibraryTracer tracer;
1760     tracer.Start("UpdateCommonAlbumIfNeeded");
1761     AccurateRefresh::AlbumRefreshTimestampRecord refreshRecord(data.albumId, hiddenState);
1762     ValuesBucket values;
1763     int err = SetUpdateValues(rdbStore, data, values, hiddenState);
1764     CHECK_AND_RETURN_RET_LOG(err >= 0, err,
1765         "Failed to set update values when updating albums, album id: %{public}d, hidden state: %{public}d",
1766         data.albumId, hiddenState ? 1 : 0);
1767     if (values.IsEmpty()) {
1768         refreshRecord.ClearRecord();
1769         return E_SUCCESS;
1770     }
1771 
1772     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
1773     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(data.albumId));
1774     predicates.BeginWrap();
1775     predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::USER_GENERIC));
1776     predicates.Or();
1777     predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::SOURCE_GENERIC));
1778     predicates.EndWrap();
1779     int32_t changedRows = 0;
1780     err = albumRefresh.Update(changedRows, values, predicates);
1781     CHECK_AND_RETURN_RET_LOG(err == NativeRdb::E_OK, err,
1782         "Failed to update album count and cover! album id: %{public}d, hidden state: %{public}d",
1783             data.albumId, hiddenState ? 1 : 0);
1784     data.hasChanged = true;
1785     refreshRecord.RefreshAlbumEnd();
1786     return E_SUCCESS;
1787 }
1788 
UpdateSourceAlbumIfNeeded(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,UpdateAlbumData & data,const bool hiddenState,AccurateRefresh::AlbumAccurateRefresh & albumRefresh)1789 static int32_t UpdateSourceAlbumIfNeeded(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,
1790     UpdateAlbumData &data, const bool hiddenState, AccurateRefresh::AlbumAccurateRefresh &albumRefresh)
1791 {
1792     MediaLibraryTracer tracer;
1793     tracer.Start("UpdateSourceAlbumIfNeeded");
1794     AccurateRefresh::AlbumRefreshTimestampRecord refreshRecord(data.albumId, hiddenState);
1795     ValuesBucket values;
1796     int err = SetUpdateValues(rdbStore, data, values, hiddenState);
1797     CHECK_AND_RETURN_RET_LOG(err >= 0, err,
1798         "Failed to set update values when updating albums, album id: %{public}d, hidden state: %{public}d",
1799         data.albumId, hiddenState ? 1 : 0);
1800     if (values.IsEmpty()) {
1801         refreshRecord.ClearRecord();
1802         return E_SUCCESS;
1803     }
1804 
1805     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
1806     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(data.albumId));
1807     predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::SOURCE_GENERIC));
1808     int32_t changedRows = 0;
1809     err = albumRefresh.Update(changedRows, values, predicates);
1810     CHECK_AND_RETURN_RET_LOG(err == NativeRdb::E_OK, err,
1811         "Failed to update album count and cover! album id: %{public}d, hidden state: %{public}d",
1812             data.albumId, hiddenState ? 1 : 0);
1813     data.hasChanged = true;
1814     refreshRecord.RefreshAlbumEnd();
1815     return E_SUCCESS;
1816 }
1817 
UpdateSysAlbumIfNeeded(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,UpdateAlbumData & data,const bool hiddenState,AccurateRefresh::AlbumAccurateRefresh & albumRefresh)1818 static int32_t UpdateSysAlbumIfNeeded(const std::shared_ptr<MediaLibraryRdbStore> rdbStore, UpdateAlbumData &data,
1819     const bool hiddenState, AccurateRefresh::AlbumAccurateRefresh &albumRefresh)
1820 {
1821     AccurateRefresh::AlbumRefreshTimestampRecord refreshRecord(data.albumId, hiddenState);
1822     auto subtype = static_cast<PhotoAlbumSubType>(data.albumSubtype);
1823     MediaLibraryTracer tracer;
1824     tracer.Start("UpdateSysAlbum: " + to_string(subtype));
1825     ValuesBucket values;
1826     int err = SetUpdateValues(rdbStore, data, values, hiddenState);
1827     CHECK_AND_RETURN_RET_LOG(err >= 0, err,
1828         "Failed to set update values when updating albums, album id: %{public}d, hidden state: %{public}d",
1829         data.albumId, hiddenState ? 1 : 0);
1830     if (values.IsEmpty()) {
1831         refreshRecord.RefreshAlbumEnd();
1832         return E_SUCCESS;
1833     }
1834 
1835     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
1836     predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(subtype));
1837     predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(data.albumId));
1838     int32_t changedRows = 0;
1839     err = albumRefresh.Update(changedRows, values, predicates);
1840     CHECK_AND_RETURN_RET_LOG(err == NativeRdb::E_OK, err,
1841         "Failed to update album count and cover! album id: %{public}d, hidden state: %{public}d",
1842             data.albumId, hiddenState ? 1 : 0);
1843     data.hasChanged = true;
1844     refreshRecord.RefreshAlbumEnd();
1845     return E_SUCCESS;
1846 }
1847 
GetPhotoAlbumDataInfo(const shared_ptr<ResultSet> albumResult,bool shouldNotify,bool shouldUpdateDateModified=false)1848 static vector<UpdateAlbumData> GetPhotoAlbumDataInfo(const shared_ptr<ResultSet> albumResult, bool shouldNotify,
1849     bool shouldUpdateDateModified = false)
1850 {
1851     vector<UpdateAlbumData> datas;
1852     while (albumResult->GoToNextRow() == E_OK) {
1853         UpdateAlbumData data;
1854         data.albumId = GetAlbumId(albumResult);
1855         data.albumSubtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
1856         data.albumCoverUri = GetAlbumCover(albumResult, PhotoAlbumColumns::ALBUM_COVER_URI);
1857         data.albumCount = GetAlbumCount(albumResult, PhotoAlbumColumns::ALBUM_COUNT);
1858         data.albumImageCount = GetAlbumCount(albumResult, PhotoAlbumColumns::ALBUM_IMAGE_COUNT);
1859         data.albumVideoCount = GetAlbumCount(albumResult, PhotoAlbumColumns::ALBUM_VIDEO_COUNT);
1860         data.coverDateTime = GetCoverDateTime(albumResult);
1861         data.shouldNotify = shouldNotify;
1862         data.shouldUpdateDateModified = shouldUpdateDateModified;
1863         datas.push_back(data);
1864     }
1865 
1866     return datas;
1867 }
1868 
GetPhotoAlbumHiddenDataInfo(const shared_ptr<ResultSet> albumResult)1869 static vector<UpdateAlbumData> GetPhotoAlbumHiddenDataInfo(const shared_ptr<ResultSet> albumResult)
1870 {
1871     vector<UpdateAlbumData> datas;
1872     while (albumResult->GoToNextRow() == E_OK) {
1873         UpdateAlbumData data;
1874         data.albumId = GetAlbumId(albumResult);
1875         data.albumSubtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
1876         data.hiddenCount = GetAlbumCount(albumResult, PhotoAlbumColumns::HIDDEN_COUNT);
1877         data.hiddenCover = GetAlbumCover(albumResult, PhotoAlbumColumns::HIDDEN_COVER);
1878         data.hiddenCoverDateTime = GetHiddenCoverDateTime(albumResult);
1879         datas.push_back(data);
1880     }
1881     return datas;
1882 }
1883 
UpdateUserAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & userAlbumIds)1884 void MediaLibraryRdbUtils::UpdateUserAlbumHiddenState(
1885     const shared_ptr<MediaLibraryRdbStore> rdbStore, const vector<string> &userAlbumIds)
1886 {
1887     MediaLibraryTracer tracer;
1888     tracer.Start("UpdateUserAlbumHiddenState");
1889     auto albumResult = GetUserAlbum(rdbStore, userAlbumIds, PHOTO_ALBUM_HIDDEN_INFO_COLUMNS);
1890     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
1891     vector<UpdateAlbumData> datas = GetPhotoAlbumHiddenDataInfo(albumResult);
1892     albumResult->Close();
1893 
1894     ForEachRow(rdbStore, datas, true, UpdateUserAlbumIfNeeded);
1895 }
1896 
CopyAssetIfNeed(int32_t fileId,int32_t albumId,const shared_ptr<MediaLibraryRdbStore> rdbStore,vector<int32_t> & updateIds,bool & hidden)1897 static bool CopyAssetIfNeed(int32_t fileId, int32_t albumId,
1898     const shared_ptr<MediaLibraryRdbStore> rdbStore, vector<int32_t> &updateIds, bool &hidden)
1899 {
1900     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1901     predicates.EqualTo(PhotoColumn::MEDIA_ID, fileId);
1902     vector<string> columns;
1903     shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->Query(predicates, columns);
1904     CHECK_AND_RETURN_RET(resultSet != nullptr, false);
1905     bool needCopy = true;
1906     int64_t newAssetId = -1;
1907     if (resultSet->GoToFirstRow() == NativeRdb::E_OK) {
1908         hidden = static_cast<bool>(GetIntValFromColumn(resultSet, MediaColumn::MEDIA_HIDDEN));
1909         auto albumIdQuery = GetIntValFromColumn(resultSet, PhotoColumn::PHOTO_OWNER_ALBUM_ID);
1910         if (albumIdQuery == albumId) {
1911             needCopy = false;
1912             updateIds.push_back(fileId);
1913         } else {
1914             needCopy = true;
1915             MEDIA_DEBUG_LOG("add assets: need copy assets id is: %{public}s", to_string(fileId).c_str());
1916             MediaLibraryAlbumFusionUtils::HandleSingleFileCopy(rdbStore, fileId, albumId, newAssetId);
1917             updateIds.push_back(newAssetId);
1918         }
1919     }
1920     return needCopy;
1921 }
1922 
UpdateUserAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris,bool shouldNotify,bool shouldUpdateDateModified)1923 void MediaLibraryRdbUtils::UpdateUserAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1924     const vector<string> &uris, bool shouldNotify, bool shouldUpdateDateModified)
1925 {
1926     MediaLibraryTracer tracer;
1927     tracer.Start("UpdateUserAlbumByUri");
1928 
1929     if (uris.size() == 0) {
1930         UpdateUserAlbumInternal(rdbStore);
1931         UpdateUserAlbumHiddenState(rdbStore);
1932     }
1933 
1934     vector<string> albumIds = QueryAlbumId(rdbStore, uris, PhotoAlbumType::USER);
1935     if (albumIds.size() > 0) {
1936         UpdateUserAlbumInternal(rdbStore, albumIds, shouldNotify, shouldUpdateDateModified);
1937         UpdateUserAlbumHiddenState(rdbStore, albumIds);
1938     }
1939 }
1940 
UpdateUserAlbumInternal(shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & userAlbumIds,bool shouldNotify,bool shouldUpdateDateModified)1941 void MediaLibraryRdbUtils::UpdateUserAlbumInternal(shared_ptr<MediaLibraryRdbStore> rdbStore,
1942     const vector<string> &userAlbumIds, bool shouldNotify, bool shouldUpdateDateModified)
1943 {
1944     MediaLibraryTracer tracer;
1945     tracer.Start("UpdateUserAlbumInternal");
1946 
1947     if (rdbStore == nullptr) {
1948         MEDIA_ERR_LOG("Failed to get rdbstore, try again!");
1949         rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1950         CHECK_AND_RETURN_LOG(rdbStore != nullptr,
1951             "Fatal error! Failed to get rdbstore, new cloud data is not processed!!");
1952     }
1953 
1954     auto albumResult = GetUserAlbum(rdbStore, userAlbumIds, PHOTO_ALBUM_INFO_COLUMNS);
1955     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
1956     vector<UpdateAlbumData> datas = GetPhotoAlbumDataInfo(albumResult, shouldNotify, shouldUpdateDateModified);
1957     albumResult->Close();
1958     ForEachRow(rdbStore, datas, false, UpdateUserAlbumIfNeeded);
1959 }
1960 
GetIntFromResultSet(shared_ptr<ResultSet> resultSet,const string & column,int & value)1961 static int32_t GetIntFromResultSet(shared_ptr<ResultSet> resultSet, const string &column, int &value)
1962 {
1963     CHECK_AND_RETURN_RET(resultSet != nullptr, E_HAS_DB_ERROR);
1964     int index = -1;
1965     resultSet->GetColumnIndex(column, index);
1966     CHECK_AND_RETURN_RET(index != -1, E_HAS_DB_ERROR);
1967     CHECK_AND_RETURN_RET(resultSet->GetInt(index, value) == NativeRdb::E_OK, E_HAS_DB_ERROR);
1968     return E_OK;
1969 }
1970 
GetStringFromResultSet(shared_ptr<ResultSet> resultSet,const string & column,string & value)1971 static int32_t GetStringFromResultSet(shared_ptr<ResultSet> resultSet, const string &column, string &value)
1972 {
1973     CHECK_AND_RETURN_RET(resultSet != nullptr, E_HAS_DB_ERROR);
1974     int index = -1;
1975     resultSet->GetColumnIndex(column, index);
1976     CHECK_AND_RETURN_RET(index != -1, E_HAS_DB_ERROR);
1977     CHECK_AND_RETURN_RET(resultSet->GetString(index, value) == NativeRdb::E_OK, E_HAS_DB_ERROR);
1978     return E_OK;
1979 }
1980 
UpdateTrashedAssetOnAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,RdbPredicates & predicates)1981 int32_t MediaLibraryRdbUtils::UpdateTrashedAssetOnAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1982     RdbPredicates &predicates)
1983 {
1984     vector<string> newWhereIdArgs;
1985     for (auto albumId: predicates.GetWhereArgs()) {
1986         MEDIA_INFO_LOG("Start trashed album, album id is: %{public}s", albumId.c_str());
1987         const std::string QUERY_FILE_ASSET_INFO = "SELECT file_id, data, display_name FROM"
1988             " Photos WHERE owner_album_id = " + albumId +
1989             " AND clean_flag = 0 AND hidden = 0";
1990         shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->QuerySql(QUERY_FILE_ASSET_INFO);
1991         vector<string> fileAssetsIds, fileAssetsUri;
1992         while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1993             int32_t fileId = -1;
1994             string assetData, displayName;
1995             GetIntFromResultSet(resultSet, MediaColumn::MEDIA_ID, fileId);
1996             GetStringFromResultSet(resultSet, MediaColumn::MEDIA_FILE_PATH, assetData);
1997             GetStringFromResultSet(resultSet, MediaColumn::MEDIA_NAME, displayName);
1998             fileAssetsIds.push_back(to_string(fileId));
1999             string extraUri = MediaFileUtils::GetExtraUri(displayName, assetData);
2000             string uri = MediaFileUtils::GetUriByExtrConditions(PhotoColumn::PHOTO_URI_PREFIX,
2001                 to_string(fileId), extraUri);
2002             fileAssetsUri.push_back(uri);
2003         }
2004 
2005         newWhereIdArgs.push_back(albumId);
2006         if (fileAssetsUri.empty()) {
2007             continue;
2008         }
2009 
2010         MediaLibraryPhotoOperations::UpdateSourcePath(fileAssetsIds);
2011         RdbPredicates predicatesPhotos(PhotoColumn::PHOTOS_TABLE);
2012         predicatesPhotos.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, albumId);
2013         predicatesPhotos.And()->In(MediaColumn::MEDIA_ID, fileAssetsIds);
2014         ValuesBucket values;
2015         values.Put(MediaColumn::MEDIA_DATE_TRASHED, MediaFileUtils::UTCTimeMilliSeconds());
2016         AccurateRefresh::AssetAccurateRefresh assetRefresh(AccurateRefresh::UPDATE_TRASHED_ASSETONALBUM_BUSSINESS_NAME);
2017         int32_t changedRows = assetRefresh.UpdateWithDateTime(values, predicatesPhotos);
2018         CHECK_AND_CONTINUE_ERR_LOG(changedRows >= 0,
2019             "Update failed on trashed, album id is: %{public}s", albumId.c_str());
2020         MediaLibraryRdbUtils::UpdateAnalysisAlbumByUri(rdbStore, fileAssetsUri);
2021         assetRefresh.RefreshAlbum();
2022         MediaAnalysisHelper::StartMediaAnalysisServiceAsync(
2023             static_cast<int32_t>(MediaAnalysisProxy::ActivateServiceType::START_UPDATE_INDEX), fileAssetsUri);
2024         MediaLibraryPhotoOperations::TrashPhotosSendNotify(fileAssetsUri);
2025         assetRefresh.Notify();
2026     }
2027     predicates.SetWhereArgs(newWhereIdArgs);
2028     return newWhereIdArgs.size();
2029 }
2030 
UpdateRemovedAssetToTrash(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & whereIdArgs)2031 int32_t MediaLibraryRdbUtils::UpdateRemovedAssetToTrash(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2032     const vector<string> &whereIdArgs)
2033 {
2034     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_HAS_DB_ERROR, "rdbStore is null");
2035     int32_t updateRows = 0;
2036     RdbPredicates predicatesPhotos(PhotoColumn::PHOTOS_TABLE);
2037     predicatesPhotos.In(MediaColumn::MEDIA_ID, whereIdArgs);
2038     ValuesBucket values;
2039     values.Put(MediaColumn::MEDIA_DATE_TRASHED, MediaFileUtils::UTCTimeMilliSeconds());
2040     rdbStore->Update(updateRows, values, predicatesPhotos);
2041     CHECK_AND_RETURN_RET_LOG(updateRows > 0, E_HAS_DB_ERROR,
2042         "Failed to remove assets, updateRows: %{public}d", updateRows);
2043     return updateRows;
2044 }
2045 
UpdateHighlightPlayInfo(const shared_ptr<MediaLibraryRdbStore> rdbStore,const string & albumId)2046 int32_t MediaLibraryRdbUtils::UpdateHighlightPlayInfo(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2047     const string &albumId)
2048 {
2049     MEDIA_INFO_LOG("Start update highlight play info on dismiss highlight asset");
2050     const std::string UPDATE_HIGHLIGHT_PLAY_INFO = "UPDATE tab_highlight_play_info SET status = 1 "
2051         "WHERE album_id = (SELECT id FROM tab_highlight_album WHERE album_id = " + albumId + " LIMIT 1)";
2052 
2053     int32_t ret = rdbStore->ExecuteSql(UPDATE_HIGHLIGHT_PLAY_INFO);
2054     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, ret, "Failed to execute sql:%{public}s",
2055         UPDATE_HIGHLIGHT_PLAY_INFO.c_str());
2056     return ret;
2057 }
2058 
UpdateOwnerAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<DataShare::DataShareValuesBucket> & values,vector<int32_t> & updateIds,bool & hidden)2059 int32_t MediaLibraryRdbUtils::UpdateOwnerAlbumId(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2060     const vector<DataShare::DataShareValuesBucket> &values, vector<int32_t> &updateIds, bool &hidden)
2061 {
2062     vector<string> whereIdArgs;
2063     int32_t updateRows = 0;
2064     bool isValid = false;
2065     int32_t albumId = values[0].Get(PhotoColumn::PHOTO_OWNER_ALBUM_ID, isValid);
2066     for (const auto &value : values) {
2067         bool isValidNew = false;
2068         std::string assetUri = value.Get(MediaColumn::MEDIA_ID, isValidNew);
2069         CHECK_AND_CONTINUE(MediaFileUtils::StartsWith(assetUri, PhotoColumn::PHOTO_URI_PREFIX));
2070         auto photoId = std::stoi(MediaFileUri::GetPhotoId(assetUri));
2071         if (CopyAssetIfNeed(photoId, albumId, rdbStore, updateIds, hidden)) {
2072             updateRows++;
2073             continue;
2074         }
2075         whereIdArgs.push_back(MediaFileUri::GetPhotoId(assetUri));
2076     }
2077     CHECK_AND_RETURN_RET_INFO_LOG(!whereIdArgs.empty(), updateRows,
2078         "add assets: no need copy assets is 0 for update owner album id");
2079 
2080     RdbPredicates updatePredicates(PhotoColumn::PHOTOS_TABLE);
2081     updatePredicates.In(MediaColumn::MEDIA_ID, whereIdArgs);
2082     ValuesBucket updateValues;
2083     updateValues.PutString(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
2084     int32_t changedRowsNoNeedCopy = 0;
2085     int err = rdbStore->Update(changedRowsNoNeedCopy, updateValues, updatePredicates);
2086     CHECK_AND_PRINT_LOG(err == NativeRdb::E_OK, "Failed to update owner album id");
2087     return updateRows + changedRowsNoNeedCopy;
2088 }
2089 
QueryShootingModeAlbumId(const shared_ptr<MediaLibraryRdbStore> & rdbStore,const vector<string> & assetIds,set<string> & albumIds)2090 static int32_t QueryShootingModeAlbumId(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
2091     const vector<string>& assetIds, set<string>& albumIds)
2092 {
2093     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
2094     predicates.In(MediaColumn::MEDIA_ID, assetIds);
2095     const vector<string> columns = {PhotoColumn::PHOTO_SUBTYPE, MediaColumn::MEDIA_MIME_TYPE,
2096         PhotoColumn::PHOTO_SHOOTING_MODE, PhotoColumn::MOVING_PHOTO_EFFECT_MODE, PhotoColumn::PHOTO_FRONT_CAMERA};
2097     auto resultSet = rdbStore->QueryByStep(predicates, columns);
2098     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_FAIL, "result set is nullptr");
2099     while (resultSet->GoToNextRow() == E_OK) {
2100         int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
2101         string mimeType = GetStringVal(MediaColumn::MEDIA_MIME_TYPE, resultSet);
2102         string shootingMode = GetStringVal(PhotoColumn::PHOTO_SHOOTING_MODE, resultSet);
2103         int32_t effectMode = GetInt32Val(PhotoColumn::MOVING_PHOTO_EFFECT_MODE, resultSet);
2104         string frontCamera = GetStringVal(PhotoColumn::PHOTO_FRONT_CAMERA, resultSet);
2105 
2106         vector<ShootingModeAlbumType> albumTypes = ShootingModeAlbum::GetShootingModeAlbumOfAsset(
2107             subtype, mimeType, effectMode, frontCamera, shootingMode);
2108 
2109         for (const auto &type : albumTypes) {
2110             int32_t albumId;
2111             if (MediaLibraryRdbUtils::QueryShootingModeAlbumIdByType(type, albumId)) {
2112                 albumIds.insert(to_string(albumId));
2113             }
2114         }
2115     }
2116     return E_OK;
2117 }
2118 
QueryAnalysisAlbumIdOfAssets(const vector<string> & assetIds,set<string> & albumIds)2119 int32_t MediaLibraryRdbUtils::QueryAnalysisAlbumIdOfAssets(const vector<string>& assetIds, set<string>& albumIds)
2120 {
2121     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
2122     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_FAIL, "Failed to get rdbStore.");
2123     RdbPredicates predicates(ANALYSIS_PHOTO_MAP_TABLE);
2124     predicates.In(PhotoMap::ASSET_ID, assetIds);
2125     const vector<string> columns = {
2126         "Distinct " + PhotoMap::ALBUM_ID
2127     };
2128     auto resultSet = rdbStore->QueryByStep(predicates, columns);
2129     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_FAIL, "Failed to Query Analysis Photo Map");
2130     while (resultSet->GoToNextRow() == E_OK) {
2131         albumIds.insert(to_string(GetIntValFromColumn(resultSet, 0)));
2132     }
2133 
2134     CHECK_AND_RETURN_RET_LOG(QueryShootingModeAlbumId(rdbStore, assetIds, albumIds) == E_OK, E_FAIL,
2135         "Failed to query shooting mode album id");
2136     return E_OK;
2137 }
2138 
UpdateAnalysisAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris)2139 void MediaLibraryRdbUtils::UpdateAnalysisAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2140     const vector<string> &uris)
2141 {
2142     MediaLibraryTracer tracer;
2143     tracer.Start("UpdateAnalysisAlbumByUri");
2144 
2145     if (uris.size() == 0) {
2146         UpdateAnalysisAlbumInternal(rdbStore);
2147         return;
2148     }
2149     set<string> albumIds;
2150     vector<string> idArgs;
2151     for (size_t i = 0; i < uris.size(); i++) {
2152         string fileId = GetPhotoId(uris[i]);
2153         if (fileId.size() > 0) {
2154             idArgs.push_back(fileId);
2155         }
2156         if (idArgs.size() == ALBUM_UPDATE_THRESHOLD || i == uris.size() - 1) {
2157             CHECK_AND_RETURN_LOG(QueryAnalysisAlbumIdOfAssets(idArgs, albumIds) == E_OK,
2158                 "Failed to query analysis album id");
2159             idArgs.clear();
2160         }
2161     }
2162     vector<string> albumIdVector(albumIds.begin(), albumIds.end());
2163     if (albumIdVector.size() > 0) {
2164         UpdateAnalysisAlbumInternal(rdbStore, albumIdVector);
2165     }
2166 }
2167 
GetAlbumIdsForPortrait(const shared_ptr<MediaLibraryRdbStore> & rdbStore,vector<string> & portraitAlbumIds)2168 int32_t MediaLibraryRdbUtils::GetAlbumIdsForPortrait(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
2169     vector<string> &portraitAlbumIds)
2170 {
2171     std::stringstream labelIds;
2172     unordered_set<string> resultAlbumIds;
2173     for (size_t i = 0; i < portraitAlbumIds.size(); i++) {
2174         labelIds << portraitAlbumIds[i];
2175         if (i != portraitAlbumIds.size() - 1) {
2176             labelIds << ",";
2177         }
2178         resultAlbumIds.insert(portraitAlbumIds[i]);
2179     }
2180 
2181     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
2182     predicates.SetWhereClause(GROUP_TAG + " IN(SELECT " + GROUP_TAG + " FROM " + ANALYSIS_ALBUM_TABLE +
2183         " WHERE " + ALBUM_ID + " IN (" + labelIds.str() + ") AND " + ALBUM_SUBTYPE + " = " + to_string(PORTRAIT) +")");
2184     vector<string> columns = {
2185         ALBUM_ID,
2186     };
2187     auto resultSet = rdbStore->Query(predicates, columns);
2188     CHECK_AND_RETURN_RET(resultSet != nullptr, E_HAS_DB_ERROR);
2189     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
2190         string albumId = to_string(GetIntValFromColumn(resultSet, ALBUM_ID));
2191         if (resultAlbumIds.find(albumId) == resultAlbumIds.end()) {
2192             resultAlbumIds.insert(albumId);
2193             portraitAlbumIds.push_back(albumId);
2194         }
2195     }
2196     return E_OK;
2197 }
2198 
GetAlbumSubtypeArgument(const RdbPredicates & predicates)2199 int32_t MediaLibraryRdbUtils::GetAlbumSubtypeArgument(const RdbPredicates &predicates)
2200 {
2201     string whereClause = predicates.GetWhereClause();
2202     vector<string> whereArgs = predicates.GetWhereArgs();
2203     size_t subtypePos = whereClause.find(PhotoAlbumColumns::ALBUM_SUBTYPE + " = ?");
2204     if (subtypePos == string::npos) {
2205         return E_ERR;
2206     }
2207     size_t argsIndex = 0;
2208     for (size_t i = 0; i < subtypePos; i++) {
2209         if (whereClause[i] == '?') {
2210             argsIndex++;
2211         }
2212     }
2213     CHECK_AND_RETURN_RET(argsIndex <= whereArgs.size() - 1, E_ERR);
2214     const string &subtype = whereArgs[argsIndex];
2215     bool cond = subtype.empty() || !MediaLibraryDataManagerUtils::IsNumber(subtype);
2216     CHECK_AND_RETURN_RET(!cond, E_ERR);
2217     return std::stoi(subtype);
2218 }
2219 
GetUpdateAlbumDataInfo(shared_ptr<ResultSet> albumResult,std::vector<UpdateAlbumData> & datas)2220 static void GetUpdateAlbumDataInfo(shared_ptr<ResultSet> albumResult, std::vector<UpdateAlbumData> &datas)
2221 {
2222     CHECK_AND_RETURN_LOG(albumResult != nullptr, "albumResult is nullptr");
2223     while (albumResult->GoToNextRow() == E_OK) {
2224         UpdateAlbumData data;
2225         data.albumId = GetAlbumId(albumResult);
2226         data.albumSubtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
2227         data.albumCoverUri = GetAlbumCover(albumResult, PhotoAlbumColumns::ALBUM_COVER_URI);
2228         data.albumCount = GetAlbumCount(albumResult, PhotoAlbumColumns::ALBUM_COUNT);
2229         data.isCoverSatisfied = GetIsCoverSatisfied(albumResult);
2230         data.albumName = GetStringVal(PhotoAlbumColumns::ALBUM_NAME, albumResult);
2231         datas.push_back(data);
2232     }
2233 }
2234 
PrintHighlightAlbumInfo(const PhotoAlbumSubType & subtype,const int32_t & albumId)2235 void PrintHighlightAlbumInfo(const PhotoAlbumSubType &subtype, const int32_t &albumId)
2236 {
2237     if (subtype == PhotoAlbumSubType::HIGHLIGHT) {
2238         MEDIA_INFO_LOG("The highlight album that needs to be updated is %{publlic}d", albumId);
2239     }
2240 }
2241 
UpdateAnalysisAlbumInternal(const shared_ptr<MediaLibraryRdbStore> & rdbStore,const vector<string> & anaAlbumAlbumIds)2242 void MediaLibraryRdbUtils::UpdateAnalysisAlbumInternal(const shared_ptr<MediaLibraryRdbStore>& rdbStore,
2243     const vector<string> &anaAlbumAlbumIds)
2244 {
2245     MediaLibraryTracer tracer;
2246     tracer.Start("UpdateAnalysisAlbumInternal");
2247     vector<string> columns = {
2248         PhotoAlbumColumns::ALBUM_ID, PhotoAlbumColumns::ALBUM_SUBTYPE,
2249         PhotoAlbumColumns::ALBUM_COVER_URI, PhotoAlbumColumns::ALBUM_COUNT,
2250         IS_COVER_SATISFIED, PhotoAlbumColumns::ALBUM_NAME };
2251     vector<string> tempAlbumId = anaAlbumAlbumIds;
2252     if (tempAlbumId.size() > 0) {
2253         GetAlbumIdsForPortrait(rdbStore, tempAlbumId);
2254     }
2255     auto albumResult = GetAnalysisAlbum(rdbStore, tempAlbumId, columns);
2256     CHECK_AND_RETURN_LOG(albumResult != nullptr, "Failed to get Analysis Album");
2257     std::vector<UpdateAlbumData> datas;
2258     GetUpdateAlbumDataInfo(albumResult, datas);
2259     albumResult->Close();
2260 
2261     // For each row
2262     int32_t err = NativeRdb::E_OK;
2263     map<int32_t, shared_ptr<UpdateAlbumDataWithCache>> portraitCacheMap;
2264     map<int32_t, shared_ptr<UpdateAlbumDataWithCache>> groupPhotoCacheMap;
2265     for (auto data : datas) {
2266         int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
2267         std::shared_ptr<TransactionOperations> trans = make_shared<TransactionOperations>(__func__);
2268         std::function<int(void)> func = [&]()->int {
2269             auto subtype = static_cast<PhotoAlbumSubType>(data.albumSubtype);
2270             if (subtype == PhotoAlbumSubType::PORTRAIT) {
2271                 UpdatePortraitAlbumIfNeeded(rdbStore, data, trans, portraitCacheMap);
2272             } else if (subtype == PhotoAlbumSubType::GROUP_PHOTO) {
2273                 UpdateGroupPhotoAlbumIfNeed(rdbStore, data, trans, groupPhotoCacheMap);
2274             } else {
2275                 PrintHighlightAlbumInfo(subtype, data.albumId);
2276                 UpdateAnalysisAlbumIfNeeded(rdbStore, data, false, trans);
2277             }
2278             return err;
2279         };
2280         err = trans->RetryTrans(func);
2281         CHECK_AND_PRINT_LOG(err == E_OK, "UpdateAnalysisAlbumInternal: tans finish fail!, ret:%{public}d", err);
2282         int32_t costTime = static_cast<int32_t>(MediaFileUtils::UTCTimeMilliSeconds() - start);
2283         if (costTime > UPDATE_ALBUM_TIME_OUT) {
2284             MEDIA_INFO_LOG("udpate analysis album: %{public}d cost %{public}d", data.albumId, costTime);
2285         }
2286     }
2287     portraitCacheMap.clear();
2288 }
2289 
UpdateAnalysisAlbumByFile(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & fileIds,const vector<int> & albumTypes)2290 void MediaLibraryRdbUtils::UpdateAnalysisAlbumByFile(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2291     const vector<string> &fileIds, const vector<int> &albumTypes)
2292 {
2293     CHECK_AND_RETURN_LOG(!fileIds.empty(), "Failed to UpdateAnalysisAlbumByFile cause fileIds empty");
2294     MediaLibraryTracer tracer;
2295     tracer.Start("UpdateAnalysisAlbumByFile");
2296     vector<string> columns = {
2297         PhotoMap::ALBUM_ID,
2298     };
2299     RdbPredicates predicates(ANALYSIS_PHOTO_MAP_TABLE);
2300     if (!albumTypes.empty()) {
2301         std::string files;
2302         for (std::string fileId : fileIds) {
2303             files.append("'").append(fileId).append("'").append(",");
2304         }
2305         files = files.substr(0, files.length() - 1);
2306         std::string subTypes;
2307         for (int subtype : albumTypes) {
2308             subTypes.append(to_string(subtype)).append(",");
2309         }
2310         subTypes = subTypes.substr(0, subTypes.length() - 1);
2311         predicates.SetWhereClause(PhotoMap::ASSET_ID + " in(" + files + ") and " + PhotoMap::ALBUM_ID +
2312             " in(select album_id from AnalysisAlbum where album_subtype in(" + subTypes + "))");
2313     } else {
2314         predicates.In(PhotoMap::ASSET_ID, fileIds);
2315     }
2316     shared_ptr<ResultSet> mapResult = rdbStore->Query(predicates, columns);
2317     CHECK_AND_RETURN_LOG(mapResult != nullptr, "Failed query AnalysisAlbum");
2318     vector<string> albumIds;
2319     while (mapResult->GoToNextRow() == E_OK) {
2320         albumIds.push_back(to_string(GetIntValFromColumn(mapResult, PhotoMap::ALBUM_ID)));
2321     }
2322     int err = E_HAS_DB_ERROR;
2323     int32_t deletedRows = 0;
2324     err = rdbStore->Delete(deletedRows, predicates);
2325 
2326     bool cond = (err != E_OK || deletedRows <= 0);
2327     CHECK_AND_RETURN_LOG(!cond, "Failed Delete AnalysisPhotoMap");
2328     UpdateAnalysisAlbumInternal(rdbStore, albumIds);
2329 }
2330 
UpdateCommonAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & albumIds={})2331 static void UpdateCommonAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2332     const vector<string> &albumIds = {})
2333 {
2334     MediaLibraryTracer tracer;
2335     tracer.Start("UpdateCommonAlbumHiddenState");
2336 
2337     auto albumResult = GetCommonAlbum(rdbStore, albumIds, PHOTO_ALBUM_HIDDEN_INFO_COLUMNS);
2338     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
2339     vector<UpdateAlbumData> datas = GetPhotoAlbumHiddenDataInfo(albumResult);
2340     albumResult->Close();
2341     ForEachRow(rdbStore, datas, true, UpdateCommonAlbumIfNeeded);
2342 }
2343 
UpdateSourceAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & sourceAlbumIds)2344 void MediaLibraryRdbUtils::UpdateSourceAlbumHiddenState(
2345     const shared_ptr<MediaLibraryRdbStore> rdbStore, const vector<string> &sourceAlbumIds)
2346 {
2347     MediaLibraryTracer tracer;
2348     tracer.Start("UpdateSourceAlbumHiddenState");
2349 
2350     auto albumResult = GetSourceAlbum(rdbStore, sourceAlbumIds, PHOTO_ALBUM_HIDDEN_INFO_COLUMNS);
2351     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
2352     vector<UpdateAlbumData> datas = GetPhotoAlbumHiddenDataInfo(albumResult);
2353     albumResult->Close();
2354     ForEachRow(rdbStore, datas, true, UpdateSourceAlbumIfNeeded);
2355 }
2356 
UpdateCommonAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris,bool shouldNotify,bool shouldUpdateDateModified)2357 void MediaLibraryRdbUtils::UpdateCommonAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2358     const vector<string> &uris, bool shouldNotify, bool shouldUpdateDateModified)
2359 {
2360     // it will be update all later
2361     CHECK_AND_RETURN(uris.size() != 0);
2362     MediaLibraryTracer tracer;
2363     tracer.Start("UpdateCommonAlbumByUri");
2364     vector<string> albumIds = QueryAlbumId(rdbStore, uris);
2365     if (albumIds.size() > 0) {
2366         UpdateCommonAlbumInternal(rdbStore, albumIds, shouldNotify, shouldUpdateDateModified);
2367         UpdateCommonAlbumHiddenState(rdbStore, albumIds);
2368     }
2369 }
2370 
UpdateSourceAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris,bool shouldNotify,bool shouldUpdateDateModified)2371 void MediaLibraryRdbUtils::UpdateSourceAlbumByUri(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2372     const vector<string> &uris, bool shouldNotify, bool shouldUpdateDateModified)
2373 {
2374     MediaLibraryTracer tracer;
2375     tracer.Start("UpdateSourceAlbumByUri");
2376 
2377     if (uris.size() == 0) {
2378         UpdateSourceAlbumInternal(rdbStore);
2379         UpdateSourceAlbumHiddenState(rdbStore);
2380     }
2381 
2382     vector<string> albumIds = QueryAlbumId(rdbStore, uris, PhotoAlbumType::SOURCE);
2383     if (albumIds.size() > 0) {
2384         UpdateSourceAlbumInternal(rdbStore, albumIds, shouldNotify, shouldUpdateDateModified);
2385         UpdateSourceAlbumHiddenState(rdbStore, albumIds);
2386     }
2387 }
2388 
UpdateCommonAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & albumIds,bool shouldNotify,bool shouldUpdateDateModified)2389 void MediaLibraryRdbUtils::UpdateCommonAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2390     const vector<string> &albumIds, bool shouldNotify, bool shouldUpdateDateModified)
2391 {
2392     MediaLibraryTracer tracer;
2393     tracer.Start("UpdateCommonAlbumInternal");
2394 
2395     auto albumResult = GetCommonAlbum(rdbStore, albumIds, PHOTO_ALBUM_INFO_COLUMNS);
2396     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
2397     vector<UpdateAlbumData> datas = GetPhotoAlbumDataInfo(albumResult, shouldNotify, shouldUpdateDateModified);
2398     albumResult->Close();
2399 
2400     ForEachRow(rdbStore, datas, false, UpdateCommonAlbumIfNeeded);
2401 }
2402 
UpdateSourceAlbumInternal(shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & sourceAlbumIds,bool shouldNotify,bool shouldUpdateDateModified)2403 void MediaLibraryRdbUtils::UpdateSourceAlbumInternal(shared_ptr<MediaLibraryRdbStore> rdbStore,
2404     const vector<string> &sourceAlbumIds, bool shouldNotify, bool shouldUpdateDateModified)
2405 {
2406     MediaLibraryTracer tracer;
2407     tracer.Start("UpdateSourceAlbumInternal");
2408 
2409     if (rdbStore == nullptr) {
2410         MEDIA_ERR_LOG("Failed to get rdbstore, try again!");
2411         rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
2412         CHECK_AND_RETURN_LOG(rdbStore != nullptr,
2413             "Fatal error! Failed to get rdbstore, new cloud data is not processed!!");
2414     }
2415     auto albumResult = GetSourceAlbum(rdbStore, sourceAlbumIds, PHOTO_ALBUM_INFO_COLUMNS);
2416     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
2417     vector<UpdateAlbumData> datas = GetPhotoAlbumDataInfo(albumResult, shouldNotify, shouldUpdateDateModified);
2418     albumResult->Close();
2419 
2420     ForEachRow(rdbStore, datas, false, UpdateSourceAlbumIfNeeded);
2421 }
2422 
GetSystemAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes,const vector<string> & columns)2423 static inline shared_ptr<ResultSet> GetSystemAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2424     const vector<string> &subtypes, const vector<string> &columns)
2425 {
2426     RdbPredicates predicates(PhotoAlbumColumns::TABLE);
2427     if (subtypes.empty()) {
2428         predicates.In(PhotoAlbumColumns::ALBUM_SUBTYPE, ALL_SYS_PHOTO_ALBUM);
2429     } else {
2430         predicates.In(PhotoAlbumColumns::ALBUM_SUBTYPE, subtypes);
2431     }
2432     return rdbStore->QueryWithFilter(predicates, columns);
2433 }
2434 
UpdateSystemAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes,bool shouldNotify)2435 void MediaLibraryRdbUtils::UpdateSystemAlbumInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2436     const vector<string> &subtypes, bool shouldNotify)
2437 {
2438     MediaLibraryTracer tracer;
2439     tracer.Start("UpdateSystemAlbumInternal");
2440 
2441     auto albumResult = GetSystemAlbum(rdbStore, subtypes, PHOTO_ALBUM_INFO_COLUMNS);
2442     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
2443     vector<UpdateAlbumData> datas = GetPhotoAlbumDataInfo(albumResult, shouldNotify);
2444     albumResult->Close();
2445     ForEachRow(rdbStore, datas, false, UpdateSysAlbumIfNeeded);
2446 }
2447 
UpdateSysAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes)2448 void MediaLibraryRdbUtils::UpdateSysAlbumHiddenState(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2449     const vector<string> &subtypes)
2450 {
2451     MediaLibraryTracer tracer;
2452     tracer.Start("UpdateSysAlbumHiddenState");
2453 
2454     shared_ptr<ResultSet> albumResult = nullptr;
2455 
2456     if (subtypes.empty()) {
2457         albumResult = GetSystemAlbum(rdbStore, SYSTEM_ALBUMS, PHOTO_ALBUM_HIDDEN_INFO_COLUMNS);
2458     } else {
2459         albumResult = GetSystemAlbum(rdbStore, subtypes, PHOTO_ALBUM_HIDDEN_INFO_COLUMNS);
2460     }
2461 
2462     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
2463     vector<UpdateAlbumData> datas = GetPhotoAlbumHiddenDataInfo(albumResult);
2464     albumResult->Close();
2465 
2466     ForEachRow(rdbStore, datas, true, UpdateSysAlbumIfNeeded);
2467 }
2468 
AddSystemAlbum(set<string> & systemAlbum,shared_ptr<NativeRdb::ResultSet> resultSet)2469 static void AddSystemAlbum(set<string> &systemAlbum, shared_ptr<NativeRdb::ResultSet> resultSet)
2470 {
2471     int minMediaType = GetIntValFromColumn(resultSet, "Min(" + MediaColumn::MEDIA_TYPE + ")");
2472     int maxMediaType = GetIntValFromColumn(resultSet, "Max(" + MediaColumn::MEDIA_TYPE + ")");
2473     int favorite = GetIntValFromColumn(resultSet, "Max(" + MediaColumn::MEDIA_IS_FAV + ")");
2474     int cloudAssociate = GetIntValFromColumn(resultSet, "Max(" + PhotoColumn::PHOTO_STRONG_ASSOCIATION + ")");
2475     if (minMediaType == MEDIA_TYPE_IMAGE) {
2476         systemAlbum.insert(to_string(PhotoAlbumSubType::IMAGE));
2477     }
2478     if (maxMediaType == MEDIA_TYPE_VIDEO) {
2479         systemAlbum.insert(to_string(PhotoAlbumSubType::VIDEO));
2480     }
2481     if (favorite > 0) {
2482         systemAlbum.insert(to_string(PhotoAlbumSubType::FAVORITE));
2483     }
2484     if (cloudAssociate > 0) {
2485         systemAlbum.insert(to_string(PhotoAlbumSubType::CLOUD_ENHANCEMENT));
2486     }
2487     MEDIA_INFO_LOG("AddSystemAlbum minMediaType:%{public}d, maxMediaType:%{public}d, favorite:%{public}d,"
2488         " cloudAssociate:%{public}d,", minMediaType, maxMediaType, favorite, cloudAssociate);
2489 }
2490 
GetUpdateAlbumByOperationType(set<string> & systemAlbum,set<string> & hiddenSystemAlbum,AlbumOperationType albumOperationType,int32_t hidden)2491 static void GetUpdateAlbumByOperationType(set<string> &systemAlbum, set<string> &hiddenSystemAlbum,
2492     AlbumOperationType albumOperationType, int32_t hidden)
2493 {
2494     if (albumOperationType == AlbumOperationType::DELETE_PHOTO ||
2495         albumOperationType == AlbumOperationType::RECOVER_PHOTO) {
2496         systemAlbum.insert(to_string(PhotoAlbumSubType::TRASH));
2497         if (hidden > 0) {
2498             hiddenSystemAlbum.insert(to_string(PhotoAlbumSubType::TRASH));
2499         }
2500     }
2501     if (albumOperationType == UNHIDE_PHOTO || hidden > 0) {
2502         systemAlbum.insert(to_string(PhotoAlbumSubType::HIDDEN));
2503         hiddenSystemAlbum.insert(to_string(PhotoAlbumSubType::HIDDEN));
2504     }
2505 }
2506 
GetSystemAlbumByUris(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris,AlbumOperationType albumOperationType,set<string> & systemAlbum,set<string> & hiddenSystemAlbum)2507 static void GetSystemAlbumByUris(const shared_ptr<MediaLibraryRdbStore> rdbStore, const vector<string> &uris,
2508     AlbumOperationType albumOperationType, set<string> &systemAlbum, set<string> &hiddenSystemAlbum)
2509 {
2510     MediaLibraryTracer tracer;
2511     tracer.Start("GetSystemAlbumByUris");
2512     vector<string> fileIds;
2513     for (auto uri : uris) {
2514         string fileId = GetPhotoId(uri);
2515         fileIds.push_back(fileId);
2516     }
2517     size_t queryTime = (fileIds.size() + ALBUM_UPDATE_THRESHOLD -1) / ALBUM_UPDATE_THRESHOLD;
2518     for (size_t i = 0; i < queryTime; i++) {
2519         size_t start = i * ALBUM_UPDATE_THRESHOLD;
2520         size_t end = (start + ALBUM_UPDATE_THRESHOLD) < fileIds.size() ?
2521             (start + ALBUM_UPDATE_THRESHOLD) : fileIds.size();
2522         std::vector<string> childVector(fileIds.begin() + start, fileIds.begin() + end);
2523         RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
2524         predicates.In(PhotoColumn::MEDIA_ID, childVector);
2525         predicates.GroupBy({MediaColumn::MEDIA_HIDDEN});
2526         const vector<string> columns = {
2527             MediaColumn::MEDIA_HIDDEN,
2528             "Min(" + MediaColumn::MEDIA_TYPE + ")",
2529             "Max(" + MediaColumn::MEDIA_TYPE + ")",
2530             "Max(" + MediaColumn::MEDIA_IS_FAV + ")",
2531             "Max(" + PhotoColumn::PHOTO_STRONG_ASSOCIATION + ")",
2532         };
2533 
2534         auto resultSet = rdbStore->Query(predicates, columns);
2535         CHECK_AND_CONTINUE_ERR_LOG(resultSet != nullptr, "Failed to query Systemalbum info!");
2536         while (resultSet->GoToNextRow() == E_OK) {
2537             int32_t hidden = GetIntValFromColumn(resultSet, 0);
2538             AddSystemAlbum(systemAlbum, resultSet);
2539             AddSystemAlbum(hiddenSystemAlbum, resultSet);
2540             GetUpdateAlbumByOperationType(systemAlbum, hiddenSystemAlbum, albumOperationType, hidden);
2541         }
2542         resultSet->Close();
2543     }
2544 }
2545 
UpdateSystemAlbumsByUris(const shared_ptr<MediaLibraryRdbStore> rdbStore,AlbumOperationType albumOperationType,const vector<string> & uris,NotifyAlbumType type)2546 void MediaLibraryRdbUtils::UpdateSystemAlbumsByUris(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2547     AlbumOperationType albumOperationType, const vector<string> &uris, NotifyAlbumType type)
2548 {
2549     if (uris.empty() || albumOperationType == AlbumOperationType::DEFAULT) {
2550         MediaLibraryRdbUtils::UpdateSystemAlbumInternal(rdbStore, SYSTEM_ALBUMS,
2551             type & NotifyAlbumType::SYS_ALBUM);
2552         MediaLibraryRdbUtils::UpdateSysAlbumHiddenState(rdbStore);
2553     } else {
2554         set<string> systemAlbumSet;
2555         set<string> hiddenSystemAlbumSet;
2556         GetSystemAlbumByUris(rdbStore, uris, albumOperationType, systemAlbumSet, hiddenSystemAlbumSet);
2557         vector<string> systemAlbum;
2558         vector<string> hiddenSystemAlbum;
2559         systemAlbum.assign(systemAlbumSet.begin(), systemAlbumSet.end());
2560         hiddenSystemAlbum.assign(hiddenSystemAlbumSet.begin(), hiddenSystemAlbumSet.end());
2561         MediaLibraryRdbUtils::UpdateSystemAlbumInternal(rdbStore, systemAlbum,
2562             type & NotifyAlbumType::SYS_ALBUM);
2563         if (!hiddenSystemAlbum.empty()) {
2564             MediaLibraryRdbUtils::UpdateSysAlbumHiddenState(rdbStore, hiddenSystemAlbum);
2565         }
2566     }
2567 }
2568 
UpdateAllAlbums(shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & uris,const UpdateAllAlbumsData & updateAlbumsData)2569 void MediaLibraryRdbUtils::UpdateAllAlbums(shared_ptr<MediaLibraryRdbStore> rdbStore, const vector<string> &uris,
2570     const UpdateAllAlbumsData &updateAlbumsData)
2571 {
2572     MediaLibraryTracer tracer;
2573     tracer.Start("UpdateAllAlbums");
2574     if (rdbStore == nullptr) {
2575         MEDIA_ERR_LOG("Failed to get rdbstore, try again!");
2576         rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
2577         CHECK_AND_RETURN_LOG(rdbStore != nullptr,
2578             "Fatal error! Failed to get rdbstore, new cloud data is not processed!!");
2579     }
2580 
2581     MediaLibraryRdbUtils::UpdateSystemAlbumsByUris(rdbStore, updateAlbumsData.albumOperationType, uris,
2582         updateAlbumsData.type);
2583     MediaLibraryRdbUtils::UpdateUserAlbumByUri(rdbStore, uris, false, updateAlbumsData.shouldUpdateDateModified);
2584     MediaLibraryRdbUtils::UpdateSourceAlbumByUri(rdbStore, uris, false, updateAlbumsData.shouldUpdateDateModified);
2585     if (!updateAlbumsData.isBackUpAndRestore) {
2586         std::thread([rdbStore, uris]() { MediaLibraryRdbUtils::UpdateAnalysisAlbumByUri(rdbStore, uris); }).detach();
2587     } else {
2588         MediaLibraryRdbUtils::UpdateAnalysisAlbumByUri(rdbStore, uris);
2589     }
2590 }
2591 
UpdateAlbumReplacedSignal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & albumIdVector)2592 static int32_t UpdateAlbumReplacedSignal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2593     const vector<string> &albumIdVector)
2594 {
2595     CHECK_AND_RETURN_RET(!albumIdVector.empty(), E_SUCCESS);
2596 
2597     ValuesBucket refreshValues;
2598     string insertRefreshTableSql = "INSERT OR IGNORE INTO " + ALBUM_REFRESH_TABLE + " VALUES ";
2599     for (size_t i = 0; i < albumIdVector.size(); ++i) {
2600         if (i != albumIdVector.size() - 1) {
2601             insertRefreshTableSql += "(" + albumIdVector[i] + "), ";
2602         } else {
2603             insertRefreshTableSql += "(" + albumIdVector[i] + ");";
2604         }
2605     }
2606 
2607     MEDIA_DEBUG_LOG("output insertRefreshTableSql:%{public}s", insertRefreshTableSql.c_str());
2608     int32_t ret = rdbStore->ExecuteSql(insertRefreshTableSql);
2609     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_HAS_DB_ERROR,
2610         "Can not insert refreshed table, ret:%{public}d", ret);
2611     return E_SUCCESS;
2612 }
2613 
UpdateBussinessRecord(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<BussinessRecordValue> & updateValue)2614 static int32_t UpdateBussinessRecord(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2615     const vector<BussinessRecordValue> &updateValue)
2616 {
2617     CHECK_AND_RETURN_RET(!updateValue.empty(), E_SUCCESS);
2618 
2619     ValuesBucket refreshValues;
2620     string insertTableSql = "INSERT OR IGNORE INTO " + MedialibraryBusinessRecordColumn::TABLE + "(" +
2621         MedialibraryBusinessRecordColumn::BUSINESS_TYPE + "," + MedialibraryBusinessRecordColumn::KEY + "," +
2622         MedialibraryBusinessRecordColumn::VALUE + ") VALUES ";
2623     for (size_t i = 0; i < updateValue.size(); ++i) {
2624         if (i != updateValue.size() - 1) {
2625             insertTableSql += "('" + updateValue[i].bussinessType + "', '" + updateValue[i].key + "', '" +
2626                 updateValue[i].value + "'), ";
2627         } else {
2628             insertTableSql += "('" + updateValue[i].bussinessType + "', '" + updateValue[i].key + "', '" +
2629                 updateValue[i].value + "');";
2630         }
2631     }
2632 
2633     MEDIA_DEBUG_LOG("output insertTableSql:%{public}s", insertTableSql.c_str());
2634     int32_t ret = rdbStore->ExecuteSql(insertTableSql);
2635     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_HAS_DB_ERROR,
2636         "Can not insert bussinessRecord table, ret:%{public}d", ret);
2637     return E_SUCCESS;
2638 }
2639 
UpdateSystemAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes)2640 void MediaLibraryRdbUtils::UpdateSystemAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2641     const vector<string> &subtypes)
2642 {
2643     // Only use in dfs
2644     MediaLibraryTracer tracer;
2645     tracer.Start("UpdateSystemAlbumCountInternal");
2646 
2647     vector<string> columns = { PhotoAlbumColumns::ALBUM_ID };
2648     auto albumResult = GetSystemAlbum(rdbStore, subtypes, columns);
2649     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
2650 
2651     vector<string> replaceSignalAlbumVector;
2652     while (albumResult->GoToNextRow() == NativeRdb::E_OK) {
2653         int32_t ret = GetIntValFromColumn(albumResult, PhotoAlbumColumns::ALBUM_ID);
2654         if (ret <= 0) {
2655             MEDIA_WARN_LOG("Can not get ret:%{public}d", ret);
2656         } else {
2657             replaceSignalAlbumVector.push_back(to_string(ret));
2658         }
2659     }
2660     if (!replaceSignalAlbumVector.empty()) {
2661         int32_t ret = UpdateAlbumReplacedSignal(rdbStore, replaceSignalAlbumVector);
2662         CHECK_AND_WARN_LOG(ret == E_OK, "Update sysalbum replaced signal failed ret:%{public}d", ret);
2663     }
2664     // Do not call SetNeedRefreshAlbum in this function
2665     // This is set by the notification from dfs
2666     // and is set by the media library observer after receiving the notification
2667 }
2668 
UpdateUserAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & userAlbumIds)2669 void MediaLibraryRdbUtils::UpdateUserAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2670     const vector<string> &userAlbumIds)
2671 {
2672     // only use in dfs
2673     MediaLibraryTracer tracer;
2674     tracer.Start("UpdateUserAlbumCountInternal");
2675 
2676     vector<string> columns = { PhotoAlbumColumns::ALBUM_ID };
2677     auto albumResult = GetUserAlbum(rdbStore, userAlbumIds, columns);
2678     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
2679 
2680     vector<string> replaceSignalAlbumVector;
2681     while (albumResult->GoToNextRow() == NativeRdb::E_OK) {
2682         int32_t ret = GetIntValFromColumn(albumResult, PhotoAlbumColumns::ALBUM_ID);
2683         if (ret <= 0) {
2684             MEDIA_WARN_LOG("Can not get ret:%{public}d", ret);
2685         } else {
2686             replaceSignalAlbumVector.push_back(to_string(ret));
2687         }
2688     }
2689     if (!replaceSignalAlbumVector.empty()) {
2690         int32_t ret = UpdateAlbumReplacedSignal(rdbStore, replaceSignalAlbumVector);
2691         CHECK_AND_WARN_LOG(ret == E_OK, "Update user album replaced signal failed ret:%{public}d", ret);
2692     }
2693     // Do not call SetNeedRefreshAlbum in this function
2694     // This is set by the notification from dfs
2695     // and is set by the media library observer after receiving the notification
2696 }
2697 
UpdateAnalysisAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,const vector<string> & subtypes)2698 void MediaLibraryRdbUtils::UpdateAnalysisAlbumCountInternal(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2699     const vector<string> &subtypes)
2700 {
2701     // only use in dfs
2702     MediaLibraryTracer tracer;
2703     tracer.Start("UpdateAnalysisAlbumCountInternal");
2704 
2705     vector<string> columns = { ALBUM_ID, ALBUM_SUBTYPE };
2706     auto albumResult = GetAnalysisAlbumBySubtype(rdbStore, subtypes, columns);
2707     CHECK_AND_RETURN_LOG(albumResult != nullptr, "album result is null");
2708 
2709     vector<BussinessRecordValue> updateAlbumIdList;
2710     while (albumResult->GoToNextRow() == NativeRdb::E_OK) {
2711         int32_t albumId = GetIntValFromColumn(albumResult, ALBUM_ID);
2712         int32_t subtype = GetIntValFromColumn(albumResult, ALBUM_SUBTYPE);
2713         if (albumId <= 0) {
2714             MEDIA_WARN_LOG("Can not get ret:%{public}d", albumId);
2715         } else {
2716             updateAlbumIdList.push_back({ ANALYSIS_REFRESH_BUSINESS_TYPE, to_string(subtype), to_string(albumId) });
2717         }
2718     }
2719     if (!updateAlbumIdList.empty()) {
2720         int32_t ret = UpdateBussinessRecord(rdbStore, updateAlbumIdList);
2721         CHECK_AND_WARN_LOG(ret == E_OK, "Update sysalbum replaced signal failed ret:%{public}d", ret);
2722     }
2723     // Do not call SetNeedRefreshAlbum in this function
2724     // This is set by the notification from dfs
2725     // and is set by the media library observer after receiving the notification
2726 }
2727 
HandleAnalysisAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore,vector<RefreshAlbumData> & albums,bool isUpdateAllAnalysis)2728 static void HandleAnalysisAlbum(const shared_ptr<MediaLibraryRdbStore> rdbStore, vector<RefreshAlbumData> &albums,
2729     bool isUpdateAllAnalysis)
2730 {
2731     int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
2732     int32_t count = -1;
2733     if (isUpdateAllAnalysis) {
2734         MediaLibraryRdbUtils::UpdateAnalysisAlbumInternal(rdbStore);
2735     } else {
2736         CHECK_AND_RETURN_LOG(!albums.empty(), "no album");
2737         count = static_cast<int32_t>(albums.size());
2738         std::vector<std::string> albumIds(count);
2739         for (int32_t i = 0; i < count; i++) {
2740             albumIds[i] = to_string(albums[i].albumId);
2741             MEDIA_DEBUG_LOG("analysis: %{public}s", albumIds[i].c_str());
2742         }
2743         MediaLibraryRdbUtils::UpdateAnalysisAlbumInternal(rdbStore, albumIds);
2744     }
2745     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
2746     MEDIA_INFO_LOG("%{public}d analysis albums update cost %{public}ld", count,
2747         static_cast<long>(end - start));
2748 }
2749 
RefreshPhotoAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,function<void (PhotoAlbumType,PhotoAlbumSubType,int)> refreshProcessHandler)2750 int RefreshPhotoAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2751     function<void(PhotoAlbumType, PhotoAlbumSubType, int)> refreshProcessHandler)
2752 {
2753     std::vector<RefreshAlbumData> systeAlbums;
2754     std::vector<RefreshAlbumData> analysisAlbums;
2755     bool isUpdateAllAnalysis = false;
2756     int ret = GetSystemRefreshAlbums(rdbStore, systeAlbums);
2757     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "failed to get system album id from refresh album");
2758     ret = GetAnalysisRefreshAlbums(rdbStore, analysisAlbums, isUpdateAllAnalysis);
2759     DeleteAllAlbumId(rdbStore);
2760     CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, ret, "failed to get analysis album id from refresh album");
2761     bool cond = (systeAlbums.empty() && analysisAlbums.empty());
2762     CHECK_AND_RETURN_RET_INFO_LOG(!cond, E_EMPTY_ALBUM_ID, "all album are empty");
2763 
2764     int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
2765     ret = RefreshAlbums(rdbStore, systeAlbums, refreshProcessHandler);
2766     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
2767     MEDIA_INFO_LOG("%{public}d system albums update cost %{public}ld", (int)systeAlbums.size(), (long)(end - start));
2768     HandleAnalysisAlbum(rdbStore, analysisAlbums, isUpdateAllAnalysis);
2769     return ret;
2770 }
2771 
RefreshAnalysisAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,const std::vector<UpdateAlbumData> & datas,function<void (PhotoAlbumType,PhotoAlbumSubType,int)> refreshProcessHandler,const vector<string> & subtypes)2772 static int32_t RefreshAnalysisAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2773     const std::vector<UpdateAlbumData> &datas,
2774     function<void(PhotoAlbumType, PhotoAlbumSubType, int)> refreshProcessHandler,
2775     const vector<string> &subtypes)
2776 {
2777     for (auto data : datas) {
2778         int ret = UpdateAnalysisAlbumIfNeeded(rdbStore, data, false);
2779         CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, E_HAS_DB_ERROR, "UpdateAnalysisAlbumIfNeeded fail");
2780         auto subtype = static_cast<PhotoAlbumSubType>(data.albumSubtype);
2781         int32_t albumId = data.albumId;
2782         refreshProcessHandler(PhotoAlbumType::SMART, subtype, albumId);
2783     }
2784 
2785     string deleteRefreshTableSql = "DELETE FROM " + MedialibraryBusinessRecordColumn::TABLE + " WHERE " +
2786         MedialibraryBusinessRecordColumn::BUSINESS_TYPE + " = '" + ANALYSIS_REFRESH_BUSINESS_TYPE + "'";
2787     int32_t ret = rdbStore->ExecuteSql(deleteRefreshTableSql);
2788     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_HAS_DB_ERROR,
2789         "Failed to execute sql:%{private}s", deleteRefreshTableSql.c_str());
2790     MEDIA_DEBUG_LOG("Delete RefreshAnalysisAlbums success");
2791     return E_SUCCESS;
2792 }
2793 
GetRefreshAnalysisAlbumIds(const shared_ptr<MediaLibraryRdbStore> rdbStore,vector<string> & albumIds,const vector<string> & subtypes)2794 static int32_t GetRefreshAnalysisAlbumIds(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2795     vector<string> &albumIds, const vector<string> &subtypes)
2796 {
2797     RdbPredicates predicates(MedialibraryBusinessRecordColumn::TABLE);
2798     if (!subtypes.empty()) {
2799         predicates.In(MedialibraryBusinessRecordColumn::KEY, subtypes);
2800     } else {
2801         predicates.In(MedialibraryBusinessRecordColumn::KEY, ALL_ANALYSIS_ALBUM);
2802     }
2803     predicates.EqualTo(MedialibraryBusinessRecordColumn::BUSINESS_TYPE, ANALYSIS_REFRESH_BUSINESS_TYPE);
2804 
2805     vector<string> columns = { MedialibraryBusinessRecordColumn::VALUE };
2806     auto resultSet = rdbStore->Query(predicates, columns);
2807     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "Can not query ALBUM_REFRESH_TABLE");
2808 
2809     int32_t count = 0;
2810     int32_t ret = resultSet->GetRowCount(count);
2811     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_HAS_DB_ERROR,
2812         "GetRowCount failed ret:%{public}d", ret);
2813     if (count == 0) {
2814         MEDIA_DEBUG_LOG("count is zero, break");
2815         return E_SUCCESS;
2816     }
2817 
2818     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
2819         int32_t columnIndex = 0;
2820         ret = resultSet->GetColumnIndex(MedialibraryBusinessRecordColumn::VALUE, columnIndex);
2821         CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_HAS_DB_ERROR,
2822             "GetColumnIndex failed ret:%{public}d", ret);
2823         string refreshAlbumId;
2824         ret = resultSet->GetString(columnIndex, refreshAlbumId);
2825         CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_HAS_DB_ERROR,
2826             "GetString failed ret:%{public}d", ret);
2827         albumIds.push_back(refreshAlbumId);
2828     }
2829     return E_SUCCESS;
2830 }
2831 
RefreshAnalysisPhotoAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,function<void (PhotoAlbumType,PhotoAlbumSubType,int)> refreshProcessHandler,const vector<string> & subtypes)2832 int RefreshAnalysisPhotoAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2833     function<void(PhotoAlbumType, PhotoAlbumSubType, int)> refreshProcessHandler, const vector<string> &subtypes)
2834 {
2835     int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
2836     vector<string> albumIds;
2837     int ret = GetRefreshAnalysisAlbumIds(rdbStore, albumIds, subtypes);
2838     CHECK_AND_RETURN_RET(ret == E_SUCCESS, ret);
2839     if (albumIds.empty()) {
2840         MEDIA_DEBUG_LOG("albumIds is empty");
2841         return E_EMPTY_ALBUM_ID;
2842     }
2843     vector<string> columns = {
2844         PhotoAlbumColumns::ALBUM_ID,
2845         PhotoAlbumColumns::ALBUM_SUBTYPE,
2846         PhotoAlbumColumns::ALBUM_COVER_URI,
2847         PhotoAlbumColumns::ALBUM_COUNT,
2848     };
2849     auto resultSet = GetAnalysisAlbum(rdbStore, albumIds, columns);
2850     CHECK_AND_RETURN_RET(resultSet != nullptr, E_HAS_DB_ERROR);
2851 
2852     std::vector<UpdateAlbumData> datas;
2853     while (resultSet->GoToNextRow() == E_OK) {
2854         UpdateAlbumData data;
2855         data.albumId = GetAlbumId(resultSet);
2856         data.albumSubtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(resultSet));
2857         data.albumCoverUri = GetAlbumCover(resultSet, PhotoAlbumColumns::ALBUM_COVER_URI);
2858         data.albumCount = GetAlbumCount(resultSet, PhotoAlbumColumns::ALBUM_COUNT);
2859         datas.push_back(data);
2860     }
2861     resultSet->Close();
2862 
2863     ret = RefreshAnalysisAlbums(rdbStore, datas, refreshProcessHandler, subtypes);
2864     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
2865     MEDIA_INFO_LOG("%{public}d analysis albums update cost %{public}ld", (int)albumIds.size(), (long)(end - start));
2866     return ret;
2867 }
2868 
IsRefreshAlbumEmpty(const shared_ptr<MediaLibraryRdbStore> rdbStore)2869 static bool IsRefreshAlbumEmpty(const shared_ptr<MediaLibraryRdbStore> rdbStore)
2870 {
2871     RdbPredicates predicates(ALBUM_REFRESH_TABLE);
2872     vector<string> columns = { MEDIA_COLUMN_COUNT_1 };
2873     auto resultSet = rdbStore->Query(predicates, columns);
2874     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, true, "Can not query ALBUM_REFRESH_TABLE");
2875     int32_t count = GetFileCount(resultSet);
2876     MEDIA_DEBUG_LOG("RefreshAllAlbuming remain count:%{public}d", count);
2877     return count <= 0;
2878 }
2879 
RefreshAllAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,function<void (PhotoAlbumType,PhotoAlbumSubType,int)> refreshProcessHandler,function<void ()> refreshCallback)2880 int32_t MediaLibraryRdbUtils::RefreshAllAlbums(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2881     function<void(PhotoAlbumType, PhotoAlbumSubType, int)> refreshProcessHandler, function<void()> refreshCallback)
2882 {
2883     unique_lock<mutex> lock(sRefreshAlbumMutex_);
2884     if (IsInRefreshTask()) {
2885         lock.unlock();
2886         MEDIA_DEBUG_LOG("RefreshAllAlbuming, quit");
2887         return E_OK;
2888     }
2889     isInRefreshTask = true;
2890     lock.unlock();
2891 
2892     MediaLibraryTracer tracer;
2893     tracer.Start("RefreshAllAlbums");
2894 
2895     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_HAS_DB_ERROR, "Can not get rdb");
2896 
2897     int ret = E_SUCCESS;
2898     bool isRefresh = false;
2899     while (IsNeedRefreshAlbum() || !IsRefreshAlbumEmpty(rdbStore)) {
2900         SetNeedRefreshAlbum(false);
2901         ret = RefreshPhotoAlbums(rdbStore, refreshProcessHandler);
2902         if (ret == E_EMPTY_ALBUM_ID) {
2903             ret = E_SUCCESS;
2904             continue;
2905         }
2906         CHECK_AND_BREAK(ret == E_SUCCESS);
2907         this_thread::sleep_for(chrono::milliseconds(PowerEfficiencyManager::GetAlbumUpdateInterval()));
2908         isRefresh = true;
2909     }
2910     // update SHOOTING_MODE album
2911     vector<string> subtype = { std::to_string(PhotoAlbumSubType::SHOOTING_MODE) };
2912     ret = RefreshAnalysisPhotoAlbums(rdbStore, refreshProcessHandler, subtype);
2913     CHECK_AND_EXECUTE(ret != E_EMPTY_ALBUM_ID, ret = E_SUCCESS);
2914 
2915     if (ret != E_SUCCESS) {
2916         // refresh failed and set flag, try to refresh next time
2917         SetNeedRefreshAlbum(true);
2918     } else {
2919         // refresh task is successful
2920         SetNeedRefreshAlbum(false);
2921     }
2922     isInRefreshTask = false;
2923     CHECK_AND_EXECUTE(!isRefresh, refreshCallback());
2924 
2925     return ret;
2926 }
2927 
NotifyShootingModeAlbumFunc(PhotoAlbumType albumtype,PhotoAlbumSubType subtype,int32_t albumId)2928 static void NotifyShootingModeAlbumFunc(PhotoAlbumType albumtype, PhotoAlbumSubType subtype, int32_t albumId)
2929 {
2930     const static set<PhotoAlbumSubType> NEED_FLUSH_ANALYSIS_ALBUM = {
2931         PhotoAlbumSubType::SHOOTING_MODE,
2932     };
2933     if (NEED_FLUSH_ANALYSIS_ALBUM.find(subtype) != NEED_FLUSH_ANALYSIS_ALBUM.end()) {
2934         auto watch = MediaLibraryNotify::GetInstance();
2935         if (watch == nullptr) {
2936             MEDIA_ERR_LOG("Can not get MediaLibraryNotify Instance");
2937             return;
2938         }
2939         if (albumId > 0) {
2940             watch->Notify(MediaFileUtils::GetUriByExtrConditions(PhotoAlbumColumns::ANALYSIS_ALBUM_URI_PREFIX,
2941                 std::to_string(albumId)), NotifyType::NOTIFY_ADD);
2942         } else {
2943             watch->Notify(PhotoAlbumColumns::ANALYSIS_ALBUM_URI_PREFIX, NotifyType::NOTIFY_ADD);
2944         }
2945     }
2946 }
2947 
UpdateAllAlbumsForCloud(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2948 void MediaLibraryRdbUtils::UpdateAllAlbumsForCloud(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2949 {
2950     // 注意,端云同步代码仓也有相同函数,添加新相册时,请通知端云同步进行相应修改
2951     MediaLibraryRdbUtils::UpdateSystemAlbumInternal(rdbStore);
2952     MediaLibraryRdbUtils::UpdateUserAlbumInternal(rdbStore);
2953     MediaLibraryRdbUtils::UpdateAnalysisAlbumInternal(rdbStore);
2954 }
2955 
UpdateAllAlbumsCountForCloud(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)2956 void MediaLibraryRdbUtils::UpdateAllAlbumsCountForCloud(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
2957 {
2958     // 注意,端云同步代码仓也有相同函数,添加新相册时,请通知端云同步进行相应修改
2959     MediaLibraryRdbUtils::UpdateSystemAlbumCountInternal(rdbStore);
2960     MediaLibraryRdbUtils::UpdateUserAlbumCountInternal(rdbStore);
2961     vector<string> subtype = { "4101" };
2962     MediaLibraryRdbUtils::UpdateAnalysisAlbumCountInternal(rdbStore, subtype);
2963 }
2964 
AddQueryIndex(AbsPredicates & predicates,const vector<string> & columns)2965 void MediaLibraryRdbUtils::AddQueryIndex(AbsPredicates& predicates, const vector<string>& columns)
2966 {
2967     auto it = find(columns.begin(), columns.end(), MEDIA_COLUMN_COUNT);
2968     if (it == columns.end()) {
2969         return;
2970     }
2971     const string &group = predicates.GetGroup();
2972     if (group.empty()) {
2973         predicates.GroupBy({ PhotoColumn::PHOTO_DATE_DAY });
2974         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_DAY_INDEX);
2975         return;
2976     }
2977     if (group == PhotoColumn::MEDIA_TYPE) {
2978         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_MEDIA_TYPE_INDEX);
2979         return;
2980     }
2981     if (group == PhotoColumn::PHOTO_DATE_DAY) {
2982         predicates.IndexedBy(PhotoColumn::PHOTO_SCHPT_DAY_INDEX);
2983         return;
2984     }
2985 }
2986 
AddVirtualColumnsOfDateType(vector<string> & columns)2987 void MediaLibraryRdbUtils::AddVirtualColumnsOfDateType(vector<string>& columns)
2988 {
2989     vector<string> dateTypes = { MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_DATE_TRASHED, MEDIA_DATA_DB_DATE_MODIFIED,
2990             MEDIA_DATA_DB_DATE_TAKEN };
2991     vector<string> dateTypeSeconds = { MEDIA_DATA_DB_DATE_ADDED_TO_SECOND,
2992             MEDIA_DATA_DB_DATE_TRASHED_TO_SECOND, MEDIA_DATA_DB_DATE_MODIFIED_TO_SECOND,
2993             MEDIA_DATA_DB_DATE_TAKEN_TO_SECOND };
2994     for (size_t i = 0; i < dateTypes.size(); i++) {
2995         auto it = find(columns.begin(), columns.end(), dateTypes[i]);
2996         if (it != columns.end()) {
2997             columns.push_back(dateTypeSeconds[i]);
2998         }
2999     }
3000 }
3001 
CleanAmbiguousColumn(std::vector<std::string> & columns,DataShare::DataSharePredicates & predicates,const std::string tableName)3002 void MediaLibraryRdbUtils::CleanAmbiguousColumn(std::vector<std::string> &columns,
3003     DataShare::DataSharePredicates &predicates, const std::string tableName)
3004 {
3005     size_t FIELD_IDX = 0;
3006     size_t VALUE_IDX = 1;
3007     vector<DataShare::OperationItem> operationItemsNew;
3008     auto operationItems = predicates.GetOperationList();
3009     for (DataShare::OperationItem item : operationItems) {
3010         if (item.singleParams.empty()) {
3011             operationItemsNew.push_back(item);
3012             continue;
3013         }
3014         if (static_cast<string>(item.GetSingle(FIELD_IDX)) == MediaColumn::MEDIA_ID) {
3015             vector<DataShare::SingleValue::Type> newSingleParam;
3016             newSingleParam.push_back(tableName + "." + MediaColumn::MEDIA_ID);
3017             for (size_t i = VALUE_IDX; i < item.singleParams.size(); i++) {
3018                 newSingleParam.push_back(item.singleParams[i]);
3019             }
3020             operationItemsNew.push_back({ item.operation, newSingleParam, move(item.multiParams)});
3021             continue;
3022         }
3023         operationItemsNew.push_back(item);
3024     }
3025     predicates = DataShare::DataSharePredicates(operationItemsNew);
3026     transform(columns.begin(), columns.end(), columns.begin(),
3027         [tableName](const std::string &column) {
3028             if (column == MediaColumn::MEDIA_ID) {
3029                 return tableName + "." + column;
3030             } else {
3031                 return column;
3032             }
3033         });
3034 }
3035 
GetPhotoAndKnowledgeConnection()3036 vector<string> GetPhotoAndKnowledgeConnection()
3037 {
3038     vector<string> clauses;
3039     clauses.push_back(
3040         PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LATITUDE + " = " + GEO_KNOWLEDGE_TABLE + "." + LATITUDE);
3041     clauses.push_back(
3042         PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LONGITUDE + " = " + GEO_KNOWLEDGE_TABLE + "." + LONGITUDE);
3043     return clauses;
3044 }
3045 
QueryCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,const RdbPredicates & predicates)3046 int QueryCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore, const RdbPredicates &predicates)
3047 {
3048     const vector<string> columns = { MEDIA_COLUMN_COUNT_1 };
3049     auto fetchResult = QueryGoToFirst(rdbStore, predicates, columns);
3050     CHECK_AND_RETURN_RET(fetchResult != nullptr, 0);
3051     return GetFileCount(fetchResult);
3052 }
3053 
GetNewKnowledgeDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3054 int GetNewKnowledgeDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3055 {
3056     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
3057     predicates.BeginWrap()->BeginWrap()
3058         ->LessThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LATITUDE, LOCATION_LATITUDE_MAX)
3059         ->And()->GreaterThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LATITUDE, LOCATION_DB_ZERO)
3060         ->EndWrap()->Or()->BeginWrap()
3061         ->LessThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LATITUDE, LOCATION_DB_ZERO)
3062         ->And()->GreaterThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LATITUDE, LOCATION_LATITUDE_MIN)
3063         ->EndWrap()->EndWrap()->And()->BeginWrap()->BeginWrap()
3064         ->LessThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LONGITUDE, LOCATION_LONGITUDE_MAX)->And()
3065         ->GreaterThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LONGITUDE, LOCATION_DB_ZERO)->EndWrap()
3066         ->Or()->BeginWrap()->LessThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LONGITUDE, LOCATION_DB_ZERO)
3067         ->And()->GreaterThan(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_LONGITUDE, LOCATION_LONGITUDE_MIN)
3068         ->EndWrap()->EndWrap();
3069     auto clauses = GetPhotoAndKnowledgeConnection();
3070     predicates.LeftOuterJoin(GEO_KNOWLEDGE_TABLE)->On(clauses);
3071     predicates.And()->BeginWrap()
3072         ->IsNull(GEO_KNOWLEDGE_TABLE + "." + LATITUDE)
3073         ->Or()->IsNull(GEO_KNOWLEDGE_TABLE + "." + LONGITUDE)
3074         ->Or()->IsNull(GEO_KNOWLEDGE_TABLE + "." + LANGUAGE)
3075         ->EndWrap();
3076 
3077     return QueryCount(rdbStore, predicates);
3078 }
3079 
GetUpdateKnowledgeDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3080 int GetUpdateKnowledgeDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3081 {
3082     RdbPredicates predicates(GEO_KNOWLEDGE_TABLE);
3083     predicates.LessThan(GEO_KNOWLEDGE_TABLE + "." + LOCATION_KEY, 0);
3084     return QueryCount(rdbStore, predicates);
3085 }
3086 
GetNewDictionaryDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3087 int GetNewDictionaryDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3088 {
3089     RdbPredicates predicates(GEO_KNOWLEDGE_TABLE);
3090     vector<string> clauses;
3091     clauses.push_back(GEO_KNOWLEDGE_TABLE + "." + CITY_ID + " = " + GEO_DICTIONARY_TABLE + "." + CITY_ID);
3092     clauses.push_back(GEO_KNOWLEDGE_TABLE + "." + LANGUAGE + " = " + GEO_DICTIONARY_TABLE + "." + LANGUAGE);
3093     predicates.LeftOuterJoin(GEO_DICTIONARY_TABLE)->On(clauses);
3094     predicates.BeginWrap()->IsNull(GEO_DICTIONARY_TABLE + "." + CITY_ID)
3095         ->And()->IsNotNull(GEO_KNOWLEDGE_TABLE + "." + COUNTRY)->EndWrap();
3096     vector<string> columns;
3097     auto resultSet = QueryGoToFirst(rdbStore, predicates, columns);
3098     CHECK_AND_RETURN_RET(resultSet != nullptr, 0);
3099     set<string> citySet;
3100     do {
3101         string cityId = GetStringValFromColumn(resultSet, CITY_ID);
3102         string cityName = GetStringValFromColumn(resultSet, CITY_NAME);
3103         bool cond = (cityId == "" || cityName == "");
3104         CHECK_AND_CONTINUE(!cond);
3105         citySet.insert(cityId);
3106     } while (!resultSet->GoToNextRow());
3107     return citySet.size();
3108 }
3109 
HasLocationData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3110 bool HasLocationData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3111 {
3112     int newDataCount = GetNewKnowledgeDataCount(rdbStore);
3113     int updateDataCount = GetUpdateKnowledgeDataCount(rdbStore);
3114     MEDIA_INFO_LOG("loc newDataCount:%{public}d, updateDataCount:%{public}d", newDataCount, updateDataCount);
3115 
3116     int newDictionaryCount = GetNewDictionaryDataCount(rdbStore);
3117     MEDIA_INFO_LOG("newDictionaryCount:%{public}d", newDictionaryCount);
3118     return (newDataCount + updateDataCount + newDictionaryCount) > 0;
3119 }
3120 
GetCvDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3121 int GetCvDataCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3122 {
3123     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
3124     vector<string> clauses;
3125     clauses.push_back(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_ID  + " = " +
3126         VISION_TOTAL_TABLE + "." + PhotoColumn::MEDIA_ID);
3127     predicates.InnerJoin(VISION_TOTAL_TABLE)->On(clauses);
3128     predicates.BeginWrap()->EqualTo(VISION_TOTAL_TABLE + "." + STATUS, 0)->And()
3129         ->BeginWrap()->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_TIME_PENDING, 0)->And()
3130         ->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_DATE_TRASHED, 0)->And()
3131         ->BeginWrap()->NotEqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_POSITION, CLOUD_POSITION_STATUS)
3132         ->Or()->BeginWrap()
3133         ->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_POSITION, CLOUD_POSITION_STATUS)->And()
3134         ->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_THUMB_STATUS, 0)
3135         ->EndWrap()->EndWrap()->EndWrap()->EndWrap();
3136     return QueryCount(rdbStore, predicates);
3137 }
3138 
HasCvData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3139 bool HasCvData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3140 {
3141     int count = GetCvDataCount(rdbStore);
3142     MEDIA_INFO_LOG("cv count:%{public}d", count);
3143     return count > 0;
3144 }
3145 
GetSearchBaseCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3146 int GetSearchBaseCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3147 {
3148     RdbPredicates predicates(SEARCH_TOTAL_TABLE);
3149     vector<string> clasues;
3150     clasues.push_back(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_FILE_ID + " = " +
3151         PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_ID);
3152     predicates.InnerJoin(PhotoColumn::PHOTOS_TABLE)->On(clasues);
3153     predicates.EqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_PHOTO_STATUS, 0)
3154         ->And()
3155         ->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_TIME_PENDING, 0)
3156         ->And()
3157         ->GreaterThanOrEqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_FILE_ID, 0);
3158     return QueryCount(rdbStore, predicates);
3159 }
3160 
GetSearchUpdateCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3161 int GetSearchUpdateCount(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3162 {
3163     RdbPredicates predicates(SEARCH_TOTAL_TABLE);
3164     vector<string> clauses;
3165     clauses.push_back(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_FILE_ID + " = " +
3166         PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_ID);
3167     vector<string> clausesTotal;
3168     clausesTotal.push_back(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_FILE_ID + " = " +
3169         VISION_TOTAL_TABLE + "." + PhotoColumn::MEDIA_ID);
3170     vector<string> clausesGeo;
3171     clausesGeo.push_back(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LATITUDE + " = " + GEO_KNOWLEDGE_TABLE + "." + LATITUDE);
3172     clausesGeo.push_back(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LONGITUDE +
3173         " = " + GEO_KNOWLEDGE_TABLE + "." + LONGITUDE);
3174     predicates.InnerJoin(PhotoColumn::PHOTOS_TABLE)->On(clauses);
3175     predicates.InnerJoin(VISION_TOTAL_TABLE)->On(clausesTotal);
3176     predicates.LeftOuterJoin(GEO_KNOWLEDGE_TABLE)->On(clausesGeo);
3177     predicates.GreaterThanOrEqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_FILE_ID, 0)->And()
3178         ->EqualTo(PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::MEDIA_TIME_PENDING, 0)->And()
3179         ->GreaterThan(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_PHOTO_STATUS, 0)->And()
3180         ->BeginWrap()->EqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_PHOTO_STATUS, SEARCH_UPDATE_STATUS)->Or()
3181         ->BeginWrap()->EqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_CV_STATUS, SEARCH_UPDATE_STATUS)->And()
3182         ->EqualTo(VISION_TOTAL_TABLE + "." + FACE, FACE_CLUSTERED)->EndWrap()->Or()
3183         ->BeginWrap()->EqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_CV_STATUS, 0)->And()
3184         ->BeginWrap()->NotEqualTo(VISION_TOTAL_TABLE + "." + OCR, 0)->Or()
3185         ->NotEqualTo(VISION_TOTAL_TABLE + "." + LABEL, 0)->Or()
3186         ->BeginWrap()->NotEqualTo(VISION_TOTAL_TABLE + "." + FACE, 0)->And()
3187         ->NotEqualTo(VISION_TOTAL_TABLE + "." + FACE, FACE_RECOGNITION)->And()
3188         ->NotEqualTo(VISION_TOTAL_TABLE + "." + FACE, FACE_FEATURE)->EndWrap()->EndWrap()->EndWrap()->Or()
3189         ->BeginWrap()->EqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_GEO_STATUS, 0)->And()
3190         ->BeginWrap()->NotEqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LATITUDE, 0)->Or()
3191         ->NotEqualTo(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LONGITUDE, 0)->EndWrap()->And()
3192         ->IsNotNull(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LATITUDE)->And()
3193         ->IsNotNull(SEARCH_TOTAL_TABLE + "." + TBL_SEARCH_LONGITUDE)->And()
3194         ->BeginWrap()->IsNotNull(GEO_KNOWLEDGE_TABLE + "." + LATITUDE)->And()
3195         ->IsNotNull(GEO_KNOWLEDGE_TABLE + "." + LONGITUDE)->EndWrap()->EndWrap()->EndWrap();
3196     return QueryCount(rdbStore, predicates);
3197 }
3198 
HasSearchData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3199 bool HasSearchData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3200 {
3201     int baseCount = GetSearchBaseCount(rdbStore);
3202     int upateCount = GetSearchUpdateCount(rdbStore);
3203     MEDIA_INFO_LOG("baseCount:%{public}d, upateCount:%{public}d", baseCount, upateCount);
3204     return (baseCount + upateCount) > 0;
3205 }
3206 
HasHighLightData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3207 bool HasHighLightData(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3208 {
3209     RdbPredicates predicates(ANALYSIS_ALBUM_TABLE);
3210     vector<string> clauses;
3211     clauses.push_back(ANALYSIS_ALBUM_TABLE + "." + ALBUM_ID + " = " +
3212         HIGHLIGHT_COVER_INFO_TABLE + "." + ALBUM_ID);
3213     predicates.InnerJoin(HIGHLIGHT_COVER_INFO_TABLE)->On(clauses);
3214     predicates.EqualTo(ANALYSIS_ALBUM_TABLE + "." + ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::HIGHLIGHT))->And()
3215         ->NotEqualTo(ANALYSIS_ALBUM_TABLE + "." + PhotoAlbumColumns::ALBUM_COVER_URI,
3216         HIGHLIGHT_COVER_INFO_TABLE + "." + COVER_KEY);
3217     int count = QueryCount(rdbStore, predicates);
3218     MEDIA_INFO_LOG("highligh count:%{public}d", count);
3219     return (count > 0);
3220 }
3221 
HasDataToAnalysis(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)3222 bool MediaLibraryRdbUtils::HasDataToAnalysis(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
3223 {
3224     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, false, "HasDataToAnalysis rdbstore is null");
3225     bool loc = HasLocationData(rdbStore);
3226     bool cv = HasCvData(rdbStore);
3227     bool search = HasSearchData(rdbStore);
3228     bool highlight = HasHighLightData(rdbStore);
3229     return (loc || cv || search || highlight);
3230 }
3231 
UpdateThumbnailRelatedDataToDefault(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,const int64_t fileId)3232 int32_t MediaLibraryRdbUtils::UpdateThumbnailRelatedDataToDefault(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,
3233     const int64_t fileId)
3234 {
3235     int32_t err = -1;
3236     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, err, "RdbStore is null!");
3237 
3238     ValuesBucket values;
3239     values.PutLong(PhotoColumn::PHOTO_THUMBNAIL_READY, 0);
3240     values.PutLong(PhotoColumn::PHOTO_THUMBNAIL_VISIBLE, 0);
3241     values.PutLong(PhotoColumn::PHOTO_LCD_VISIT_TIME, 0);
3242 
3243     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
3244     predicates.EqualTo(MediaColumn::MEDIA_ID, fileId);
3245     int32_t changedRows = 0;
3246     err = rdbStore->Update(changedRows, values, predicates);
3247     CHECK_AND_PRINT_LOG(err == NativeRdb::E_OK, "RdbStore Update failed! err: %{public}d", err);
3248     return err;
3249 }
3250 
QueryNeedTransformPermission(const shared_ptr<MediaLibraryRdbStore> & store)3251 static shared_ptr<NativeRdb::ResultSet> QueryNeedTransformPermission(const shared_ptr<MediaLibraryRdbStore> &store)
3252 {
3253     NativeRdb::RdbPredicates rdbPredicate(AppUriPermissionColumn::APP_URI_PERMISSION_TABLE);
3254     vector<string> permissionTypes;
3255     permissionTypes.emplace_back(to_string(PERSIST_READ_IMAGEVIDEO));
3256     permissionTypes.emplace_back(to_string(PERSIST_READWRITE_IMAGEVIDEO));
3257     rdbPredicate.In(AppUriPermissionColumn::PERMISSION_TYPE, permissionTypes);
3258     rdbPredicate.BeginWrap();
3259     rdbPredicate.EqualTo(AppUriPermissionColumn::TARGET_TOKENID, "");
3260     rdbPredicate.Or();
3261     rdbPredicate.IsNull(AppUriPermissionColumn::TARGET_TOKENID);
3262     rdbPredicate.EndWrap();
3263     vector<string> columns{
3264         AppUriPermissionColumn::APP_ID
3265     };
3266     rdbPredicate.GroupBy(columns);
3267     return store->Query(rdbPredicate, columns);
3268 }
3269 
QueryTokenIdMap(const shared_ptr<NativeRdb::ResultSet> & resultSet)3270 static std::map<std::string, int64_t> QueryTokenIdMap(const shared_ptr<NativeRdb::ResultSet> &resultSet)
3271 {
3272     std::map<std::string, int64_t> appIdTokenIdMap;
3273     while (resultSet->GoToNextRow() == E_OK) {
3274         string appId;
3275         GetStringFromResultSet(resultSet, AppUriPermissionColumn::APP_ID, appId);
3276         int64_t tokenId;
3277         CHECK_AND_EXECUTE(!PermissionUtils::GetMainTokenId(appId, tokenId),
3278             appIdTokenIdMap.emplace(appId, tokenId));
3279     }
3280     return appIdTokenIdMap;
3281 }
3282 
TransformAppId2TokenId(const shared_ptr<MediaLibraryRdbStore> & store)3283 void MediaLibraryRdbUtils::TransformAppId2TokenId(const shared_ptr<MediaLibraryRdbStore> &store)
3284 {
3285     MEDIA_INFO_LOG("TransformAppId2TokenId start!");
3286     auto resultSet = QueryNeedTransformPermission(store);
3287     CHECK_AND_RETURN_LOG(resultSet != nullptr, "TransformAppId2TokenId failed");
3288 
3289     std::map<std::string, int64_t> tokenIdMap = QueryTokenIdMap(resultSet);
3290     resultSet->Close();
3291     CHECK_AND_RETURN_WARN_LOG(tokenIdMap.size() != 0, "TransformAppId2TokenId tokenIdMap empty");
3292     int32_t successCount = 0;
3293     for (auto &pair : tokenIdMap) {
3294         NativeRdb::RdbPredicates rdbPredicate(AppUriPermissionColumn::APP_URI_PERMISSION_TABLE);
3295         vector<string> permissionTypes;
3296         permissionTypes.emplace_back(to_string(PERSIST_READ_IMAGEVIDEO));
3297         permissionTypes.emplace_back(to_string(PERSIST_READWRITE_IMAGEVIDEO));
3298         rdbPredicate.In(AppUriPermissionColumn::PERMISSION_TYPE, permissionTypes);
3299         rdbPredicate.EqualTo(AppUriPermissionColumn::APP_ID, pair.first);
3300         rdbPredicate.BeginWrap();
3301         rdbPredicate.EqualTo(AppUriPermissionColumn::TARGET_TOKENID, "");
3302         rdbPredicate.Or();
3303         rdbPredicate.IsNull(AppUriPermissionColumn::TARGET_TOKENID);
3304         rdbPredicate.EndWrap();
3305         ValuesBucket refreshValues;
3306         refreshValues.PutLong(AppUriPermissionColumn::TARGET_TOKENID, pair.second);
3307         refreshValues.PutLong(AppUriPermissionColumn::SOURCE_TOKENID, pair.second);
3308         int changeRows = 0;
3309         CHECK_AND_EXECUTE(store->Update(changeRows, refreshValues, rdbPredicate) != E_OK, successCount++);
3310     }
3311     MEDIA_INFO_LOG("TransformAppId2TokenId updatecount:%{public}zu, successcount:%{public}d",
3312         tokenIdMap.size(), successCount);
3313 }
3314 
QueryNeedTransformOwnerAppid(const shared_ptr<MediaLibraryRdbStore> & store)3315 static shared_ptr<NativeRdb::ResultSet> QueryNeedTransformOwnerAppid(const shared_ptr<MediaLibraryRdbStore> &store)
3316 {
3317     NativeRdb::RdbPredicates rdbPredicate(PhotoColumn::PHOTOS_TABLE);
3318     rdbPredicate.IsNotNull(MediaColumn::MEDIA_OWNER_APPID);
3319     vector<string> columns{
3320         MediaColumn::MEDIA_ID,
3321         MediaColumn::MEDIA_OWNER_APPID,
3322     };
3323     return store->Query(rdbPredicate, columns);
3324 }
3325 
TransformOwnerAppIdToTokenId(const shared_ptr<MediaLibraryRdbStore> & store)3326 void MediaLibraryRdbUtils::TransformOwnerAppIdToTokenId(const shared_ptr<MediaLibraryRdbStore> &store)
3327 {
3328     MEDIA_INFO_LOG("TransformOwnerAppId2TokenId start!");
3329     auto resultSet = QueryNeedTransformOwnerAppid(store);
3330     CHECK_AND_RETURN_LOG(resultSet != nullptr, "TransformOwnerAppId2TokenId failed");
3331     int32_t successCount = 0;
3332     std::map<std::string, int64_t> tokenIdMap;
3333     vector<ValuesBucket> values;
3334     while (resultSet->GoToNextRow() == E_OK) {
3335         string appId;
3336         GetStringFromResultSet(resultSet, MediaColumn::MEDIA_OWNER_APPID, appId);
3337         int32_t fileId = 0;
3338         GetIntFromResultSet(resultSet, MediaColumn::MEDIA_ID, fileId);
3339         if (appId.empty() || fileId == 0) {
3340             MEDIA_ERR_LOG("failed to get resultset!");
3341             continue;
3342         }
3343         int64_t tokenId = 0;
3344         if (tokenIdMap.find(appId) != tokenIdMap.end()) {
3345             tokenId = tokenIdMap[appId];
3346         } else {
3347             if (PermissionUtils::GetMainTokenId(appId, tokenId) != E_OK) {
3348                 MEDIA_ERR_LOG("failed to get maintokenId : %{public}s", appId.c_str());
3349                 continue;
3350             }
3351             tokenIdMap.emplace(appId, tokenId);
3352         }
3353         ValuesBucket insertValue;
3354         insertValue.PutString(AppUriPermissionColumn::APP_ID, appId);
3355         insertValue.PutLong(AppUriPermissionColumn::SOURCE_TOKENID, tokenId);
3356         insertValue.PutLong(AppUriPermissionColumn::TARGET_TOKENID, tokenId);
3357         insertValue.PutInt(AppUriPermissionColumn::FILE_ID, fileId);
3358         insertValue.PutInt(AppUriPermissionColumn::URI_TYPE, AppUriPermissionColumn::URI_PHOTO);
3359         insertValue.PutInt(AppUriPermissionColumn::PERMISSION_TYPE,
3360             AppUriPermissionColumn::PERMISSION_PERSIST_READ_WRITE);
3361         insertValue.PutLong(AppUriPermissionColumn::DATE_MODIFIED, MediaFileUtils::UTCTimeMilliSeconds());
3362         values.push_back(insertValue);
3363     }
3364     resultSet->Close();
3365     if (values.size() > 0) {
3366         int64_t rowId = 0;
3367         int32_t ret = store->BatchInsert(rowId, AppUriPermissionColumn::APP_URI_PERMISSION_TABLE, values);
3368         MEDIA_INFO_LOG("TransformOwnerAppId2TokenId end, rowId : %{public}ld", static_cast<long>(rowId));
3369     }
3370 }
3371 
UpdateSystemAlbumExcludeSource(bool shouldNotify)3372 void MediaLibraryRdbUtils::UpdateSystemAlbumExcludeSource(bool shouldNotify)
3373 {
3374     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
3375     CHECK_AND_RETURN_LOG(rdbStore != nullptr, "Failed to get rdbStore.");
3376     MediaLibraryRdbUtils::UpdateSystemAlbumInternal(rdbStore,
3377         SYSTEM_ALBUMS, shouldNotify);
3378 }
3379 
AnalyzePhotosData()3380 bool MediaLibraryRdbUtils::AnalyzePhotosData()
3381 {
3382     shared_ptr<MediaLibraryRdbStore> rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
3383     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, false, "can not get rdb store, failed to analyze photos data");
3384     const string analyzeSql = "ANALYZE " + PhotoColumn::PHOTOS_TABLE;
3385     MEDIA_INFO_LOG("start analyze photos data");
3386     int32_t ret = rdbStore->ExecuteSql(analyzeSql);
3387     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, false, "Failed to execute sql, analyze photos data failed");
3388     MEDIA_INFO_LOG("end analyze photos data");
3389     return true;
3390 }
3391 
GetUpdateValues(const shared_ptr<MediaLibraryRdbStore> rdbStore,UpdateAlbumData & data,ValuesBucket & values,const bool hiddenState)3392 int32_t MediaLibraryRdbUtils::GetUpdateValues(const shared_ptr<MediaLibraryRdbStore> rdbStore,
3393     UpdateAlbumData &data, ValuesBucket &values, const bool hiddenState)
3394 {
3395     return SetUpdateValues(rdbStore, data, values, hiddenState);
3396 }
3397 
QueryShootingModeAlbumIdByType(ShootingModeAlbumType type,int32_t & resultAlbumId)3398 bool MediaLibraryRdbUtils::QueryShootingModeAlbumIdByType(ShootingModeAlbumType type, int32_t& resultAlbumId)
3399 {
3400     static std::unordered_map<ShootingModeAlbumType, int32_t> SHOOTING_MODE_ALBUM_ID_CACHE_MAP = {
3401         {ShootingModeAlbumType::PORTRAIT, -1},
3402         {ShootingModeAlbumType::WIDE_APERTURE, -1},
3403         {ShootingModeAlbumType::NIGHT_SHOT, -1},
3404         {ShootingModeAlbumType::MOVING_PICTURE, -1},
3405         {ShootingModeAlbumType::PRO_PHOTO, -1},
3406         {ShootingModeAlbumType::SLOW_MOTION, -1},
3407         {ShootingModeAlbumType::LIGHT_PAINTING, -1},
3408         {ShootingModeAlbumType::HIGH_PIXEL, -1},
3409         {ShootingModeAlbumType::SUPER_MACRO, -1},
3410         {ShootingModeAlbumType::PANORAMA_MODE, -1},
3411         {ShootingModeAlbumType::BURST_MODE_ALBUM, -1},
3412         {ShootingModeAlbumType::FRONT_CAMERA_ALBUM, -1},
3413         {ShootingModeAlbumType::RAW_IMAGE_ALBUM, -1},
3414     };
3415     if (SHOOTING_MODE_ALBUM_ID_CACHE_MAP.find(type) == SHOOTING_MODE_ALBUM_ID_CACHE_MAP.end()) {
3416         MEDIA_ERR_LOG("Shooting mode type %{public}d is not in the map", static_cast<int32_t>(type));
3417         return false;
3418     }
3419     int32_t mappedId = SHOOTING_MODE_ALBUM_ID_CACHE_MAP.at(type);
3420     if (mappedId <= 0) {
3421         auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
3422         CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, false, "Failed to get rdbStore.");
3423         NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(ANALYSIS_ALBUM_TABLE);
3424         predicates.EqualTo("album_subtype",
3425             std::to_string(static_cast<int32_t>(PhotoAlbumSubType::SHOOTING_MODE)));
3426         predicates.EqualTo("album_name", std::to_string(static_cast<int32_t>(type)));
3427         vector<string> columns = { "album_id" };
3428         auto resultSet = rdbStore->QueryByStep(predicates, columns);
3429         CHECK_AND_RETURN_RET_LOG(TryToGoToFirstRow(resultSet), false, "Query album id failed, type: %{public}d",
3430             static_cast<int32_t>(type));
3431         mappedId = GetInt32Val("album_id", resultSet);
3432         SHOOTING_MODE_ALBUM_ID_CACHE_MAP[type] = mappedId;
3433         resultSet->Close();
3434     }
3435     CHECK_AND_RETURN_RET_LOG(mappedId > 0, false, "Invalid id: %{public}d, type: %{public}d",
3436         mappedId, static_cast<int32_t>(type));
3437     resultAlbumId = mappedId;
3438     return true;
3439 }
3440 
QueryAllShootingModeAlbumIds(vector<int32_t> & albumIds)3441 bool MediaLibraryRdbUtils::QueryAllShootingModeAlbumIds(vector<int32_t>& albumIds)
3442 {
3443     for (int32_t i = static_cast<int32_t>(ShootingModeAlbumType::START);
3444         i <= static_cast<int32_t>(ShootingModeAlbumType::END); ++i) {
3445         ShootingModeAlbumType type = static_cast<ShootingModeAlbumType>(i);
3446         int32_t albumId = -1;
3447         CHECK_AND_RETURN_RET_LOG(QueryShootingModeAlbumIdByType(type, albumId), false,
3448             "Failed to query shooting mode album id, type is %{public}d", static_cast<int32_t>(type));
3449         albumIds.push_back(albumId);
3450     }
3451     return true;
3452 }
3453 
GetAlbumIdBySubType(PhotoAlbumSubType subtype)3454 int32_t MediaLibraryRdbUtils::GetAlbumIdBySubType(PhotoAlbumSubType subtype)
3455 {
3456     if (subType2AlbumIdMap.empty()) {
3457         auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
3458         CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "Failed to get rdbStore");
3459         auto albumResult = GetSystemAlbum(rdbStore, SYSTEM_ALBUMS, PHOTO_ALBUM_INFO_COLUMNS);
3460         CHECK_AND_RETURN_RET_LOG(albumResult != nullptr, E_ERR, "album result is null");
3461         while (albumResult->GoToNextRow() == E_OK) {
3462             auto albumId = GetAlbumId(albumResult);
3463             auto albumSubtype = static_cast<PhotoAlbumSubType>(GetAlbumSubType(albumResult));
3464             subType2AlbumIdMap.insert_or_assign(albumSubtype, albumId);
3465         }
3466     }
3467     auto iter = subType2AlbumIdMap.find(subtype);
3468     if (iter == subType2AlbumIdMap.end()) {
3469         MEDIA_ERR_LOG("no subtype[%{public}d] albumId", subtype);
3470         return E_ERR;
3471     }
3472     return iter->second;
3473 }
3474 
ExecuteDatabaseQuickCheck(const shared_ptr<MediaLibraryRdbStore> & rdbStore)3475 bool MediaLibraryRdbUtils::ExecuteDatabaseQuickCheck(const shared_ptr<MediaLibraryRdbStore> &rdbStore)
3476 {
3477     MEDIA_INFO_LOG("Start ExecuteDatabaseQuickChecky");
3478     string checkSql = "PRAGMA " + INTEGRITY_CHECK_COLUMN;
3479     vector<string> selectionArgs;
3480     auto resultSet = rdbStore->QuerySql(checkSql, selectionArgs);
3481     if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
3482         MEDIA_ERR_LOG ("Check database failed");
3483         return false;
3484     }
3485     std::string result = GetStringVal(INTEGRITY_CHECK_COLUMN, resultSet);
3486     MEDIA_INFO_LOG("Check db integrity: %{public}s", result.c_str());
3487     resultSet->Close();
3488     return result == DB_INTEGRITY_CHECK;
3489 }
3490 } // namespace OHOS::Media
3491