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