1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef OHOS_MEDIA_CLONE_RESTORE_H
17 #define OHOS_MEDIA_CLONE_RESTORE_H
18
19 #include <optional>
20 #include <type_traits>
21 #include <set>
22 #include <sstream>
23 #include <algorithm>
24 #include <iterator>
25 #include <vector>
26
27 #include "base_restore.h"
28 #include "backup_const.h"
29 #include "medialibrary_rdb_utils.h"
30 #include "medialibrary_errno.h"
31 #include "medialibrary_kvstore_manager.h"
32 #include "backup_database_utils.h"
33 #include "photo_album_clone.h"
34 #include "photos_clone.h"
35
36 namespace OHOS {
37 namespace Media {
38 class CloneRestore : public BaseRestore {
39 public:
40 CloneRestore();
41 virtual ~CloneRestore() = default;
42 // upgradePath is useless now
43 void StartRestore(const std::string &backupRestorePath, const std::string &upgradePath) override;
44 int32_t Init(const std::string &backupRestoreDir, const std::string &upgradeFilePath, bool isUpgrade) override;
45 NativeRdb::ValuesBucket GetInsertValue(const FileInfo &fileInfo, const std::string &newPath,
46 int32_t sourceType) override;
47 std::string GetBackupInfo() override;
48 void StartBackup() override;
49 using CoverUriInfo = std::pair<std::string, std::pair<std::string, int32_t>>;
50
51 private:
52 void RestorePhoto(void) override;
53 void HandleRestData(void) override;
54 std::vector<FileInfo> QueryFileInfos(int32_t offset, int32_t isRelatedToPhotoMap = 0);
55 bool ParseResultSet(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, FileInfo &info,
56 std::string dbName = "") override;
57 bool ParseResultSetForAudio(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, FileInfo &info) override;
58 void AnalyzeSource() override;
59 void RestoreAlbum(void);
60 void RestoreAudio(void) override;
61 int InsertPhoto(std::vector<FileInfo> &fileInfos);
62 std::vector<NativeRdb::ValuesBucket> GetInsertValues(int32_t sceneCode, std::vector<FileInfo> &fileInfos,
63 int32_t sourceType);
64 std::vector<NativeRdb::ValuesBucket> GetInsertValues(std::vector<AnalysisAlbumTbl> &analysisAlbumTbl);
65 int32_t MoveAsset(FileInfo &fileInfo);
66 bool IsFilePathExist(const std::string &filePath) const;
67 int32_t QueryTotalNumber(const std::string &tableName);
68 std::vector<AlbumInfo> QueryAlbumInfos(const std::string &tableName, int32_t offset);
69 bool ParseAlbumResultSet(const std::string &tableName, const std::shared_ptr<NativeRdb::ResultSet> &resultSet,
70 AlbumInfo &albumInfo);
71 bool PrepareCommonColumnInfoMap(const std::string &tableName,
72 const std::unordered_map<std::string, std::string> &srcColumnInfoMap,
73 const std::unordered_map<std::string, std::string> &dstColumnInfoMap);
74 bool HasSameColumn(const std::unordered_map<std::string, std::string> &columnInfoMap, const std::string &columnName,
75 const std::string &columnType);
76 void GetValFromResultSet(const std::shared_ptr<NativeRdb::ResultSet> &resultSet,
77 std::unordered_map<std::string, std::variant<int32_t, int64_t, double, std::string>> &valMap,
78 const std::string &columnName, const std::string &columnType);
79 void PrepareCommonColumnVal(NativeRdb::ValuesBucket &values, const std::string &columnName,
80 const std::variant<int32_t, int64_t, double, std::string> &columnVal,
81 const std::unordered_map<std::string, std::string> &commonColumnInfoMap) const;
82 void GetQueryWhereClause(const std::string &tableName,
83 const std::unordered_map<std::string, std::string> &columnInfoMap);
84 void BatchQueryPhoto(std::vector<FileInfo> &fileInfos);
85 void BatchNotifyPhoto(const std::vector<FileInfo> &fileInfos);
86 void InsertAlbum(std::vector<AlbumInfo> &albumInfos, const std::string &tableName);
87 std::vector<NativeRdb::ValuesBucket> GetInsertValues(std::vector<AlbumInfo> &albumInfos,
88 const std::string &tableName);
89 bool HasSameAlbum(const AlbumInfo &albumInfo, const std::string &tableName);
90 void BatchQueryAlbum(std::vector<AlbumInfo> &albumInfos, const std::string &tableName);
91 void BatchInsertMap(const std::vector<FileInfo> &fileInfos, int64_t &totalRowNum);
92 NativeRdb::ValuesBucket GetInsertValue(const MapInfo &mapInfo) const;
93 NativeRdb::ValuesBucket GetInsertValue(const AlbumInfo &albumInfo, const std::string &tableName) const;
94 void CheckTableColumnStatus(std::shared_ptr<NativeRdb::RdbStore> rdbStore,
95 const std::vector<std::vector<std::string>> &cloneTableList);
96 bool HasColumns(const std::unordered_map<std::string, std::string> &columnInfoMap,
97 const std::unordered_set<std::string> &columnSet);
98 bool HasColumn(const std::unordered_map<std::string, std::string> &columnInfoMap, const std::string &columnName);
99 void GetAlbumExtraQueryWhereClause(const std::string &tableName);
100 bool IsReadyForRestore(const std::string &tableName);
101 void PrepareEditTimeVal(NativeRdb::ValuesBucket &values, int64_t editTime, const FileInfo &fileInfo,
102 const std::unordered_map<std::string, std::string> &commonColumnInfoMap) const;
103 void RestoreGallery();
104 bool PrepareCloudPath(const std::string &tableName, FileInfo &fileInfo);
105 void RestoreMusic();
106 std::vector<FileInfo> QueryFileInfos(const std::string &tableName, int32_t offset);
107 bool ParseResultSet(const std::string &tableName, const std::shared_ptr<NativeRdb::ResultSet> &resultSet,
108 FileInfo &fileInfo);
109 void InsertAudio(std::vector<FileInfo> &fileInfos);
110 int32_t QueryTotalNumberByMediaType(std::shared_ptr<NativeRdb::RdbStore> rdbStore, const std::string &tableName,
111 MediaType mediaType);
112 size_t StatClonetotalSize(std::shared_ptr<NativeRdb::RdbStore> mediaRdb);
113 std::string GetBackupInfoByCount(int32_t photoCount, int32_t videoCount, int32_t audioCount, size_t totalSize);
114 void MoveMigrateFile(std::vector<FileInfo> &fileInfos, int64_t &fileMoveCount, int64_t &videoFileMoveCount);
115 void RestorePhotoBatch(int32_t offset, int32_t isRelatedToPhotoMap = 0);
116 void RestoreAudioBatch(int32_t offset);
117 void InsertPhotoRelated(std::vector<FileInfo> &fileInfos);
118 void SetFileIdReference(const std::vector<FileInfo> &fileInfos, std::string &selection,
119 std::unordered_map<int32_t, int32_t> &fileIdMap);
120 int32_t QueryMapTotalNumber(const std::string &baseQuerySql);
121 std::vector<MapInfo> QueryMapInfos(const std::string &tableName, const std::string &baseQuerySql, int32_t offset,
122 const std::unordered_map<int32_t, int32_t> &fileIdMap, const std::unordered_map<int32_t, int32_t> &albumIdMap);
123 int64_t InsertMapByTable(const std::string &tableName, const std::vector<MapInfo> &mapInfos,
124 std::unordered_set<int32_t> &albumSet);
125 std::vector<NativeRdb::ValuesBucket> GetInsertValues(const std::vector<MapInfo> &mapInfos);
126 std::string GetQueryWhereClauseByTable(const std::string &tableName);
127 void SetSpecialAttributes(const std::string &tableName, const std::shared_ptr<NativeRdb::ResultSet> &resultSet,
128 FileInfo &fileInfo);
129 bool IsSameFileForClone(const std::string &tableName, FileInfo &fileInfo);
130 int32_t MovePicture(FileInfo &fileInfo);
131 int32_t MoveMovingPhotoVideo(FileInfo &fileInfo);
132 NativeRdb::ValuesBucket GetInsertValue(const AnalysisAlbumTbl &portraitAlbumInfo);
133 int32_t InsertPortraitAlbumByTable(std::vector<AnalysisAlbumTbl> &analysisAlbumTbl);
134 void InsertPortraitAlbum(std::vector<AnalysisAlbumTbl> &analysisAlbumTbl);
135 void ParsePortraitAlbumResultSet(const std::shared_ptr<NativeRdb::ResultSet> &resultSet,
136 AnalysisAlbumTbl &analysisAlbumTbl);
137 std::vector<AnalysisAlbumTbl> QueryPortraitAlbumTbl(int32_t offset,
138 const std::vector<std::string>& commonColumns);
139 void RestoreFromGalleryPortraitAlbum();
140 int32_t QueryPortraitAlbumTotalNumber(std::shared_ptr<NativeRdb::RdbStore> rdbPtr, std::string query);
141 std::unordered_map<std::string, std::string> CreateImgFaceColumnFieldMap();
142 void ParseImageFaceResultSet(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, ImageFaceTbl &imageFaceTbl);
143 void ParseFaceTagResultSet(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, FaceTagTbl &faceTagTbl);
144 NativeRdb::ValuesBucket CreateValuesBucketFromImageFaceTbl(const ImageFaceTbl& imageFaceTbl);
145 void BatchInsertImageFaces(const std::vector<ImageFaceTbl>& imageFaceTbls);
146 std::vector<ImageFaceTbl> ProcessImageFaceTbls(const std::vector<ImageFaceTbl>& imageFaceTbls,
147 const std::vector<FileIdPair>& fileIdPairs);
148 std::vector<ImageFaceTbl> QueryImageFaceTbl(int32_t offset, std::string &fileIdClause,
149 const std::vector<std::string>& commonColumns);
150 std::vector<PortraitAlbumDfx> QueryAllPortraitAlbum(int32_t& offset, int32_t& rowCount);
151 void RecordOldPortraitAlbumDfx();
152 std::unordered_set<std::string> QueryAllPortraitAlbum();
153 void LogPortraitCloneDfx();
154 void RestoreImageFaceInfo(std::vector<FileInfo> &fileInfos);
155 NativeRdb::ValuesBucket CreateValuesBucketFromFaceTagTbl(const FaceTagTbl& faceTagTbl);
156 void BatchInsertFaceTags(const std::vector<FaceTagTbl>& faceTagTbls);
157 void DeleteExistingFaceTagData(const std::string& inClause);
158 std::vector<FaceTagTbl> QueryFaceTagTbl(int32_t offset, std::vector<std::string> &commonColumns);
159 void RestorePortraitClusteringInfo();
160 void ReportPortraitCloneStat(int32_t sceneCode);
161 void AppendExtraWhereClause(std::string& whereClause, const std::string& tableName);
162 void GenNewCoverUris(const std::vector<CoverUriInfo>& coverUriInfo,
163 std::vector<FileInfo> &fileInfos);
164 bool GetFileInfoByFileId(int32_t fileId, const std::vector<FileInfo>& fileInfos, FileInfo& outFileInfo);
165 std::string GenCoverUriUpdateSql(const std::unordered_map<std::string, std::pair<std::string, int32_t>>&
166 tagIdToCoverInfo, const std::unordered_map<std::string, int32_t>& oldToNewFileId,
167 const std::vector<FileInfo>& fileInfos, std::vector<std::string>& tagIds);
168 std::string ProcessUriAndGenNew(const std::string& tagId, const std::string& oldCoverUri,
169 const std::unordered_map<std::string, int32_t>& oldToNewFileId, const std::vector<FileInfo>& fileInfos);
170 int32_t MoveThumbnail(FileInfo &fileInfo);
171 int32_t MoveThumbnailDir(FileInfo &fileInfo);
172 int32_t MoveAstc(FileInfo &fileInfo);
173 void InitThumbnailStatus();
174 bool InitAllKvStore();
175 void CloseAllKvStore();
176 bool BackupKvStore();
177 void GetThumbnailInsertValue(const FileInfo &fileInfo, NativeRdb::ValuesBucket &values);
178 int32_t GetNoNeedMigrateCount() override;
179
180 template<typename T>
181 static void PutIfPresent(NativeRdb::ValuesBucket& values, const std::string& columnName,
182 const std::optional<T>& optionalValue);
183
184 template<typename T>
185 void PutWithDefault(NativeRdb::ValuesBucket& values, const std::string& columnName,
186 const std::optional<T>& optionalValue, const T& defaultValue);
187 int32_t MoveEditedData(FileInfo &fileInfo);
188
189 private:
190 std::atomic<uint64_t> migrateDatabaseAlbumNumber_{0};
191 std::atomic<uint64_t> migrateDatabaseMapNumber_{0};
192 std::shared_ptr<NativeRdb::RdbStore> mediaRdb_;
193 std::string filePath_;
194 std::string dbPath_;
195 std::unordered_map<std::string, bool> tableColumnStatusMap_;
196 std::unordered_map<std::string, std::string> tableQueryWhereClauseMap_;
197 std::unordered_map<std::string, std::string> tableExtraQueryWhereClauseMap_;
198 std::unordered_map<std::string, std::unordered_map<int32_t, int32_t>> tableAlbumIdMap_;
199 std::unordered_map<std::string, std::unordered_map<std::string, std::string>> tableCommonColumnInfoMap_;
200 std::string garbagePath_;
201 std::vector<CoverUriInfo> coverUriInfo_;
202 std::vector<PortraitAlbumDfx> portraitAlbumDfx_;
203 PhotoAlbumClone photoAlbumClone_;
204 PhotosClone photosClone_;
205 static constexpr int32_t INVALID_COVER_SATISFIED_STATUS = -1;
206 bool hasCloneThumbnailDir_{false};
207 bool isInitKvstoreSuccess_{false};
208 std::shared_ptr<MediaLibraryKvStore> oldMonthKvStorePtr_ = nullptr;
209 std::shared_ptr<MediaLibraryKvStore> oldYearKvStorePtr_ = nullptr;
210 std::shared_ptr<MediaLibraryKvStore> newMonthKvStorePtr_ = nullptr;
211 std::shared_ptr<MediaLibraryKvStore> newYearKvStorePtr_ = nullptr;
212 std::vector<int> photosFailedOffsets;
213 };
214
215 template<typename T>
PutIfPresent(NativeRdb::ValuesBucket & values,const std::string & columnName,const std::optional<T> & optionalValue)216 void CloneRestore::PutIfPresent(NativeRdb::ValuesBucket& values, const std::string& columnName,
217 const std::optional<T>& optionalValue)
218 {
219 if (optionalValue.has_value()) {
220 if constexpr (std::is_same_v<std::decay_t<T>, int32_t>) {
221 values.PutInt(columnName, optionalValue.value());
222 } else if constexpr (std::is_same_v<std::decay_t<T>, int64_t>) {
223 values.PutLong(columnName, optionalValue.value());
224 } else if constexpr (std::is_same_v<std::decay_t<T>, std::string>) {
225 values.PutString(columnName, optionalValue.value());
226 } else if constexpr (std::is_same_v<std::decay_t<T>, double>) {
227 values.PutDouble(columnName, optionalValue.value());
228 }
229 }
230 }
231
232 template<typename T>
PutWithDefault(NativeRdb::ValuesBucket & values,const std::string & columnName,const std::optional<T> & optionalValue,const T & defaultValue)233 void CloneRestore::PutWithDefault(NativeRdb::ValuesBucket& values, const std::string& columnName,
234 const std::optional<T>& optionalValue, const T& defaultValue)
235 {
236 if (optionalValue.has_value()) {
237 PutIfPresent(values, columnName, optionalValue);
238 } else {
239 PutIfPresent(values, columnName, std::optional<T>(defaultValue));
240 }
241 }
242 } // namespace Media
243 } // namespace OHOS
244
245 #endif // OHOS_MEDIA_CLONE_RESTORE_H
246