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 #ifndef OHOS_MEDIA_PHOTOS_CLONE
16 #define OHOS_MEDIA_PHOTOS_CLONE
17 
18 #include <string>
19 #include <vector>
20 
21 #include "rdb_store.h"
22 #include "backup_const.h"
23 #include "photos_dao.h"
24 #include "photo_album_dao.h"
25 
26 namespace OHOS::Media {
27 class PhotosClone {
28 public:
29     /**
30      * @brief Restore Start Event Handler.
31      */
OnStart(std::shared_ptr<NativeRdb::RdbStore> mediaLibraryTargetRdb,std::shared_ptr<NativeRdb::RdbStore> mediaLibraryOriginalRdb)32     int32_t OnStart(std::shared_ptr<NativeRdb::RdbStore> mediaLibraryTargetRdb,
33         std::shared_ptr<NativeRdb::RdbStore> mediaLibraryOriginalRdb)
34     {
35         this->SetMediaLibraryTargetRdb(mediaLibraryTargetRdb)
36             .SetMediaLibraryOriginalRdb(mediaLibraryOriginalRdb)
37             .LoadBasicInfo();
38         return 0;
39     }
40 
41     /**
42      * @brief Load the PhotoAlbum cache of target media_library.db for quick access.
43      */
LoadPhotoAlbums()44     void LoadPhotoAlbums()
45     {
46         this->photoAlbumDao_.LoadPhotoAlbums();
47     }
48 
OnStop(std::atomic<uint64_t> & totalNumber,std::atomic<int32_t> & processStatus)49     int32_t OnStop(std::atomic<uint64_t> &totalNumber, std::atomic<int32_t> &processStatus)
50     {
51         processStatus = ProcessStatus::START;
52         this->FixDuplicateBurstKeyInDifferentAlbum(totalNumber);
53         processStatus = ProcessStatus::STOP;
54         return 0;
55     }
56 
FindSameFile(const FileInfo & fileInfo)57     PhotosDao::PhotosRowData FindSameFile(const FileInfo &fileInfo)
58     {
59         int32_t maxFileId = this->photosBasicInfo_.maxFileId;
60         return this->photosDao_.FindSameFile(fileInfo, maxFileId);
61     }
62 
63     std::shared_ptr<NativeRdb::ResultSet> GetPhotosInPhotoMap(int32_t offset, int32_t pageSize);
64     std::shared_ptr<NativeRdb::ResultSet> GetPhotosNotInPhotoMap(int32_t offset, int32_t pageSize);
65     int32_t GetPhotosRowCountInPhotoMap();
66     int32_t GetPhotosRowCountNotInPhotoMap();
67     std::string FindlPath(const FileInfo &fileInfo);
68     int32_t FindAlbumId(const FileInfo &fileInfo);
69     std::string FindPackageName(const FileInfo &info);
70     std::string FindBundleName(const FileInfo &info);
71     int32_t FindPhotoQuality(const FileInfo &fileInfo);
72     std::string FindSourcePath(const FileInfo &fileInfo);
73     int32_t GetNoNeedMigrateCount();
74 
75 private:
76     enum { UUID_STR_LENGTH = 37 };
77 
78 private:
SetMediaLibraryTargetRdb(std::shared_ptr<NativeRdb::RdbStore> mediaLibraryTargetRdb)79     PhotosClone &SetMediaLibraryTargetRdb(std::shared_ptr<NativeRdb::RdbStore> mediaLibraryTargetRdb)
80     {
81         this->mediaLibraryTargetRdb_ = mediaLibraryTargetRdb;
82         this->photosDao_.SetMediaLibraryRdb(mediaLibraryTargetRdb);
83         this->photoAlbumDao_.SetMediaLibraryRdb(mediaLibraryTargetRdb);
84         return *this;
85     }
SetMediaLibraryOriginalRdb(std::shared_ptr<NativeRdb::RdbStore> mediaLibraryOriginalRdb)86     PhotosClone &SetMediaLibraryOriginalRdb(std::shared_ptr<NativeRdb::RdbStore> mediaLibraryOriginalRdb)
87     {
88         this->mediaLibraryOriginalRdb_ = mediaLibraryOriginalRdb;
89         return *this;
90     }
LoadBasicInfo()91     void LoadBasicInfo()
92     {
93         this->photosBasicInfo_ = this->photosDao_.GetBasicInfo();
94     }
95     PhotoAlbumDao::PhotoAlbumRowData FindAlbumInfo(const FileInfo &fileInfo);
96     int32_t FixDuplicateBurstKeyInDifferentAlbum(std::atomic<uint64_t> &totalNumber);
97     std::vector<PhotosDao::PhotosRowData> FindDuplicateBurstKey();
98     std::string ToString(const std::vector<NativeRdb::ValueObject> &values);
99     std::string GenerateUuid();
100     std::string ToString(const FileInfo &fileInfo);
101     std::string ToLower(const std::string &str);
102 
103 private:
104     std::shared_ptr<NativeRdb::RdbStore> mediaLibraryTargetRdb_;
105     std::shared_ptr<NativeRdb::RdbStore> mediaLibraryOriginalRdb_;
106     PhotosDao::PhotosBasicInfo photosBasicInfo_;
107     PhotosDao photosDao_;
108     PhotoAlbumDao photoAlbumDao_;
109 
110 private:
111     const std::string SQL_PHOTOS_TABLE_COUNT_IN_PHOTO_MAP = "\
112         SELECT COUNT(1) AS count \
113         FROM PhotoAlbum \
114             INNER JOIN PhotoMap \
115             ON PhotoAlbum.album_id=PhotoMap.map_album \
116             INNER JOIN Photos \
117             ON PhotoMap.map_asset=Photos.file_id \
118         WHERE Photos.position IN (1, 3) AND \
119             (PhotoAlbum.album_type != 2048 OR PhotoAlbum.album_name != '.hiddenAlbum');";
120     const std::string SQL_PHOTOS_TABLE_QUERY_IN_PHOTO_MAP = "\
121         SELECT PhotoAlbum.lpath, \
122             Photos.* \
123         FROM PhotoAlbum \
124             INNER JOIN PhotoMap \
125             ON PhotoAlbum.album_id=PhotoMap.map_album \
126             INNER JOIN Photos \
127             ON PhotoMap.map_asset=Photos.file_id \
128         WHERE Photos.position IN (1, 3) AND \
129             (PhotoAlbum.album_type != 2048 OR PhotoAlbum.album_name != '.hiddenAlbum') \
130         ORDER BY Photos.file_id \
131         LIMIT ?, ? ;";
132     const std::string SQL_PHOTOS_TABLE_COUNT_NOT_IN_PHOTO_MAP = "\
133         SELECT COUNT(1) AS count \
134         FROM Photos \
135             LEFT JOIN PhotoAlbum \
136             ON Photos.owner_album_id = PhotoAlbum.album_id \
137         WHERE position IN (1, 3) AND \
138             (COALESCE(PhotoAlbum.album_type, 0) != 2048 OR COALESCE(PhotoAlbum.album_name, '') != '.hiddenAlbum');";
139     const std::string SQL_PHOTOS_TABLE_QUERY_NOT_IN_PHOTO_MAP = "\
140         SELECT \
141             PhotoAlbum.lpath, \
142             Photos.* \
143         FROM Photos \
144             LEFT JOIN PhotoAlbum \
145             ON Photos.owner_album_id=PhotoAlbum.album_id \
146         WHERE position IN (1, 3) AND \
147             (COALESCE(PhotoAlbum.album_type, 0) != 2048 OR COALESCE(PhotoAlbum.album_name, '') != '.hiddenAlbum') \
148         ORDER BY Photos.file_id \
149         LIMIT ?, ? ;";
150     const std::string SQL_PHOTOS_TABLE_BURST_KEY_DUPLICATE_QUERY = "\
151         SELECT DISTINCT \
152             Photos.owner_album_id, \
153             Photos.burst_key \
154         FROM \
155         ( \
156             SELECT burst_key, \
157                 COUNT(1) AS count \
158             FROM \
159             ( \
160                 SELECT owner_album_id, burst_key \
161                 FROM Photos \
162                 WHERE COALESCE(burst_key, '') <> '' \
163                 GROUP BY owner_album_id, burst_key \
164             ) \
165             GROUP BY burst_key \
166         ) AS BURST \
167         INNER JOIN Photos \
168         ON BURST.burst_key = Photos.burst_key \
169         WHERE BURST.count > 1 \
170         ORDER BY Photos.burst_key \
171         LIMIT ?, ? ;";
172     const std::string SQL_PHOTOS_TABLE_BURST_KEY_UPDATE = "\
173         UPDATE Photos \
174         SET burst_key = ? \
175         WHERE owner_album_id = ? AND \
176             burst_key = ?;";
177     const std::string SOURCE_PATH_PREFIX = "/storage/emulated/0";
178     const std::string SQL_PHOTOS_TABLE_COUNT_NO_NEED_MIGRATE = "\
179         SELECT COUNT(1) AS count \
180         FROM Photos \
181         WHERE position NOT IN (1, 3) AND \
182             sync_status = 0 AND \
183             clean_flag = 0 AND \
184             time_pending = 0 AND \
185             is_temp = 0;";
186 };
187 }  // namespace OHOS::Media
188 #endif