• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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