1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #define MLOG_TAG "Media_Cloud_Dao"
17
18 #include "cloud_media_data_dao.h"
19
20 #include <string>
21 #include <utime.h>
22 #include <vector>
23
24 #include "abs_rdb_predicates.h"
25 #include "media_column.h"
26 #include "photo_album_column.h"
27 #include "photo_map_column.h"
28 #include "media_log.h"
29 #include "medialibrary_rdbstore.h"
30 #include "media_file_utils.h"
31 #include "cloud_media_file_utils.h"
32 #include "cloud_media_sync_utils.h"
33 #include "cloud_media_dao_utils.h"
34 #include "cloud_media_operation_code.h"
35 #include "medialibrary_unistore_manager.h"
36 #include "moving_photo_file_utils.h"
37 #include "result_set.h"
38 #include "result_set_utils.h"
39 #include "thumbnail_const.h"
40 #include "userfile_manager_types.h"
41 #include "result_set_reader.h"
42 #include "photos_po_writer.h"
43 #include "photo_album_po_writer.h"
44 #include "cloud_sync_convert.h"
45 #include "photo_map_column.h"
46 #include "medialibrary_rdb_transaction.h"
47 #include "medialibrary_rdb_utils.h"
48 #include "scanner_utils.h"
49 #include "media_refresh_album_column.h"
50 #include "cloud_media_dao_const.h"
51 #include "asset_accurate_refresh.h"
52 #include "refresh_business_name.h"
53
54 namespace OHOS::Media::CloudSync {
UpdateDirty(const std::string & cloudId,int32_t dirtyType)55 int32_t CloudMediaDataDao::UpdateDirty(const std::string &cloudId, int32_t dirtyType)
56 {
57 MEDIA_INFO_LOG("enter UpdateDirty, cloudId: %{public}s, dirtyType: %{public}d", cloudId.c_str(), dirtyType);
58 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
59 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "UpdateDirty Failed to get rdbStore.");
60
61 NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
62 predicates.EqualTo(PhotoColumn::PHOTO_CLOUD_ID, cloudId);
63
64 NativeRdb::ValuesBucket values;
65 values.PutInt(PhotoColumn::PHOTO_DIRTY, dirtyType);
66
67 int32_t changedRows = DEFAULT_VALUE;
68 int32_t ret = rdbStore->Update(changedRows, values, predicates);
69 CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "Failed to UpdateDirty, ret: %{public}d", ret);
70 CHECK_AND_PRINT_LOG(changedRows > 0, "UpdateDirty Check updateRows: %{public}d.", changedRows);
71 return ret;
72 }
73
UpdatePosition(const std::vector<std::string> & cloudIds,int32_t position)74 int32_t CloudMediaDataDao::UpdatePosition(const std::vector<std::string> &cloudIds, int32_t position)
75 {
76 MEDIA_INFO_LOG("enter UpdatePosition, cloudIds size: %{public}zu, position: %{public}d", cloudIds.size(), position);
77
78 NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
79 predicates.In(PhotoColumn::PHOTO_CLOUD_ID, cloudIds);
80
81 NativeRdb::ValuesBucket values;
82 values.PutInt(PhotoColumn::PHOTO_POSITION, position);
83
84 int32_t changedRows = DEFAULT_VALUE;
85 AccurateRefresh::AssetAccurateRefresh assetRefresh(AccurateRefresh::UPDATE_POSITION_BUSSINESS_NAME);
86 int32_t ret = assetRefresh.Update(changedRows, values, predicates);
87 CHECK_AND_RETURN_RET_LOG(ret == AccurateRefresh::ACCURATE_REFRESH_RET_OK, ret,
88 "Failed to UpdatePosition, ret: %{public}d.", ret);
89 CHECK_AND_PRINT_LOG(changedRows > 0, "UpdatePosition Check updateRows: %{public}d.", changedRows);
90 assetRefresh.Notify();
91 return ret;
92 }
93
UpdateSyncStatus(const std::string & cloudId,int32_t syncStatus)94 int32_t CloudMediaDataDao::UpdateSyncStatus(const std::string &cloudId, int32_t syncStatus)
95 {
96 MEDIA_INFO_LOG("enter UpdateSyncStatus, cloudId: %{public}s, syncStatus: %{public}d", cloudId.c_str(), syncStatus);
97 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
98 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "UpdateSyncStatus Failed to get rdbStore.");
99
100 NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
101 predicates.EqualTo(PhotoColumn::PHOTO_CLOUD_ID, cloudId);
102
103 NativeRdb::ValuesBucket values;
104 values.PutInt(PhotoColumn::PHOTO_SYNC_STATUS, syncStatus);
105
106 int32_t changedRows = DEFAULT_VALUE;
107 int32_t ret = rdbStore->Update(changedRows, values, predicates);
108 CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "Failed to UpdateSyncStatus, ret: %{public}d.", ret);
109 CHECK_AND_PRINT_LOG(changedRows > 0, "UpdateSyncStatus Check updateRows: %{public}d.", changedRows);
110 return ret;
111 }
112
UpdateThmStatus(const std::string & cloudId,int32_t thmStatus)113 int32_t CloudMediaDataDao::UpdateThmStatus(const std::string &cloudId, int32_t thmStatus)
114 {
115 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
116 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Failed to get rdbStore.");
117
118 NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
119 predicates.EqualTo(PhotoColumn::PHOTO_CLOUD_ID, cloudId);
120
121 NativeRdb::ValuesBucket values;
122 values.PutInt(PhotoColumn::PHOTO_THUMB_STATUS, thmStatus);
123
124 int32_t changedRows = DEFAULT_VALUE;
125 int32_t ret = rdbStore->Update(changedRows, values, predicates);
126 CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "Failed to UpdateThmStatusForCloudCheck, ret: %{public}d", ret);
127 CHECK_AND_PRINT_LOG(changedRows > 0, "Check updateRows: %{public}d.", changedRows);
128 return ret;
129 }
130
QueryFilePosStat(const int32_t position,int & num)131 int32_t CloudMediaDataDao::QueryFilePosStat(const int32_t position, int &num)
132 {
133 MEDIA_INFO_LOG("enter QueryFilePosStat, position: %{public}d", position);
134 num = 0;
135 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
136 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "QueryFilePosStat Failed to get rdbStore.");
137 NativeRdb::AbsRdbPredicates queryPredicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
138 queryPredicates.EqualTo(PhotoColumn::PHOTO_POSITION, std::to_string(position));
139 std::vector<std::string> queryColums = {"COUNT(1) AS count"};
140 auto resultSet = rdbStore->Query(queryPredicates, queryColums);
141 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
142 MEDIA_ERR_LOG("resultSet is null or failed to get row");
143 return E_RDB;
144 }
145 num = GetInt32Val("count", resultSet);
146 resultSet->Close();
147 MEDIA_INFO_LOG("QueryFilePosStat end %{public}d", num);
148 return E_OK;
149 }
150
QueryCloudThmStat(const int32_t cloudThmStat,int & num)151 int32_t CloudMediaDataDao::QueryCloudThmStat(const int32_t cloudThmStat, int &num)
152 {
153 MEDIA_INFO_LOG("enter QueryCloudThmStat, cloudThmStat: %{public}d", cloudThmStat);
154 num = 0;
155 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
156 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "QueryCloudThmStat Failed to get rdbStore.");
157 NativeRdb::AbsRdbPredicates queryPredicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
158 queryPredicates.EqualTo(PhotoColumn::PHOTO_THUMB_STATUS, cloudThmStat)
159 ->And()
160 ->BeginWrap()
161 ->EqualTo(PhotoColumn::PHOTO_POSITION, static_cast<int32_t>(PhotoPositionType::CLOUD))
162 ->Or()
163 ->EqualTo(PhotoColumn::PHOTO_POSITION, static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD))
164 ->EndWrap();
165 std::vector<std::string> queryColums = {"COUNT(1) AS count"};
166 auto resultSet = rdbStore->Query(queryPredicates, queryColums);
167 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
168 MEDIA_ERR_LOG("resultSet is null or failed to get row");
169 return E_RDB;
170 }
171 num = GetInt32Val("count", resultSet);
172 resultSet->Close();
173 MEDIA_INFO_LOG("QueryCloudThmStat end %{public}d", num);
174 return E_OK;
175 }
176
QueryDirtyTypeStat(const int32_t dirtyType,int64_t & num)177 int32_t CloudMediaDataDao::QueryDirtyTypeStat(const int32_t dirtyType, int64_t &num)
178 {
179 num = 0;
180 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
181 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Failed to get rdbStore.");
182 NativeRdb::AbsRdbPredicates queryPredicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
183 queryPredicates.EqualTo(PhotoColumn::PHOTO_DIRTY, std::to_string(dirtyType));
184 vector<string> queryColums = {"COUNT(1) AS count"};
185 auto resultSet = rdbStore->Query(queryPredicates, queryColums);
186 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
187 MEDIA_ERR_LOG("resultSet is null or failed to get row");
188 return E_RDB;
189 }
190 num = GetInt64Val("count", resultSet);
191 resultSet->Close();
192 MEDIA_INFO_LOG("QueryDirtyTypeStat, dirtyType: %{public}d, num: %{public}" PRIu64, dirtyType, num);
193 return E_OK;
194 }
195
InitDirtyTypeStat(std::vector<uint64_t> & dirtyTypeStat)196 void CloudMediaDataDao::InitDirtyTypeStat(std::vector<uint64_t> &dirtyTypeStat)
197 {
198 dirtyTypeStat.clear();
199 for (int32_t i = 0; i < DIRTY_TYPE_STAT_SIZE; i++) {
200 dirtyTypeStat.push_back(0);
201 }
202 return;
203 }
204
GetDirtyTypeStat(std::vector<uint64_t> & dirtyTypeStat,const int32_t dirtyType)205 int32_t CloudMediaDataDao::GetDirtyTypeStat(std::vector<uint64_t> &dirtyTypeStat, const int32_t dirtyType)
206 {
207 CHECK_AND_RETURN_RET_LOG(0 <= dirtyType && dirtyType < DIRTY_TYPE_STAT_SIZE,
208 E_INVAL_ARG,
209 "dirtyType is invalid, dirtyType: %{public}d",
210 dirtyType);
211 CHECK_AND_EXECUTE(
212 static_cast<int32_t>(dirtyTypeStat.size()) == DIRTY_TYPE_STAT_SIZE, InitDirtyTypeStat(dirtyTypeStat));
213 int64_t num = 0;
214 int32_t ret = this->QueryDirtyTypeStat(dirtyType, num);
215 CHECK_AND_RETURN_RET_LOG(
216 ret == E_OK, ret, "Failed to GetDirtyTypeStat, dirtyType: %{public}d, ret: %{public}d", dirtyType, ret);
217 dirtyTypeStat[dirtyType] = static_cast<uint64_t>(num);
218 return E_OK;
219 }
220
GetDirtyTypeStat(std::vector<uint64_t> & dirtyTypeStat)221 int32_t CloudMediaDataDao::GetDirtyTypeStat(std::vector<uint64_t> &dirtyTypeStat)
222 {
223 int32_t ret = E_OK;
224 for (int32_t i = 0; i < DIRTY_TYPE_STAT_SIZE; i++) {
225 ret = this->GetDirtyTypeStat(dirtyTypeStat, i);
226 CHECK_AND_RETURN_RET_LOG(
227 ret == E_OK, ret, "Failed to GetDirtyTypeStat, ret: %{public}d, dirtyType: %{public}d", ret, i);
228 }
229 MEDIA_INFO_LOG(
230 "GetDirtyTypeStat, dirtyTypeStat: %{public}s", CloudMediaDaoUtils::VectorToString(dirtyTypeStat).c_str());
231 return E_OK;
232 }
233
GetVideoToCache(std::vector<PhotosPo> & photosPos)234 int32_t CloudMediaDataDao::GetVideoToCache(std::vector<PhotosPo> &photosPos)
235 {
236 MEDIA_INFO_LOG("GetVideoToCache begin");
237 std::vector<PhotosDto> photosDtoVec;
238 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
239 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Failed to get rdbStore.");
240 NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
241 predicates.EqualTo(PhotoColumn::MEDIA_TYPE, static_cast<int32_t>(MediaType::MEDIA_TYPE_VIDEO));
242 predicates.EqualTo(PhotoColumn::PHOTO_POSITION, static_cast<int32_t>(PhotoPositionType::CLOUD));
243 predicates.OrderByDesc(PhotoColumn::MEDIA_DATE_TAKEN);
244 predicates.Limit(CACHE_VIDEO_NUM);
245 auto resultSet = rdbStore->Query(predicates, this->COLUMNS_VIDEO_CACHE_QUERY);
246 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_RESULT_SET_NULL, "Failed to query.");
247
248 int32_t ret = ResultSetReader<PhotosPoWriter, PhotosPo>(resultSet).ReadRecords(photosPos);
249 CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "GetVideoToCache Failed to query, ret: %{public}d", ret);
250 return E_OK;
251 }
252
GetAgingFile(const AgingFileQueryDto & queryDto,std::vector<PhotosPo> & photosPos)253 int32_t CloudMediaDataDao::GetAgingFile(const AgingFileQueryDto &queryDto, std::vector<PhotosPo> &photosPos)
254 {
255 int64_t time = queryDto.time;
256 int32_t mediaType = queryDto.mediaType;
257 int32_t sizeLimit = queryDto.sizeLimit;
258 auto currentTime = MediaFileUtils::UTCTimeSeconds();
259 MEDIA_INFO_LOG("enter GetAgingFile, queryDto: %{public}s", queryDto.ToString().c_str());
260 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
261 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Failed to get rdbStore.");
262 NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
263 if (mediaType != -1) {
264 predicates.EqualTo(MediaColumn::MEDIA_TYPE, mediaType);
265 }
266 std::string timeRangeCon = std::to_string(TO_MILLISECONDS * (currentTime - time));
267 predicates.LessThanOrEqualTo(PhotoColumn::PHOTO_LAST_VISIT_TIME, timeRangeCon);
268 predicates.And()->LessThanOrEqualTo(MediaColumn::MEDIA_DATE_TAKEN, timeRangeCon);
269 predicates.And()->EqualTo(PhotoColumn::PHOTO_POSITION, static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD));
270 predicates.OrderByAsc(PhotoColumn::PHOTO_LAST_VISIT_TIME);
271 predicates.Limit(sizeLimit);
272 const std::vector<std::string> columns = {};
273 auto resultSet = rdbStore->Query(predicates, columns);
274 int32_t ret = ResultSetReader<PhotosPoWriter, PhotosPo>(resultSet).ReadRecords(photosPos);
275 CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "GetAgingFile Failed to query, ret: %{public}d", ret);
276 return E_OK;
277 }
278
GetActiveAgingFile(const AgingFileQueryDto & queryDto,std::vector<PhotosPo> & photosPos)279 int32_t CloudMediaDataDao::GetActiveAgingFile(const AgingFileQueryDto &queryDto, std::vector<PhotosPo> &photosPos)
280 {
281 int64_t time = queryDto.time;
282 int32_t mediaType = queryDto.mediaType;
283 int32_t sizeLimit = queryDto.sizeLimit;
284 auto currentTime = MediaFileUtils::UTCTimeSeconds();
285 MEDIA_INFO_LOG("enter GetActiveAgingFile, queryDto: %{public}s", queryDto.ToString().c_str());
286 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
287 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Failed to get rdbStore.");
288
289 NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
290 if (mediaType != -1) {
291 predicates.EqualTo(MediaColumn::MEDIA_TYPE, mediaType);
292 }
293 std::string timeRangeCon = std::to_string(TO_MILLISECONDS * (currentTime - time));
294 predicates.LessThanOrEqualTo(PhotoColumn::PHOTO_LAST_VISIT_TIME, timeRangeCon);
295 predicates.And()->LessThanOrEqualTo(MediaColumn::MEDIA_DATE_TAKEN, timeRangeCon);
296 predicates.And()->EqualTo(PhotoColumn::PHOTO_POSITION, static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD));
297 predicates.And()->EqualTo(PhotoColumn::MEDIA_HIDDEN, 0); // 非隐藏文件
298 predicates.OrderByAsc(PhotoColumn::PHOTO_LAST_VISIT_TIME);
299 predicates.Limit(sizeLimit);
300 const std::vector<std::string> columns = {};
301 auto resultSet = rdbStore->Query(predicates, columns);
302 int32_t ret = ResultSetReader<PhotosPoWriter, PhotosPo>(resultSet).ReadRecords(photosPos);
303 CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "GetActiveAgingFile Failed to query, ret: %{public}d", ret);
304 return E_OK;
305 }
306
UpdateLocalFileDirty(std::string & cloudId)307 int32_t CloudMediaDataDao::UpdateLocalFileDirty(std::string &cloudId)
308 {
309 MEDIA_INFO_LOG("enter UpdateLocalFileDirty");
310 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
311 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "UpdateLocalFileDirty get store failed.");
312 NativeRdb::ValuesBucket valuesBucket;
313 valuesBucket.PutInt(PhotoColumn::PHOTO_DIRTY, static_cast<int32_t>(DirtyType::TYPE_FDIRTY));
314 int32_t changedRows;
315 int32_t ret = rdbStore->Update(
316 changedRows, PhotoColumn::PHOTOS_TABLE, valuesBucket, PhotoColumn::PHOTO_CLOUD_ID + " = ?", {cloudId});
317 MEDIA_INFO_LOG("UpdateLocalFileDirty changedRows: %{public}d, ret: %{public}d", changedRows, ret);
318 return ret;
319 }
320 } // namespace OHOS::Media::CloudSync