1 /* 2 * Copyright (C) 2024-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 16 #ifndef OHOS_MEDIA_PHOTO_ALBUM_LPATH_OPERATION_H 17 #define OHOS_MEDIA_PHOTO_ALBUM_LPATH_OPERATION_H 18 19 #include <string> 20 #include <vector> 21 22 #include "medialibrary_rdbstore.h" 23 #include "photo_album_info_po.h" 24 25 namespace OHOS::Media { 26 class PhotoAlbumLPathOperation { 27 public: 28 static PhotoAlbumLPathOperation &GetInstance(); 29 PhotoAlbumLPathOperation &SetRdbStore(const std::shared_ptr<MediaLibraryRdbStore> &rdbStorePtr); 30 PhotoAlbumLPathOperation &CleanInvalidPhotoAlbums(); 31 PhotoAlbumLPathOperation &CleanDuplicatePhotoAlbums(); 32 PhotoAlbumLPathOperation &CleanEmptylPathPhotoAlbums(); 33 int32_t GetAlbumAffectedCount() const; 34 PhotoAlbumLPathOperation &Start(); 35 void Stop(); 36 37 private: 38 std::string ToString(const std::vector<NativeRdb::ValueObject> &values); 39 std::vector<PhotoAlbumInfoPo> GetInvalidPhotoAlbums(); 40 std::vector<PhotoAlbumInfoPo> GetDuplicatelPathAlbumInfoMain(); 41 std::vector<PhotoAlbumInfoPo> GetDuplicatelPathAlbumInfoSub(const PhotoAlbumInfoPo &albumInfo); 42 int32_t MergePhotoAlbum(const PhotoAlbumInfoPo &mainAlbumInfo, const PhotoAlbumInfoPo &subAlbumInfo); 43 std::vector<PhotoAlbumInfoPo> GetEmptylPathAlbumInfo(); 44 int32_t CleanDuplicatePhotoAlbum(const PhotoAlbumInfoPo &mainAlbumInfo); 45 int32_t CleanEmptylPathPhotoAlbum(const PhotoAlbumInfoPo &subAlbumInfo); 46 PhotoAlbumInfoPo GetLatestAlbumInfoBylPath(const std::string &lPath); 47 int32_t UpdateAlbumInfoFromAlbumPluginByAlbumId(const PhotoAlbumInfoPo &albumInfo); 48 int32_t UpdateAlbumLPathByAlbumId(const PhotoAlbumInfoPo &albumInfo); 49 50 private: 51 std::shared_ptr<MediaLibraryRdbStore> rdbStorePtr_; 52 int32_t albumAffectedCount_; 53 std::atomic<bool> isContinue_{true}; 54 static std::shared_ptr<PhotoAlbumLPathOperation> instance_; 55 static std::mutex objMutex_; 56 57 private: 58 const std::string SQL_PHOTO_ALBUM_EMPTY_QUERY = "\ 59 SELECT \ 60 album_id, \ 61 album_name, \ 62 album_type, \ 63 album_subtype, \ 64 lpath, \ 65 bundle_name, \ 66 dirty, \ 67 count, \ 68 cloud_id, \ 69 priority \ 70 FROM PhotoAlbum \ 71 WHERE COALESCE(lpath, '') = '' AND \ 72 album_type = 2048 AND \ 73 COALESCE(PhotoAlbum.dirty, 1) <> 4 AND \ 74 album_id NOT IN ( \ 75 SELECT DISTINCT owner_album_id \ 76 FROM Photos \ 77 ) AND \ 78 album_id NOT IN ( \ 79 SELECT DISTINCT map_album \ 80 FROM PhotoMap \ 81 INNER JOIN Photos \ 82 ON PhotoMap.map_asset = Photos.file_id \ 83 );"; 84 const std::string SQL_PHOTO_ALBUM_EMPTY_DELETE = "\ 85 DELETE FROM PhotoAlbum \ 86 WHERE COALESCE(lpath, '') = '' AND \ 87 album_type = 2048 AND \ 88 COALESCE(PhotoAlbum.dirty, 1) <> 4 AND \ 89 album_id NOT IN ( \ 90 SELECT DISTINCT owner_album_id \ 91 FROM Photos \ 92 ) AND \ 93 album_id NOT IN ( \ 94 SELECT DISTINCT map_album \ 95 FROM PhotoMap \ 96 INNER JOIN Photos \ 97 ON PhotoMap.map_asset = Photos.file_id \ 98 ) ;"; 99 const std::string SQL_PHOTO_ALBUM_DUPLICATE_LPATH_MAIN_QUERY = "\ 100 SELECT \ 101 album_id, \ 102 album_name, \ 103 album_type, \ 104 album_subtype, \ 105 lpath, \ 106 bundle_name, \ 107 dirty, \ 108 count, \ 109 cloud_id, \ 110 priority \ 111 FROM PhotoAlbum \ 112 WHERE album_id IN \ 113 ( \ 114 SELECT \ 115 MAX(album_id) AS album_id \ 116 FROM PhotoAlbum \ 117 WHERE album_type IN (0, 2048) AND \ 118 COALESCE(lpath, '') <> '' \ 119 GROUP BY LOWER(lpath) \ 120 HAVING COUNT(1) > 1 \ 121 ) \ 122 ORDER BY album_id;"; 123 const std::string SQL_PHOTO_ALBUM_DUPLICATE_LPATH_SUB_QUERY = "\ 124 SELECT \ 125 PhotoAlbum.album_id, \ 126 album_name, \ 127 album_type, \ 128 album_subtype, \ 129 PhotoAlbum.lpath, \ 130 bundle_name, \ 131 dirty, \ 132 count, \ 133 cloud_id, \ 134 priority \ 135 FROM PhotoAlbum \ 136 LEFT JOIN \ 137 ( \ 138 SELECT \ 139 ? AS album_id, \ 140 ? AS lpath \ 141 ) AS INPUT \ 142 ON 1 = 1 \ 143 WHERE album_type IN (0, 2048) AND \ 144 LOWER(COALESCE(PhotoAlbum.lpath, '')) = LOWER(INPUT.lpath) AND \ 145 PhotoAlbum.album_id <> INPUT.album_id \ 146 ORDER BY PhotoAlbum.album_id;"; 147 const std::string SQL_PHOTO_ALBUM_FIX_LPATH_QUERY = "\ 148 SELECT \ 149 album_id, \ 150 album_name, \ 151 album_type, \ 152 album_subtype, \ 153 lpath, \ 154 bundle_name, \ 155 dirty, \ 156 count, \ 157 cloud_id, \ 158 priority \ 159 FROM \ 160 ( \ 161 SELECT \ 162 album_id, \ 163 EMPTY.album_name, \ 164 album_type, \ 165 album_subtype, \ 166 CASE WHEN COALESCE(BUNDLE.bundle_name, '') <> '' THEN BUNDLE.lpath \ 167 WHEN COALESCE(cloud_id, '') <> '' THEN '' \ 168 WHEN COALESCE(NAME.album_name, '') <> '' THEN NAME.lpath \ 169 ELSE '/Pictures/'||EMPTY.album_name \ 170 END AS lpath, \ 171 EMPTY.bundle_name, \ 172 dirty, \ 173 count, \ 174 cloud_id, \ 175 priority \ 176 FROM \ 177 ( \ 178 SELECT \ 179 album_id, \ 180 album_name, \ 181 album_type, \ 182 album_subtype, \ 183 lpath, \ 184 bundle_name, \ 185 dirty, \ 186 count, \ 187 cloud_id, \ 188 priority \ 189 FROM PhotoAlbum \ 190 WHERE COALESCE(lPath, '') = '' AND \ 191 album_type = 2048 \ 192 ) AS EMPTY \ 193 LEFT JOIN \ 194 ( \ 195 SELECT DISTINCT \ 196 bundle_name, \ 197 lpath \ 198 FROM album_plugin \ 199 WHERE COALESCE(bundle_name, '') <> '' AND \ 200 COALESCE(priority, 1) = 1 \ 201 ) AS BUNDLE \ 202 ON COALESCE(EMPTY.bundle_name, '') = COALESCE(BUNDLE.bundle_name, '') \ 203 LEFT JOIN \ 204 ( \ 205 SELECT DISTINCT album_name, \ 206 album_name_en, \ 207 lpath \ 208 FROM album_plugin \ 209 WHERE COALESCE(album_name, '') <> '' AND \ 210 COALESCE(priority, 1) = 1 \ 211 ) AS NAME \ 212 ON COALESCE(EMPTY.album_name, '') = COALESCE(NAME.album_name, '') OR \ 213 COALESCE(EMPTY.album_name, '') = COALESCE(NAME.album_name_en, '') \ 214 ) \ 215 WHERE COALESCE(lpath, '') <> '' \ 216 ORDER BY album_id; "; 217 const std::string SQL_PHOTO_ALBUM_SYNC_BUNDLE_NAME_UPDATE = "\ 218 UPDATE PhotoAlbum \ 219 SET \ 220 album_name = COALESCE( \ 221 ( \ 222 SELECT album_name \ 223 FROM album_plugin \ 224 WHERE LOWER(lpath) = LOWER(?) \ 225 LIMIT 1 \ 226 ), album_name), \ 227 bundle_name = COALESCE( \ 228 ( \ 229 SELECT bundle_name \ 230 FROM album_plugin \ 231 WHERE LOWER(lpath) = LOWER(?) \ 232 LIMIT 1 \ 233 ), bundle_name), \ 234 priority = COALESCE( \ 235 ( \ 236 SELECT priority \ 237 FROM album_plugin \ 238 WHERE LOWER(lpath) = LOWER(?) \ 239 LIMIT 1 \ 240 ), priority) \ 241 WHERE album_id = ? AND \ 242 LOWER(lpath) = LOWER(?) AND \ 243 LOWER(lpath) IN ( \ 244 SELECT DISTINCT LOWER(lpath) \ 245 FROM album_plugin \ 246 WHERE COALESCE(lpath,'') <> '' \ 247 );"; 248 const std::string SQL_PHOTO_ALBUM_QUERY_BY_LPATH = "\ 249 SELECT \ 250 album_id, \ 251 album_name, \ 252 album_type, \ 253 album_subtype, \ 254 lpath, \ 255 bundle_name, \ 256 dirty, \ 257 count, \ 258 cloud_id, \ 259 priority \ 260 FROM PhotoAlbum \ 261 WHERE LOWER(COALESCE(lpath, '')) = LOWER(?) \ 262 ORDER BY album_id DESC \ 263 LIMIT 1;"; 264 const std::string SQL_PHOTO_ALBUM_UPDATE_LPATH_BY_ALBUM_ID = "\ 265 UPDATE PhotoAlbum \ 266 SET lpath = ? \ 267 WHERE album_id = ? AND \ 268 album_type = 2048 AND \ 269 COALESCE(lpath, '') = '' AND \ 270 LOWER(?) NOT IN ( \ 271 SELECT DISTINCT LOWER(PA.lpath) \ 272 FROM PhotoAlbum AS PA \ 273 WHERE COALESCE(PA.lpath, '') <> '' \ 274 );"; 275 }; 276 } // namespace OHOS::Media 277 #endif // OHOS_MEDIA_PHOTO_ALBUM_LPATH_OPERATION_H