1 /*
2 * Copyright (C) 2022 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 #define MLOG_TAG "ObjectUtils"
16
17 #include "medialibrary_object_utils.h"
18
19 #include <cerrno>
20
21 #include "album_asset.h"
22 #include "datashare_predicates.h"
23 #include "directory_ex.h"
24 #include "fetch_result.h"
25 #include "media_file_utils.h"
26 #include "media_log.h"
27 #include "media_privacy_manager.h"
28 #include "media_scanner_manager.h"
29 #include "medialibrary_data_manager.h"
30 #include "medialibrary_data_manager_utils.h"
31 #include "medialibrary_dir_operations.h"
32 #include "medialibrary_errno.h"
33 #include "medialibrary_smartalbum_map_db.h"
34 #include "result_set_utils.h"
35 #include "thumbnail_service.h"
36 #include "value_object.h"
37
38 using namespace std;
39 using namespace OHOS::NativeRdb;
40
41 namespace OHOS {
42 namespace Media {
43 static const string NO_MEDIA_TAG = ".nomedia";
CreateDirWithPath(const string & dirPath)44 int32_t MediaLibraryObjectUtils::CreateDirWithPath(const string &dirPath)
45 {
46 if (dirPath.empty()) {
47 return E_INVALID_PATH;
48 }
49
50 int64_t rowId = -1;
51 ValuesBucket values;
52 values.PutString(MEDIA_DATA_DB_FILE_PATH, dirPath);
53 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ALBUM, OperationType::CREATE, values);
54 int32_t ret = CreateDirObj(cmd, rowId);
55 if (ret == E_FILE_EXIST || ret == E_SUCCESS) {
56 return rowId;
57 }
58 return ret;
59 }
60
GetDirAsset(const string & path)61 NativeAlbumAsset MediaLibraryObjectUtils::GetDirAsset(const string &path)
62 {
63 NativeAlbumAsset dirAsset;
64 if (path.empty()) {
65 MEDIA_ERR_LOG("Path is empty, create failed!");
66 dirAsset.SetAlbumId(E_INVALID_PATH);
67 return dirAsset;
68 }
69
70 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
71 if (uniStore == nullptr) {
72 MEDIA_ERR_LOG("uniStore is nullptr!");
73 dirAsset.SetAlbumId(E_HAS_DB_ERROR);
74 return dirAsset;
75 }
76
77 int32_t dirId = CreateDirWithPath(path);
78 MEDIA_DEBUG_LOG("After CreateDirWithPath, get dirId = %{private}d!", dirId);
79 dirAsset.SetAlbumId(dirId);
80 if (dirId < 0) {
81 return dirAsset;
82 }
83
84 string nameVal = GetStringColumnByIdFromDb(to_string(dirId), MEDIA_DATA_DB_NAME);
85 if (nameVal.empty()) {
86 MEDIA_ERR_LOG("Get dir name failed!");
87 return dirAsset;
88 }
89 dirAsset.SetAlbumName(nameVal);
90 MEDIA_DEBUG_LOG("bucketId = %{private}d bucketName = %{private}s", dirId, nameVal.c_str());
91 return dirAsset;
92 }
93
DeleteInvalidRowInDb(const string & path)94 int32_t MediaLibraryObjectUtils::DeleteInvalidRowInDb(const string &path)
95 {
96 if (GetIdByPathFromDb(path) < 0) {
97 // path is not in database, no need to delete
98 return E_SUCCESS;
99 }
100
101 FileAsset fileAsset;
102 if (fileAsset.IsFileExists(path)) {
103 // File aready exist, not need to create again
104 return E_SUCCESS;
105 }
106
107 MediaLibraryCommand deleteCmd(OperationObject::FILESYSTEM_ASSET, OperationType::DELETE);
108 if (DeleteInfoByPathInDb(deleteCmd, path) != E_SUCCESS) {
109 // Delete the record in database if file is not in filesystem any more
110 MEDIA_ERR_LOG("CreateFileAsset: delete info in db failed");
111 return E_DELETE_DIR_FAIL;
112 }
113 return E_SUCCESS;
114 }
115
InsertFileInDb(MediaLibraryCommand & cmd,const FileAsset & fileAsset,const NativeAlbumAsset & dirAsset)116 int32_t MediaLibraryObjectUtils::InsertFileInDb(MediaLibraryCommand &cmd,
117 const FileAsset &fileAsset, const NativeAlbumAsset &dirAsset)
118 {
119 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
120 if (uniStore == nullptr) {
121 MEDIA_ERR_LOG("uniStore is nullptr!");
122 return E_HAS_DB_ERROR;
123 }
124
125 // Fill basic file information into DB
126 string displayName = fileAsset.GetDisplayName();
127 ValuesBucket assetInfo;
128 assetInfo.PutInt(MEDIA_DATA_DB_MEDIA_TYPE, fileAsset.GetMediaType());
129 assetInfo.PutString(MEDIA_DATA_DB_URI, MediaLibraryDataManagerUtils::GetMediaTypeUri(fileAsset.GetMediaType()));
130 string extension = ScannerUtils::GetFileExtensionFromFileUri(displayName);
131 assetInfo.PutString(MEDIA_DATA_DB_MIME_TYPE, ScannerUtils::GetMimeTypeFromExtension(extension));
132 assetInfo.PutString(MEDIA_DATA_DB_RELATIVE_PATH, fileAsset.GetRelativePath());
133 assetInfo.PutString(MEDIA_DATA_DB_NAME, displayName);
134 assetInfo.PutString(MEDIA_DATA_DB_TITLE, MediaLibraryDataManagerUtils::GetFileTitle(displayName));
135 struct stat statInfo {};
136 if (stat(fileAsset.GetPath().c_str(), &statInfo) == 0) {
137 assetInfo.PutLong(MEDIA_DATA_DB_SIZE, statInfo.st_size);
138 assetInfo.PutLong(MEDIA_DATA_DB_DATE_ADDED, MediaFileUtils::UTCTimeSeconds());
139 assetInfo.PutLong(MEDIA_DATA_DB_DATE_MODIFIED, statInfo.st_mtime);
140 }
141 assetInfo.PutString(MEDIA_DATA_DB_FILE_PATH, fileAsset.GetPath());
142 assetInfo.PutInt(MEDIA_DATA_DB_BUCKET_ID, dirAsset.GetAlbumId());
143 assetInfo.PutInt(MEDIA_DATA_DB_PARENT_ID, dirAsset.GetAlbumId());
144 assetInfo.PutString(MEDIA_DATA_DB_BUCKET_NAME, dirAsset.GetAlbumName());
145 cmd.SetValueBucket(assetInfo);
146 int64_t outRowId = -1;
147 int32_t errCode = uniStore->Insert(cmd, outRowId);
148 return (errCode == NativeRdb::E_OK) ? outRowId : errCode;
149 }
150
GetRelativePathFromValues(ValuesBucket & values,string & relativePath,int32_t mediaType)151 void GetRelativePathFromValues(ValuesBucket &values, string &relativePath, int32_t mediaType)
152 {
153 ValueObject valueObject;
154 if (values.GetObject(MEDIA_DATA_DB_RELATIVE_PATH, valueObject)) {
155 valueObject.GetString(relativePath);
156 return;
157 }
158 if (values.GetObject(MEDIA_DATA_DB_URI, valueObject)) {
159 string albumUri;
160 valueObject.GetString(albumUri);
161 auto albumAsset = MediaLibraryObjectUtils::GetFileAssetFromDb(albumUri);
162 if (albumAsset != nullptr) {
163 relativePath = albumAsset->GetRelativePath() + albumAsset->GetDisplayName() + SLASH_CHAR;
164 }
165 } else {
166 MediaLibraryObjectUtils::GetDefaultRelativePath(mediaType, relativePath);
167 }
168 }
169
170 // create
CreateFileObj(MediaLibraryCommand & cmd)171 int32_t MediaLibraryObjectUtils::CreateFileObj(MediaLibraryCommand &cmd)
172 {
173 string relativePath;
174 string path;
175 string displayName;
176 int32_t mediaType = static_cast<int32_t>(MEDIA_TYPE_FILE);
177 FileAsset fileAsset;
178 ValueObject valueObject;
179 ValuesBucket &values = cmd.GetValueBucket();
180 if (values.GetObject(MEDIA_DATA_DB_NAME, valueObject)) {
181 valueObject.GetString(displayName);
182 fileAsset.SetDisplayName(displayName);
183 }
184
185 if (values.GetObject(MEDIA_DATA_DB_MEDIA_TYPE, valueObject)) {
186 valueObject.GetInt(mediaType);
187 fileAsset.SetMediaType(static_cast<MediaType>(mediaType));
188 }
189
190 GetRelativePathFromValues(values, relativePath, mediaType);
191 if (!relativePath.empty()) {
192 values.PutString(MEDIA_DATA_DB_RELATIVE_PATH, relativePath);
193 path = ROOT_MEDIA_DIR + relativePath + displayName;
194 fileAsset.SetRelativePath(relativePath);
195 fileAsset.SetPath(path);
196 }
197
198 MediaLibraryDirOperations dirOprn;
199 int32_t errCode = dirOprn.HandleDirOperations(MEDIA_DIROPRN_CHECKDIR_AND_EXTENSION, values,
200 MediaLibraryDataManager::GetInstance()->rdbStore_, MediaLibraryDataManager::GetInstance()->GetDirQuerySetMap());
201 if (errCode != E_SUCCESS) {
202 return errCode;
203 }
204
205 NativeAlbumAsset dirAsset = GetDirAsset(ROOT_MEDIA_DIR + relativePath);
206 if (dirAsset.GetAlbumId() < 0) {
207 return dirAsset.GetAlbumId();
208 }
209
210 // delete rows in database but not in real filesystem
211 errCode = DeleteInvalidRowInDb(path);
212 if (errCode != E_SUCCESS) {
213 MEDIA_ERR_LOG("Delete invalid row in database failed");
214 return errCode;
215 }
216
217 errCode = fileAsset.CreateAsset(path);
218 if (errCode != E_SUCCESS) {
219 MEDIA_ERR_LOG("CreateFileAsset: create file asset failed");
220 return errCode;
221 }
222
223 return InsertFileInDb(cmd, fileAsset, dirAsset);
224 }
225
GetLastDirExistInDb(const std::string & dirPath)226 NativeAlbumAsset MediaLibraryObjectUtils::GetLastDirExistInDb(const std::string &dirPath)
227 {
228 MEDIA_DEBUG_LOG("enter");
229 NativeAlbumAsset dirAsset;
230 string lastPath = dirPath;
231 if (lastPath.back() == '/') {
232 lastPath.pop_back();
233 }
234 int32_t dirId = 0;
235 int32_t lastPathId = -1;
236 do {
237 size_t slashIndex = lastPath.rfind(SLASH_CHAR);
238 if (slashIndex == string::npos || lastPath.length() <= ROOT_MEDIA_DIR.length()) {
239 break;
240 }
241 lastPath = lastPath.substr(0, slashIndex);
242 lastPathId = GetIdByPathFromDb(lastPath);
243 if (lastPathId >= 0) {
244 dirId = lastPathId;
245 }
246 } while (lastPathId < 0);
247 MEDIA_INFO_LOG("GetLastAlbumExistInDb lastPath = %{private}s", lastPath.c_str());
248 dirAsset.SetAlbumId(dirId);
249 dirAsset.SetAlbumPath(lastPath);
250 return dirAsset;
251 }
252
DeleteRows(const std::vector<int64_t> & rowIds)253 int32_t MediaLibraryObjectUtils::DeleteRows(const std::vector<int64_t> &rowIds)
254 {
255 int32_t errCode = 0;
256
257 for (auto id : rowIds) {
258 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::DELETE);
259 errCode = DeleteInfoByIdInDb(cmd, to_string(id));
260 }
261 return errCode;
262 }
263
SetDirValuesByPath(ValuesBucket & values,const string & path,int32_t parentId)264 int32_t SetDirValuesByPath(ValuesBucket &values, const string &path, int32_t parentId)
265 {
266 string title = MediaLibraryDataManagerUtils::GetFileName(path);
267 if (!MediaFileUtils::CheckDisplayName(title)) {
268 MEDIA_ERR_LOG("Check display name failed!");
269 return E_INVAVLID_DISPLAY_NAME;
270 }
271
272 string relativePath;
273 string parentPath = MediaLibraryDataManagerUtils::GetParentPath(path);
274 if (parentPath.length() > ROOT_MEDIA_DIR.length()) {
275 relativePath = parentPath.substr(ROOT_MEDIA_DIR.length()) + "/";
276 }
277
278 values.PutString(MEDIA_DATA_DB_FILE_PATH, path);
279 values.PutString(MEDIA_DATA_DB_RELATIVE_PATH, relativePath);
280 values.PutString(MEDIA_DATA_DB_TITLE, title);
281 values.PutString(MEDIA_DATA_DB_NAME, title);
282 values.PutInt(MEDIA_DATA_DB_MEDIA_TYPE, MediaType::MEDIA_TYPE_ALBUM);
283 values.PutInt(MEDIA_DATA_DB_PARENT_ID, parentId);
284 values.PutLong(MEDIA_DATA_DB_DATE_ADDED, MediaFileUtils::UTCTimeSeconds());
285
286 struct stat statInfo {};
287 if (stat(path.c_str(), &statInfo) == 0) {
288 values.PutLong(MEDIA_DATA_DB_SIZE, statInfo.st_size);
289 values.PutLong(MEDIA_DATA_DB_DATE_MODIFIED, statInfo.st_mtime);
290 }
291 return E_SUCCESS;
292 }
293
InsertDirToDbRecursively(const std::string & dirPath,int64_t & rowId)294 int32_t MediaLibraryObjectUtils::InsertDirToDbRecursively(const std::string &dirPath, int64_t &rowId)
295 {
296 CHECK_AND_RETURN_RET_LOG(!dirPath.empty(), E_VIOLATION_PARAMETERS, "Input parameter dirPath is empty!");
297
298 NativeAlbumAsset dirAsset = GetLastDirExistInDb(dirPath);
299 string parentPath = dirAsset.GetAlbumPath();
300 int32_t parentId = dirAsset.GetAlbumId();
301 if ((parentId == 0) && ((parentPath + "/") != ROOT_MEDIA_DIR)) {
302 return E_INVALID_PATH;
303 }
304 vector<int64_t> outIds;
305 rowId = parentId;
306
307 string path = dirPath;
308 if (path.back() != '/') {
309 path.append("/");
310 }
311 while (parentPath.length() < (path.length() - 1)) {
312 size_t index = path.find("/", parentPath.length() + 1);
313 string currentPath = path.substr(0, index);
314 ValuesBucket values;
315 auto ret = SetDirValuesByPath(values, currentPath, parentId);
316 if (ret == E_INVAVLID_DISPLAY_NAME) {
317 DeleteRows(outIds);
318 }
319 if (ret != E_SUCCESS) {
320 return ret;
321 }
322
323 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ALBUM, OperationType::CREATE, values);
324 rowId = InsertInDb(cmd);
325 if (rowId <= 0) {
326 rowId = parentId;
327 return E_HAS_DB_ERROR;
328 }
329 parentId = rowId;
330 parentPath = currentPath;
331 outIds.push_back(rowId);
332 }
333 return E_SUCCESS;
334 }
335
CreateDirObj(MediaLibraryCommand & cmd,int64_t & rowId)336 int32_t MediaLibraryObjectUtils::CreateDirObj(MediaLibraryCommand &cmd, int64_t &rowId)
337 {
338 MEDIA_DEBUG_LOG("enter");
339 string dirPath;
340 ValueObject valueObject;
341 const ValuesBucket &values = cmd.GetValueBucket();
342 if (values.GetObject(MEDIA_DATA_DB_FILE_PATH, valueObject)) {
343 valueObject.GetString(dirPath);
344 }
345 if (dirPath.empty()) {
346 MEDIA_ERR_LOG("Dir path is empty!");
347 return E_INVALID_PATH;
348 }
349
350 AlbumAsset dirAsset;
351 dirAsset.SetAlbumPath(dirPath);
352 rowId = GetIdByPathFromDb(dirPath);
353 MEDIA_DEBUG_LOG("dirPath %{private}s id in database is %{private}d", dirPath.c_str(), static_cast<int>(rowId));
354 if (rowId < 0) {
355 if (!dirAsset.CreateAlbumAsset()) {
356 return E_FAIL;
357 }
358 return InsertDirToDbRecursively(dirPath, rowId);
359 }
360
361 if (!MediaFileUtils::IsDirectory(dirPath)) {
362 dirAsset.CreateAlbumAsset();
363 return E_SUCCESS;
364 }
365 return E_FILE_EXIST;
366 }
367
DeleteEmptyDirsRecursively(int32_t dirId)368 int32_t MediaLibraryObjectUtils::DeleteEmptyDirsRecursively(int32_t dirId)
369 {
370 if (dirId <= 0) {
371 return E_INVALID_FILEID;
372 }
373 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
374 if (uniStore == nullptr) {
375 MEDIA_ERR_LOG("uniStore is nullptr!");
376 return E_HAS_DB_ERROR;
377 }
378
379 int err = E_ERR;
380 const int32_t MAX_DIR_DEPTH = 15;
381 int depth = 0;
382 while ((depth++ < MAX_DIR_DEPTH) && (dirId > 0)) {
383 if (IsColumnValueExist(to_string(dirId), MEDIA_DATA_DB_PARENT_ID)) {
384 return E_SUCCESS;
385 }
386
387 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
388 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_ID, to_string(dirId));
389 auto queryParentResultSet = uniStore->Query(cmd, {});
390 if (queryParentResultSet->GoToNextRow() != NativeRdb::E_OK) {
391 return E_SUCCESS;
392 }
393 int32_t colIndex = 0;
394 int32_t parentIdVal = 0;
395 string dirVal;
396 queryParentResultSet->GetColumnIndex(MEDIA_DATA_DB_PARENT_ID, colIndex);
397 queryParentResultSet->GetInt(colIndex, parentIdVal);
398 queryParentResultSet->GetColumnIndex(MEDIA_DATA_DB_FILE_PATH, colIndex);
399 queryParentResultSet->GetString(colIndex, dirVal);
400 if (parentIdVal == 0) {
401 return E_SUCCESS;
402 }
403 MEDIA_DEBUG_LOG("dirVal = %{private}s, parentIdVal = %{public}d", dirVal.c_str(), parentIdVal);
404
405 // Do not delete user created dir
406 if (MediaFileUtils::IsFileExists(dirVal + "/" + ".nofile")) {
407 return E_SUCCESS;
408 }
409 if (!MediaFileUtils::IsDirEmpty(dirVal)) {
410 return E_SUCCESS;
411 }
412
413 if (!MediaFileUtils::DeleteDir(dirVal)) {
414 MEDIA_ERR_LOG("Delete dir in filesystem failed, errno = %{public}d", errno);
415 err = E_HAS_FS_ERROR;
416 break;
417 }
418 MediaLibraryCommand deleteDirCmd(OperationObject::FILESYSTEM_DIR, OperationType::DELETE);
419 int32_t deletedRows = DeleteInfoByIdInDb(deleteDirCmd, to_string(dirId));
420 if (deletedRows < 0) {
421 MEDIA_ERR_LOG("Delete dir info failed, err: %{public}d", deletedRows);
422 err = deletedRows;
423 break;
424 } else if (deletedRows == 0) {
425 MEDIA_ERR_LOG("Failed to delete dir in db!");
426 return E_HAS_DB_ERROR;
427 }
428 dirId = parentIdVal;
429 }
430 return err;
431 }
432
InvalidateThumbnail(const string & id)433 static inline void InvalidateThumbnail(const string &id)
434 {
435 auto thumbnailService = ThumbnailService::GetInstance();
436 if (thumbnailService != nullptr) {
437 thumbnailService->InvalidateThumbnail(id);
438 }
439 }
440
GetFileInfoById(const string & fileId,int32_t & mediaType,int32_t & isTrash)441 bool GetFileInfoById(const string &fileId, int32_t &mediaType, int32_t &isTrash)
442 {
443 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
444 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_ID, fileId);
445 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
446 if (uniStore == nullptr) {
447 MEDIA_ERR_LOG("uniStore is nullptr!");
448 return E_HAS_DB_ERROR;
449 }
450 auto result = uniStore->Query(cmd, {});
451 if (result->GoToFirstRow() != NativeRdb::E_OK) {
452 return false;
453 }
454 int32_t colIndex = 0;
455 CHECK_AND_RETURN_RET_LOG(result->GetColumnIndex(MEDIA_DATA_DB_MEDIA_TYPE, colIndex) == NativeRdb::E_OK, false,
456 "failed to obtain the index");
457 CHECK_AND_RETURN_RET_LOG(result->GetInt(colIndex, mediaType) == NativeRdb::E_OK, false,
458 "get media_type failed");
459 CHECK_AND_RETURN_RET_LOG(result->GetColumnIndex(MEDIA_DATA_DB_IS_TRASH, colIndex) == NativeRdb::E_OK, false,
460 "failed to obtain the index");
461 CHECK_AND_RETURN_RET_LOG(result->GetInt(colIndex, isTrash) == NativeRdb::E_OK, false,
462 "get is_trash failed");
463 return true;
464 }
465
DeleteInfoRecursively(const string & fileId)466 bool DeleteInfoRecursively(const string &fileId)
467 {
468 int32_t mediaType = MEDIA_TYPE_ALL;
469 int32_t isTrash = -1;
470 if (!GetFileInfoById(fileId, mediaType, isTrash)) {
471 return false;
472 }
473 if (mediaType == MEDIA_TYPE_ALBUM) {
474 MediaLibraryCommand queryCmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
475 queryCmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_PARENT_ID, fileId);
476 if (isTrash == NOT_ISTRASH) {
477 queryCmd.GetAbsRdbPredicates()->And()->EqualTo(MEDIA_DATA_DB_IS_TRASH, to_string(NOT_ISTRASH));
478 } else {
479 queryCmd.GetAbsRdbPredicates()->And()->EqualTo(MEDIA_DATA_DB_IS_TRASH, to_string(CHILD_ISTRASH));
480 }
481 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
482 if (uniStore == nullptr) {
483 MEDIA_ERR_LOG("uniStore is nullptr!");
484 return E_HAS_DB_ERROR;
485 }
486 auto result = uniStore->Query(queryCmd, {});
487 while (result->GoToNextRow() == NativeRdb::E_OK) {
488 int32_t colIndex = 0;
489 int32_t childId = -1;
490 CHECK_AND_RETURN_RET_LOG(result->GetColumnIndex(MEDIA_DATA_DB_ID, colIndex) == NativeRdb::E_OK, false,
491 "failed to obtain the index");
492 CHECK_AND_RETURN_RET_LOG(result->GetInt(colIndex, childId) == NativeRdb::E_OK, false,
493 "get file_id failed");
494 if (!DeleteInfoRecursively(to_string(childId))) {
495 return false;
496 }
497 }
498 }
499
500 InvalidateThumbnail(fileId);
501 MediaLibraryCommand deleteCmd(Uri(MEDIALIBRARY_DATA_URI), OperationType::DELETE);
502 int32_t deleteRows = MediaLibraryObjectUtils::DeleteInfoByIdInDb(deleteCmd, fileId);
503 if (deleteRows <= 0) {
504 MEDIA_ERR_LOG("Delete file info in database failed, file_id: %{public}s", fileId.c_str());
505 return false;
506 }
507 return true;
508 }
509
510 // Restriction: input param cmd MUST have file id in either uri or valuebucket
DeleteFileObj(MediaLibraryCommand & cmd,const string & filePath)511 int32_t MediaLibraryObjectUtils::DeleteFileObj(MediaLibraryCommand &cmd, const string &filePath)
512 {
513 MEDIA_DEBUG_LOG("enter");
514 FileAsset fileAsset;
515 int32_t errCode = fileAsset.DeleteAsset(filePath);
516 if (errCode != E_SUCCESS) {
517 MEDIA_ERR_LOG("Delete file in filesystem failed!");
518 return errCode;
519 }
520 // must get parent id BEFORE deleting file in database
521 string fileId = cmd.GetOprnFileId();
522 if (fileId.empty()) {
523 MEDIA_ERR_LOG("Get id from uri or valuebucket failed!");
524 return E_INVALID_FILEID;
525 }
526
527 int32_t parentId = GetParentIdByIdFromDb(fileId);
528 if (!DeleteInfoRecursively(fileId)) {
529 MEDIA_ERR_LOG("Delete file info in database failed, file_id: %{public}s", fileId.c_str());
530 }
531
532 // if delete successfully, 1) update modify time
533 string dirPath = MediaLibraryDataManagerUtils::GetParentPath(filePath);
534 UpdateDateModified(dirPath);
535 // 2) recursively delete empty parent dirs
536 if (DeleteEmptyDirsRecursively(parentId) != E_SUCCESS) {
537 return E_DELETE_DIR_FAIL;
538 }
539 // 3) delete relative records in smart album
540 MediaLibraryCommand deleteSmartMapCmd(OperationObject::SMART_ALBUM_MAP, OperationType::DELETE);
541 deleteSmartMapCmd.GetAbsRdbPredicates()->EqualTo(SMARTALBUMMAP_DB_CHILD_ASSET_ID, fileId);
542 return DeleteInfoByIdInDb(deleteSmartMapCmd);
543 }
544
DeleteDirObj(MediaLibraryCommand & cmd,const string & dirPath)545 int32_t MediaLibraryObjectUtils::DeleteDirObj(MediaLibraryCommand &cmd, const string &dirPath)
546 {
547 MEDIA_DEBUG_LOG("enter, path = %{private}s", dirPath.c_str());
548 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
549 if (uniStore == nullptr) {
550 MEDIA_ERR_LOG("uniStore is nullptr!");
551 return E_HAS_DB_ERROR;
552 }
553
554 AlbumAsset dirAsset;
555 if (!dirAsset.DeleteAlbumAsset(dirPath)) {
556 MEDIA_ERR_LOG("Delete album asset failed!");
557 return E_DELETE_DIR_FAIL;
558 }
559
560 int32_t parentId = GetParentIdByIdFromDb(cmd.GetOprnFileId());
561 int32_t deleteRows = DeleteInfoByIdInDb(cmd);
562 if (deleteRows <= 0) {
563 MEDIA_ERR_LOG("Delete album info in database failed!");
564 return E_DELETE_DIR_FAIL;
565 }
566 // need to delete subfiles in the album when deleting album, delete: xx/xxx/album_name/%
567 MediaLibraryCommand deleteSubfilesCmd(OperationObject::FILESYSTEM_ASSET, OperationType::DELETE);
568 string pathPrefix = dirPath.back() != '/' ? (dirPath + "/") : dirPath;
569 deleteSubfilesCmd.GetAbsRdbPredicates()->BeginsWith(MEDIA_DATA_DB_FILE_PATH, pathPrefix);
570
571 int32_t deletedRows = -1;
572 int32_t deleteResult = uniStore->Delete(deleteSubfilesCmd, deletedRows);
573 if (deleteResult != NativeRdb::E_OK) {
574 MEDIA_ERR_LOG("Delete subfiles in album %{private}s failed", pathPrefix.c_str());
575 return deleteResult;
576 }
577 if (DeleteEmptyDirsRecursively(parentId) != E_SUCCESS) {
578 return E_DELETE_DIR_FAIL;
579 }
580 return deleteRows;
581 }
582
583 // Restriction: input param cmd MUST have id in uri
RenameFileObj(MediaLibraryCommand & cmd,const string & srcFilePath,const string & dstFilePath)584 int32_t MediaLibraryObjectUtils::RenameFileObj(MediaLibraryCommand &cmd,
585 const string &srcFilePath, const string &dstFilePath)
586 {
587 MEDIA_DEBUG_LOG("enter, srcFilePath = %{private}s, dstFilePath = %{private}s",
588 srcFilePath.c_str(), dstFilePath.c_str());
589 if (srcFilePath.empty() || dstFilePath.empty()) {
590 MEDIA_ERR_LOG("srcFilePath or dstFilePath is empty, rename failed!");
591 return E_INVALID_PATH;
592 }
593 if (srcFilePath.compare(dstFilePath) == 0) {
594 MEDIA_DEBUG_LOG("Skip modify the file, the path of new file is the same as old");
595 return E_SUCCESS;
596 }
597
598 MediaLibraryDirOperations dirOprn;
599 int32_t errCode = dirOprn.HandleDirOperations(MEDIA_DIROPRN_CHECKDIR_AND_EXTENSION, cmd.GetValueBucket(),
600 MediaLibraryDataManager::GetInstance()->rdbStore_, MediaLibraryDataManager::GetInstance()->GetDirQuerySetMap());
601 if (errCode != E_SUCCESS) {
602 return errCode;
603 }
604
605 string dstAlbumPath = MediaLibraryDataManagerUtils::GetParentPath(dstFilePath);
606 NativeAlbumAsset dirAsset = GetDirAsset(dstAlbumPath);
607 if (dirAsset.GetAlbumId() <= 0) {
608 MEDIA_ERR_LOG("Failed to get or create directory");
609 return dirAsset.GetAlbumId();
610 }
611
612 FileAsset fileAsset;
613 errCode = fileAsset.ModifyAsset(srcFilePath, dstFilePath);
614 if (errCode != E_SUCCESS) {
615 if (errCode != E_FILE_EXIST) {
616 MEDIA_ERR_LOG("Failed to modify the file in the device, errCode = %{public}d", errCode);
617 }
618 return errCode;
619 }
620 string dstFileName = MediaLibraryDataManagerUtils::GetFileName(dstFilePath);
621 if (ProcessNoMediaFile(dstFileName, dstAlbumPath) || ProcessHiddenFile(dstFileName, srcFilePath)) {
622 MEDIA_ERR_LOG("New file is a .nomedia file or hidden file.");
623 // why: return fail insteal of success
624 return E_FAIL;
625 }
626
627 auto ret = UpdateFileInfoInDb(cmd, dstFilePath, dirAsset.GetAlbumId(), dirAsset.GetAlbumName());
628 if (ret > 0) {
629 UpdateDateModified(dstAlbumPath);
630 string srcAlbumPath = MediaLibraryDataManagerUtils::GetParentPath(srcFilePath);
631 UpdateDateModified(srcAlbumPath);
632 }
633 return ret;
634 }
635
636 // Restriction: input param cmd MUST have id in uri
RenameDirObj(MediaLibraryCommand & cmd,const string & srcDirPath,const string & dstDirPath)637 int32_t MediaLibraryObjectUtils::RenameDirObj(MediaLibraryCommand &cmd,
638 const string &srcDirPath, const string &dstDirPath)
639 {
640 MEDIA_DEBUG_LOG("enter, srcDirPath = %{private}s, dstDirPath = %{private}s",
641 srcDirPath.c_str(), dstDirPath.c_str());
642 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
643 if (uniStore == nullptr) {
644 MEDIA_ERR_LOG("uniStore is nullptr!");
645 return E_HAS_DB_ERROR;
646 }
647
648 if (srcDirPath.empty() || dstDirPath.empty()) {
649 MEDIA_ERR_LOG("srcDirPath or dstDirPath is empty, rename failed!");
650 return E_INVALID_PATH;
651 }
652 if (!MediaFileUtils::RenameDir(srcDirPath, dstDirPath)) {
653 MEDIA_ERR_LOG("Rename directory failed!");
654 return E_HAS_FS_ERROR;
655 }
656 string dstDirName = MediaLibraryDataManagerUtils::GetFileName(dstDirPath);
657 if (ProcessHiddenDir(dstDirName, srcDirPath) == E_SUCCESS) {
658 MEDIA_ERR_LOG("New album is a hidden album.");
659 return E_SUCCESS;
660 }
661
662 ValuesBucket &values = cmd.GetValueBucket();
663 values.PutString(Media::MEDIA_DATA_DB_RELATIVE_PATH, MediaLibraryDataManagerUtils::GetParentPath(dstDirPath));
664 values.PutString(Media::MEDIA_DATA_DB_FILE_PATH, dstDirPath);
665 values.PutLong(MEDIA_DATA_DB_DATE_MODIFIED, MediaFileUtils::GetAlbumDateModified(dstDirPath));
666 int32_t retVal = ModifyInfoByIdInDb(cmd);
667 if (retVal <= 0) {
668 return retVal;
669 }
670
671 // Update the path, relative path and album Name for internal files
672 const std::string modifyAlbumInternalsStmt =
673 "UPDATE " + MEDIALIBRARY_TABLE + " SET " + MEDIA_DATA_DB_FILE_PATH + " = replace(" +
674 MEDIA_DATA_DB_FILE_PATH + ", '" + srcDirPath + "/' , '" + dstDirPath + "/'), " +
675 MEDIA_DATA_DB_RELATIVE_PATH + " = replace(" + MEDIA_DATA_DB_RELATIVE_PATH + ", '" + srcDirPath + "', '" +
676 dstDirPath + "'), " + MEDIA_DATA_DB_ALBUM_NAME + " = replace(" + MEDIA_DATA_DB_ALBUM_NAME + ", '" +
677 MediaLibraryDataManagerUtils::GetFileName(srcDirPath) + "', '" + dstDirName + "')" + "where " +
678 MEDIA_DATA_DB_FILE_PATH + " LIKE '" + srcDirPath + "/%'";
679 if (uniStore->ExecuteSql(modifyAlbumInternalsStmt) != NativeRdb::E_OK) {
680 MEDIA_ERR_LOG("Album update sql failed");
681 return E_HAS_DB_ERROR;
682 }
683 return E_SUCCESS;
684 }
685
OpenAsset(const string & filePath,const string & mode)686 static int32_t OpenAsset(const string &filePath, const string &mode)
687 {
688 std::string absFilePath;
689 if (!PathToRealPath(filePath, absFilePath)) {
690 MEDIA_ERR_LOG("Failed to get real path: %{private}s", filePath.c_str());
691 return E_ERR;
692 }
693 MEDIA_DEBUG_LOG("File absFilePath is %{private}s", absFilePath.c_str());
694
695 return MediaPrivacyManager(absFilePath, mode).Open();
696 }
697
OpenFile(MediaLibraryCommand & cmd,const string & mode)698 int32_t MediaLibraryObjectUtils::OpenFile(MediaLibraryCommand &cmd, const string &mode)
699 {
700 MEDIA_DEBUG_LOG("enter");
701 string uriString = cmd.GetUri().ToString();
702 shared_ptr<FileAsset> fileAsset = GetFileAssetFromDb(uriString);
703 if (fileAsset == nullptr) {
704 MEDIA_ERR_LOG("Failed to obtain path from Database");
705 return E_INVALID_URI;
706 }
707
708 string path = MediaFileUtils::UpdatePath(fileAsset->GetPath(), fileAsset->GetUri());
709 int32_t fd = OpenAsset(path, mode);
710 if (fd < 0) {
711 MEDIA_ERR_LOG("open file fd %{private}d, errno %{private}d", fd, errno);
712 return E_HAS_FS_ERROR;
713 }
714
715 MEDIA_DEBUG_LOG("MediaLibraryDataManager OpenFile: Success");
716 return fd;
717 }
718
CloseFile(MediaLibraryCommand & cmd)719 int32_t MediaLibraryObjectUtils::CloseFile(MediaLibraryCommand &cmd)
720 {
721 MEDIA_DEBUG_LOG("enter");
722 string strFileId = cmd.GetOprnFileId();
723 if (strFileId.empty()) {
724 MEDIA_ERR_LOG("Get id from uri or valuesBucket failed!");
725 return E_INVALID_FILEID;
726 }
727
728 string srcPath = GetPathByIdFromDb(strFileId);
729 if (srcPath.empty()) {
730 MEDIA_ERR_LOG("Get path of id %{public}s from database file!", strFileId.c_str());
731 return E_INVALID_FILEID;
732 }
733
734 string fileName = MediaLibraryDataManagerUtils::GetFileName(srcPath);
735 if ((fileName.length() != 0) && (fileName.at(0) != '.')) {
736 string dirPath = MediaLibraryDataManagerUtils::GetParentPath(srcPath);
737 UpdateDateModified(dirPath);
738 }
739
740 InvalidateThumbnail(strFileId);
741 ScanFile(srcPath);
742 return E_SUCCESS;
743 }
744
ScanFile(string & path)745 void MediaLibraryObjectUtils::ScanFile(string &path)
746 {
747 MEDIA_DEBUG_LOG("enter, path = %{private}s", path.c_str());
748 std::shared_ptr<ScanFileCallback> scanFileCb = make_shared<ScanFileCallback>();
749 if (scanFileCb == nullptr) {
750 MEDIA_ERR_LOG("Failed to create scan file callback object");
751 return ;
752 }
753 int ret = MediaScannerManager::GetInstance()->ScanFileSync(path, scanFileCb);
754 if (ret != 0) {
755 MEDIA_ERR_LOG("Scan file failed!");
756 }
757 }
758
ProcessNoMediaFile(const string & dstFileName,const string & dstAlbumPath)759 bool MediaLibraryObjectUtils::ProcessNoMediaFile(const string &dstFileName, const string &dstAlbumPath)
760 {
761 MEDIA_DEBUG_LOG("enter, dstFileName = %{private}s, dstAlbumPath = %{private}s",
762 dstFileName.c_str(), dstAlbumPath.c_str());
763 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
764 if (uniStore == nullptr) {
765 MEDIA_ERR_LOG("uniStore is nullptr!");
766 return E_HAS_DB_ERROR;
767 }
768
769 if (dstFileName.empty() || dstAlbumPath.empty() || dstFileName != NO_MEDIA_TAG) {
770 MEDIA_INFO_LOG("Not a .nomedia file, no need to do anything.");
771 return false;
772 }
773
774 // the whole folder containing .nomedia file is invisible in database
775 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::DELETE);
776 string dstAlbumPathPrefix = dstAlbumPath.back() != '/' ? (dstAlbumPath + "/") : dstAlbumPath;
777 cmd.GetAbsRdbPredicates()->BeginsWith(MEDIA_DATA_DB_FILE_PATH, dstAlbumPathPrefix);
778 cmd.GetAbsRdbPredicates()->Or()->EqualTo(MEDIA_DATA_DB_FILE_PATH, dstAlbumPath);
779
780 int32_t deletedRows = -1;
781 if (uniStore->Delete(cmd, deletedRows) != NativeRdb::E_OK) {
782 MEDIA_ERR_LOG("Delete rows for the hidden album failed");
783 }
784 return true;
785 }
786
ProcessHiddenFile(const string & dstFileName,const string & srcPath)787 bool MediaLibraryObjectUtils::ProcessHiddenFile(const string &dstFileName, const string &srcPath)
788 {
789 MEDIA_DEBUG_LOG("enter, dstFileName = %{private}s, srcPath = %{private}s",
790 dstFileName.c_str(), srcPath.c_str());
791 if (dstFileName.empty() || srcPath.empty() || dstFileName.at(0) != '.') {
792 MEDIA_INFO_LOG("Not a hidden file (file name begin with \'.\'), no need to do anything.");
793 return false;
794 }
795 MediaLibraryCommand deleteCmd(OperationObject::FILESYSTEM_ASSET, OperationType::DELETE);
796 if (DeleteInfoByPathInDb(deleteCmd, srcPath) != E_SUCCESS) {
797 MEDIA_ERR_LOG("Delete rows for the old path failed");
798 }
799 return true;
800 }
801
ProcessHiddenDir(const string & dstDirName,const string & srcDirPath)802 int32_t MediaLibraryObjectUtils::ProcessHiddenDir(const string &dstDirName, const string &srcDirPath)
803 {
804 if (dstDirName.empty() || srcDirPath.empty() || dstDirName.at(0) != '.') {
805 MEDIA_INFO_LOG("Not a hidden dir(name begin with \'.\'), no need to do anything.");
806 return E_INVALID_PATH;
807 }
808 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
809 if (uniStore == nullptr) {
810 MEDIA_ERR_LOG("uniStore is nullptr!");
811 return E_HAS_DB_ERROR;
812 }
813
814 MediaLibraryCommand deleteCmd(OperationObject::FILESYSTEM_ASSET, OperationType::DELETE);
815 string dstAlbumPathPrefix = srcDirPath.back() != '/' ? (srcDirPath + "/") : srcDirPath;
816 deleteCmd.GetAbsRdbPredicates()->BeginsWith(MEDIA_DATA_DB_FILE_PATH, dstAlbumPathPrefix);
817 deleteCmd.GetAbsRdbPredicates()->Or()->EqualTo(MEDIA_DATA_DB_FILE_PATH, srcDirPath);
818
819 int32_t deletedRows = -1;
820 if (uniStore->Delete(deleteCmd, deletedRows) != NativeRdb::E_OK) {
821 MEDIA_ERR_LOG("Delete src dir in database failed!");
822 return E_HAS_DB_ERROR;
823 }
824 return E_SUCCESS;
825 }
826
UpdateDateModified(const string & dirPath)827 void MediaLibraryObjectUtils::UpdateDateModified(const string &dirPath)
828 {
829 if (dirPath.empty()) {
830 MEDIA_ERR_LOG("Path is empty, update failed!");
831 return;
832 }
833
834 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::UPDATE);
835 ValuesBucket valuesBucket;
836 valuesBucket.PutLong(MEDIA_DATA_DB_DATE_MODIFIED, MediaFileUtils::GetAlbumDateModified(dirPath));
837 cmd.SetValueBucket(valuesBucket);
838
839 (void)ModifyInfoByPathInDb(cmd, dirPath);
840 }
841
GetFileAssetFromDb(const string & uriStr)842 shared_ptr<FileAsset> MediaLibraryObjectUtils::GetFileAssetFromDb(const string &uriStr)
843 {
844 MEDIA_DEBUG_LOG("enter");
845
846 string id = MediaLibraryDataManagerUtils::GetIdFromUri(uriStr);
847 string networkId = MediaFileUtils::GetNetworkIdFromUri(uriStr);
848
849 if ((id.empty()) || (!MediaLibraryDataManagerUtils::IsNumber(id)) || (stoi(id) == -1)) {
850 MEDIA_ERR_LOG("Id for the path is incorrect: %{public}s", id.c_str());
851 return nullptr;
852 }
853
854 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY, networkId);
855 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_ID, id);
856
857 shared_ptr<AbsSharedResultSet> resultSet = QueryWithCondition(cmd, {});
858 if (resultSet == nullptr) {
859 MEDIA_ERR_LOG("Failed to obtain file asset from database");
860 return nullptr;
861 }
862
863 shared_ptr<FetchResult<FileAsset>> fetchFileResult = make_shared<FetchResult<FileAsset>>();
864 if (fetchFileResult == nullptr) {
865 MEDIA_ERR_LOG("Failed to obtain fetch file result");
866 return nullptr;
867 }
868 fetchFileResult->SetNetworkId(networkId);
869 return fetchFileResult->GetObjectFromRdb(resultSet, 0);
870 }
871
GetDefaultRelativePath(const int32_t mediaType,string & relativePath)872 void MediaLibraryObjectUtils::GetDefaultRelativePath(const int32_t mediaType, string &relativePath)
873 {
874 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_DIR, OperationType::QUERY);
875 cmd.GetAbsRdbPredicates()->EqualTo(CATEGORY_MEDIATYPE_DIRECTORY_DB_MEDIA_TYPE, to_string(mediaType));
876
877 shared_ptr<AbsSharedResultSet> resultSet = QueryWithCondition(cmd, {});
878 if (resultSet == nullptr) {
879 MEDIA_ERR_LOG("Failed to obtain file asset from database, mediaType: %{public}d", static_cast<int>(mediaType));
880 return;
881 }
882
883 if (resultSet->GoToFirstRow() == NativeRdb::E_OK) {
884 relativePath = get<string>(ResultSetUtils::GetValFromColumn(CATEGORY_MEDIATYPE_DIRECTORY_DB_DIRECTORY,
885 resultSet, TYPE_STRING));
886 }
887 }
888
GetRelativePathFromFilePath(const string & path)889 string GetRelativePathFromFilePath(const string &path)
890 {
891 string relativePath;
892 if (path.length() > ROOT_MEDIA_DIR.length()) {
893 relativePath = path.substr(ROOT_MEDIA_DIR.length());
894 }
895 size_t pos = relativePath.rfind('/');
896 if (pos != string::npos) {
897 relativePath = relativePath.substr(0, pos + 1);
898 }
899 return relativePath;
900 }
901
UpdateFileInfoInDb(MediaLibraryCommand & cmd,const string & dstPath,const int32_t & bucketId,const string & bucketName)902 int32_t MediaLibraryObjectUtils::UpdateFileInfoInDb(MediaLibraryCommand &cmd, const string &dstPath,
903 const int32_t &bucketId, const string &bucketName)
904 {
905 MEDIA_DEBUG_LOG("enter, dstPath: %{private}s,", dstPath.c_str());
906 if (dstPath.empty()) {
907 MEDIA_ERR_LOG("Input argument is empty.");
908 return E_INVALID_PATH;
909 }
910
911 // dispName doesn't be used, maybe forget
912 size_t found = dstPath.rfind("/");
913 string dispName;
914 if (found != string::npos) {
915 dispName = dstPath.substr(found + 1);
916 }
917
918 struct stat statInfo;
919 if (stat(dstPath.c_str(), &statInfo) != 0) {
920 MEDIA_ERR_LOG("dstPath %{private}s is invalid. Modify failed!", dstPath.c_str());
921 return E_HAS_FS_ERROR;
922 }
923 string fileId = cmd.GetOprnFileId();
924 string mimeType = ScannerUtils::GetMimeTypeFromExtension(ScannerUtils::GetFileExtensionFromFileUri(dstPath));
925 MediaType mediaType = ScannerUtils::GetMediatypeFromMimetype(mimeType);
926 string displayName = MediaLibraryDataManagerUtils::GetDisPlayNameFromPath(dstPath);
927 ValuesBucket values;
928 values.PutString(MEDIA_DATA_DB_NAME, displayName);
929 values.PutString(MEDIA_DATA_DB_TITLE, MediaLibraryDataManagerUtils::GetFileTitle(displayName));
930 values.PutString(MEDIA_DATA_DB_FILE_PATH, dstPath);
931 values.PutString(MEDIA_DATA_DB_RELATIVE_PATH, GetRelativePathFromFilePath(dstPath));
932 values.PutString(MEDIA_DATA_DB_BUCKET_NAME, bucketName);
933 values.PutString(MEDIA_DATA_DB_MIME_TYPE, mimeType);
934 values.PutString(MEDIA_DATA_DB_URI, MediaLibraryDataManagerUtils::GetMediaTypeUri(mediaType));
935 values.PutInt(MEDIA_DATA_DB_MEDIA_TYPE, mediaType);
936 values.PutInt(MEDIA_DATA_DB_BUCKET_ID, bucketId);
937 values.PutInt(MEDIA_DATA_DB_PARENT_ID, bucketId);
938 values.PutLong(MEDIA_DATA_DB_SIZE, statInfo.st_size);
939 values.PutLong(MEDIA_DATA_DB_DATE_MODIFIED, statInfo.st_mtime);
940 cmd.SetValueBucket(values);
941
942 return ModifyInfoByIdInDb(cmd, fileId);
943 }
944
GetPathByIdFromDb(const string & id)945 string MediaLibraryObjectUtils::GetPathByIdFromDb(const string &id)
946 {
947 return GetStringColumnByIdFromDb(id, MEDIA_DATA_DB_FILE_PATH);
948 }
949
GetRecyclePathByIdFromDb(const string & id)950 string MediaLibraryObjectUtils::GetRecyclePathByIdFromDb(const string &id)
951 {
952 return GetStringColumnByIdFromDb(id, MEDIA_DATA_DB_RECYCLE_PATH);
953 }
954
GetStringColumnByIdFromDb(const string & id,const string & column)955 string MediaLibraryObjectUtils::GetStringColumnByIdFromDb(const string &id, const string &column)
956 {
957 MEDIA_DEBUG_LOG("enter column %{private}s", column.c_str());
958 string value;
959 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
960 if (uniStore == nullptr) {
961 MEDIA_ERR_LOG("uniStore is nullptr!");
962 return value;
963 }
964
965 if ((id.empty()) || (!MediaLibraryDataManagerUtils::IsNumber(id)) || (stoi(id) == -1)) {
966 MEDIA_ERR_LOG("Id for the path is incorrect or rdbStore is null");
967 return value;
968 }
969
970 int32_t columnIndex = 0;
971 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
972 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_ID, id);
973
974 vector<string> columns;
975 columns.push_back(column);
976
977 auto queryResultSet = uniStore->Query(cmd, columns);
978 CHECK_AND_RETURN_RET_LOG(queryResultSet != nullptr, value, "Failed to obtain value from database");
979
980 auto ret = queryResultSet->GoToFirstRow();
981 CHECK_AND_RETURN_RET_LOG(ret == 0, value, "Failed to shift at first row");
982
983 ret = queryResultSet->GetColumnIndex(column, columnIndex);
984 CHECK_AND_RETURN_RET_LOG(ret == 0, value, "Failed to obtain column index");
985
986 ret = queryResultSet->GetString(columnIndex, value);
987 CHECK_AND_RETURN_RET_LOG(ret == 0, value, "Failed to obtain value");
988
989 return value;
990 }
991
GetIdByPathFromDb(const string & path)992 int32_t MediaLibraryObjectUtils::GetIdByPathFromDb(const string &path)
993 {
994 MEDIA_DEBUG_LOG("enter, path = %{private}s", path.c_str());
995 if (path.empty()) {
996 return E_INVALID_PATH;
997 }
998 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
999 if (uniStore == nullptr) {
1000 MEDIA_ERR_LOG("uniStore is nullptr!");
1001 return E_HAS_DB_ERROR;
1002 }
1003
1004 int32_t columnIndex = 0;
1005 string newPath = path;
1006 if (newPath.back() == '/') {
1007 newPath.pop_back();
1008 }
1009 int32_t fileId = E_INVALID_FILEID;
1010
1011 vector<string> columns;
1012 columns.push_back(MEDIA_DATA_DB_ID);
1013
1014 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
1015 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_FILE_PATH, newPath);
1016 cmd.GetAbsRdbPredicates()->And()->EqualTo(MEDIA_DATA_DB_IS_TRASH, to_string(NOT_ISTRASH));
1017
1018 auto queryResultSet = uniStore->Query(cmd, columns);
1019 CHECK_AND_RETURN_RET_LOG(queryResultSet != nullptr, fileId, "Failed to obtain path from database");
1020
1021 auto ret = queryResultSet->GoToFirstRow();
1022 CHECK_AND_RETURN_RET_LOG(ret == 0, fileId, "Failed to shift at first row");
1023
1024 ret = queryResultSet->GetColumnIndex(MEDIA_DATA_DB_ID, columnIndex);
1025 CHECK_AND_RETURN_RET_LOG(ret == 0, fileId, "Failed to obtain column index");
1026
1027 ret = queryResultSet->GetInt(columnIndex, fileId);
1028 CHECK_AND_RETURN_RET_LOG(ret == 0, fileId, "Failed to obtain file id");
1029
1030 return fileId;
1031 }
1032
GetParentIdByIdFromDb(const string & fileId)1033 int32_t MediaLibraryObjectUtils::GetParentIdByIdFromDb(const string &fileId)
1034 {
1035 MEDIA_DEBUG_LOG("enter, fileId = %{private}s", fileId.c_str());
1036 if (fileId.empty() || fileId == "-1") {
1037 return E_INVALID_FILEID;
1038 }
1039 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1040 if (uniStore == nullptr) {
1041 MEDIA_ERR_LOG("uniStore is nullptr!");
1042 return E_HAS_DB_ERROR;
1043 }
1044
1045 int32_t parentIdVal = -1;
1046 int32_t columnIndex = 0;
1047 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
1048 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_ID, fileId);
1049 auto queryResultSet = uniStore->Query(cmd, {});
1050 CHECK_AND_RETURN_RET_LOG(queryResultSet != nullptr, parentIdVal, "Failed to obtain path from database");
1051
1052 auto ret = queryResultSet->GoToNextRow();
1053 CHECK_AND_RETURN_RET_LOG(ret == 0, parentIdVal, "Failed to shift at next row");
1054
1055 ret = queryResultSet->GetColumnIndex(MEDIA_DATA_DB_PARENT_ID, columnIndex);
1056 CHECK_AND_RETURN_RET_LOG(ret == 0, parentIdVal, "Failed to obtain column index");
1057
1058 ret = queryResultSet->GetInt(columnIndex, parentIdVal);
1059 CHECK_AND_RETURN_RET_LOG(ret == 0, parentIdVal, "Failed to obtain file id");
1060
1061 return parentIdVal;
1062 }
1063
InsertInDb(MediaLibraryCommand & cmd)1064 int32_t MediaLibraryObjectUtils::InsertInDb(MediaLibraryCommand &cmd)
1065 {
1066 MEDIA_DEBUG_LOG("enter");
1067 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1068 if (uniStore == nullptr) {
1069 MEDIA_ERR_LOG("uniStore is nullptr!");
1070 return E_HAS_DB_ERROR;
1071 }
1072
1073 int64_t outRowId = E_HAS_DB_ERROR;
1074 int32_t result = uniStore->Insert(cmd, outRowId);
1075 if (result != NativeRdb::E_OK) {
1076 MEDIA_ERR_LOG("Insert operation failed. Result %{public}d. Deleted %{public}d",
1077 result, static_cast<int32_t>(outRowId));
1078 return E_HAS_DB_ERROR;
1079 }
1080 return static_cast<int32_t>(outRowId);
1081 }
1082
DeleteInfoByPathInDb(MediaLibraryCommand & cmd,const string & path)1083 int32_t MediaLibraryObjectUtils::DeleteInfoByPathInDb(MediaLibraryCommand &cmd, const string &path)
1084 {
1085 MEDIA_DEBUG_LOG("enter, path = %{private}s", path.c_str());
1086 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1087 if (uniStore == nullptr) {
1088 MEDIA_ERR_LOG("uniStore is nullptr!");
1089 return E_HAS_DB_ERROR;
1090 }
1091
1092 int32_t deletedRows = E_HAS_DB_ERROR;
1093 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_FILE_PATH, path);
1094 int32_t result = uniStore->Delete(cmd, deletedRows);
1095 if (result != NativeRdb::E_OK) {
1096 MEDIA_ERR_LOG("Delete operation failed. Result %{public}d. Deleted %{public}d", result, deletedRows);
1097 return E_HAS_DB_ERROR;
1098 }
1099
1100 return E_SUCCESS;
1101 }
1102
DeleteInfoByIdInDb(MediaLibraryCommand & cmd,const string & fileId)1103 int32_t MediaLibraryObjectUtils::DeleteInfoByIdInDb(MediaLibraryCommand &cmd, const string &fileId)
1104 {
1105 MEDIA_DEBUG_LOG("enter, fileId = %{private}s", fileId.c_str());
1106 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1107 if (uniStore == nullptr) {
1108 MEDIA_ERR_LOG("uniStore is nullptr!");
1109 return E_HAS_DB_ERROR;
1110 }
1111
1112 string strDeleteCondition = cmd.GetAbsRdbPredicates()->GetWhereClause();
1113 if (strDeleteCondition.empty()) {
1114 string strRow = fileId.empty() ? cmd.GetOprnFileId() : fileId;
1115 if (strRow.empty() || !MediaLibraryDataManagerUtils::IsNumber(strRow)) {
1116 MEDIA_ERR_LOG("MediaLibraryObjectUtils DeleteFile: Index not digit");
1117 return E_INVALID_FILEID;
1118 }
1119 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_ID, strRow);
1120 }
1121
1122 int32_t deletedRows = E_HAS_DB_ERROR;
1123 int32_t result = uniStore->Delete(cmd, deletedRows);
1124 if (result != NativeRdb::E_OK) {
1125 MEDIA_ERR_LOG("Delete operation failed. Result %{public}d. Deleted %{public}d", result, deletedRows);
1126 }
1127
1128 return deletedRows;
1129 }
1130
ModifyInfoByPathInDb(MediaLibraryCommand & cmd,const string & path)1131 int32_t MediaLibraryObjectUtils::ModifyInfoByPathInDb(MediaLibraryCommand &cmd, const string &path)
1132 {
1133 MEDIA_DEBUG_LOG("enter, path = %{private}s", path.c_str());
1134 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1135 if (uniStore == nullptr) {
1136 MEDIA_ERR_LOG("uniStore is nullptr!");
1137 return E_HAS_DB_ERROR;
1138 }
1139
1140 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_FILE_PATH, path);
1141 int32_t updatedRows = E_HAS_DB_ERROR;
1142 int32_t result = uniStore->Update(cmd, updatedRows);
1143 if (result != NativeRdb::E_OK || updatedRows <= 0) {
1144 MEDIA_ERR_LOG("Update operation failed. Result %{public}d. Updated %{public}d", result, updatedRows);
1145 }
1146
1147 return updatedRows;
1148 }
1149
ModifyInfoByIdInDb(MediaLibraryCommand & cmd,const string & fileId)1150 int32_t MediaLibraryObjectUtils::ModifyInfoByIdInDb(MediaLibraryCommand &cmd, const string &fileId)
1151 {
1152 MEDIA_DEBUG_LOG("enter, fileId = %{private}s", fileId.c_str());
1153 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1154 if (uniStore == nullptr) {
1155 MEDIA_ERR_LOG("uniStore is nullptr!");
1156 return E_HAS_DB_ERROR;
1157 }
1158
1159 string strDeleteCondition = cmd.GetAbsRdbPredicates()->GetWhereClause();
1160 if (strDeleteCondition.empty()) {
1161 string strRow = fileId.empty() ? cmd.GetOprnFileId() : fileId;
1162 if (strRow.empty() || !MediaLibraryDataManagerUtils::IsNumber(strRow) || (stoi(strRow) == -1)) {
1163 MEDIA_ERR_LOG("DeleteFile: Index not digit");
1164 return E_INVALID_FILEID;
1165 }
1166 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_ID, strRow);
1167 }
1168
1169 int32_t updatedRows = E_HAS_DB_ERROR;
1170 int32_t result = uniStore->Update(cmd, updatedRows);
1171 if (result != NativeRdb::E_OK || updatedRows <= 0) {
1172 MEDIA_ERR_LOG("Update operation failed. Result %{public}d. Updated %{public}d", result, updatedRows);
1173 }
1174
1175 return updatedRows;
1176 }
1177
QueryWithCondition(MediaLibraryCommand & cmd,const vector<string> & columns,const string & conditionColumn)1178 shared_ptr<AbsSharedResultSet> MediaLibraryObjectUtils::QueryWithCondition(MediaLibraryCommand &cmd,
1179 const vector<string> &columns, const string &conditionColumn)
1180 {
1181 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1182 if (uniStore == nullptr) {
1183 MEDIA_ERR_LOG("uniStore is nullptr!");
1184 return nullptr;
1185 }
1186
1187 string strQueryCondition = cmd.GetAbsRdbPredicates()->GetWhereClause();
1188 if (strQueryCondition.empty()) {
1189 if (conditionColumn.empty()) {
1190 return uniStore->QuerySql("SELECT * FROM " + cmd.GetTableName());
1191 }
1192 string strFileId = cmd.GetOprnFileId();
1193 if (strFileId.empty()) {
1194 MEDIA_ERR_LOG("Get file id from uri or valuebucket failed!");
1195 return nullptr;
1196 }
1197 cmd.GetAbsRdbPredicates()->EqualTo(conditionColumn, strFileId);
1198 }
1199
1200 return uniStore->Query(cmd, columns);
1201 }
1202
IsColumnValueExist(const string & value,const string & column)1203 bool MediaLibraryObjectUtils::IsColumnValueExist(const string &value, const string &column)
1204 {
1205 if (column.empty()) {
1206 MEDIA_ERR_LOG("Empty column param");
1207 return false;
1208 }
1209 auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1210 if (uniStore == nullptr) {
1211 MEDIA_ERR_LOG("uniStore is nullptr!");
1212 return false;
1213 }
1214
1215 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
1216 cmd.GetAbsRdbPredicates()->EqualTo(column, value);
1217 vector<string> columns;
1218 columns.push_back(column);
1219 auto queryResultSet = uniStore->Query(cmd, columns);
1220 if (queryResultSet != nullptr) {
1221 int32_t count = 0;
1222 queryResultSet->GetRowCount(count);
1223 MEDIA_DEBUG_LOG("count is %{private}d", count);
1224 if (count > 0) {
1225 return true;
1226 }
1227 }
1228 return false;
1229 }
1230
IsAssetExistInDb(const int32_t id)1231 bool MediaLibraryObjectUtils::IsAssetExistInDb(const int32_t id)
1232 {
1233 if (id <= 0) {
1234 MEDIA_ERR_LOG("Invalid id param");
1235 return false;
1236 }
1237
1238 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
1239 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_ID, to_string(id));
1240 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_IS_TRASH, to_string(NOT_ISTRASH));
1241 vector<string> columns;
1242 auto queryResultSet = QueryWithCondition(cmd, columns);
1243 if (queryResultSet != nullptr && queryResultSet->GoToNextRow() == NativeRdb::E_OK) {
1244 return true;
1245 }
1246 return false;
1247 }
1248
IsFileExistInDb(const string & path)1249 bool MediaLibraryObjectUtils::IsFileExistInDb(const string &path)
1250 {
1251 if (path.empty()) {
1252 MEDIA_ERR_LOG("path is incorrect");
1253 return false;
1254 }
1255
1256 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
1257 cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_FILE_PATH, path)
1258 ->And()->EqualTo(MEDIA_DATA_DB_IS_TRASH, "0");
1259
1260 vector<string> columns;
1261 columns.push_back(MEDIA_DATA_DB_FILE_PATH);
1262 auto queryResultSet = QueryWithCondition(cmd, columns);
1263 if (queryResultSet != nullptr && queryResultSet->GoToNextRow() == NativeRdb::E_OK) {
1264 return true;
1265 }
1266
1267 return false;
1268 }
1269 } // namespace Media
1270 } // namespace OHOS
1271