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 30 private: 31 int32_t UpgradeAlbumPlugin(NativeRdb::RdbStore &store); 32 int32_t UpgradePhotoAlbum(NativeRdb::RdbStore &store); 33 int32_t UpgradePhotos(NativeRdb::RdbStore &store); 34 int32_t UpgradePhotoMap(NativeRdb::RdbStore &store); 35 int32_t MergeAlbumFromOldBundleNameToNewBundleName(NativeRdb::RdbStore &store); 36 int32_t UpgradePhotosBelongsToAlbum(NativeRdb::RdbStore &store); 37 38 private: 39 int32_t AddOwnerAlbumIdColumn(NativeRdb::RdbStore &store); 40 int32_t AddlPathColumn(NativeRdb::RdbStore &store); 41 int32_t MoveSingleRelationshipToPhotos(NativeRdb::RdbStore &store); 42 int32_t DropPhotoAlbumTrigger(NativeRdb::RdbStore &store); 43 int32_t UpdatelPathColumn(NativeRdb::RdbStore &store); 44 int32_t ExecSqlsInternal(NativeRdb::RdbStore &store, const std::string &sql, 45 const std::vector<NativeRdb::ValueObject> &args = {}); 46 47 private: 48 DbUpgradeUtils dbUpgradeUtils_; 49 50 private: 51 const std::vector<std::string> SQL_PHOTO_ALBUM_TABLE_DROP_TRIGGER = {"DROP TRIGGER IF EXISTS album_delete_trigger", 52 "DROP TRIGGER IF EXISTS album_insert_cloud_sync_trigger", 53 "DROP TRIGGER IF EXISTS album_modify_trigger", 54 "DROP TRIGGER IF EXISTS album_update_search_trigger", 55 "DROP TRIGGER IF EXISTS insert_order_trigger", 56 "DROP TRIGGER IF EXISTS photo_album_clear_map", 57 "DROP TRIGGER IF EXISTS update_order_trigger"}; 58 const std::string SQL_PHOTO_ALBUM_TABLE_ADD_LPATH_COLUMN = "ALTER TABLE PhotoAlbum ADD COLUMN lpath TEXT;"; 59 const std::string SQL_PHOTO_ALBUM_TABLE_UPDATE_LPATH_COLUMN = "\ 60 UPDATE PhotoAlbum \ 61 SET lpath = \ 62 ( \ 63 SELECT \ 64 CASE \ 65 WHEN COALESCE(album_plugin.bundle_name, '') <> '' \ 66 AND COALESCE(album_plugin.lpath, '') <> '' THEN album_plugin.lpath \ 67 WHEN album_type=2048 THEN '/Pictures/'||PA.album_name \ 68 WHEN album_type=0 THEN '/Pictures/Users/'||PA.album_name \ 69 ELSE '/Pictures/其它' \ 70 END AS lpath \ 71 FROM PhotoAlbum AS PA \ 72 LEFT JOIN album_plugin \ 73 ON PA.bundle_name = album_plugin.bundle_name \ 74 WHERE PhotoAlbum.album_id=PA.album_id \ 75 ORDER BY album_plugin.priority DESC, album_plugin.lpath ASC \ 76 LIMIT 1 \ 77 ) \ 78 WHERE COALESCE(PhotoAlbum.album_name, '') <> '' AND \ 79 PhotoAlbum.album_subtype != 1024 AND \ 80 COALESCE(PhotoAlbum.lpath, '') = '';"; 81 const std::string SQL_PHOTOS_TABLE_ADD_OWNER_ALBUM_ID = "\ 82 ALTER TABLE Photos ADD COLUMN owner_album_id INT DEFAULT 0;"; 83 const std::string SQL_TEMP_PHOTO_MAP_TABLE_DROP = "DROP TABLE IF EXISTS temp_photo_map;"; 84 // 使用 group 分组查找 Photos 的一条关联关系 85 const std::string SQL_TEMP_PHOTO_MAP_TABLE_CREATE = "\ 86 CREATE TABLE IF NOT EXISTS temp_photo_map \ 87 AS \ 88 SELECT MIN(map_album) AS map_album, \ 89 map_asset \ 90 FROM PhotoMap \ 91 INNER JOIN Photos \ 92 ON PhotoMap.map_asset=Photos.file_id \ 93 WHERE position IN (1, 3) \ 94 GROUP BY map_asset;"; 95 const std::vector<std::string> SQL_TEMP_PHOTO_MAP_TABLE_CREATE_INDEX_ARRAY = { 96 "CREATE INDEX IF NOT EXISTS unique_index_temp_photo_map_map_asset ON temp_photo_map ( \ 97 map_asset \ 98 );", 99 "CREATE UNIQUE INDEX IF NOT EXISTS unique_index_temp_photo_map_all ON temp_photo_map ( \ 100 map_album, map_asset \ 101 );"}; 102 const std::vector<std::string> SQL_PHOTOS_TABLE_DROP_TRIGGER_ARRAY = { 103 "DROP TRIGGER IF EXISTS photos_delete_trigger;", 104 "DROP TRIGGER IF EXISTS photos_fdirty_trigger;", 105 "DROP TRIGGER IF EXISTS photos_mdirty_trigger;", 106 "DROP TRIGGER IF EXISTS photo_insert_cloud_sync_trigger;", 107 "DROP TRIGGER IF EXISTS photo_update_cloud_sync_trigger;", 108 "DROP TRIGGER IF EXISTS delete_photo_clear_map;", 109 "DROP TRIGGER IF EXISTS update_vision_trigger;", 110 "DROP TRIGGER IF EXISTS delete_vision_trigger;", 111 "DROP TRIGGER IF EXISTS insert_vision_trigger;", 112 "DROP TRIGGER IF EXISTS insert_photo_insert_source_album;", 113 "DROP TRIGGER IF EXISTS insert_photo_update_source_album;", 114 "DROP TRIGGER IF EXISTS insert_photo_update_album_bundlename;", 115 "DROP TRIGGER IF EXISTS insert_search_trigger;", 116 "DROP TRIGGER IF EXISTS update_search_trigger;", 117 "DROP TRIGGER IF EXISTS update_search_status_trigger;", 118 "DROP TRIGGER IF EXISTS delete_search_trigger;"}; 119 // owner_album_id 默认值是 0,使用 UNION 避免无查询结果时,被更新为 NULL 120 const std::string SQL_PHOTOS_TABLE_UPDATE_ALBUM_ID = "\ 121 UPDATE Photos SET owner_album_id = \ 122 ( \ 123 SELECT map_album \ 124 FROM temp_photo_map \ 125 WHERE file_id=map_asset \ 126 UNION \ 127 SELECT 0 AS map_album \ 128 ORDER BY map_album DESC \ 129 LIMIT 1 \ 130 ) \ 131 WHERE COALESCE(owner_album_id, 0)=0;"; 132 const std::vector<std::string> SQL_PHOTO_MAP_TABLE_DROP_TRIGGER_ARRAY = { 133 "DROP TRIGGER IF EXISTS album_map_delete_search_trigger;", 134 "DROP TRIGGER IF EXISTS album_map_delete_trigger;", 135 "DROP TRIGGER IF EXISTS album_map_insert_cloud_sync_trigger;", 136 "DROP TRIGGER IF EXISTS album_map_insert_search_trigger;"}; 137 const std::string SQL_PHOTO_MAP_TABLE_DELETE_SINGLE_RELATIONSHIP = "\ 138 DELETE FROM PhotoMap \ 139 WHERE EXISTS \ 140 ( \ 141 SELECT 1 \ 142 FROM temp_photo_map \ 143 WHERE PhotoMap.map_album=temp_photo_map.map_album AND \ 144 PhotoMap.map_asset=temp_photo_map.map_asset \ 145 );"; 146 /* Clear the cache table. */ 147 const std::string SQL_TEMP_ALBUM_BUNDLE_NAME_DELETE = "\ 148 DROP TABLE IF EXISTS temp_album_bundle_name;"; 149 /* Cache the mapping of old to new bundle names */ 150 const std::string SQL_TEMP_ALBUM_BUNDLE_NAME_CREATE = "\ 151 CREATE TABLE IF NOT EXISTS temp_album_bundle_name \ 152 AS \ 153 SELECT \ 154 'com.huawei.ohos.screenrecorder' AS bundle_name_old, \ 155 'com.huawei.hmos.screenrecorder' AS bundle_name_new \ 156 UNION \ 157 SELECT \ 158 'com.huawei.ohos.screenshot' AS bundle_name_old, \ 159 'com.huawei.hmos.screenshot' AS bundle_name_new \ 160 ;"; 161 /* Create the Album if it doesn't exist */ 162 const std::string SQL_PHOTO_ALBUM_INSERT_NEW_ALBUM = "\ 163 INSERT INTO PhotoAlbum( \ 164 album_type, \ 165 album_subtype, \ 166 album_name, \ 167 bundle_name, \ 168 lpath \ 169 ) \ 170 SELECT \ 171 PA1.album_type, \ 172 PA1.album_subtype, \ 173 PA1.album_name, \ 174 M.bundle_name_new AS bundle_name, \ 175 CASE \ 176 WHEN COALESCE(album_plugin.lpath,'') <> '' THEN album_plugin.lpath \ 177 ELSE '/Pictures/'||PA1.album_name \ 178 END AS lpath \ 179 FROM PhotoAlbum AS PA1 \ 180 INNER JOIN temp_album_bundle_name AS M \ 181 ON PA1.bundle_name=M.bundle_name_old \ 182 LEFT JOIN PhotoAlbum AS PA2 \ 183 ON M.bundle_name_new=PA2.bundle_name \ 184 LEFT JOIN album_plugin \ 185 ON M.bundle_name_new=album_plugin.bundle_name \ 186 WHERE PA2.bundle_name IS NULL;"; 187 /* Add the relationship in PhotoMap for new Album and Photo */ 188 const std::string SQL_PHOTO_MAP_INSERT_NEW_ALBUM = "\ 189 INSERT INTO PhotoMap( \ 190 map_album, \ 191 map_asset \ 192 ) \ 193 SELECT \ 194 PA2.album_id AS album_id_new, \ 195 PM.map_asset \ 196 FROM PhotoAlbum AS PA1 \ 197 INNER JOIN temp_album_bundle_name AS M \ 198 ON PA1.bundle_name=M.bundle_name_old \ 199 INNER JOIN PhotoAlbum AS PA2 \ 200 ON M.bundle_name_new=PA2.bundle_name \ 201 INNER JOIN PhotoMap AS PM \ 202 ON PA1.album_id=PM.map_album \ 203 EXCEPT \ 204 SELECT PA.album_id, \ 205 PM.map_asset \ 206 FROM PhotoAlbum AS PA \ 207 INNER JOIN temp_album_bundle_name AS M \ 208 ON PA.bundle_name=M.bundle_name_new \ 209 INNER JOIN PhotoMap AS PM \ 210 ON PA.album_id=PM.map_album \ 211 ; "; 212 /* Remove the relationship in PhotoMap for old Album and Photo */ 213 const std::string SQL_PHOTO_MAP_DELETE_OLD_ALBUM = "\ 214 DELETE FROM PhotoMap \ 215 WHERE map_album IN \ 216 ( \ 217 SELECT \ 218 PA1.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 );"; 223 /* Replace the relationship in Photos for new Album and Photo */ 224 const std::string SQL_PHOTOS_UPDATE_NEW_ALBUM = "\ 225 UPDATE Photos \ 226 SET owner_album_id=( \ 227 SELECT PA2.album_id \ 228 FROM PhotoAlbum AS PA1 \ 229 INNER JOIN temp_album_bundle_name AS M \ 230 ON PA1.bundle_name=M.bundle_name_old \ 231 INNER JOIN PhotoAlbum AS PA2 \ 232 ON M.bundle_name_new=PA2.bundle_name \ 233 WHERE Photos.owner_album_id=PA1.album_id \ 234 ) \ 235 WHERE owner_album_id IN \ 236 ( \ 237 SELECT \ 238 PA1.album_id \ 239 FROM PhotoAlbum AS PA1 \ 240 INNER JOIN temp_album_bundle_name AS M \ 241 ON PA1.bundle_name=M.bundle_name_old \ 242 ); "; 243 /* Remove the relationship in Photos for old Album and Photo */ 244 const std::string SQL_PHOTO_ALBUM_DELETE_OLD_ALBUM = "\ 245 DELETE FROM PhotoAlbum \ 246 WHERE album_id IN \ 247 ( \ 248 SELECT \ 249 PA.album_id \ 250 FROM PhotoAlbum AS PA \ 251 INNER JOIN temp_album_bundle_name AS M \ 252 ON PA.bundle_name=M.bundle_name_old \ 253 ); "; 254 const std::vector<std::string> SQL_MERGE_ALBUM_FROM_OLD_BUNDLE_NAME_TO_NEW_BUNDLE_NAME = { 255 SQL_TEMP_ALBUM_BUNDLE_NAME_DELETE, 256 SQL_TEMP_ALBUM_BUNDLE_NAME_CREATE, 257 SQL_PHOTO_ALBUM_INSERT_NEW_ALBUM, 258 SQL_PHOTO_MAP_INSERT_NEW_ALBUM, 259 SQL_PHOTO_MAP_DELETE_OLD_ALBUM, 260 SQL_PHOTOS_UPDATE_NEW_ALBUM, 261 SQL_PHOTO_ALBUM_DELETE_OLD_ALBUM, 262 SQL_TEMP_ALBUM_BUNDLE_NAME_DELETE, 263 }; 264 /* Create the Album if it doesn't exist */ 265 const std::string SQL_PHOTO_ALBUM_INSERT_OTHER_ALBUM = "\ 266 INSERT INTO PhotoAlbum( \ 267 album_type, \ 268 album_subtype, \ 269 album_name, \ 270 bundle_name, \ 271 lpath \ 272 ) \ 273 SELECT \ 274 2048 AS album_type, \ 275 2049 AS album_subtype, \ 276 '其它' AS album_name, \ 277 'com.other.album' AS bundle_name, \ 278 '/Pictures/其它' AS lpath \ 279 EXCEPT \ 280 SELECT \ 281 album_type, \ 282 album_subtype, \ 283 album_name, \ 284 bundle_name, \ 285 lpath \ 286 FROM PhotoAlbum ;"; 287 /* The Photo, doesn't belong to any album, should belongs to '其它' album */ 288 const std::string SQL_PHOTOS_UPDATE_OTHER_ALBUM = "\ 289 UPDATE Photos \ 290 SET owner_album_id=( \ 291 SELECT album_id \ 292 FROM PhotoAlbum \ 293 WHERE lpath='/Pictures/其它' \ 294 LIMIT 1 \ 295 ) \ 296 WHERE file_id IN \ 297 ( \ 298 SELECT file_id \ 299 FROM Photos \ 300 LEFT JOIN PhotoMap \ 301 ON Photos.file_id = PhotoMap.map_asset \ 302 WHERE PhotoMap.map_asset IS NULL AND \ 303 COALESCE(Photos.owner_album_id, 0) = 0 AND \ 304 Photos.position IN (1, 3) \ 305 );"; 306 const std::vector<std::string> SQL_PHOTOS_NEED_TO_BELONGS_TO_ALBUM = { 307 SQL_PHOTO_ALBUM_INSERT_OTHER_ALBUM, 308 SQL_PHOTOS_UPDATE_OTHER_ALBUM, 309 }; 310 }; 311 } // namespace DataTransfer 312 } // namespace OHOS::Media 313 #endif // OHOS_MEDIA_DATATRANSFER_MEDIA_LIBRARY_DB_UPGRADE_H