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