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 16 #ifndef OHOS_MEDIA_DATATRANSFER_MEDIA_LIBRARY_DB_UPGRADE_H 17 #define OHOS_MEDIA_DATATRANSFER_MEDIA_LIBRARY_DB_UPGRADE_H 18 19 #include <string> 20 21 #include "rdb_store.h" 22 #include "db_upgrade_utils.h" 23 24 namespace OHOS::Media { 25 namespace DataTransfer { 26 class MediaLibraryDbUpgrade { 27 public: 28 int32_t OnUpgrade(NativeRdb::RdbStore &store); 29 int32_t CreateClassifyAlbum(const std::string &newAlbumName, NativeRdb::RdbStore &store); 30 bool CheckClassifyAlbumExist(const std::string &newAlbumName, NativeRdb::RdbStore &store); 31 32 private: 33 int32_t UpgradeAlbumPlugin(NativeRdb::RdbStore &store); 34 int32_t UpgradePhotoAlbum(NativeRdb::RdbStore &store); 35 int32_t UpgradePhotos(NativeRdb::RdbStore &store); 36 int32_t UpgradePhotoMap(NativeRdb::RdbStore &store); 37 int32_t MergeAlbumFromOldBundleNameToNewBundleName(NativeRdb::RdbStore &store); 38 int32_t UpgradePhotosBelongsToAlbum(NativeRdb::RdbStore &store); 39 void AggregateClassifyAlbum(NativeRdb::RdbStore &store); 40 41 private: 42 int32_t AddOwnerAlbumIdColumn(NativeRdb::RdbStore &store); 43 int32_t AddlPathColumn(NativeRdb::RdbStore &store); 44 int32_t MoveSingleRelationshipToPhotos(NativeRdb::RdbStore &store); 45 int32_t UpdatelPathColumn(NativeRdb::RdbStore &store); 46 int32_t ExecSqlWithRetry(std::function<int32_t()> execSql); 47 void ProcessClassifyAlbum(const std::string &newAlbumName, const std::vector<std::string> &oriAlbumNames, 48 NativeRdb::RdbStore &store); 49 void ProcessOcrClassifyAlbum(const std::string &newAlbumName, const std::vector<std::string> &ocrText, 50 NativeRdb::RdbStore &store); 51 52 private: 53 DbUpgradeUtils dbUpgradeUtils_; 54 55 private: 56 const std::string SQL_PHOTO_ALBUM_TABLE_ADD_LPATH_COLUMN = "ALTER TABLE PhotoAlbum ADD COLUMN lpath TEXT;"; 57 const std::string SQL_PHOTO_ALBUM_TABLE_UPDATE_LPATH_COLUMN = "\ 58 UPDATE PhotoAlbum \ 59 SET lpath = \ 60 ( \ 61 SELECT \ 62 CASE \ 63 WHEN COALESCE(album_plugin.lpath, '') <> '' THEN album_plugin.lpath \ 64 WHEN COALESCE(plugin_v2.lpath, '') <> '' THEN plugin_v2.lpath \ 65 WHEN album_type = 2048 THEN '/Pictures/'||PA.album_name \ 66 WHEN album_type = 0 THEN '/Pictures/Users/'||PA.album_name \ 67 ELSE '/Pictures/其它' \ 68 END AS s_lpath \ 69 FROM PhotoAlbum AS PA \ 70 LEFT JOIN album_plugin \ 71 ON COALESCE(PA.bundle_name, '') <> '' AND PA.bundle_name = album_plugin.bundle_name \ 72 LEFT JOIN album_plugin AS plugin_v2 \ 73 ON PA.album_type = 2048 AND PA.album_name = plugin_v2.album_name \ 74 WHERE PhotoAlbum.album_id = PA.album_id \ 75 ORDER BY \ 76 ( \ 77 CASE \ 78 WHEN COALESCE(album_plugin.lpath, '') <> '' THEN album_plugin.priority \ 79 WHEN COALESCE(plugin_v2.lpath, '') <> '' THEN plugin_v2.priority \ 80 ELSE 1 \ 81 END \ 82 ) DESC, s_lpath ASC \ 83 LIMIT 1 \ 84 ) \ 85 WHERE COALESCE(PhotoAlbum.album_name, '') <> '' AND \ 86 PhotoAlbum.album_subtype != 1024 AND \ 87 COALESCE(PhotoAlbum.lpath, '') = '';"; 88 const std::string SQL_PHOTOS_TABLE_ADD_OWNER_ALBUM_ID = "\ 89 ALTER TABLE Photos ADD COLUMN owner_album_id INT DEFAULT 0;"; 90 const std::string SQL_TEMP_PHOTO_MAP_TABLE_DROP = "DROP TABLE IF EXISTS temp_photo_map;"; 91 // 使用 group 分组查找 Photos 的一条关联关系 92 const std::string SQL_TEMP_PHOTO_MAP_TABLE_CREATE = "\ 93 CREATE TABLE IF NOT EXISTS temp_photo_map \ 94 AS \ 95 SELECT MIN(map_album) AS map_album, \ 96 map_asset \ 97 FROM PhotoMap \ 98 INNER JOIN Photos \ 99 ON PhotoMap.map_asset=Photos.file_id \ 100 WHERE position IN (1, 3) AND \ 101 COALESCE(owner_album_id, 0) = 0 \ 102 GROUP BY map_asset;"; 103 const std::vector<std::string> SQL_TEMP_PHOTO_MAP_TABLE_CREATE_INDEX_ARRAY = { 104 "CREATE INDEX IF NOT EXISTS unique_index_temp_photo_map_map_asset ON temp_photo_map ( \ 105 map_asset \ 106 );", 107 "CREATE UNIQUE INDEX IF NOT EXISTS unique_index_temp_photo_map_all ON temp_photo_map ( \ 108 map_album, map_asset \ 109 );"}; 110 // owner_album_id 默认值是 0,使用 UNION 避免无查询结果时,被更新为 NULL 111 const std::string SQL_PHOTOS_TABLE_UPDATE_ALBUM_ID = "\ 112 UPDATE Photos SET owner_album_id = \ 113 ( \ 114 SELECT map_album \ 115 FROM temp_photo_map \ 116 WHERE file_id=map_asset \ 117 UNION \ 118 SELECT 0 AS map_album \ 119 ORDER BY map_album DESC \ 120 LIMIT 1 \ 121 ) \ 122 WHERE COALESCE(owner_album_id, 0)=0;"; 123 const std::string SQL_PHOTO_MAP_TABLE_DELETE_SINGLE_RELATIONSHIP = "\ 124 DELETE FROM PhotoMap \ 125 WHERE EXISTS \ 126 ( \ 127 SELECT 1 \ 128 FROM temp_photo_map \ 129 WHERE PhotoMap.map_album=temp_photo_map.map_album AND \ 130 PhotoMap.map_asset=temp_photo_map.map_asset \ 131 );"; 132 /* Clear the cache table. */ 133 const std::string SQL_TEMP_ALBUM_BUNDLE_NAME_DELETE = "\ 134 DROP TABLE IF EXISTS temp_album_bundle_name;"; 135 136 /* Cache the mapping of old to new bundle names */ 137 const std::string SQL_TEMP_ALBUM_BUNDLE_NAME_CREATE = 138 "CREATE TABLE IF NOT EXISTS temp_album_bundle_name (" 139 "bundle_name_old TEXT," 140 "bundle_name_new TEXT" 141 ");"; 142 143 const std::string SQL_TEMP_ALBUM_BUNDLE_NAME_INSERT = 144 "INSERT INTO temp_album_bundle_name (bundle_name_old, bundle_name_new) VALUES " 145 "('com.huawei.ohos.screenrecorder', 'com.huawei.hmos.screenrecorder')," 146 "('com.huawei.ohos.screenshot', 'com.huawei.hmos.screenshot');"; 147 148 /* Create the Album if it doesn't exist */ 149 const std::string SQL_PHOTO_ALBUM_INSERT_NEW_ALBUM = "\ 150 INSERT INTO PhotoAlbum( \ 151 album_type, \ 152 album_subtype, \ 153 album_name, \ 154 bundle_name, \ 155 lpath, \ 156 date_modified, \ 157 date_added \ 158 ) \ 159 SELECT \ 160 PA1.album_type, \ 161 PA1.album_subtype, \ 162 PA1.album_name, \ 163 M.bundle_name_new AS bundle_name, \ 164 CASE \ 165 WHEN COALESCE(album_plugin.lpath,'') <> '' THEN album_plugin.lpath \ 166 ELSE '/Pictures/'||PA1.album_name \ 167 END AS lpath, \ 168 strftime('%s000', 'now') AS date_modified, \ 169 strftime('%s000', 'now') AS date_added \ 170 FROM PhotoAlbum AS PA1 \ 171 INNER JOIN temp_album_bundle_name AS M \ 172 ON PA1.bundle_name=M.bundle_name_old \ 173 LEFT JOIN PhotoAlbum AS PA2 \ 174 ON M.bundle_name_new=PA2.bundle_name \ 175 LEFT JOIN album_plugin \ 176 ON M.bundle_name_new=album_plugin.bundle_name \ 177 WHERE PA2.bundle_name IS NULL;"; 178 /* Add the relationship in PhotoMap for new Album and Photo */ 179 const std::string SQL_PHOTO_MAP_INSERT_NEW_ALBUM = "\ 180 INSERT INTO PhotoMap( \ 181 map_album, \ 182 map_asset \ 183 ) \ 184 SELECT \ 185 PA2.album_id AS album_id_new, \ 186 PM.map_asset \ 187 FROM PhotoAlbum AS PA1 \ 188 INNER JOIN temp_album_bundle_name AS M \ 189 ON PA1.bundle_name=M.bundle_name_old \ 190 INNER JOIN PhotoAlbum AS PA2 \ 191 ON M.bundle_name_new=PA2.bundle_name \ 192 INNER JOIN PhotoMap AS PM \ 193 ON PA1.album_id=PM.map_album \ 194 EXCEPT \ 195 SELECT PA.album_id, \ 196 PM.map_asset \ 197 FROM PhotoAlbum AS PA \ 198 INNER JOIN temp_album_bundle_name AS M \ 199 ON PA.bundle_name=M.bundle_name_new \ 200 INNER JOIN PhotoMap AS PM \ 201 ON PA.album_id=PM.map_album \ 202 ; "; 203 /* Remove the relationship in PhotoMap for old Album and Photo */ 204 const std::string SQL_PHOTO_MAP_DELETE_OLD_ALBUM = "\ 205 DELETE FROM PhotoMap \ 206 WHERE map_album IN \ 207 ( \ 208 SELECT \ 209 PA1.album_id \ 210 FROM PhotoAlbum AS PA1 \ 211 INNER JOIN temp_album_bundle_name AS M \ 212 ON PA1.bundle_name=M.bundle_name_old \ 213 );"; 214 /* Replace the relationship in Photos for new Album and Photo */ 215 const std::string SQL_PHOTOS_UPDATE_NEW_ALBUM = "\ 216 UPDATE Photos \ 217 SET owner_album_id=( \ 218 SELECT PA2.album_id \ 219 FROM PhotoAlbum AS PA1 \ 220 INNER JOIN temp_album_bundle_name AS M \ 221 ON PA1.bundle_name=M.bundle_name_old \ 222 INNER JOIN PhotoAlbum AS PA2 \ 223 ON M.bundle_name_new=PA2.bundle_name \ 224 WHERE Photos.owner_album_id=PA1.album_id \ 225 ) \ 226 WHERE owner_album_id IN \ 227 ( \ 228 SELECT \ 229 PA1.album_id \ 230 FROM PhotoAlbum AS PA1 \ 231 INNER JOIN temp_album_bundle_name AS M \ 232 ON PA1.bundle_name=M.bundle_name_old \ 233 ); "; 234 /* Remove the relationship in Photos for old Album and Photo */ 235 const std::string SQL_PHOTO_ALBUM_DELETE_OLD_ALBUM = "\ 236 DELETE FROM PhotoAlbum \ 237 WHERE album_id IN \ 238 ( \ 239 SELECT \ 240 PA.album_id \ 241 FROM PhotoAlbum AS PA \ 242 INNER JOIN temp_album_bundle_name AS M \ 243 ON PA.bundle_name=M.bundle_name_old \ 244 ); "; 245 const std::vector<std::string> SQL_MERGE_ALBUM_FROM_OLD_BUNDLE_NAME_TO_NEW_BUNDLE_NAME = { 246 SQL_TEMP_ALBUM_BUNDLE_NAME_DELETE, 247 SQL_TEMP_ALBUM_BUNDLE_NAME_CREATE, 248 SQL_TEMP_ALBUM_BUNDLE_NAME_INSERT, 249 SQL_PHOTO_ALBUM_INSERT_NEW_ALBUM, 250 SQL_PHOTO_MAP_INSERT_NEW_ALBUM, 251 SQL_PHOTO_MAP_DELETE_OLD_ALBUM, 252 SQL_PHOTOS_UPDATE_NEW_ALBUM, 253 SQL_PHOTO_ALBUM_DELETE_OLD_ALBUM, 254 SQL_TEMP_ALBUM_BUNDLE_NAME_DELETE, 255 }; 256 /* Create the Album if it doesn't exist */ 257 const std::string SQL_PHOTO_ALBUM_INSERT_OTHER_ALBUM = "\ 258 INSERT INTO PhotoAlbum( \ 259 album_type, \ 260 album_subtype, \ 261 album_name, \ 262 bundle_name, \ 263 lpath \ 264 ) \ 265 SELECT \ 266 2048 AS album_type, \ 267 2049 AS album_subtype, \ 268 '其它' AS album_name, \ 269 'com.other.album' AS bundle_name, \ 270 '/Pictures/其它' AS lpath \ 271 EXCEPT \ 272 SELECT \ 273 album_type, \ 274 album_subtype, \ 275 album_name, \ 276 bundle_name, \ 277 lpath \ 278 FROM PhotoAlbum ;"; 279 /* The Photo, doesn't belong to any album, should belongs to '其它' album */ 280 const std::string SQL_PHOTOS_UPDATE_OTHER_ALBUM = "\ 281 UPDATE Photos \ 282 SET owner_album_id=( \ 283 SELECT album_id \ 284 FROM PhotoAlbum \ 285 WHERE lpath='/Pictures/其它' \ 286 LIMIT 1 \ 287 ) \ 288 WHERE file_id IN \ 289 ( \ 290 SELECT file_id \ 291 FROM Photos \ 292 LEFT JOIN PhotoMap \ 293 ON Photos.file_id = PhotoMap.map_asset \ 294 WHERE PhotoMap.map_asset IS NULL AND \ 295 COALESCE(Photos.owner_album_id, 0) = 0 AND \ 296 Photos.position IN (1, 3) \ 297 );"; 298 const std::vector<std::string> SQL_PHOTOS_NEED_TO_BELONGS_TO_ALBUM = { 299 SQL_PHOTO_ALBUM_INSERT_OTHER_ALBUM, 300 SQL_PHOTOS_UPDATE_OTHER_ALBUM, 301 }; 302 const std::string SQL_QUERY_CLASSIFY_ALBUM_EXIST = " \ 303 SELECT \ 304 count(1) AS count \ 305 FROM AnalysisAlbum \ 306 WHERE \ 307 album_type = ? \ 308 AND \ 309 album_subtype = ? \ 310 AND \ 311 album_name = ?;"; 312 const std::string SQL_CREATE_CLASSIFY_ALBUM = " \ 313 INSERT INTO AnalysisAlbum( \ 314 album_type, \ 315 album_subtype, \ 316 album_name, \ 317 is_local, \ 318 date_modified, \ 319 count \ 320 ) \ 321 VALUES( \ 322 ?, \ 323 ?, \ 324 ?, \ 325 1, \ 326 0, \ 327 0 \ 328 );"; 329 const std::string SQL_INSERT_MAPPING_RESULT = " \ 330 INSERT INTO AnalysisPhotoMap( \ 331 map_album, \ 332 map_asset \ 333 ) \ 334 SELECT DISTINCT ( \ 335 SELECT \ 336 album_id \ 337 FROM AnalysisAlbum \ 338 WHERE album_name = ? \ 339 ) AS album_id, \ 340 AnalysisPhotoMap.map_asset \ 341 FROM AnalysisAlbum \ 342 INNER JOIN AnalysisPhotoMap \ 343 ON AnalysisAlbum.album_id = AnalysisPhotoMap.map_album \ 344 AND AnalysisAlbum.album_type = ? \ 345 AND AnalysisAlbum.album_subtype = ? \ 346 AND AnalysisAlbum.album_name IN "; 347 const std::string SQL_SELECT_CLASSIFY_OCR = " \ 348 WITH TempResult AS ( \ 349 SELECT DISTINCT ( \ 350 SELECT \ 351 album_id \ 352 FROM AnalysisAlbum \ 353 WHERE album_name = ? \ 354 ) AS album_id, \ 355 AnalysisPhotoMap.map_asset as map_asset \ 356 FROM AnalysisAlbum \ 357 INNER JOIN AnalysisPhotoMap \ 358 ON AnalysisAlbum.album_id = AnalysisPhotoMap.map_album \ 359 AND AnalysisAlbum.album_type = ? \ 360 AND AnalysisAlbum.album_subtype = ? \ 361 AND AnalysisAlbum.album_name = ? \ 362 INNER JOIN tab_analysis_ocr \ 363 ON AnalysisPhotoMap.map_asset = tab_analysis_ocr.file_id \ 364 AND ("; 365 }; 366 } // namespace DataTransfer 367 } // namespace OHOS::Media 368 #endif // OHOS_MEDIA_DATATRANSFER_MEDIA_LIBRARY_DB_UPGRADE_H