1 /*
2 * Copyright (C) 2024 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 #include "photos_dao.h"
16
17 #include <string>
18 #include <vector>
19 #include <sstream>
20
21 #include "backup_database_utils.h"
22 #include "rdb_store.h"
23 #include "result_set_utils.h"
24 #include "userfile_manager_types.h"
25 #include "backup_const.h"
26
27 namespace OHOS::Media {
28 /**
29 * @brief Find FileInfo related PhotoAlbu, by lPath, displayName, fileSize and orientation.
30 */
FindSameFileInAlbum(const FileInfo & fileInfo,int32_t maxFileId)31 PhotosDao::PhotosRowData PhotosDao::FindSameFileInAlbum(const FileInfo &fileInfo, int32_t maxFileId)
32 {
33 PhotosDao::PhotosRowData rowData;
34 CHECK_AND_RETURN_RET(maxFileId > 0, rowData);
35 // pictureFlag: 0 for video, 1 for photo; Only search for photo in this case.
36 int pictureFlag = fileInfo.fileType == MEDIA_TYPE_VIDEO ? 0 : 1;
37 const std::vector<NativeRdb::ValueObject> params = {
38 fileInfo.lPath, maxFileId, fileInfo.displayName, fileInfo.fileSize, pictureFlag, fileInfo.orientation};
39 std::string querySql = this->SQL_PHOTOS_FIND_SAME_FILE_IN_ALBUM;
40 CHECK_AND_RETURN_RET_LOG(this->mediaLibraryRdb_ != nullptr, rowData, "Media_Restore: mediaLibraryRdb_ is null.");
41
42 auto resultSet = this->mediaLibraryRdb_->QuerySql(querySql, params);
43 bool cond = (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK);
44 CHECK_AND_RETURN_RET(!cond, rowData);
45 rowData.fileId = GetInt32Val("file_id", resultSet);
46 rowData.data = GetStringVal("data", resultSet);
47 rowData.cleanFlag = GetInt32Val("clean_flag", resultSet);
48 rowData.position = GetInt32Val("position", resultSet);
49 return rowData;
50 }
51
52 /**
53 * @brief Find FileInfo, which is not related PhotoAlbum, by displayName, fileSize and orientation.
54 */
FindSameFileWithoutAlbum(const FileInfo & fileInfo,int32_t maxFileId)55 PhotosDao::PhotosRowData PhotosDao::FindSameFileWithoutAlbum(const FileInfo &fileInfo, int32_t maxFileId)
56 {
57 PhotosDao::PhotosRowData rowData;
58 CHECK_AND_RETURN_RET(maxFileId > 0, rowData);
59 // pictureFlag: 0 for video, 1 for photo; Only search for photo in this case.
60 int pictureFlag = fileInfo.fileType == MEDIA_TYPE_VIDEO ? 0 : 1;
61 const std::vector<NativeRdb::ValueObject> params = {
62 maxFileId, fileInfo.displayName, fileInfo.fileSize, pictureFlag, fileInfo.orientation};
63 std::string querySql = this->SQL_PHOTOS_FIND_SAME_FILE_WITHOUT_ALBUM;
64 CHECK_AND_RETURN_RET_LOG(this->mediaLibraryRdb_ != nullptr, rowData, "Media_Restore: mediaLibraryRdb_ is null.");
65
66 auto resultSet = this->mediaLibraryRdb_->QuerySql(querySql, params);
67 bool cond = (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK);
68 CHECK_AND_RETURN_RET(!cond, rowData);
69 rowData.fileId = GetInt32Val("file_id", resultSet);
70 rowData.data = GetStringVal("data", resultSet);
71 rowData.cleanFlag = GetInt32Val("clean_flag", resultSet);
72 rowData.position = GetInt32Val("position", resultSet);
73 return rowData;
74 }
75
76 /**
77 * @brief Get basic information of the Photos.
78 */
GetBasicInfo()79 PhotosDao::PhotosBasicInfo PhotosDao::GetBasicInfo()
80 {
81 PhotosDao::PhotosBasicInfo basicInfo = {0, 0};
82 std::string querySql = this->SQL_PHOTOS_BASIC_INFO;
83 if (this->mediaLibraryRdb_ == nullptr) {
84 MEDIA_ERR_LOG("Media_Restore: mediaLibraryRdb_ is null.");
85 return basicInfo;
86 }
87 auto resultSet = this->mediaLibraryRdb_->QuerySql(querySql);
88 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
89 MEDIA_WARN_LOG("Media_Restore: GetBasicInfo resultSet is null. querySql: %{public}s", querySql.c_str());
90 return basicInfo;
91 }
92 basicInfo.maxFileId = GetInt32Val("max_file_id", resultSet);
93 basicInfo.count = GetInt32Val("count", resultSet);
94 MEDIA_INFO_LOG("Media_Restore: max_file_id: %{public}d, count: %{public}d", basicInfo.maxFileId, basicInfo.count);
95 return basicInfo;
96 }
97
98 /**
99 * @brief Find same file info by lPath, displayName, size, orientation.
100 * lPath - if original fileInfo's lPath is empty, it will be ignored.
101 * orientation - if original fileInfo's fileType is not Video(2), it will be ignored.
102 */
FindSameFile(const FileInfo & fileInfo,const int32_t maxFileId)103 PhotosDao::PhotosRowData PhotosDao::FindSameFile(const FileInfo &fileInfo, const int32_t maxFileId)
104 {
105 PhotosDao::PhotosRowData rowData;
106 CHECK_AND_RETURN_RET(maxFileId > 0, rowData);
107 if (fileInfo.lPath.empty()) {
108 rowData = this->FindSameFileWithoutAlbum(fileInfo, maxFileId);
109 MEDIA_ERR_LOG("Media_Restore: FindSameFile - lPath is empty, DB Info: %{public}s, Object: %{public}s",
110 this->ToString(rowData).c_str(),
111 this->ToString(fileInfo).c_str());
112 return rowData;
113 }
114 rowData = this->FindSameFileInAlbum(fileInfo, maxFileId);
115 bool cond = (!rowData.data.empty() || rowData.fileId != 0);
116 CHECK_AND_RETURN_RET(!cond, rowData);
117
118 rowData = this->FindSameFileBySourcePath(fileInfo, maxFileId);
119 if (!rowData.data.empty() || rowData.fileId != 0) {
120 MEDIA_WARN_LOG("Media_Restore: FindSameFile - find Photos by sourcePath, "
121 "DB Info: %{public}s, Object: %{public}s",
122 this->ToString(rowData).c_str(),
123 this->ToString(fileInfo).c_str());
124 return rowData;
125 }
126 return rowData;
127 }
128
129 /**
130 * @brief Find FileInfo not related PhotoAlbum, by sourcePath, displayName, fileSize and orientation.
131 */
FindSameFileBySourcePath(const FileInfo & fileInfo,const int32_t maxFileId)132 PhotosDao::PhotosRowData PhotosDao::FindSameFileBySourcePath(const FileInfo &fileInfo, const int32_t maxFileId)
133 {
134 PhotosDao::PhotosRowData rowData;
135 CHECK_AND_RETURN_RET(maxFileId > 0, rowData);
136 // pictureFlag: 0 for video, 1 for photo; Only search for photo in this case.
137 int pictureFlag = fileInfo.fileType == MEDIA_TYPE_VIDEO ? 0 : 1;
138 std::string sourcePath = this->SOURCE_PATH_PREFIX + fileInfo.lPath + "/" + fileInfo.displayName;
139 const std::vector<NativeRdb::ValueObject> params = {
140 sourcePath, maxFileId, fileInfo.displayName, fileInfo.fileSize, pictureFlag, fileInfo.orientation};
141 std::string querySql = this->SQL_PHOTOS_FIND_SAME_FILE_BY_SOURCE_PATH;
142 CHECK_AND_RETURN_RET_LOG(this->mediaLibraryRdb_ != nullptr, rowData, "Media_Restore: mediaLibraryRdb_ is null.");
143
144 auto resultSet = this->mediaLibraryRdb_->QuerySql(querySql, params);
145 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
146 return rowData;
147 }
148 rowData.fileId = GetInt32Val("file_id", resultSet);
149 rowData.data = GetStringVal("data", resultSet);
150 rowData.cleanFlag = GetInt32Val("clean_flag", resultSet);
151 rowData.position = GetInt32Val("position", resultSet);
152 return rowData;
153 }
154
ToString(const FileInfo & fileInfo)155 std::string PhotosDao::ToString(const FileInfo &fileInfo)
156 {
157 std::stringstream ss;
158 ss << "FileInfo[ fileId: " << fileInfo.fileIdOld << ", displayName: " << fileInfo.displayName
159 << ", bundleName: " << fileInfo.bundleName << ", lPath: " << fileInfo.lPath << ", size: " << fileInfo.fileSize
160 << ", fileType: " << fileInfo.fileType << ", oldPath: " << fileInfo.oldPath
161 << ", sourcePath: " << fileInfo.sourcePath << " ]";
162 return ss.str();
163 }
164
ToString(const PhotosDao::PhotosRowData & rowData)165 std::string PhotosDao::ToString(const PhotosDao::PhotosRowData &rowData)
166 {
167 std::stringstream ss;
168 ss << "PhotosRowData[ fileId: " << rowData.fileId << ", data: " << rowData.data << " ]";
169 return ss.str();
170 }
171
ToLower(const std::string & str)172 std::string PhotosDao::ToLower(const std::string &str)
173 {
174 std::string lowerStr;
175 std::transform(
176 str.begin(), str.end(), std::back_inserter(lowerStr), [](unsigned char c) { return std::tolower(c); });
177 return lowerStr;
178 }
179
GetDirtyFilesCount()180 int32_t PhotosDao::GetDirtyFilesCount()
181 {
182 std::vector<NativeRdb::ValueObject> params = { static_cast<int32_t>(SyncStatusType::TYPE_BACKUP) };
183 return BackupDatabaseUtils::QueryInt(mediaLibraryRdb_, SQL_PHOTOS_GET_DIRTY_FILES_COUNT, "count", params);
184 }
185
GetDirtyFiles(int32_t offset)186 std::vector<PhotosDao::PhotosRowData> PhotosDao::GetDirtyFiles(int32_t offset)
187 {
188 std::vector<PhotosDao::PhotosRowData> rowDataList;
189 std::vector<NativeRdb::ValueObject> params = { static_cast<int32_t>(SyncStatusType::TYPE_BACKUP),
190 offset, QUERY_COUNT };
191 auto resultSet = BackupDatabaseUtils::QuerySql(mediaLibraryRdb_, SQL_PHOTOS_GET_DIRTY_FILES, params);
192 CHECK_AND_RETURN_RET(resultSet != nullptr, rowDataList);
193 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
194 PhotosDao::PhotosRowData rowData;
195 rowData.data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
196 rowData.fileId = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
197 rowDataList.emplace_back(rowData);
198 }
199 resultSet->Close();
200 return rowDataList;
201 }
202 } // namespace OHOS::Media