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