1 /*
2  * Copyright (C) 2022-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 #define MLOG_TAG "RdbStore"
16 
17 #include "medialibrary_rdbstore.h"
18 
19 #include <mutex>
20 
21 #include "album_plugin_table_event_handler.h"
22 #include "cloud_sync_helper.h"
23 #include "dfx_manager.h"
24 #include "dfx_timer.h"
25 #include "dfx_const.h"
26 #include "dfx_reporter.h"
27 #include "ipc_skeleton.h"
28 #include "location_column.h"
29 #include "media_column.h"
30 #include "media_app_uri_permission_column.h"
31 #include "media_file_uri.h"
32 #include "media_file_utils.h"
33 #include "media_log.h"
34 #include "media_remote_thumbnail_column.h"
35 #include "media_smart_album_column.h"
36 #include "preferences.h"
37 #include "preferences_helper.h"
38 #ifdef DISTRIBUTED
39 #include "medialibrary_device.h"
40 #endif
41 #include "medialibrary_album_fusion_utils.h"
42 #include "medialibrary_album_compatibility_fusion_sql.h"
43 #include "medialibrary_album_refresh.h"
44 #include "medialibrary_business_record_column.h"
45 #include "medialibrary_db_const_sqls.h"
46 #include "medialibrary_errno.h"
47 #include "medialibrary_object_utils.h"
48 #include "medialibrary_photo_operations.h"
49 #include "medialibrary_restore.h"
50 #include "medialibrary_tracer.h"
51 #include "media_container_types.h"
52 #include "media_scanner.h"
53 #include "media_scanner_manager.h"
54 #include "medialibrary_notify.h"
55 #include "medialibrary_rdb_utils.h"
56 #include "medialibrary_unistore_manager.h"
57 #include "moving_photo_processor.h"
58 #include "parameters.h"
59 #include "parameter.h"
60 #include "photo_album_column.h"
61 #include "photo_map_column.h"
62 #include "post_event_utils.h"
63 #include "rdb_sql_utils.h"
64 #include "result_set_utils.h"
65 #include "source_album.h"
66 #include "tab_old_photos_table_event_handler.h"
67 #include "vision_column.h"
68 #include "search_column.h"
69 #include "form_map.h"
70 #include "shooting_mode_column.h"
71 #include "story_cover_info_column.h"
72 #include "story_db_sqls.h"
73 #include "story_play_info_column.h"
74 #include "dfx_const.h"
75 #include "dfx_timer.h"
76 #include "vision_multi_crop_column.h"
77 #include "preferences.h"
78 #include "preferences_helper.h"
79 #include "medialibrary_rdb_transaction.h"
80 #include "thumbnail_service.h"
81 
82 using namespace std;
83 using namespace OHOS::NativeRdb;
84 namespace OHOS::Media {
85 const std::string DIR_ALL_AUDIO_CONTAINER_TYPE = "." + AUDIO_CONTAINER_TYPE_AAC + "?" +
86                                                  "." + AUDIO_CONTAINER_TYPE_MP3 + "?" +
87                                                  "." + AUDIO_CONTAINER_TYPE_FLAC + "?" +
88                                                  "." + AUDIO_CONTAINER_TYPE_WAV + "?" +
89                                                  "." + AUDIO_CONTAINER_TYPE_OGG + "?" +
90                                                  "." + AUDIO_CONTAINER_TYPE_M4A + "?";
91 
92 const std::string DIR_ALL_VIDEO_CONTAINER_TYPE = "." + VIDEO_CONTAINER_TYPE_MP4 + "?" +
93                                                  "." + VIDEO_CONTAINER_TYPE_3GP + "?" +
94                                                  "." + VIDEO_CONTAINER_TYPE_MPG + "?" +
95                                                  "." + VIDEO_CONTAINER_TYPE_MOV + "?" +
96                                                  "." + VIDEO_CONTAINER_TYPE_WEBM + "?" +
97                                                  "." + VIDEO_CONTAINER_TYPE_MKV + "?" +
98                                                  "." + VIDEO_CONTAINER_TYPE_H264 + "?" +
99                                                  "." + VIDEO_CONTAINER_TYPE_MPEG + "?" +
100                                                  "." + VIDEO_CONTAINER_TYPE_TS + "?" +
101                                                  "." + VIDEO_CONTAINER_TYPE_M4V + "?" +
102                                                  "." + VIDEO_CONTAINER_TYPE_3G2 + "?";
103 
104 const std::string DIR_ALL_IMAGE_CONTAINER_TYPE = "." + IMAGE_CONTAINER_TYPE_BMP + "?" +
105                                                  "." + IMAGE_CONTAINER_TYPE_BM + "?" +
106                                                  "." + IMAGE_CONTAINER_TYPE_GIF + "?" +
107                                                  "." + IMAGE_CONTAINER_TYPE_JPG + "?" +
108                                                  "." + IMAGE_CONTAINER_TYPE_JPEG + "?" +
109                                                  "." + IMAGE_CONTAINER_TYPE_JPE + "?" +
110                                                  "." + IMAGE_CONTAINER_TYPE_PNG + "?" +
111                                                  "." + IMAGE_CONTAINER_TYPE_WEBP + "?" +
112                                                  "." + IMAGE_CONTAINER_TYPE_RAW + "?" +
113                                                  "." + IMAGE_CONTAINER_TYPE_SVG + "?" +
114                                                  "." + IMAGE_CONTAINER_TYPE_HEIF + "?";
115 
116 const std::string CAMERA_EXTENSION_VALUES = DIR_ALL_IMAGE_CONTAINER_TYPE + DIR_ALL_VIDEO_CONTAINER_TYPE;
117 
118 const std::string VIDEO_EXTENSION_VALUES = DIR_ALL_VIDEO_CONTAINER_TYPE;
119 
120 const std::string PIC_EXTENSION_VALUES = DIR_ALL_IMAGE_CONTAINER_TYPE;
121 
122 const std::string AUDIO_EXTENSION_VALUES = DIR_ALL_AUDIO_CONTAINER_TYPE;
123 
124 const std::string RDB_CONFIG = "/data/storage/el2/base/preferences/rdb_config.xml";
125 
126 const std::string RDB_OLD_VERSION = "rdb_old_version";
127 
128 constexpr ssize_t RDB_WAL_LIMIT_SIZE = 1024 * 1024 * 1024; /* default wal file maximum size : 1GB */
129 constexpr ssize_t RDB_CHECK_WAL_SIZE = 50 * 1024 * 1024;   /* check wal file size : 50MB */
130 std::mutex MediaLibraryRdbStore::walCheckPointMutex_;
131 
132 shared_ptr<NativeRdb::RdbStore> MediaLibraryRdbStore::rdbStore_;
133 
134 std::mutex MediaLibraryRdbStore::reconstructLock_;
135 
136 int32_t oldVersion_ = -1;
137 struct UniqueMemberValuesBucket {
138     std::string assetMediaType;
139     int32_t startNumber;
140 };
141 
142 
143 struct ShootingModeValueBucket {
144     int32_t albumType;
145     int32_t albumSubType;
146     std::string albumName;
147 };
148 
ExecSqlWithRetry(std::function<int32_t ()> execSql)149 static int32_t ExecSqlWithRetry(std::function<int32_t()> execSql)
150 {
151     int32_t currentTime = 0;
152     int32_t busyRetryTime = 0;
153     int32_t err = NativeRdb::E_OK;
154     bool isSkipCloudSync = false;
155     while (busyRetryTime < MAX_BUSY_TRY_TIMES && currentTime <= MAX_TRY_TIMES) {
156         err = execSql();
157         if (err == NativeRdb::E_OK) {
158             break;
159         } else if (err == NativeRdb::E_SQLITE_LOCKED) {
160             std::this_thread::sleep_for(std::chrono::milliseconds(TRANSACTION_WAIT_INTERVAL));
161             currentTime++;
162             MEDIA_ERR_LOG("execSql busy, err: %{public}d, currentTime: %{public}d", err, currentTime);
163         } else if (err == NativeRdb::E_SQLITE_BUSY || err == NativeRdb::E_DATABASE_BUSY) {
164             busyRetryTime++;
165             MEDIA_ERR_LOG("execSql busy, err:%{public}d, busyRetryTime:%{public}d", err, busyRetryTime);
166             if (err == NativeRdb::E_SQLITE_BUSY && !isSkipCloudSync) {
167                 MEDIA_INFO_LOG("Stop cloud sync");
168                 FileManagement::CloudSync::CloudSyncManager::GetInstance()
169                     .StopSync("com.ohos.medialibrary.medialibrarydata");
170                 isSkipCloudSync = true;
171             }
172         } else {
173             MEDIA_ERR_LOG("execSql failed, err: %{public}d, currentTime: %{public}d", err, currentTime);
174             break;
175         }
176     }
177     if (isSkipCloudSync) {
178         MEDIA_INFO_LOG("recover cloud sync after execsql busy");
179         CloudSyncHelper::GetInstance()->StartSync();
180     }
181     return err;
182 }
183 
CloudSyncTriggerFunc(const std::vector<std::string> & args)184 const std::string MediaLibraryRdbStore::CloudSyncTriggerFunc(const std::vector<std::string> &args)
185 {
186     CloudSyncHelper::GetInstance()->StartSync();
187     return "";
188 }
189 
IsCallerSelfFunc(const std::vector<std::string> & args)190 const std::string MediaLibraryRdbStore::IsCallerSelfFunc(const std::vector<std::string> &args)
191 {
192     return "true";
193 }
194 
PhotoAlbumNotifyFunc(const std::vector<std::string> & args)195 const std::string MediaLibraryRdbStore::PhotoAlbumNotifyFunc(const std::vector<std::string> &args)
196 {
197     if (args.size() < 1) {
198         MEDIA_ERR_LOG("Invalid input: args must contain at least 1 strings");
199         return "";
200     }
201     std::string albumId = args[0].c_str();
202     MEDIA_DEBUG_LOG("albumId = %{public}s", albumId.c_str());
203     auto watch = MediaLibraryNotify::GetInstance();
204     if (watch == nullptr) {
205         MEDIA_ERR_LOG("Failed to get MediaLibraryNotify");
206         return "";
207     }
208     watch->Notify(MediaFileUtils::GetUriByExtrConditions(PhotoAlbumColumns::ALBUM_URI_PREFIX, albumId),
209         NotifyType::NOTIFY_ADD);
210     return "";
211 }
212 
MediaLibraryRdbStore(const shared_ptr<OHOS::AbilityRuntime::Context> & context)213 MediaLibraryRdbStore::MediaLibraryRdbStore(const shared_ptr<OHOS::AbilityRuntime::Context> &context)
214 {
215     if (context == nullptr) {
216         MEDIA_ERR_LOG("Failed to get context");
217         return;
218     }
219     string databaseDir = context->GetDatabaseDir();
220     string name = MEDIA_DATA_ABILITY_DB_NAME;
221     int32_t errCode = 0;
222     string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, name, errCode);
223     config_.SetHaMode(HAMode::MANUAL_TRIGGER);
224     config_.SetAllowRebuild(true);
225     config_.SetName(move(name));
226     config_.SetPath(move(realPath));
227     config_.SetBundleName(context->GetBundleName());
228     config_.SetArea(context->GetArea());
229     config_.SetSecurityLevel(SecurityLevel::S3);
230     config_.SetScalarFunction("cloud_sync_func", 0, CloudSyncTriggerFunc);
231     config_.SetScalarFunction("is_caller_self_func", 0, IsCallerSelfFunc);
232     config_.SetWalLimitSize(RDB_WAL_LIMIT_SIZE);
233     config_.SetScalarFunction("photo_album_notify_func", 1, PhotoAlbumNotifyFunc);
234 }
235 
236 bool g_upgradeErr = false;
UpdateFail(const string & errFile,const int & errLine)237 void UpdateFail(const string &errFile, const int &errLine)
238 {
239     g_upgradeErr = true;
240     VariantMap map = {{KEY_ERR_FILE, errFile}, {KEY_ERR_LINE, errLine}};
241     PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_UPGRADE_ERR, map);
242 }
243 
ExecSqls(const vector<string> & sqls,RdbStore & store)244 static int32_t ExecSqls(const vector<string> &sqls, RdbStore &store)
245 {
246     int32_t err = NativeRdb::E_OK;
247     for (const auto &sql : sqls) {
248         err = ExecSqlWithRetry([&]() { return store.ExecuteSql(sql); });
249         if (err != NativeRdb::E_OK) {
250             MEDIA_ERR_LOG("Failed to exec: %{private}s", sql.c_str());
251             /* try update as much as possible */
252             UpdateFail(__FILE__, __LINE__);
253             continue;
254         }
255     }
256     return NativeRdb::E_OK;
257 }
258 
CreateBurstIndex(const shared_ptr<MediaLibraryRdbStore> store)259 void MediaLibraryRdbStore::CreateBurstIndex(const shared_ptr<MediaLibraryRdbStore> store)
260 {
261     const vector<string> sqls = {
262         PhotoColumn::DROP_SCHPT_DAY_INDEX,
263         PhotoColumn::CREATE_SCHPT_DAY_INDEX,
264         PhotoColumn::DROP_SCHPT_HIDDEN_TIME_INDEX,
265         PhotoColumn::CREATE_SCHPT_HIDDEN_TIME_INDEX,
266         PhotoColumn::DROP_PHOTO_FAVORITE_INDEX,
267         PhotoColumn::CREATE_PHOTO_FAVORITE_INDEX,
268         PhotoColumn::DROP_INDEX_SCTHP_ADDTIME,
269         PhotoColumn::INDEX_SCTHP_ADDTIME,
270         PhotoColumn::DROP_SCHPT_MEDIA_TYPE_INDEX,
271         PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_INDEX,
272         PhotoColumn::CREATE_PHOTO_BURSTKEY_INDEX
273     };
274     MEDIA_INFO_LOG("start create idx_burstkey");
275     ExecSqls(sqls, *store->GetRaw().get());
276     MEDIA_INFO_LOG("end create idx_burstkey");
277 }
278 
UpdateBurstDirty(const shared_ptr<MediaLibraryRdbStore> store)279 void MediaLibraryRdbStore::UpdateBurstDirty(const shared_ptr<MediaLibraryRdbStore> store)
280 {
281     const vector<string> sqls = {
282         "UPDATE " + PhotoColumn::PHOTOS_TABLE + " SET " + PhotoColumn::PHOTO_DIRTY + " = " +
283         to_string(static_cast<int32_t>(DirtyTypes::TYPE_NEW)) + " WHERE " + PhotoColumn::PHOTO_SUBTYPE + " = " +
284         to_string(static_cast<int32_t>(PhotoSubType::BURST)) + " AND " + PhotoColumn::PHOTO_DIRTY + " = -1 ",
285     };
286     MEDIA_INFO_LOG("start UpdateBurstDirty");
287     ExecSqls(sqls, *store->GetRaw().get());
288     MEDIA_INFO_LOG("end UpdateBurstDirty");
289 }
290 
UpdateReadyOnThumbnailUpgrade(const shared_ptr<MediaLibraryRdbStore> store)291 void MediaLibraryRdbStore::UpdateReadyOnThumbnailUpgrade(const shared_ptr<MediaLibraryRdbStore> store)
292 {
293     const vector<string> sqls = {
294         PhotoColumn::UPDATE_READY_ON_THUMBNAIL_UPGRADE,
295     };
296     MEDIA_INFO_LOG("start update ready for thumbnail upgrade");
297     ExecSqls(sqls, *store->GetRaw().get());
298     MEDIA_INFO_LOG("finish update ready for thumbnail upgrade");
299 }
300 
ClearAudios(const shared_ptr<MediaLibraryRdbStore> store)301 void MediaLibraryRdbStore::ClearAudios(const shared_ptr<MediaLibraryRdbStore> store)
302 {
303     const vector<string> sqls = {
304         "DELETE From Audios",
305     };
306     MEDIA_INFO_LOG("clear audios start");
307     ExecSqls(sqls, *store->GetRaw().get());
308     MEDIA_INFO_LOG("clear audios end");
309 }
310 
UpdateDateTakenToMillionSecond(const shared_ptr<MediaLibraryRdbStore> store)311 void MediaLibraryRdbStore::UpdateDateTakenToMillionSecond(const shared_ptr<MediaLibraryRdbStore> store)
312 {
313     MEDIA_INFO_LOG("UpdateDateTakenToMillionSecond start");
314     const vector<string> updateSql = {
315         "UPDATE " + PhotoColumn::PHOTOS_TABLE + " SET " +
316             MediaColumn::MEDIA_DATE_TAKEN + " = " + MediaColumn::MEDIA_DATE_TAKEN +  "*1000 WHERE " +
317             MediaColumn::MEDIA_DATE_TAKEN + " < 1e10",
318     };
319     ExecSqls(updateSql, *store->GetRaw().get());
320     MEDIA_INFO_LOG("UpdateDateTakenToMillionSecond end");
321 }
322 
UpdateDateTakenIndex(const shared_ptr<MediaLibraryRdbStore> store)323 void MediaLibraryRdbStore::UpdateDateTakenIndex(const shared_ptr<MediaLibraryRdbStore> store)
324 {
325     const vector<string> sqls = {
326         PhotoColumn::DROP_SCHPT_MEDIA_TYPE_INDEX,
327         PhotoColumn::DROP_PHOTO_FAVORITE_INDEX,
328         PhotoColumn::DROP_INDEX_SCTHP_ADDTIME,
329         PhotoColumn::DROP_INDEX_SCHPT_READY,
330         PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_INDEX,
331         PhotoColumn::CREATE_PHOTO_FAVORITE_INDEX,
332         PhotoColumn::INDEX_SCTHP_ADDTIME,
333         PhotoColumn::INDEX_SCHPT_READY,
334     };
335     MEDIA_INFO_LOG("update index for datetaken change start");
336     ExecSqls(sqls, *store->GetRaw().get());
337     MEDIA_INFO_LOG("update index for datetaken change end");
338 }
339 
UpdateDateTakenAndDetalTime(const shared_ptr<MediaLibraryRdbStore> store)340 void MediaLibraryRdbStore::UpdateDateTakenAndDetalTime(const shared_ptr<MediaLibraryRdbStore> store)
341 {
342     MEDIA_INFO_LOG("UpdateDateTakenAndDetalTime start");
343     string updateDateTakenSql = "UPDATE " + PhotoColumn::PHOTOS_TABLE + " SET " + MediaColumn::MEDIA_DATE_TAKEN +
344             " = " + PhotoColumn::MEDIA_DATE_MODIFIED + "," + PhotoColumn::PHOTO_DETAIL_TIME +
345             " = strftime('%Y:%m:%d %H:%M:%S', " + MediaColumn::MEDIA_DATE_MODIFIED +
346             "/1000, 'unixepoch', 'localtime')" + " WHERE " + MediaColumn::MEDIA_DATE_TAKEN + " = 0";
347     string updateDetalTimeSql = "UPDATE " + PhotoColumn::PHOTOS_TABLE + " SET " + PhotoColumn::PHOTO_DETAIL_TIME +
348             " = strftime('%Y:%m:%d %H:%M:%S', " + MediaColumn::MEDIA_DATE_TAKEN + "/1000, 'unixepoch', 'localtime')" +
349             " WHERE " + PhotoColumn::PHOTO_DETAIL_TIME + " IS NULL";
350     const vector<string> updateSql = {
351         updateDateTakenSql,
352         updateDetalTimeSql,
353     };
354     ExecSqls(updateSql, *store->GetRaw().get());
355     MEDIA_INFO_LOG("UpdateDateTakenAndDetalTime end");
356 }
357 
RevertFixDateAddedIndex(const shared_ptr<MediaLibraryRdbStore> store)358 void MediaLibraryRdbStore::RevertFixDateAddedIndex(const shared_ptr<MediaLibraryRdbStore> store)
359 {
360     MEDIA_INFO_LOG("start revert fix date added index");
361     const vector<string> sqls = {
362         PhotoColumn::DROP_INDEX_SCTHP_ADDTIME,
363         PhotoColumn::INDEX_SCTHP_ADDTIME,
364         PhotoColumn::DROP_INDEX_SCHPT_ADDTIME_ALBUM,
365     };
366     ExecSqls(sqls, *store->GetRaw().get());
367     MEDIA_INFO_LOG("end revert fix date added index");
368 }
369 
UpdateLcdStatusNotUploaded(const std::shared_ptr<MediaLibraryRdbStore> store)370 void MediaLibraryRdbStore::UpdateLcdStatusNotUploaded(const std::shared_ptr<MediaLibraryRdbStore> store)
371 {
372     const vector<string> sqls = {
373         PhotoColumn::UPDATE_LCD_STATUS_NOT_UPLOADED,
374     };
375     MEDIA_INFO_LOG("start update lcd status for photos have not been uploaded");
376     ExecSqls(sqls, *store->GetRaw().get());
377     MEDIA_INFO_LOG("finish update lcd status for photos have not been uploaded");
378 
379     MEDIA_INFO_LOG("start CheckLcdSizeAndUpdateStatus");
380     ThumbnailService::GetInstance()->CheckLcdSizeAndUpdateStatus();
381     MEDIA_INFO_LOG("finish CheckLcdSizeAndUpdateStatus");
382 }
383 
AddReadyCountIndex(const shared_ptr<MediaLibraryRdbStore> store)384 void MediaLibraryRdbStore::AddReadyCountIndex(const shared_ptr<MediaLibraryRdbStore> store)
385 {
386     MEDIA_INFO_LOG("start add ready count index");
387     const vector<string> sqls = {
388         PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_COUNT_READY_INDEX,
389         PhotoColumn::CREATE_SCHPT_YEAR_COUNT_READY_INDEX,
390         PhotoColumn::CREATE_SCHPT_MONTH_COUNT_READY_INDEX,
391     };
392     ExecSqls(sqls, *store->GetRaw().get());
393     MEDIA_INFO_LOG("end add ready count index");
394 }
395 
Init()396 int32_t MediaLibraryRdbStore::Init()
397 {
398     MEDIA_INFO_LOG("Init rdb store: [version: %{public}d]", MEDIA_RDB_VERSION);
399     if (rdbStore_ != nullptr) {
400         return E_OK;
401     }
402 
403     int32_t errCode = 0;
404     MediaLibraryDataCallBack rdbDataCallBack;
405     MediaLibraryTracer tracer;
406     tracer.Start("MediaLibraryRdbStore::Init GetRdbStore");
407     rdbStore_ = RdbHelper::GetRdbStore(config_, MEDIA_RDB_VERSION, rdbDataCallBack, errCode);
408     tracer.Finish();
409     if (rdbStore_ == nullptr) {
410         MEDIA_ERR_LOG("GetRdbStore is failed ");
411         return errCode;
412     }
413     MEDIA_INFO_LOG("MediaLibraryRdbStore::Init(), SUCCESS");
414     return E_OK;
415 }
416 
Init(const RdbStoreConfig & config,int version,RdbOpenCallback & openCallback)417 int32_t MediaLibraryRdbStore::Init(const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback)
418 {
419     MEDIA_INFO_LOG("Init rdb store: [version: %{public}d]", version);
420     if (rdbStore_ != nullptr) {
421         return E_OK;
422     }
423     int32_t errCode = 0;
424     MediaLibraryTracer tracer;
425     tracer.Start("MediaLibraryRdbStore::Init GetRdbStore with config");
426     rdbStore_ = RdbHelper::GetRdbStore(config, version, openCallback, errCode);
427     tracer.Finish();
428     if (rdbStore_ == nullptr) {
429         MEDIA_ERR_LOG("GetRdbStore with config is failed");
430         return errCode;
431     }
432     MEDIA_INFO_LOG("MediaLibraryRdbStore::Init with config, SUCCESS");
433     return E_OK;
434 }
435 
436 MediaLibraryRdbStore::~MediaLibraryRdbStore() = default;
437 
Stop()438 void MediaLibraryRdbStore::Stop()
439 {
440     rdbStore_ = nullptr;
441 }
442 
CheckRdbStore()443 bool MediaLibraryRdbStore::CheckRdbStore()
444 {
445     return rdbStore_ != nullptr;
446 }
447 
GetRaw()448 shared_ptr<NativeRdb::RdbStore> MediaLibraryRdbStore::GetRaw()
449 {
450     return rdbStore_;
451 }
452 
453 #ifdef DISTRIBUTED
GetAllNetworkId(vector<string> & networkIds)454 void GetAllNetworkId(vector<string> &networkIds)
455 {
456     vector<OHOS::DistributedHardware::DmDeviceInfo> deviceList;
457     MediaLibraryDevice::GetInstance()->GetAllNetworkId(deviceList);
458     for (auto& deviceInfo : deviceList) {
459         networkIds.push_back(deviceInfo.networkId);
460     }
461 }
462 #endif
463 
Insert(MediaLibraryCommand & cmd,int64_t & rowId)464 int32_t MediaLibraryRdbStore::Insert(MediaLibraryCommand &cmd, int64_t &rowId)
465 {
466     DfxTimer dfxTimer(DfxType::RDB_INSERT, INVALID_DFX, RDB_TIME_OUT, false);
467     MediaLibraryTracer tracer;
468     tracer.Start("MediaLibraryRdbStore::Insert");
469     if (!MediaLibraryRdbStore::CheckRdbStore()) {
470         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
471         return E_HAS_DB_ERROR;
472     }
473 
474     int32_t ret = ExecSqlWithRetry([&]() {
475         return MediaLibraryRdbStore::GetRaw()->Insert(rowId, cmd.GetTableName(), cmd.GetValueBucket());
476     });
477     if (ret != NativeRdb::E_OK) {
478         MEDIA_ERR_LOG("rdbStore_->Insert failed, ret = %{public}d", ret);
479         MediaLibraryRestore::GetInstance().CheckRestore(ret);
480         return E_HAS_DB_ERROR;
481     }
482 
483     MEDIA_DEBUG_LOG("rdbStore_->Insert end, rowId = %d, ret = %{public}d", (int)rowId, ret);
484     return ret;
485 }
486 
BatchInsert(int64_t & outRowId,const std::string & table,const std::vector<NativeRdb::ValuesBucket> & values)487 int32_t MediaLibraryRdbStore::BatchInsert(int64_t &outRowId, const std::string &table,
488     const std::vector<NativeRdb::ValuesBucket> &values)
489 {
490     DfxTimer dfxTimer(DfxType::RDB_INSERT, INVALID_DFX, RDB_TIME_OUT, false);
491     MediaLibraryTracer tracer;
492     tracer.Start("MediaLibraryRdbStore::BatchInsert");
493     if (!MediaLibraryRdbStore::CheckRdbStore()) {
494         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
495         return E_HAS_DB_ERROR;
496     }
497     int32_t ret = ExecSqlWithRetry([&]() {
498         return MediaLibraryRdbStore::GetRaw()->BatchInsert(outRowId, table, values);
499     });
500     if (ret != NativeRdb::E_OK) {
501         MEDIA_ERR_LOG("rdbStore_->BatchInsert failed, ret = %{public}d", ret);
502         MediaLibraryRestore::GetInstance().CheckRestore(ret);
503         return E_HAS_DB_ERROR;
504     }
505 
506     MEDIA_DEBUG_LOG("rdbStore_->BatchInsert end, rowId = %d, ret = %{public}d", (int)outRowId, ret);
507     return ret;
508 }
509 
BatchInsert(MediaLibraryCommand & cmd,int64_t & outInsertNum,const std::vector<ValuesBucket> & values)510 int32_t MediaLibraryRdbStore::BatchInsert(MediaLibraryCommand &cmd, int64_t& outInsertNum,
511     const std::vector<ValuesBucket>& values)
512 {
513     DfxTimer dfxTimer(DfxType::RDB_BATCHINSERT, INVALID_DFX, RDB_TIME_OUT, false);
514     MediaLibraryTracer tracer;
515     tracer.Start("MediaLibraryRdbStore::BatchInsert");
516     if (!MediaLibraryRdbStore::CheckRdbStore()) {
517         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
518         return E_HAS_DB_ERROR;
519     }
520     int32_t ret = ExecSqlWithRetry([&]() {
521         return MediaLibraryRdbStore::GetRaw()->BatchInsert(outInsertNum, cmd.GetTableName(), values);
522     });
523     if (ret != NativeRdb::E_OK) {
524         MEDIA_ERR_LOG("rdbStore_->BatchInsert failed, ret = %{public}d", ret);
525         MediaLibraryRestore::GetInstance().CheckRestore(ret);
526         return E_HAS_DB_ERROR;
527     }
528     tracer.Finish();
529     MEDIA_DEBUG_LOG("rdbStore_->BatchInsert end, rowId = %d, ret = %{public}d", (int)outInsertNum, ret);
530     return ret;
531 }
532 
DoDeleteFromPredicates(const AbsRdbPredicates & predicates,int32_t & deletedRows)533 int32_t MediaLibraryRdbStore::DoDeleteFromPredicates(const AbsRdbPredicates &predicates, int32_t &deletedRows)
534 {
535     DfxTimer dfxTimer(DfxType::RDB_DELETE, INVALID_DFX, RDB_TIME_OUT, false);
536     if (!MediaLibraryRdbStore::CheckRdbStore()) {
537         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
538         return E_HAS_DB_ERROR;
539     }
540     int32_t ret = NativeRdb::E_ERROR;
541     string tableName = predicates.GetTableName();
542     ValuesBucket valuesBucket;
543     if (tableName == MEDIALIBRARY_TABLE || tableName == PhotoColumn::PHOTOS_TABLE) {
544         valuesBucket.PutInt(MEDIA_DATA_DB_DIRTY, static_cast<int32_t>(DirtyType::TYPE_DELETED));
545         valuesBucket.PutInt(MEDIA_DATA_DB_SYNC_STATUS, static_cast<int32_t>(SyncStatusType::TYPE_UPLOAD));
546         valuesBucket.PutLong(PhotoColumn::PHOTO_META_DATE_MODIFIED, MediaFileUtils::UTCTimeMilliSeconds());
547         ret = ExecSqlWithRetry([&]() {
548             return MediaLibraryRdbStore::GetRaw()->Update(deletedRows, tableName, valuesBucket,
549                 predicates.GetWhereClause(), predicates.GetWhereArgs());
550         });
551     } else if (tableName == PhotoAlbumColumns::TABLE) {
552         valuesBucket.PutInt(PhotoAlbumColumns::ALBUM_DIRTY, static_cast<int32_t>(DirtyType::TYPE_DELETED));
553         ret = ExecSqlWithRetry([&]() {
554             return MediaLibraryRdbStore::GetRaw()->Update(deletedRows, tableName, valuesBucket,
555                 predicates.GetWhereClause(), predicates.GetWhereArgs());
556         });
557     } else if (tableName == PhotoMap::TABLE) {
558         valuesBucket.PutInt(PhotoMap::DIRTY, static_cast<int32_t>(DirtyType::TYPE_DELETED));
559         ret = ExecSqlWithRetry([&]() {
560             return MediaLibraryRdbStore::GetRaw()->Update(deletedRows, tableName, valuesBucket,
561                 predicates.GetWhereClause(), predicates.GetWhereArgs());
562         });
563     } else {
564         ret = ExecSqlWithRetry([&]() {
565             return MediaLibraryRdbStore::GetRaw()->Delete(deletedRows, tableName, predicates.GetWhereClause(),
566                 predicates.GetWhereArgs());
567         });
568     }
569     return ret;
570 }
571 
Delete(MediaLibraryCommand & cmd,int32_t & deletedRows)572 int32_t MediaLibraryRdbStore::Delete(MediaLibraryCommand &cmd, int32_t &deletedRows)
573 {
574     MediaLibraryTracer tracer;
575     tracer.Start("RdbStore->DeleteByCmd");
576     /* local delete */
577     int32_t ret = DoDeleteFromPredicates(*(cmd.GetAbsRdbPredicates()), deletedRows);
578     if (ret != NativeRdb::E_OK) {
579         MEDIA_ERR_LOG("rdbStore_->Delete failed, ret = %{public}d", ret);
580         MediaLibraryRestore::GetInstance().CheckRestore(ret);
581         return E_HAS_DB_ERROR;
582     }
583     CloudSyncHelper::GetInstance()->StartSync();
584     return ret;
585 }
586 
Update(MediaLibraryCommand & cmd,int32_t & changedRows)587 int32_t MediaLibraryRdbStore::Update(MediaLibraryCommand &cmd, int32_t &changedRows)
588 {
589     if (!MediaLibraryRdbStore::CheckRdbStore()) {
590         MEDIA_ERR_LOG("rdbStore_ is nullptr");
591         return E_HAS_DB_ERROR;
592     }
593 
594     if (cmd.GetTableName() == PhotoColumn::PHOTOS_TABLE) {
595         cmd.GetValueBucket().PutLong(PhotoColumn::PHOTO_META_DATE_MODIFIED,
596             MediaFileUtils::UTCTimeMilliSeconds());
597         cmd.GetValueBucket().PutLong(PhotoColumn::PHOTO_LAST_VISIT_TIME,
598             MediaFileUtils::UTCTimeMilliSeconds());
599     }
600 
601     DfxTimer dfxTimer(DfxType::RDB_UPDATE_BY_CMD, INVALID_DFX, RDB_TIME_OUT, false);
602     MediaLibraryTracer tracer;
603     tracer.Start("RdbStore->UpdateByCmd");
604     int32_t ret = ExecSqlWithRetry([&]() {
605         return MediaLibraryRdbStore::GetRaw()->Update(changedRows, cmd.GetTableName(), cmd.GetValueBucket(),
606             cmd.GetAbsRdbPredicates()->GetWhereClause(), cmd.GetAbsRdbPredicates()->GetWhereArgs());
607     });
608     if (ret != NativeRdb::E_OK) {
609         MEDIA_ERR_LOG("rdbStore_->Update failed, ret = %{public}d", ret);
610         MediaLibraryRestore::GetInstance().CheckRestore(ret);
611         return E_HAS_DB_ERROR;
612     }
613     return ret;
614 }
615 
GetIndexOfUri(const AbsRdbPredicates & predicates,const vector<string> & columns,const string & id)616 shared_ptr<NativeRdb::ResultSet> MediaLibraryRdbStore::GetIndexOfUri(const AbsRdbPredicates &predicates,
617     const vector<string> &columns, const string &id)
618 {
619     if (!MediaLibraryRdbStore::CheckRdbStore()) {
620         MEDIA_ERR_LOG("rdbStore_ is nullptr");
621         return nullptr;
622     }
623     MediaLibraryTracer tracer;
624     tracer.Start("GetIndexOfUri");
625     string sql;
626     sql.append("SELECT ").append(PHOTO_INDEX).append(" From (");
627     sql.append(RdbSqlUtils::BuildQueryString(predicates, columns));
628     sql.append(") where "+ MediaColumn::MEDIA_ID + " = ").append(id);
629     MEDIA_DEBUG_LOG("sql = %{private}s", sql.c_str());
630     const vector<string> &args = predicates.GetWhereArgs();
631     for (const auto &arg : args) {
632         MEDIA_DEBUG_LOG("arg = %{private}s", arg.c_str());
633     }
634     auto resultSet = rdbStore_->QuerySql(sql, args);
635     MediaLibraryRestore::GetInstance().CheckResultSet(resultSet);
636     return resultSet;
637 }
638 
GetIndexOfUriForPhotos(const AbsRdbPredicates & predicates,const vector<string> & columns,const string & id)639 shared_ptr<NativeRdb::ResultSet> MediaLibraryRdbStore::GetIndexOfUriForPhotos(const AbsRdbPredicates &predicates,
640     const vector<string> &columns, const string &id)
641 {
642     if (!MediaLibraryRdbStore::CheckRdbStore()) {
643         MEDIA_ERR_LOG("rdbStore_ is nullptr");
644         return nullptr;
645     }
646     MediaLibraryTracer tracer;
647     tracer.Start("GetIndexOfUriForPhotos");
648     string sql;
649     sql.append(RdbSqlUtils::BuildQueryString(predicates, columns));
650     MEDIA_DEBUG_LOG("sql = %{private}s", sql.c_str());
651     const vector<string> &args = predicates.GetWhereArgs();
652     for (const auto &arg : args) {
653         MEDIA_DEBUG_LOG("arg = %{private}s", arg.c_str());
654     }
655     auto resultSet = MediaLibraryRdbStore::GetRaw()->QuerySql(sql, args);
656     MediaLibraryRestore::GetInstance().CheckResultSet(resultSet);
657     return resultSet;
658 }
659 
UpdateLastVisitTime(const string & id)660 int32_t MediaLibraryRdbStore::UpdateLastVisitTime(const string &id)
661 {
662     if (!MediaLibraryRdbStore::CheckRdbStore()) {
663         MEDIA_ERR_LOG("rdbStore_ is nullptr");
664         return E_HAS_DB_ERROR;
665     }
666     MediaLibraryTracer tracer;
667     tracer.Start("UpdateLastVisitTime");
668     ValuesBucket values;
669     int32_t changedRows = 0;
670     values.PutLong(PhotoColumn::PHOTO_LAST_VISIT_TIME, MediaFileUtils::UTCTimeMilliSeconds());
671     string whereClause = MediaColumn::MEDIA_ID + " = ?";
672     vector<string> whereArgs = {id};
673     int32_t ret = ExecSqlWithRetry([&]() {
674         return MediaLibraryRdbStore::GetRaw()->Update(changedRows, PhotoColumn::PHOTOS_TABLE, values, whereClause,
675             whereArgs);
676     });
677     if (ret != NativeRdb::E_OK || changedRows <= 0) {
678         MEDIA_ERR_LOG("rdbStore_->UpdateLastVisitTime failed, changedRows = %{public}d, ret = %{public}d",
679             changedRows, ret);
680         MediaLibraryRestore::GetInstance().CheckRestore(ret);
681     }
682     return changedRows;
683 }
684 
Query(MediaLibraryCommand & cmd,const vector<string> & columns)685 shared_ptr<NativeRdb::ResultSet> MediaLibraryRdbStore::Query(MediaLibraryCommand &cmd,
686     const vector<string> &columns)
687 {
688     if (!MediaLibraryRdbStore::CheckRdbStore()) {
689         MEDIA_ERR_LOG("rdbStore_ is nullptr");
690         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_HAS_DB_ERROR},
691             {KEY_OPT_TYPE, OptType::QUERY}};
692         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
693         return nullptr;
694     }
695 
696     MediaLibraryTracer tracer;
697     tracer.Start("RdbStore->QueryByCmd");
698 #ifdef MEDIALIBRARY_COMPATIBILITY
699     auto predicates = cmd.GetAbsRdbPredicates();
700     MEDIA_DEBUG_LOG("tablename = %{private}s", predicates->GetTableName().c_str());
701     for (const auto &col : columns) {
702         MEDIA_DEBUG_LOG("col = %{private}s", col.c_str());
703     }
704     MEDIA_DEBUG_LOG("whereClause = %{private}s", predicates->GetWhereClause().c_str());
705     const vector<string> &args = predicates->GetWhereArgs();
706     for (const auto &arg : args) {
707         MEDIA_DEBUG_LOG("whereArgs = %{private}s", arg.c_str());
708     }
709     MEDIA_DEBUG_LOG("limit = %{public}d", predicates->GetLimit());
710 #endif
711 
712     /*
713      * adapter pattern:
714      * Reuse predicates-based query so that no need to modify both func
715      * if later logic changes take place
716      */
717     auto resultSet = QueryWithFilter(*cmd.GetAbsRdbPredicates(), columns);
718     if (resultSet == nullptr) {
719         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_HAS_DB_ERROR},
720             {KEY_OPT_TYPE, OptType::QUERY}};
721         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
722     }
723     return resultSet;
724 }
725 
QueryWithFilter(const AbsRdbPredicates & predicates,const vector<string> & columns)726 shared_ptr<NativeRdb::ResultSet> MediaLibraryRdbStore::QueryWithFilter(const AbsRdbPredicates &predicates,
727     const vector<string> &columns)
728 {
729     if (!MediaLibraryRdbStore::CheckRdbStore()) {
730         MEDIA_ERR_LOG("rdbStore_ is nullptr");
731         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_HAS_DB_ERROR},
732             {KEY_OPT_TYPE, OptType::QUERY}};
733         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
734         return nullptr;
735     }
736 
737     /* add filter */
738     MediaLibraryRdbUtils::AddQueryFilter(const_cast<AbsRdbPredicates &>(predicates));
739     DfxTimer dfxTimer(RDB_QUERY, INVALID_DFX, RDB_TIME_OUT, false);
740     MediaLibraryTracer tracer;
741     tracer.Start("RdbStore->QueryByPredicates");
742     MEDIA_DEBUG_LOG("Predicates Statement is %{public}s", predicates.GetStatement().c_str());
743     auto resultSet = MediaLibraryRdbStore::GetRaw()->QueryByStep(predicates, columns);
744     MediaLibraryRestore::GetInstance().CheckResultSet(resultSet);
745     if (resultSet == nullptr) {
746         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_HAS_DB_ERROR},
747             {KEY_OPT_TYPE, OptType::QUERY}};
748         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
749     }
750     return resultSet;
751 }
752 
ExecuteSql(const string & sql)753 int32_t MediaLibraryRdbStore::ExecuteSql(const string &sql)
754 {
755     if (!MediaLibraryRdbStore::CheckRdbStore()) {
756         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
757         return E_HAS_DB_ERROR;
758     }
759     DfxTimer dfxTimer(RDB_EXECUTE_SQL, INVALID_DFX, RDB_TIME_OUT, false);
760     MediaLibraryTracer tracer;
761     tracer.Start("RdbStore->ExecuteSql");
762     int32_t ret = ExecSqlWithRetry([&]() { return MediaLibraryRdbStore::GetRaw()->ExecuteSql(sql); });
763     if (ret != NativeRdb::E_OK) {
764         MEDIA_ERR_LOG("rdbStore_->ExecuteSql failed, ret = %{public}d", ret);
765         MediaLibraryRestore::GetInstance().CheckRestore(ret);
766         return E_HAS_DB_ERROR;
767     }
768     return ret;
769 }
770 
QueryPragma(const string & key,int64_t & value)771 int32_t MediaLibraryRdbStore::QueryPragma(const string &key, int64_t &value)
772 {
773     if (!MediaLibraryRdbStore::CheckRdbStore()) {
774         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
775         return E_HAS_DB_ERROR;
776     }
777     std::shared_ptr<ResultSet> resultSet = MediaLibraryRdbStore::GetRaw()->QuerySql("PRAGMA " + key);
778     MediaLibraryRestore::GetInstance().CheckResultSet(resultSet);
779     if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
780         MEDIA_ERR_LOG("rdbStore_->QuerySql failed");
781         return E_HAS_DB_ERROR;
782     }
783     resultSet->GetLong(0, value);
784     resultSet->Close();
785     return E_OK;
786 }
787 
BuildValuesSql(const NativeRdb::ValuesBucket & values,vector<ValueObject> & bindArgs,string & sql)788 void MediaLibraryRdbStore::BuildValuesSql(const NativeRdb::ValuesBucket &values, vector<ValueObject> &bindArgs,
789     string &sql)
790 {
791     map<string, ValueObject> valuesMap;
792     values.GetAll(valuesMap);
793     sql.append("(");
794     for (auto iter = valuesMap.begin(); iter != valuesMap.end(); iter++) {
795         sql.append(((iter == valuesMap.begin()) ? "" : ", "));
796         sql.append(iter->first);               // columnName
797         bindArgs.push_back(iter->second); // columnValue
798     }
799 
800     sql.append(") select ");
801     for (size_t i = 0; i < valuesMap.size(); i++) {
802         sql.append(((i == 0) ? "?" : ", ?"));
803     }
804     sql.append(" ");
805 }
806 
BuildQuerySql(const AbsRdbPredicates & predicates,const vector<string> & columns,vector<ValueObject> & bindArgs,string & sql)807 void MediaLibraryRdbStore::BuildQuerySql(const AbsRdbPredicates &predicates, const vector<string> &columns,
808     vector<ValueObject> &bindArgs, string &sql)
809 {
810     sql.append(RdbSqlUtils::BuildQueryString(predicates, columns));
811     const vector<string> &args = predicates.GetWhereArgs();
812     for (const auto &arg : args) {
813         bindArgs.emplace_back(arg);
814     }
815 }
816 
StepQueryWithoutCheck(const AbsRdbPredicates & predicates,const vector<string> & columns)817 shared_ptr<NativeRdb::ResultSet> MediaLibraryRdbStore::StepQueryWithoutCheck(const AbsRdbPredicates &predicates,
818     const vector<string> &columns)
819 {
820     if (!MediaLibraryRdbStore::CheckRdbStore()) {
821         MEDIA_ERR_LOG("rdbStore_ is nullptr");
822         VariantMap map = { { KEY_ERR_FILE, __FILE__ },
823             { KEY_ERR_LINE, __LINE__ },
824             { KEY_ERR_CODE, E_HAS_DB_ERROR },
825             { KEY_OPT_TYPE, OptType::QUERY } };
826         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
827         return nullptr;
828     }
829 
830     MediaLibraryRdbUtils::AddQueryFilter(const_cast<AbsRdbPredicates &>(predicates));
831     DfxTimer dfxTimer(RDB_QUERY, INVALID_DFX, RDB_TIME_OUT, false);
832     MediaLibraryTracer tracer;
833     tracer.Start("StepQueryWithoutCheck");
834     MEDIA_DEBUG_LOG("Predicates Statement is %{public}s", predicates.GetStatement().c_str());
835     auto resultSet = MediaLibraryRdbStore::GetRaw()->QueryByStep(predicates, columns, false);
836     if (resultSet == nullptr) {
837         VariantMap map = { { KEY_ERR_FILE, __FILE__ },
838             { KEY_ERR_LINE, __LINE__ },
839             { KEY_ERR_CODE, E_HAS_DB_ERROR },
840             { KEY_OPT_TYPE, OptType::QUERY } };
841         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
842     }
843     return resultSet;
844 }
845 
846 /**
847  * Returns last insert row id. If insert succeed but no new rows inserted, then return -1.
848  * Return E_HAS_DB_ERROR on error cases.
849  */
ExecuteForLastInsertedRowId(const string & sql,const vector<ValueObject> & bindArgs)850 int32_t MediaLibraryRdbStore::ExecuteForLastInsertedRowId(const string &sql, const vector<ValueObject> &bindArgs)
851 {
852     if (!MediaLibraryRdbStore::CheckRdbStore()) {
853         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
854         return E_HAS_DB_ERROR;
855     }
856 
857     int64_t lastInsertRowId = 0;
858     int32_t err = ExecSqlWithRetry(
859         [&]() { return MediaLibraryRdbStore::GetRaw()->ExecuteForLastInsertedRowId(lastInsertRowId, sql, bindArgs); });
860     if (err != E_OK) {
861         MEDIA_ERR_LOG("Failed to execute insert, err: %{public}d", err);
862         MediaLibraryRestore::GetInstance().CheckRestore(err);
863         return E_HAS_DB_ERROR;
864     }
865     return lastInsertRowId;
866 }
867 
Delete(const AbsRdbPredicates & predicates)868 int32_t MediaLibraryRdbStore::Delete(const AbsRdbPredicates &predicates)
869 {
870     int err = E_ERR;
871     int32_t deletedRows = 0;
872     err = DoDeleteFromPredicates(predicates, deletedRows);
873     if (err != E_OK) {
874         MEDIA_ERR_LOG("Failed to execute delete, err: %{public}d", err);
875         MediaLibraryRestore::GetInstance().CheckRestore(err);
876         return E_HAS_DB_ERROR;
877     }
878     CloudSyncHelper::GetInstance()->StartSync();
879     return deletedRows;
880 }
881 
882 /**
883  * Return changed rows on success, or negative values on error cases.
884  */
UpdateWithDateTime(ValuesBucket & values,const AbsRdbPredicates & predicates)885 int32_t MediaLibraryRdbStore::UpdateWithDateTime(ValuesBucket &values,
886     const AbsRdbPredicates &predicates)
887 {
888     if (!MediaLibraryRdbStore::CheckRdbStore()) {
889         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
890         return E_HAS_DB_ERROR;
891     }
892 
893     if (predicates.GetTableName() == PhotoColumn::PHOTOS_TABLE) {
894         values.PutLong(PhotoColumn::PHOTO_META_DATE_MODIFIED, MediaFileUtils::UTCTimeMilliSeconds());
895         values.PutLong(PhotoColumn::PHOTO_LAST_VISIT_TIME, MediaFileUtils::UTCTimeMilliSeconds());
896     }
897 
898     DfxTimer dfxTimer(DfxType::RDB_UPDATE, INVALID_DFX, RDB_TIME_OUT, false);
899     MediaLibraryTracer tracer;
900     tracer.Start("MediaLibraryRdbStore::Update by predicates");
901     int32_t changedRows = -1;
902     int32_t err =
903         ExecSqlWithRetry([&]() { return MediaLibraryRdbStore::GetRaw()->Update(changedRows, values, predicates); });
904     if (err != E_OK) {
905         MEDIA_ERR_LOG("Failed to execute update, err: %{public}d", err);
906         MediaLibraryRestore::GetInstance().CheckRestore(err);
907         return E_HAS_DB_ERROR;
908     }
909 
910     return changedRows;
911 }
912 
QuerySql(const string & sql,const vector<string> & selectionArgs)913 shared_ptr<NativeRdb::ResultSet> MediaLibraryRdbStore::QuerySql(const string &sql, const vector<string> &selectionArgs)
914 {
915     if (!MediaLibraryRdbStore::CheckRdbStore()) {
916         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
917         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_HAS_DB_ERROR},
918             {KEY_OPT_TYPE, OptType::QUERY}};
919         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
920         return nullptr;
921     }
922 
923     MediaLibraryTracer tracer;
924     tracer.Start("RdbStore->QuerySql");
925     auto resultSet = MediaLibraryRdbStore::GetRaw()->QuerySql(sql, selectionArgs);
926     MediaLibraryRestore::GetInstance().CheckResultSet(resultSet);
927     if (resultSet == nullptr) {
928         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_HAS_DB_ERROR},
929             {KEY_OPT_TYPE, OptType::QUERY}};
930         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
931     }
932 
933     return resultSet;
934 }
935 
ReplacePredicatesUriToId(AbsRdbPredicates & predicates)936 void MediaLibraryRdbStore::ReplacePredicatesUriToId(AbsRdbPredicates &predicates)
937 {
938     const vector<string> &whereUriArgs = predicates.GetWhereArgs();
939     vector<string> whereIdArgs;
940     whereIdArgs.reserve(whereUriArgs.size());
941     for (const auto &arg : whereUriArgs) {
942         if (!MediaFileUtils::StartsWith(arg, PhotoColumn::PHOTO_URI_PREFIX)) {
943             whereIdArgs.push_back(arg);
944             continue;
945         }
946         whereIdArgs.push_back(MediaFileUri::GetPhotoId(arg));
947     }
948 
949     predicates.SetWhereArgs(whereIdArgs);
950 }
951 
GetInt(const shared_ptr<ResultSet> & resultSet,const string & column)952 int32_t MediaLibraryRdbStore::GetInt(const shared_ptr<ResultSet> &resultSet, const string &column)
953 {
954     return get<int32_t>(ResultSetUtils::GetValFromColumn(column, resultSet, TYPE_INT32));
955 }
956 
GetString(const shared_ptr<ResultSet> & resultSet,const string & column)957 string MediaLibraryRdbStore::GetString(const shared_ptr<ResultSet> &resultSet, const string &column)
958 {
959     return get<string>(ResultSetUtils::GetValFromColumn(column, resultSet, TYPE_STRING));
960 }
961 
BuildInsertSystemAlbumSql(const ValuesBucket & values,const AbsRdbPredicates & predicates,string & sql,vector<ValueObject> & bindArgs)962 inline void BuildInsertSystemAlbumSql(const ValuesBucket &values, const AbsRdbPredicates &predicates,
963     string &sql, vector<ValueObject> &bindArgs)
964 {
965     // Build insert sql
966     sql.append("INSERT").append(" OR ROLLBACK ").append(" INTO ").append(PhotoAlbumColumns::TABLE).append(" ");
967     MediaLibraryRdbStore::BuildValuesSql(values, bindArgs, sql);
968     sql.append(" WHERE NOT EXISTS (");
969     MediaLibraryRdbStore::BuildQuerySql(predicates, { PhotoAlbumColumns::ALBUM_ID }, bindArgs, sql);
970     sql.append(");");
971 }
972 
PrepareAlbumPlugin(RdbStore & store)973 int32_t PrepareAlbumPlugin(RdbStore &store)
974 {
975     AlbumPluginTableEventHandler albumPluginTableEventHander;
976     int32_t ret = albumPluginTableEventHander.OnCreate(store);
977     // after initiate album_plugin table, add 2 default album into PhotoAlbum.
978     ExecSqlWithRetry([&]() {
979         return store.ExecuteSql(CREATE_DEFALUT_ALBUM_FOR_NO_RELATIONSHIP_ASSET);
980     });
981     ExecSqlWithRetry([&]() {
982         return store.ExecuteSql(CREATE_HIDDEN_ALBUM_FOR_DUAL_ASSET);
983     });
984     return ret;
985 }
986 
PrepareSystemAlbums(RdbStore & store)987 int32_t PrepareSystemAlbums(RdbStore &store)
988 {
989     ValuesBucket values;
990     int32_t err = E_FAIL;
991     MEDIA_INFO_LOG("PrepareSystemAlbums start");
992     auto [errCode, transaction] = store.CreateTransaction(OHOS::NativeRdb::Transaction::DEFERRED);
993     DfxTransaction reporter{ __func__ };
994     if (errCode != NativeRdb::E_OK || transaction == nullptr) {
995         reporter.ReportError(DfxTransaction::AbnormalType::CREATE_ERROR, errCode);
996         MEDIA_ERR_LOG("transaction failed, err:%{public}d", errCode);
997         return errCode;
998     }
999     for (int32_t i = PhotoAlbumSubType::SYSTEM_START; i <= PhotoAlbumSubType::SYSTEM_END; i++) {
1000         values.PutInt(PhotoAlbumColumns::ALBUM_TYPE, PhotoAlbumType::SYSTEM);
1001         values.PutInt(PhotoAlbumColumns::ALBUM_SUBTYPE, i);
1002         values.PutInt(PhotoAlbumColumns::ALBUM_ORDER, i - PhotoAlbumSubType::SYSTEM_START);
1003 
1004         AbsRdbPredicates predicates(PhotoAlbumColumns::TABLE);
1005         predicates.EqualTo(PhotoAlbumColumns::ALBUM_TYPE, to_string(PhotoAlbumType::SYSTEM));
1006         predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(i));
1007 
1008         string sql;
1009         vector<ValueObject> bindArgs;
1010         BuildInsertSystemAlbumSql(values, predicates, sql, bindArgs);
1011         auto res = transaction->Execute(sql, bindArgs);
1012         err = res.first;
1013         if (err != E_OK) {
1014             reporter.ReportError(DfxTransaction::AbnormalType::EXECUTE_ERROR, err);
1015             transaction->Rollback();
1016             MEDIA_ERR_LOG("Execute sql failed, err: %{public}d", err);
1017             return err;
1018         }
1019         values.Clear();
1020     }
1021     err = transaction->Commit();
1022     if (err != NativeRdb::E_OK) {
1023         reporter.ReportError(DfxTransaction::AbnormalType::COMMIT_ERROR, err);
1024         MEDIA_ERR_LOG("transaction Commit failed, err: %{public}d", err);
1025     } else {
1026         reporter.ReportIfTimeout();
1027     }
1028     return E_OK;
1029 }
1030 
PrepareDir(RdbStore & store)1031 int32_t MediaLibraryDataCallBack::PrepareDir(RdbStore &store)
1032 {
1033     DirValuesBucket cameraDir = {
1034         CAMERA_DIRECTORY_TYPE_VALUES, CAMERA_DIR_VALUES, CAMERA_TYPE_VALUES, CAMERA_EXTENSION_VALUES
1035     };
1036     DirValuesBucket videoDir = {
1037         VIDEO_DIRECTORY_TYPE_VALUES, VIDEO_DIR_VALUES, VIDEO_TYPE_VALUES, VIDEO_EXTENSION_VALUES
1038     };
1039     DirValuesBucket pictureDir = {
1040         PIC_DIRECTORY_TYPE_VALUES, PIC_DIR_VALUES, PIC_TYPE_VALUES, PIC_EXTENSION_VALUES
1041     };
1042     DirValuesBucket audioDir = {
1043         AUDIO_DIRECTORY_TYPE_VALUES, AUDIO_DIR_VALUES, AUDIO_TYPE_VALUES, AUDIO_EXTENSION_VALUES
1044     };
1045     DirValuesBucket documentDir = {
1046         DOC_DIRECTORY_TYPE_VALUES, DOCS_PATH, DOC_TYPE_VALUES, DOC_EXTENSION_VALUES
1047     };
1048     DirValuesBucket downloadDir = {
1049         DOWNLOAD_DIRECTORY_TYPE_VALUES, DOCS_PATH, DOWNLOAD_TYPE_VALUES, DOWNLOAD_EXTENSION_VALUES
1050     };
1051 
1052     vector<DirValuesBucket> dirValuesBuckets = {
1053         cameraDir, videoDir, pictureDir, audioDir, documentDir, downloadDir
1054     };
1055 
1056     for (const auto& dirValuesBucket : dirValuesBuckets) {
1057         int32_t insertResult = InsertDirValues(dirValuesBucket, store);
1058         if (insertResult != NativeRdb::E_OK) {
1059             MEDIA_ERR_LOG("insert failed, insertResult: %{public}d", insertResult);
1060         }
1061     }
1062     return NativeRdb::E_OK;
1063 }
1064 
InsertDirValues(const DirValuesBucket & dirValuesBucket,RdbStore & store)1065 int32_t MediaLibraryDataCallBack::InsertDirValues(const DirValuesBucket &dirValuesBucket, RdbStore &store)
1066 {
1067     ValuesBucket valuesBucket;
1068     valuesBucket.PutInt(DIRECTORY_DB_DIRECTORY_TYPE, dirValuesBucket.directoryType);
1069     valuesBucket.PutString(DIRECTORY_DB_DIRECTORY, dirValuesBucket.dirValues);
1070     valuesBucket.PutString(DIRECTORY_DB_MEDIA_TYPE, dirValuesBucket.typeValues);
1071     valuesBucket.PutString(DIRECTORY_DB_EXTENSION, dirValuesBucket.extensionValues);
1072     int64_t outRowId = -1;
1073     int32_t insertResult = ExecSqlWithRetry([&]() {
1074         return store.Insert(outRowId, MEDIATYPE_DIRECTORY_TABLE, valuesBucket);
1075     });
1076     MEDIA_DEBUG_LOG("insert dir outRowId: %{public}ld insertResult: %{public}d", (long)outRowId, insertResult);
1077     return insertResult;
1078 }
1079 
PrepareSmartAlbum(RdbStore & store)1080 int32_t MediaLibraryDataCallBack::PrepareSmartAlbum(RdbStore &store)
1081 {
1082     SmartAlbumValuesBucket trashAlbum = {
1083         TRASH_ALBUM_ID_VALUES, TRASH_ALBUM_NAME_VALUES, TRASH_ALBUM_TYPE_VALUES
1084     };
1085 
1086     SmartAlbumValuesBucket favAlbum = {
1087         FAVOURITE_ALBUM_ID_VALUES, FAVOURTIE_ALBUM_NAME_VALUES, FAVOURITE_ALBUM_TYPE_VALUES
1088     };
1089 
1090     vector<SmartAlbumValuesBucket> smartAlbumValuesBuckets = {
1091         trashAlbum, favAlbum
1092     };
1093 
1094     for (const auto& smartAlbum : smartAlbumValuesBuckets) {
1095         if (InsertSmartAlbumValues(smartAlbum, store) != NativeRdb::E_OK) {
1096             MEDIA_ERR_LOG("Prepare smartAlbum failed");
1097             return NativeRdb::E_ERROR;
1098         }
1099     }
1100     return NativeRdb::E_OK;
1101 }
1102 
InsertShootingModeAlbumValues(const ShootingModeValueBucket & shootingModeAlbum,RdbStore & store)1103 static int32_t InsertShootingModeAlbumValues(
1104     const ShootingModeValueBucket &shootingModeAlbum, RdbStore &store)
1105 {
1106     ValuesBucket valuesBucket;
1107     valuesBucket.PutInt(SMARTALBUM_DB_ALBUM_TYPE, shootingModeAlbum.albumType);
1108     valuesBucket.PutInt(COMPAT_ALBUM_SUBTYPE, shootingModeAlbum.albumSubType);
1109     valuesBucket.PutString(MEDIA_DATA_DB_ALBUM_NAME, shootingModeAlbum.albumName);
1110     valuesBucket.PutInt(MEDIA_DATA_DB_IS_LOCAL, 1); // local album is 1.
1111     int64_t outRowId = -1;
1112     int32_t insertResult = ExecSqlWithRetry([&]() {
1113         return store.Insert(outRowId, ANALYSIS_ALBUM_TABLE, valuesBucket);
1114     });
1115     return insertResult;
1116 }
1117 
PrepareShootingModeAlbum(RdbStore & store)1118 static int32_t PrepareShootingModeAlbum(RdbStore &store)
1119 {
1120     ShootingModeValueBucket portraitAlbum = {
1121         SHOOTING_MODE_TYPE, SHOOTING_MODE_SUB_TYPE, PORTRAIT_ALBUM
1122     };
1123     ShootingModeValueBucket wideApertureAlbum = {
1124         SHOOTING_MODE_TYPE, SHOOTING_MODE_SUB_TYPE, WIDE_APERTURE_ALBUM
1125     };
1126     ShootingModeValueBucket nightShotAlbum = {
1127         SHOOTING_MODE_TYPE, SHOOTING_MODE_SUB_TYPE, NIGHT_SHOT_ALBUM
1128     };
1129     ShootingModeValueBucket movingPictureAlbum = {
1130         SHOOTING_MODE_TYPE, SHOOTING_MODE_SUB_TYPE, MOVING_PICTURE_ALBUM
1131     };
1132     ShootingModeValueBucket proPhotoAlbum = {
1133         SHOOTING_MODE_TYPE, SHOOTING_MODE_SUB_TYPE, PRO_PHOTO_ALBUM
1134     };
1135     ShootingModeValueBucket slowMotionAlbum = {
1136         SHOOTING_MODE_TYPE, SHOOTING_MODE_SUB_TYPE, SLOW_MOTION_ALBUM
1137     };
1138     ShootingModeValueBucket lightPaintingAlbum = {
1139         SHOOTING_MODE_TYPE, SHOOTING_MODE_SUB_TYPE, LIGHT_PAINTING_ALBUM
1140     };
1141     ShootingModeValueBucket highPixelAlbum = {
1142         SHOOTING_MODE_TYPE, SHOOTING_MODE_SUB_TYPE, HIGH_PIXEL_ALBUM
1143     };
1144     ShootingModeValueBucket superMicroAlbum = {
1145         SHOOTING_MODE_TYPE, SHOOTING_MODE_SUB_TYPE, SUPER_MACRO_ALBUM
1146     };
1147 
1148     vector<ShootingModeValueBucket> shootingModeValuesBucket = {
1149         portraitAlbum, wideApertureAlbum, nightShotAlbum, movingPictureAlbum,
1150         proPhotoAlbum, lightPaintingAlbum, highPixelAlbum, superMicroAlbum, slowMotionAlbum
1151     };
1152     for (const auto& shootingModeAlbum : shootingModeValuesBucket) {
1153         if (InsertShootingModeAlbumValues(shootingModeAlbum, store) != NativeRdb::E_OK) {
1154             MEDIA_ERR_LOG("Prepare shootingMode album failed");
1155             return NativeRdb::E_ERROR;
1156         }
1157     }
1158     return NativeRdb::E_OK;
1159 }
1160 
InsertSmartAlbumValues(const SmartAlbumValuesBucket & smartAlbum,RdbStore & store)1161 int32_t MediaLibraryDataCallBack::InsertSmartAlbumValues(const SmartAlbumValuesBucket &smartAlbum, RdbStore &store)
1162 {
1163     ValuesBucket valuesBucket;
1164     valuesBucket.PutInt(SMARTALBUM_DB_ID, smartAlbum.albumId);
1165     valuesBucket.PutString(SMARTALBUM_DB_NAME, smartAlbum.albumName);
1166     valuesBucket.PutInt(SMARTALBUM_DB_ALBUM_TYPE, smartAlbum.albumType);
1167     int64_t outRowId = -1;
1168     int32_t insertResult = ExecSqlWithRetry([&]() {
1169         return store.Insert(outRowId, SMARTALBUM_TABLE, valuesBucket);
1170     });
1171     return insertResult;
1172 }
1173 
InsertUniqueMemberTableValues(const UniqueMemberValuesBucket & uniqueMemberValues,RdbStore & store)1174 static int32_t InsertUniqueMemberTableValues(const UniqueMemberValuesBucket &uniqueMemberValues,
1175     RdbStore &store)
1176 {
1177     ValuesBucket valuesBucket;
1178     valuesBucket.PutString(ASSET_MEDIA_TYPE, uniqueMemberValues.assetMediaType);
1179     valuesBucket.PutInt(UNIQUE_NUMBER, uniqueMemberValues.startNumber);
1180     int64_t outRowId = -1;
1181     int32_t insertResult = ExecSqlWithRetry([&]() {
1182         return store.Insert(outRowId, ASSET_UNIQUE_NUMBER_TABLE, valuesBucket);
1183     });
1184     return insertResult;
1185 }
1186 
PrepareUniqueMemberTable(RdbStore & store)1187 static int32_t PrepareUniqueMemberTable(RdbStore &store)
1188 {
1189     string queryRowSql = "SELECT COUNT(*) as count FROM " + ASSET_UNIQUE_NUMBER_TABLE;
1190     auto resultSet = store.QuerySql(queryRowSql);
1191     if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
1192         MEDIA_ERR_LOG("Can not get AssetUniqueNumberTable count");
1193         UpdateFail(__FILE__, __LINE__);
1194         return NativeRdb::E_ERROR;
1195     }
1196     if (GetInt32Val("count", resultSet) != 0) {
1197         MEDIA_DEBUG_LOG("AssetUniqueNumberTable is already inited");
1198         return E_OK;
1199     }
1200 
1201     UniqueMemberValuesBucket imageBucket = { IMAGE_ASSET_TYPE, 0 };
1202     UniqueMemberValuesBucket videoBucket = { VIDEO_ASSET_TYPE, 0 };
1203     UniqueMemberValuesBucket audioBucket = { AUDIO_ASSET_TYPE, 0 };
1204 
1205     vector<UniqueMemberValuesBucket> uniqueNumberValueBuckets = {
1206         imageBucket, videoBucket, audioBucket
1207     };
1208 
1209     for (const auto& uniqueNumberValueBucket : uniqueNumberValueBuckets) {
1210         if (InsertUniqueMemberTableValues(uniqueNumberValueBucket, store) != NativeRdb::E_OK) {
1211             MEDIA_ERR_LOG("Prepare smartAlbum failed");
1212             UpdateFail(__FILE__, __LINE__);
1213             return NativeRdb::E_ERROR;
1214         }
1215     }
1216     return NativeRdb::E_OK;
1217 }
1218 
TriggerDeleteAlbumClearMap()1219 static const string &TriggerDeleteAlbumClearMap()
1220 {
1221     static const string TRIGGER_CLEAR_MAP = BaseColumn::CreateTrigger() + "photo_album_clear_map" +
1222     " AFTER DELETE ON " + PhotoAlbumColumns::TABLE +
1223     " BEGIN " +
1224         "DELETE FROM " + PhotoMap::TABLE +
1225         " WHERE " + PhotoMap::ALBUM_ID + "=" + "OLD." + PhotoAlbumColumns::ALBUM_ID + ";" +
1226     " END;";
1227     return TRIGGER_CLEAR_MAP;
1228 }
1229 
TriggerAddAssets()1230 static const string &TriggerAddAssets()
1231 {
1232     static const string TRIGGER_ADD_ASSETS = BaseColumn::CreateTrigger() + "photo_album_insert_asset" +
1233     " AFTER INSERT ON " + PhotoMap::TABLE +
1234     " BEGIN " +
1235         "UPDATE " + PhotoAlbumColumns::TABLE + " SET " +
1236             PhotoAlbumColumns::ALBUM_COUNT + " = " + PhotoAlbumColumns::ALBUM_COUNT + " + 1 " +
1237         "WHERE " + PhotoAlbumColumns::ALBUM_ID + " = " + "NEW." + PhotoMap::ALBUM_ID + ";" +
1238     " END;";
1239     return TRIGGER_ADD_ASSETS;
1240 }
1241 
TriggerRemoveAssets()1242 static const string &TriggerRemoveAssets()
1243 {
1244     static const string TRIGGER_REMOVE_ASSETS = BaseColumn::CreateTrigger() + "photo_album_delete_asset" +
1245     " AFTER DELETE ON " + PhotoMap::TABLE +
1246     " BEGIN " +
1247         "UPDATE " + PhotoAlbumColumns::TABLE + " SET " +
1248             PhotoAlbumColumns::ALBUM_COUNT + " = " + PhotoAlbumColumns::ALBUM_COUNT + " - 1 " +
1249         "WHERE " + PhotoAlbumColumns::ALBUM_ID + " = " + "OLD." + PhotoMap::ALBUM_ID + ";" +
1250     " END;";
1251     return TRIGGER_REMOVE_ASSETS;
1252 }
1253 
TriggerDeletePhotoClearMap()1254 static const string &TriggerDeletePhotoClearMap()
1255 {
1256     static const string TRIGGER_DELETE_ASSETS = BaseColumn::CreateTrigger() + "delete_photo_clear_map" +
1257     " AFTER DELETE ON " + PhotoColumn::PHOTOS_TABLE +
1258     " BEGIN " +
1259         "DELETE FROM " + PhotoMap::TABLE +
1260         " WHERE " + PhotoMap::ASSET_ID + "=" + "OLD." + MediaColumn::MEDIA_ID + ";" +
1261         "DELETE FROM " + ANALYSIS_PHOTO_MAP_TABLE +
1262         " WHERE " + PhotoMap::ASSET_ID + "=" + "OLD." + MediaColumn::MEDIA_ID + ";" +
1263     " END;";
1264     return TRIGGER_DELETE_ASSETS;
1265 }
1266 
QueryAlbumJoinMap()1267 static const string &QueryAlbumJoinMap()
1268 {
1269     static const string QUERY_ALBUM_JOIN_MAP = " SELECT " + PhotoAlbumColumns::ALBUM_ID +
1270         " FROM " + PhotoAlbumColumns::TABLE + " INNER JOIN " + PhotoMap::TABLE + " ON " +
1271             PhotoAlbumColumns::ALBUM_ID + " = " + PhotoMap::ALBUM_ID + " AND " +
1272             PhotoMap::ASSET_ID + " = " + "NEW." + MediaColumn::MEDIA_ID;
1273     return QUERY_ALBUM_JOIN_MAP;
1274 }
1275 
SetHiddenUpdateCount()1276 static const string &SetHiddenUpdateCount()
1277 {
1278     // Photos.hidden 1 -> 0
1279     static const string SET_HIDDEN_UPDATE_COUNT = " UPDATE " + PhotoAlbumColumns::TABLE +
1280         " SET " + PhotoAlbumColumns::ALBUM_COUNT + " = " + PhotoAlbumColumns::ALBUM_COUNT + " + 1" +
1281         " WHERE " + PhotoAlbumColumns::ALBUM_ID + " IN (" +
1282             QueryAlbumJoinMap() + " WHERE " +
1283                 "NEW." + MediaColumn::MEDIA_HIDDEN + " = 0" + " AND " +
1284                 "(OLD." + MediaColumn::MEDIA_HIDDEN + " - NEW." + MediaColumn::MEDIA_HIDDEN + " > 0)" +
1285         ");";
1286     return SET_HIDDEN_UPDATE_COUNT;
1287 }
1288 
SetTrashUpdateCount()1289 static const string &SetTrashUpdateCount()
1290 {
1291     // Photos.date_trashed timestamp -> 0
1292     static const string SET_TRASH_UPDATE_COUNT = " UPDATE " + PhotoAlbumColumns::TABLE +
1293         " SET " + PhotoAlbumColumns::ALBUM_COUNT + " = " + PhotoAlbumColumns::ALBUM_COUNT + " + 1" +
1294         " WHERE " + PhotoAlbumColumns::ALBUM_ID + " IN (" +
1295             QueryAlbumJoinMap() + " WHERE " +
1296                 "SIGN(NEW." + MediaColumn::MEDIA_DATE_TRASHED + ") = 0" + " AND " +
1297                 "NEW." + MediaColumn::MEDIA_HIDDEN + " = 0" + " AND " +
1298                 "(" +
1299                     "SIGN(OLD." + MediaColumn::MEDIA_DATE_TRASHED + ") - " +
1300                     "SIGN(NEW." + MediaColumn::MEDIA_DATE_TRASHED + ") > 0" +
1301                 ")" +
1302         ");";
1303     return SET_TRASH_UPDATE_COUNT;
1304 }
1305 
UnSetHiddenUpdateCount()1306 static const string &UnSetHiddenUpdateCount()
1307 {
1308     // Photos.hidden 0 -> 1
1309     static const string UNSET_HIDDEN_UPDATE_COUNT = " UPDATE " + PhotoAlbumColumns::TABLE +
1310         " SET " + PhotoAlbumColumns::ALBUM_COUNT + " = " + PhotoAlbumColumns::ALBUM_COUNT + " - 1" +
1311         " WHERE " + PhotoAlbumColumns::ALBUM_ID + " IN (" +
1312             QueryAlbumJoinMap() + " WHERE " +
1313                 "NEW." + MediaColumn::MEDIA_HIDDEN + " = 1" + " AND " +
1314                 "(NEW." + MediaColumn::MEDIA_HIDDEN + " - OLD." + MediaColumn::MEDIA_HIDDEN + " > 0)" +
1315         ");";
1316     return UNSET_HIDDEN_UPDATE_COUNT;
1317 }
1318 
UnSetTrashUpdateCount()1319 static const string &UnSetTrashUpdateCount()
1320 {
1321     // Photos.date_trashed 0 -> timestamp
1322     static const string UNSET_TRASH_UPDATE_COUNT = " UPDATE " + PhotoAlbumColumns::TABLE +
1323         " SET " + PhotoAlbumColumns::ALBUM_COUNT + " = " + PhotoAlbumColumns::ALBUM_COUNT + " - 1" +
1324         " WHERE " + PhotoAlbumColumns::ALBUM_ID + " IN (" +
1325             QueryAlbumJoinMap() + " WHERE " +
1326                 "SIGN(NEW." + MediaColumn::MEDIA_DATE_TRASHED + ") = 1" + " AND " +
1327                 "NEW." + MediaColumn::MEDIA_HIDDEN + " = 0" + " AND " +
1328                 "(" +
1329                     "SIGN(NEW." + MediaColumn::MEDIA_DATE_TRASHED + ") - "
1330                     "SIGN(OLD." + MediaColumn::MEDIA_DATE_TRASHED + ") > 0" +
1331                 ")" +
1332         ");";
1333     return UNSET_TRASH_UPDATE_COUNT;
1334 }
1335 
TriggerUpdateUserAlbumCount()1336 static const string &TriggerUpdateUserAlbumCount()
1337 {
1338     static const string TRIGGER_UPDATE_USER_ALBUM_COUNT = BaseColumn::CreateTrigger() + "update_user_album_count" +
1339         " AFTER UPDATE ON " + PhotoColumn::PHOTOS_TABLE +
1340         " BEGIN " +
1341             SetHiddenUpdateCount() +
1342             SetTrashUpdateCount() +
1343             UnSetHiddenUpdateCount() +
1344             UnSetTrashUpdateCount() +
1345         " END;";
1346     return TRIGGER_UPDATE_USER_ALBUM_COUNT;
1347 }
1348 
TriggerDeletePhotoClearAppUriPermission()1349 static const string &TriggerDeletePhotoClearAppUriPermission()
1350 {
1351     static const string TRIGGER_PHOTO_DELETE_APP_URI_PERMISSION = BaseColumn::CreateTrigger() +
1352     "delete_photo_clear_App_uri_permission" + " AFTER DELETE ON " + PhotoColumn::PHOTOS_TABLE +
1353     " BEGIN " +
1354         "DELETE FROM " + AppUriPermissionColumn::APP_URI_PERMISSION_TABLE +
1355         " WHERE " + AppUriPermissionColumn::FILE_ID + "=" + "OLD." + MediaColumn::MEDIA_ID +
1356         " AND " + AppUriPermissionColumn::URI_TYPE + "=" + std::to_string(AppUriPermissionColumn::URI_PHOTO) + ";" +
1357     " END;";
1358     return TRIGGER_PHOTO_DELETE_APP_URI_PERMISSION;
1359 }
1360 
TriggerDeleteAudioClearAppUriPermission()1361 static const string &TriggerDeleteAudioClearAppUriPermission()
1362 {
1363     static const string TRIGGER_AUDIO_DELETE_APP_URI_PERMISSION = BaseColumn::CreateTrigger() +
1364     "delete_audio_clear_App_uri_permission" + " AFTER DELETE ON " + AudioColumn::AUDIOS_TABLE +
1365     " BEGIN " +
1366         "DELETE FROM " + AppUriPermissionColumn::APP_URI_PERMISSION_TABLE +
1367         " WHERE " + AppUriPermissionColumn::FILE_ID + "=" + "OLD." + MediaColumn::MEDIA_ID +
1368         " AND " + AppUriPermissionColumn::URI_TYPE + "=" + std::to_string(AppUriPermissionColumn::URI_AUDIO) + ";" +
1369     " END;";
1370     return TRIGGER_AUDIO_DELETE_APP_URI_PERMISSION;
1371 }
1372 
1373 static const vector<string> onCreateSqlStrs = {
1374     CREATE_MEDIA_TABLE,
1375     PhotoColumn::CREATE_PHOTO_TABLE,
1376     PhotoColumn::CREATE_CLOUD_ID_INDEX,
1377     PhotoColumn::INDEX_SCTHP_ADDTIME,
1378     PhotoColumn::INDEX_CAMERA_SHOT_KEY,
1379     PhotoColumn::INDEX_SCHPT_READY,
1380     PhotoColumn::CREATE_YEAR_INDEX,
1381     PhotoColumn::CREATE_MONTH_INDEX,
1382     PhotoColumn::CREATE_DAY_INDEX,
1383     PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_INDEX,
1384     PhotoColumn::CREATE_SCHPT_DAY_INDEX,
1385     PhotoColumn::CREATE_SCHPT_YEAR_COUNT_READY_INDEX,
1386     PhotoColumn::CREATE_SCHPT_MONTH_COUNT_READY_INDEX,
1387     PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_COUNT_READY_INDEX,
1388     PhotoColumn::CREATE_HIDDEN_TIME_INDEX,
1389     PhotoColumn::CREATE_SCHPT_HIDDEN_TIME_INDEX,
1390     PhotoColumn::CREATE_PHOTO_FAVORITE_INDEX,
1391     PhotoColumn::CREATE_PHOTOS_DELETE_TRIGGER,
1392     PhotoColumn::CREATE_PHOTOS_FDIRTY_TRIGGER,
1393     PhotoColumn::CREATE_PHOTOS_MDIRTY_TRIGGER,
1394     PhotoColumn::CREATE_PHOTOS_INSERT_CLOUD_SYNC,
1395     PhotoColumn::CREATE_PHOTOS_UPDATE_CLOUD_SYNC,
1396     AudioColumn::CREATE_AUDIO_TABLE,
1397     CREATE_SMARTALBUM_TABLE,
1398     CREATE_SMARTALBUMMAP_TABLE,
1399     CREATE_DEVICE_TABLE,
1400     CREATE_CATEGORY_SMARTALBUMMAP_TABLE,
1401     CREATE_ASSET_UNIQUE_NUMBER_TABLE,
1402     CREATE_ALBUM_REFRESH_TABLE,
1403     CREATE_IMAGE_VIEW,
1404     CREATE_VIDEO_VIEW,
1405     CREATE_AUDIO_VIEW,
1406     CREATE_ALBUM_VIEW,
1407     CREATE_SMARTALBUMASSETS_VIEW,
1408     CREATE_ASSETMAP_VIEW,
1409     CREATE_MEDIATYPE_DIRECTORY_TABLE,
1410     CREATE_BUNDLE_PREMISSION_TABLE,
1411     CREATE_MEDIALIBRARY_ERROR_TABLE,
1412     CREATE_REMOTE_THUMBNAIL_TABLE,
1413     CREATE_FILES_DELETE_TRIGGER,
1414     CREATE_FILES_MDIRTY_TRIGGER,
1415     CREATE_FILES_FDIRTY_TRIGGER,
1416     CREATE_INSERT_CLOUD_SYNC_TRIGGER,
1417     PhotoAlbumColumns::CREATE_TABLE,
1418     PhotoAlbumColumns::INDEX_ALBUM_TYPES,
1419     PhotoAlbumColumns::CREATE_ALBUM_INSERT_TRIGGER,
1420     PhotoAlbumColumns::CREATE_ALBUM_MDIRTY_TRIGGER,
1421     PhotoAlbumColumns::CREATE_ALBUM_DELETE_TRIGGER,
1422     PhotoAlbumColumns::ALBUM_DELETE_ORDER_TRIGGER,
1423     PhotoAlbumColumns::ALBUM_INSERT_ORDER_TRIGGER,
1424     PhotoMap::CREATE_TABLE,
1425     PhotoMap::CREATE_NEW_TRIGGER,
1426     PhotoMap::CREATE_DELETE_TRIGGER,
1427     PhotoMap::CREATE_IDX_FILEID_FOR_PHOTO_MAP,
1428     TriggerDeleteAlbumClearMap(),
1429     TriggerDeletePhotoClearMap(),
1430     CREATE_TAB_ANALYSIS_OCR,
1431     CREATE_TAB_ANALYSIS_LABEL,
1432     CREATE_TAB_ANALYSIS_VIDEO_LABEL,
1433     CREATE_TAB_ANALYSIS_AESTHETICS,
1434     CREATE_TAB_ANALYSIS_OBJECT,
1435     CREATE_TAB_ANALYSIS_RECOMMENDATION,
1436     CREATE_TAB_ANALYSIS_SEGMENTATION,
1437     CREATE_TAB_ANALYSIS_COMPOSITION,
1438     CREATE_TAB_ANALYSIS_SALIENCY_DETECT,
1439     CREATE_TAB_ANALYSIS_HEAD,
1440     CREATE_TAB_ANALYSIS_POSE,
1441     CREATE_TAB_IMAGE_FACE,
1442     CREATE_TAB_VIDEO_FACE,
1443     CREATE_TAB_FACE_TAG,
1444     CREATE_TAB_ANALYSIS_TOTAL_FOR_ONCREATE,
1445     CREATE_VISION_UPDATE_TRIGGER,
1446     CREATE_VISION_DELETE_TRIGGER,
1447     CREATE_GEO_KNOWLEDGE_TABLE,
1448     CREATE_GEO_DICTIONARY_TABLE,
1449     CREATE_VISION_INSERT_TRIGGER_FOR_ONCREATE,
1450     CREATE_IMAGE_FACE_INDEX,
1451     CREATE_VIDEO_FACE_INDEX,
1452     CREATE_OBJECT_INDEX,
1453     CREATE_RECOMMENDATION_INDEX,
1454     CREATE_COMPOSITION_INDEX,
1455     CREATE_HEAD_INDEX,
1456     CREATE_POSE_INDEX,
1457     CREATE_ANALYSIS_ALBUM_FOR_ONCREATE,
1458     CREATE_ANALYSIS_ALBUM_MAP,
1459     CREATE_HIGHLIGHT_ALBUM_TABLE,
1460     CREATE_HIGHLIGHT_COVER_INFO_TABLE,
1461     CREATE_HIGHLIGHT_PLAY_INFO_TABLE,
1462     CREATE_USER_PHOTOGRAPHY_INFO_TABLE,
1463     CREATE_INSERT_SOURCE_PHOTO_CREATE_SOURCE_ALBUM_TRIGGER,
1464     CREATE_INSERT_SOURCE_UPDATE_ALBUM_ID_TRIGGER,
1465     INSERT_PHOTO_UPDATE_ALBUM_BUNDLENAME,
1466     CREATE_SOURCE_ALBUM_INDEX,
1467     CREATE_DICTIONARY_INDEX,
1468     CREATE_NEW_KNOWLEDGE_INDEX,
1469     CREATE_CITY_NAME_INDEX,
1470     CREATE_LOCATION_KEY_INDEX,
1471     CREATE_IDX_FILEID_FOR_ANALYSIS_TOTAL,
1472     CREATE_IDX_FILEID_FOR_ANALYSIS_PHOTO_MAP,
1473     CREATE_ANALYSIS_ALBUM_ASET_MAP_TABLE,
1474     CREATE_ANALYSIS_ASSET_SD_MAP_TABLE,
1475 
1476     // search
1477     CREATE_SEARCH_TOTAL_TABLE,
1478     CREATE_SEARCH_INSERT_TRIGGER,
1479     CREATE_SEARCH_UPDATE_TRIGGER,
1480     CREATE_SEARCH_UPDATE_STATUS_TRIGGER,
1481     CREATE_SEARCH_DELETE_TRIGGER,
1482     CREATE_IDX_FILEID_FOR_SEARCH_INDEX,
1483     CREATE_ALBUM_MAP_INSERT_SEARCH_TRIGGER,
1484     CREATE_ALBUM_MAP_DELETE_SEARCH_TRIGGER,
1485     CREATE_ALBUM_UPDATE_SEARCH_TRIGGER,
1486     CREATE_ANALYSIS_UPDATE_SEARCH_TRIGGER,
1487     MedialibraryBusinessRecordColumn::CREATE_TABLE,
1488     MedialibraryBusinessRecordColumn::CREATE_BUSINESS_KEY_INDEX,
1489     FormMap::CREATE_FORM_MAP_TABLE,
1490     CREATE_ANALYSIS_ALBUM_UPDATE_SEARCH_TRIGGER,
1491     PhotoExtColumn::CREATE_PHOTO_EXT_TABLE,
1492     PhotoColumn::CREATE_PHOTO_DISPLAYNAME_INDEX,
1493     PhotoColumn::CREATE_PHOTO_BURSTKEY_INDEX,
1494     AppUriPermissionColumn::CREATE_APP_URI_PERMISSION_TABLE,
1495     AppUriPermissionColumn::CREATE_URI_URITYPE_APPID_INDEX,
1496     TriggerDeletePhotoClearAppUriPermission(),
1497     TriggerDeleteAudioClearAppUriPermission(),
1498     PhotoColumn::UPDATA_PHOTOS_DATA_UNIQUE,
1499 };
1500 
ExecuteSql(RdbStore & store)1501 static int32_t ExecuteSql(RdbStore &store)
1502 {
1503     for (const string& sqlStr : onCreateSqlStrs) {
1504         auto ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(sqlStr); });
1505         if (ret != NativeRdb::E_OK) {
1506             return NativeRdb::E_ERROR;
1507         }
1508     }
1509     if (TabOldPhotosTableEventHandler().OnCreate(store) != NativeRdb::E_OK) {
1510         return NativeRdb::E_ERROR;
1511     }
1512     return NativeRdb::E_OK;
1513 }
1514 
OnCreate(RdbStore & store)1515 int32_t MediaLibraryDataCallBack::OnCreate(RdbStore &store)
1516 {
1517     MEDIA_INFO_LOG("Rdb OnCreate");
1518     if (ExecuteSql(store) != NativeRdb::E_OK) {
1519         return NativeRdb::E_ERROR;
1520     }
1521 
1522     if (PrepareSystemAlbums(store) != NativeRdb::E_OK) {
1523         return NativeRdb::E_ERROR;
1524     }
1525 
1526     if (PrepareAlbumPlugin(store) != NativeRdb::E_OK) {
1527         return NativeRdb::E_ERROR;
1528     }
1529 
1530     if (PrepareDir(store) != NativeRdb::E_OK) {
1531         return NativeRdb::E_ERROR;
1532     }
1533 
1534     if (PrepareSmartAlbum(store) != NativeRdb::E_OK) {
1535         return NativeRdb::E_ERROR;
1536     }
1537 
1538     if (PrepareUniqueMemberTable(store) != NativeRdb::E_OK) {
1539         return NativeRdb::E_ERROR;
1540     }
1541 
1542     if (PrepareShootingModeAlbum(store)!= NativeRdb::E_OK) {
1543         return NativeRdb::E_ERROR;
1544     }
1545 
1546     MediaLibraryRdbStore::SetOldVersion(MEDIA_RDB_VERSION);
1547     return NativeRdb::E_OK;
1548 }
1549 
VersionAddCloud(RdbStore & store)1550 void VersionAddCloud(RdbStore &store)
1551 {
1552     const std::string alterCloudId = "ALTER TABLE " + MEDIALIBRARY_TABLE +
1553         " ADD COLUMN " + MEDIA_DATA_DB_CLOUD_ID +" TEXT";
1554     int32_t result = ExecSqlWithRetry([&]() { return store.ExecuteSql(alterCloudId); });
1555     if (result != NativeRdb::E_OK) {
1556         UpdateFail(__FILE__, __LINE__);
1557         MEDIA_ERR_LOG("Upgrade rdb cloud_id error %{private}d", result);
1558     }
1559     const std::string alterDirty = "ALTER TABLE " + MEDIALIBRARY_TABLE +
1560         " ADD COLUMN " + MEDIA_DATA_DB_DIRTY +" INT DEFAULT 0";
1561     result = ExecSqlWithRetry([&]() { return store.ExecuteSql(alterDirty); });
1562     if (result != NativeRdb::E_OK) {
1563         UpdateFail(__FILE__, __LINE__);
1564         MEDIA_ERR_LOG("Upgrade rdb dirty error %{private}d", result);
1565     }
1566     const std::string alterSyncStatus = "ALTER TABLE " + MEDIALIBRARY_TABLE +
1567         " ADD COLUMN " + MEDIA_DATA_DB_SYNC_STATUS +" INT DEFAULT 0";
1568     result = ExecSqlWithRetry([&]() { return store.ExecuteSql(alterSyncStatus); });
1569     if (result != NativeRdb::E_OK) {
1570         UpdateFail(__FILE__, __LINE__);
1571         MEDIA_ERR_LOG("Upgrade rdb syncStatus error %{private}d", result);
1572     }
1573     const std::string alterPosition = "ALTER TABLE " + MEDIALIBRARY_TABLE +
1574         " ADD COLUMN " + MEDIA_DATA_DB_POSITION +" INT DEFAULT 1";
1575     result = ExecSqlWithRetry([&]() { return store.ExecuteSql(alterPosition); });
1576     if (result != NativeRdb::E_OK) {
1577         UpdateFail(__FILE__, __LINE__);
1578         MEDIA_ERR_LOG("Upgrade rdb position error %{private}d", result);
1579     }
1580 }
1581 
AddPortraitInAnalysisAlbum(RdbStore & store)1582 static void AddPortraitInAnalysisAlbum(RdbStore &store)
1583 {
1584     static const vector<string> executeSqlStrs = {
1585         ADD_TAG_ID_COLUMN_FOR_ALBUM,
1586         ADD_USER_OPERATION_COLUMN_FOR_ALBUM,
1587         ADD_GROUP_TAG_COLUMN_FOR_ALBUM,
1588         ADD_USER_DISPLAY_LEVEL_COLUMN_FOR_ALBUM,
1589         ADD_IS_ME_COLUMN_FOR_ALBUM,
1590         ADD_IS_REMOVED_COLUMN_FOR_ALBUM,
1591         ADD_RENAME_OPERATION_COLUMN_FOR_ALBUM,
1592         CREATE_ANALYSIS_ALBUM_UPDATE_SEARCH_TRIGGER
1593     };
1594     MEDIA_INFO_LOG("start add aesthetic composition tables");
1595     ExecSqls(executeSqlStrs, store);
1596 }
1597 
AddMetaModifiedColumn(RdbStore & store)1598 void AddMetaModifiedColumn(RdbStore &store)
1599 {
1600     const std::string alterMetaModified =
1601         "ALTER TABLE " + MEDIALIBRARY_TABLE + " ADD COLUMN " +
1602         MEDIA_DATA_DB_META_DATE_MODIFIED + " BIGINT DEFAULT 0";
1603     int32_t result = ExecSqlWithRetry([&]() { return store.ExecuteSql(alterMetaModified); });
1604     if (result != NativeRdb::E_OK) {
1605         UpdateFail(__FILE__, __LINE__);
1606         MEDIA_ERR_LOG("Upgrade rdb meta_date_modified error %{private}d", result);
1607     }
1608     const std::string alterSyncStatus = "ALTER TABLE " + MEDIALIBRARY_TABLE +
1609         " ADD COLUMN " + MEDIA_DATA_DB_SYNC_STATUS + " INT DEFAULT 0";
1610     result = ExecSqlWithRetry([&]() { return store.ExecuteSql(alterSyncStatus); });
1611     if (result != NativeRdb::E_OK) {
1612         UpdateFail(__FILE__, __LINE__);
1613         MEDIA_ERR_LOG("Upgrade rdb syncStatus error %{private}d", result);
1614     }
1615 }
1616 
AddTableType(RdbStore & store)1617 void AddTableType(RdbStore &store)
1618 {
1619     const std::string alterTableName =
1620         "ALTER TABLE " + BUNDLE_PERMISSION_TABLE + " ADD COLUMN " + PERMISSION_TABLE_TYPE + " INT";
1621     int32_t result = ExecSqlWithRetry([&]() { return store.ExecuteSql(alterTableName); });
1622     if (result != NativeRdb::E_OK) {
1623         UpdateFail(__FILE__, __LINE__);
1624         MEDIA_ERR_LOG("Upgrade rdb table_name error %{private}d", result);
1625     }
1626 }
1627 
API10TableCreate(RdbStore & store)1628 void API10TableCreate(RdbStore &store)
1629 {
1630     static const vector<string> executeSqlStrs = {
1631         PhotoColumn::CREATE_PHOTO_TABLE,
1632         PhotoColumn::INDEX_SCTHP_ADDTIME,
1633         PhotoColumn::INDEX_CAMERA_SHOT_KEY,
1634         PhotoColumn::CREATE_PHOTOS_DELETE_TRIGGER,
1635         PhotoColumn::CREATE_PHOTOS_FDIRTY_TRIGGER,
1636         PhotoColumn::CREATE_PHOTOS_MDIRTY_TRIGGER,
1637         PhotoColumn::CREATE_PHOTOS_INSERT_CLOUD_SYNC,
1638         AudioColumn::CREATE_AUDIO_TABLE,
1639         CREATE_ASSET_UNIQUE_NUMBER_TABLE,
1640         CREATE_FILES_DELETE_TRIGGER,
1641         CREATE_FILES_MDIRTY_TRIGGER,
1642         CREATE_FILES_FDIRTY_TRIGGER,
1643         CREATE_INSERT_CLOUD_SYNC_TRIGGER,
1644         PhotoAlbumColumns::CREATE_TABLE,
1645         PhotoAlbumColumns::INDEX_ALBUM_TYPES,
1646         PhotoMap::CREATE_TABLE,
1647         FormMap::CREATE_FORM_MAP_TABLE,
1648         TriggerDeleteAlbumClearMap(),
1649         TriggerAddAssets(),
1650         TriggerRemoveAssets(),
1651         TriggerDeletePhotoClearMap(),
1652         TriggerUpdateUserAlbumCount(),
1653     };
1654 
1655     for (size_t i = 0; i < executeSqlStrs.size(); i++) {
1656         auto result = ExecSqlWithRetry([&]() { return store.ExecuteSql(executeSqlStrs[i]); });
1657         if (result != NativeRdb::E_OK) {
1658             UpdateFail(__FILE__, __LINE__);
1659             MEDIA_ERR_LOG("upgrade fail idx:%{public}zu", i);
1660         }
1661     }
1662 }
1663 
ModifySyncStatus(RdbStore & store)1664 void ModifySyncStatus(RdbStore &store)
1665 {
1666     const std::string dropSyncStatus = "ALTER TABLE " + MEDIALIBRARY_TABLE + " DROP column syncing";
1667     auto result = ExecSqlWithRetry([&]() { return store.ExecuteSql(dropSyncStatus); });
1668     if (result != NativeRdb::E_OK) {
1669         UpdateFail(__FILE__, __LINE__);
1670         MEDIA_ERR_LOG("Upgrade rdb syncing error %{private}d", result);
1671     }
1672 
1673     const std::string addSyncStatus = "ALTER TABLE " + MEDIALIBRARY_TABLE + " ADD COLUMN " +
1674         MEDIA_DATA_DB_SYNC_STATUS +" INT DEFAULT 0";
1675     result = ExecSqlWithRetry([&]() { return store.ExecuteSql(addSyncStatus); });
1676     if (result != NativeRdb::E_OK) {
1677         UpdateFail(__FILE__, __LINE__);
1678         MEDIA_ERR_LOG("Upgrade rdb syncStatus error %{private}d", result);
1679     }
1680 }
1681 
ModifyDeleteTrigger(RdbStore & store)1682 void ModifyDeleteTrigger(RdbStore &store)
1683 {
1684     /* drop old delete trigger */
1685     const std::string dropDeleteTrigger = "DROP TRIGGER IF EXISTS photos_delete_trigger";
1686     if (ExecSqlWithRetry([&]() { return store.ExecuteSql(dropDeleteTrigger); }) != NativeRdb::E_OK) {
1687         UpdateFail(__FILE__, __LINE__);
1688         MEDIA_ERR_LOG("upgrade fail: drop old delete trigger");
1689     }
1690 
1691     /* create new delete trigger */
1692     if (ExecSqlWithRetry([&]() { return store.ExecuteSql(PhotoColumn::CREATE_PHOTOS_DELETE_TRIGGER); }) !=
1693         NativeRdb::E_OK) {
1694         UpdateFail(__FILE__, __LINE__);
1695         MEDIA_ERR_LOG("upgrade fail: create new delete trigger");
1696     }
1697 }
1698 
AddCloudVersion(RdbStore & store)1699 void AddCloudVersion(RdbStore &store)
1700 {
1701     const std::string addSyncStatus = "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
1702         PhotoColumn::PHOTO_CLOUD_VERSION +" BIGINT DEFAULT 0";
1703     auto result = ExecSqlWithRetry([&]() { return store.ExecuteSql(addSyncStatus); });
1704     if (result != NativeRdb::E_OK) {
1705         UpdateFail(__FILE__, __LINE__);
1706         MEDIA_ERR_LOG("Upgrade rdb cloudVersion error %{private}d", result);
1707     }
1708 }
1709 
UpdateCloudPathSql(const string & table,const string & column)1710 static string UpdateCloudPathSql(const string &table, const string &column)
1711 {
1712     static const string LOCAL_PATH = "/storage/media/local/";
1713     static const string CLOUD_PATH = "/storage/cloud/";
1714     /*
1715      * replace only once:
1716      * UPDATE photos
1717      * SET data = ([replace](substring(data, 1, len(local_path)), local_path, cloud_path) ||
1718      * substring(data, len(local_path) + 1));
1719      */
1720     return "UPDATE " + table + " SET " + column + " = (REPLACE(SUBSTRING(" +
1721         column + ", 1, " + to_string(LOCAL_PATH.length()) + "), '" +
1722         LOCAL_PATH + "', '" + CLOUD_PATH + "') || SUBSTRING(" + column + ", " +
1723         to_string(LOCAL_PATH.length() + 1) + "))" +
1724         " WHERE " + column + " LIKE '" + LOCAL_PATH + "%';";
1725 }
1726 
UpdateMdirtyTriggerForSdirty(RdbStore & store)1727 static void UpdateMdirtyTriggerForSdirty(RdbStore &store)
1728 {
1729     const string dropMdirtyCreateTrigger = "DROP TRIGGER IF EXISTS photos_mdirty_trigger";
1730     int32_t ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(dropMdirtyCreateTrigger); });
1731     if (ret != NativeRdb::E_OK) {
1732         MEDIA_ERR_LOG("drop photos_mdirty_trigger fail, ret = %{public}d", ret);
1733         UpdateFail(__FILE__, __LINE__);
1734     }
1735 
1736     ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(PhotoColumn::CREATE_PHOTOS_MDIRTY_TRIGGER); });
1737     if (ret != NativeRdb::E_OK) {
1738         MEDIA_ERR_LOG("add photos_mdirty_trigger fail, ret = %{public}d", ret);
1739         UpdateFail(__FILE__, __LINE__);
1740     }
1741 }
1742 
UpdateCloudPath(RdbStore & store)1743 static int32_t UpdateCloudPath(RdbStore &store)
1744 {
1745     const vector<string> updateCloudPath = {
1746         UpdateCloudPathSql(MEDIALIBRARY_TABLE, MEDIA_DATA_DB_FILE_PATH),
1747         UpdateCloudPathSql(MEDIALIBRARY_TABLE, MEDIA_DATA_DB_RECYCLE_PATH),
1748         UpdateCloudPathSql(MEDIALIBRARY_ERROR_TABLE, MEDIA_DATA_ERROR),
1749         UpdateCloudPathSql(PhotoColumn::PHOTOS_TABLE, MediaColumn::MEDIA_FILE_PATH),
1750     };
1751     auto result = ExecSqls(updateCloudPath, store);
1752     if (result != NativeRdb::E_OK) {
1753         UpdateFail(__FILE__, __LINE__);
1754     }
1755     return result;
1756 }
1757 
UpdateAPI10Table(RdbStore & store)1758 void UpdateAPI10Table(RdbStore &store)
1759 {
1760     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP INDEX IF EXISTS idx_sthp_dateadded"); });
1761     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP INDEX IF EXISTS photo_album_types"); });
1762     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS photos_delete_trigger"); });
1763     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS photos_fdirty_trigger"); });
1764     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS photos_mdirty_trigger"); });
1765     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS photo_insert_cloud_sync_trigger"); });
1766     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS delete_trigger"); });
1767     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS mdirty_trigger"); });
1768     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS fdirty_trigger"); });
1769     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS insert_cloud_sync_trigger"); });
1770     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS photo_album_clear_map"); });
1771     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS photo_album_insert_asset"); });
1772     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS photo_album_delete_asset"); });
1773     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS delete_photo_clear_map"); });
1774     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TRIGGER IF EXISTS update_user_album_count"); });
1775     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TABLE IF EXISTS Photos"); });
1776     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TABLE IF EXISTS Audios"); });
1777     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TABLE IF EXISTS UniqueNumber"); });
1778     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TABLE IF EXISTS PhotoAlbum"); });
1779     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TABLE IF EXISTS PhotoMap"); });
1780     ExecSqlWithRetry([&]() { return store.ExecuteSql("DROP TABLE IF EXISTS FormMap"); });
1781 
1782     API10TableCreate(store);
1783     if (PrepareSystemAlbums(store) != NativeRdb::E_OK) {
1784         UpdateFail(__FILE__, __LINE__);
1785     }
1786 
1787     if (PrepareUniqueMemberTable(store) != NativeRdb::E_OK) {
1788         UpdateFail(__FILE__, __LINE__);
1789     }
1790 
1791     // set scan error
1792     MediaScannerManager::GetInstance()->ErrorRecord();
1793 }
1794 
AddLocationTables(RdbStore & store)1795 static void AddLocationTables(RdbStore &store)
1796 {
1797     static const vector<string> executeSqlStrs = {
1798         CREATE_GEO_DICTIONARY_TABLE,
1799         CREATE_GEO_KNOWLEDGE_TABLE,
1800     };
1801     MEDIA_INFO_LOG("start init location db");
1802     ExecSqls(executeSqlStrs, store);
1803 }
1804 
AddAnalysisTables(RdbStore & store)1805 static void AddAnalysisTables(RdbStore &store)
1806 {
1807     static const vector<string> executeSqlStrs = {
1808         "DROP TABLE IF EXISTS tab_analysis_label",
1809         CREATE_TAB_ANALYSIS_OCR,
1810         CREATE_TAB_ANALYSIS_LABEL,
1811         CREATE_TAB_ANALYSIS_AESTHETICS,
1812         CREATE_TAB_ANALYSIS_TOTAL,
1813         CREATE_VISION_UPDATE_TRIGGER,
1814         CREATE_VISION_DELETE_TRIGGER,
1815         CREATE_VISION_INSERT_TRIGGER,
1816         INIT_TAB_ANALYSIS_TOTAL,
1817     };
1818     MEDIA_INFO_LOG("start init vision db");
1819     ExecSqls(executeSqlStrs, store);
1820 }
1821 
AddFaceTables(RdbStore & store)1822 static void AddFaceTables(RdbStore &store)
1823 {
1824     static const vector<string> executeSqlStrs = {
1825         CREATE_TAB_IMAGE_FACE,
1826         CREATE_TAB_FACE_TAG,
1827         DROP_INSERT_VISION_TRIGGER,
1828         CREATE_INSERT_VISION_TRIGGER_FOR_ADD_FACE,
1829         ADD_FACE_STATUS_COLUMN,
1830         UPDATE_TOTAL_VALUE,
1831         UPDATE_NOT_SUPPORT_VALUE,
1832         CREATE_IMAGE_FACE_INDEX
1833     };
1834     MEDIA_INFO_LOG("start add face tables");
1835     ExecSqls(executeSqlStrs, store);
1836 }
1837 
AddAnalysisAlbum(RdbStore & store)1838 static void AddAnalysisAlbum(RdbStore &store)
1839 {
1840     static const vector<string> executeSqlStrs = {
1841         "ALTER TABLE tab_analysis_ocr ADD COLUMN width INT;",
1842         "ALTER TABLE tab_analysis_ocr ADD COLUMN height INT;",
1843         CREATE_ANALYSIS_ALBUM,
1844         CREATE_ANALYSIS_ALBUM_MAP,
1845     };
1846     MEDIA_INFO_LOG("start init vision album");
1847     ExecSqls(executeSqlStrs, store);
1848 }
1849 
AddSaliencyTables(RdbStore & store)1850 static void AddSaliencyTables(RdbStore &store)
1851 {
1852     static const vector<string> executeSqlStrs = {
1853         CREATE_TAB_ANALYSIS_SALIENCY_DETECT,
1854         DROP_INSERT_VISION_TRIGGER,
1855         CREATE_VISION_INSERT_TRIGGER_FOR_ADD_SALIENCY,
1856         ADD_SALIENCY_STATUS_COLUMN,
1857         UPDATE_SALIENCY_TOTAL_VALUE,
1858         UPDATE_SALIENCY_NOT_SUPPORT_VALUE
1859     };
1860     MEDIA_INFO_LOG("start add saliency tables");
1861     ExecSqls(executeSqlStrs, store);
1862 }
1863 
AddVideoLabelTable(RdbStore & store)1864 static void AddVideoLabelTable(RdbStore &store)
1865 {
1866     static const vector<string> executeSqlStrs = {
1867         CREATE_TAB_ANALYSIS_VIDEO_LABEL,
1868         DROP_INSERT_VISION_TRIGGER,
1869         DROP_UPDATE_VISION_TRIGGER,
1870         CREATE_VISION_INSERT_TRIGGER_FOR_ADD_VIDEO_LABEL,
1871         CREATE_VISION_UPDATE_TRIGGER_FOR_ADD_VIDEO_LABEL,
1872     };
1873     MEDIA_INFO_LOG("start add video label tables");
1874     ExecSqls(executeSqlStrs, store);
1875 }
1876 
UpdateVideoLabelTable(RdbStore & store)1877 static void UpdateVideoLabelTable(RdbStore &store)
1878 {
1879     static const vector<string> executeSqlStrs = {
1880         "DROP TABLE IF EXISTS tab_analysis_video_label",
1881         CREATE_TAB_ANALYSIS_VIDEO_LABEL,
1882     };
1883     MEDIA_INFO_LOG("start update video label tables");
1884     ExecSqls(executeSqlStrs, store);
1885 }
1886 
AddSourceAlbumTrigger(RdbStore & store)1887 static void AddSourceAlbumTrigger(RdbStore &store)
1888 {
1889     static const vector<string> executeSqlStrs = {
1890         DROP_INSERT_PHOTO_INSERT_SOURCE_ALBUM,
1891         DROP_INSERT_PHOTO_UPDATE_SOURCE_ALBUM,
1892         DROP_UPDATE_PHOTO_UPDATE_SOURCE_ALBUM,
1893         DROP_DELETE_PHOTO_UPDATE_SOURCE_ALBUM,
1894         INSERT_PHOTO_INSERT_SOURCE_ALBUM,
1895         INSERT_PHOTO_UPDATE_SOURCE_ALBUM,
1896         UPDATE_PHOTO_UPDATE_SOURCE_ALBUM,
1897         DELETE_PHOTO_UPDATE_SOURCE_ALBUM,
1898     };
1899     MEDIA_INFO_LOG("start add source album trigger");
1900     ExecSqls(executeSqlStrs, store);
1901 }
1902 
RemoveSourceAlbumToAnalysis(RdbStore & store)1903 static void RemoveSourceAlbumToAnalysis(RdbStore &store)
1904 {
1905     static const vector<string> executeSqlStrs = {
1906         DROP_INSERT_PHOTO_INSERT_SOURCE_ALBUM,
1907         DROP_INSERT_PHOTO_UPDATE_SOURCE_ALBUM,
1908         DROP_UPDATE_PHOTO_UPDATE_SOURCE_ALBUM,
1909         DROP_DELETE_PHOTO_UPDATE_SOURCE_ALBUM,
1910         CLEAR_SOURCE_ALBUM_PHOTO_MAP,
1911         CLEAR_SYSTEM_SOURCE_ALBUM,
1912         INSERT_PHOTO_INSERT_SOURCE_ALBUM,
1913         INSERT_PHOTO_UPDATE_SOURCE_ALBUM,
1914         UPDATE_PHOTO_UPDATE_SOURCE_ALBUM,
1915         DELETE_PHOTO_UPDATE_SOURCE_ALBUM,
1916     };
1917     MEDIA_INFO_LOG("start add source album trigger");
1918     ExecSqls(executeSqlStrs, store);
1919 }
1920 
MoveSourceAlbumToPhotoAlbumAndAddColumns(RdbStore & store)1921 static void MoveSourceAlbumToPhotoAlbumAndAddColumns(RdbStore &store)
1922 {
1923     static const vector<string> executeSqlStrs = {
1924         DROP_INSERT_PHOTO_INSERT_SOURCE_ALBUM,
1925         DROP_INSERT_PHOTO_UPDATE_SOURCE_ALBUM,
1926         DROP_UPDATE_PHOTO_UPDATE_SOURCE_ALBUM,
1927         DROP_DELETE_PHOTO_UPDATE_SOURCE_ALBUM,
1928         ADD_SOURCE_ALBUM_BUNDLE_NAME,
1929         INSERT_SOURCE_ALBUMS_FROM_PHOTOS,
1930         INSERT_SOURCE_ALBUM_MAP_FROM_PHOTOS,
1931         CLEAR_SOURCE_ALBUM_ANALYSIS_PHOTO_MAP,
1932         CLEAR_ANALYSIS_SOURCE_ALBUM,
1933         INSERT_PHOTO_INSERT_SOURCE_ALBUM,
1934         INSERT_PHOTO_UPDATE_SOURCE_ALBUM,
1935         UPDATE_PHOTO_UPDATE_SOURCE_ALBUM,
1936         DELETE_PHOTO_UPDATE_SOURCE_ALBUM,
1937     };
1938     MEDIA_INFO_LOG("start move source album to photo album & add columns");
1939     ExecSqls(executeSqlStrs, store);
1940 }
1941 
ModifySourceAlbumTriggers(RdbStore & store)1942 static void ModifySourceAlbumTriggers(RdbStore &store)
1943 {
1944     static const vector<string> executeSqlStrs = {
1945         DROP_INSERT_PHOTO_INSERT_SOURCE_ALBUM,
1946         DROP_INSERT_PHOTO_UPDATE_SOURCE_ALBUM,
1947         DROP_UPDATE_PHOTO_UPDATE_SOURCE_ALBUM,
1948         DROP_DELETE_PHOTO_UPDATE_SOURCE_ALBUM,
1949         DROP_SOURCE_ALBUM_INDEX,
1950         ADD_SOURCE_ALBUM_LOCAL_LANGUAGE,
1951         CREATE_SOURCE_ALBUM_INDEX,
1952         INSERT_SOURCE_ALBUMS_FROM_PHOTOS_FULL,
1953         INSERT_SOURCE_ALBUM_MAP_FROM_PHOTOS_FULL,
1954         INSERT_PHOTO_INSERT_SOURCE_ALBUM,
1955         INSERT_PHOTO_UPDATE_SOURCE_ALBUM,
1956     };
1957     MEDIA_INFO_LOG("start modify source album triggers");
1958     ExecSqls(executeSqlStrs, store);
1959     MediaLibraryRdbUtils::UpdateSourceAlbumInternal(MediaLibraryUnistoreManager::GetInstance().GetRdbStore());
1960     MEDIA_INFO_LOG("end modify source album triggers");
1961 }
1962 
AddAestheticCompositionTables(RdbStore & store)1963 static void AddAestheticCompositionTables(RdbStore &store)
1964 {
1965     static const vector<string> executeSqlStrs = {
1966         CREATE_TAB_ANALYSIS_OBJECT,
1967         CREATE_TAB_ANALYSIS_RECOMMENDATION,
1968         CREATE_TAB_ANALYSIS_SEGMENTATION,
1969         CREATE_TAB_ANALYSIS_COMPOSITION,
1970         DROP_INSERT_VISION_TRIGGER,
1971         CREATE_VISION_INSERT_TRIGGER_FOR_ADD_AC,
1972         AC_ADD_OBJECT_COLUMN_FOR_TOTAL,
1973         AC_UPDATE_OBJECT_TOTAL_VALUE,
1974         AC_UPDATE_OBJECT_TOTAL_NOT_SUPPORT_VALUE,
1975         AC_ADD_RECOMMENDATION_COLUMN_FOR_TOTAL,
1976         AC_UPDATE_RECOMMENDATION_TOTAL_VALUE,
1977         AC_UPDATE_RECOMMENDATION_TOTAL_NOT_SUPPORT_VALUE,
1978         AC_ADD_SEGMENTATION_COLUMN_FOR_TOTAL,
1979         AC_UPDATE_SEGMENTATION_TOTAL_VALUE,
1980         AC_UPDATE_SEGMENTATION_TOTAL_NOT_SUPPORT_VALUE,
1981         AC_ADD_COMPOSITION_COLUMN_FOR_TOTAL,
1982         AC_UPDATE_COMPOSITION_TOTAL_VALUE,
1983         AC_UPDATE_COMPOSITION_TOTAL_NOT_SUPPORT_VALUE,
1984         CREATE_OBJECT_INDEX,
1985         CREATE_RECOMMENDATION_INDEX,
1986         CREATE_COMPOSITION_INDEX,
1987     };
1988     MEDIA_INFO_LOG("start add aesthetic composition tables");
1989     ExecSqls(executeSqlStrs, store);
1990 }
1991 
UpdateSpecForAddScreenshot(RdbStore & store)1992 static void UpdateSpecForAddScreenshot(RdbStore &store)
1993 {
1994     static const vector<string> executeSqlStrs = {
1995         DROP_INSERT_VISION_TRIGGER,
1996         CREATE_VISION_INSERT_TRIGGER_FOR_UPDATE_SPEC,
1997     };
1998     MEDIA_INFO_LOG("update media analysis service specifications for add screenshot");
1999     ExecSqls(executeSqlStrs, store);
2000 }
2001 
AddHeadAndPoseTables(RdbStore & store)2002 static void AddHeadAndPoseTables(RdbStore &store)
2003 {
2004     static const vector<string> executeSqlStrs = {
2005         CREATE_TAB_ANALYSIS_HEAD,
2006         CREATE_TAB_ANALYSIS_POSE,
2007         DROP_INSERT_VISION_TRIGGER,
2008         CREATE_VISION_INSERT_TRIGGER_FOR_ADD_HEAD_AND_POSE,
2009         ADD_HEAD_STATUS_COLUMN,
2010         UPDATE_HEAD_TOTAL_VALUE,
2011         UPDATE_HEAD_NOT_SUPPORT_VALUE,
2012         ADD_POSE_STATUS_COLUMN,
2013         UPDATE_POSE_TOTAL_VALUE,
2014         UPDATE_POSE_NOT_SUPPORT_VALUE,
2015         CREATE_HEAD_INDEX,
2016         CREATE_POSE_INDEX,
2017     };
2018     MEDIA_INFO_LOG("start add head and pose tables");
2019     ExecSqls(executeSqlStrs, store);
2020 }
2021 
AddFaceOcclusionAndPoseTypeColumn(RdbStore & store)2022 static void AddFaceOcclusionAndPoseTypeColumn(RdbStore &store)
2023 {
2024     MEDIA_INFO_LOG("start add face occlusion and pose type column");
2025     MediaLibraryRdbStore::AddColumnIfNotExists(store, FACE_OCCLUSION, "INT", VISION_IMAGE_FACE_TABLE);
2026     MediaLibraryRdbStore::AddColumnIfNotExists(store, POSE_TYPE, "INT", VISION_POSE_TABLE);
2027 }
2028 
AddSegmentationColumns(RdbStore & store)2029 static void AddSegmentationColumns(RdbStore &store)
2030 {
2031     const string addNameOnSegmentation = "ALTER TABLE " + VISION_SEGMENTATION_TABLE + " ADD COLUMN " +
2032         SEGMENTATION_NAME + " INT";
2033     const string addProbOnSegmentation = "ALTER TABLE " + VISION_SEGMENTATION_TABLE + " ADD COLUMN " +
2034         PROB + " REAL";
2035 
2036     const vector<string> addSegmentationColumns = { addNameOnSegmentation, addProbOnSegmentation };
2037     ExecSqls(addSegmentationColumns, store);
2038 }
2039 
AddSearchTable(RdbStore & store)2040 static void AddSearchTable(RdbStore &store)
2041 {
2042     static const vector<string> executeSqlStrs = {
2043         "DROP TABLE IF EXISTS " + SEARCH_TOTAL_TABLE,
2044         "DROP TRIGGER IF EXISTS " + INSERT_SEARCH_TRIGGER,
2045         "DROP TRIGGER IF EXISTS " + UPDATE_SEARCH_TRIGGER,
2046         "DROP TRIGGER IF EXISTS " + UPDATE_SEARCH_STATUS_TRIGGER,
2047         "DROP TRIGGER IF EXISTS " + DELETE_SEARCH_TRIGGER,
2048         "DROP TRIGGER IF EXISTS " + ALBUM_MAP_INSERT_SEARCH_TRIGGER,
2049         "DROP TRIGGER IF EXISTS " + ALBUM_MAP_DELETE_SEARCH_TRIGGER,
2050         "DROP TRIGGER IF EXISTS " + ALBUM_UPDATE_SEARCH_TRIGGER,
2051         "DROP TRIGGER IF EXISTS " + ANALYSIS_UPDATE_SEARCH_TRIGGER,
2052         CREATE_SEARCH_TOTAL_TABLE,
2053         CREATE_SEARCH_INSERT_TRIGGER,
2054         CREATE_SEARCH_UPDATE_TRIGGER,
2055         CREATE_SEARCH_UPDATE_STATUS_TRIGGER,
2056         CREATE_SEARCH_DELETE_TRIGGER,
2057         CREATE_ALBUM_MAP_INSERT_SEARCH_TRIGGER,
2058         CREATE_ALBUM_MAP_DELETE_SEARCH_TRIGGER,
2059         CREATE_ALBUM_UPDATE_SEARCH_TRIGGER,
2060         CREATE_ANALYSIS_UPDATE_SEARCH_TRIGGER,
2061     };
2062     MEDIA_INFO_LOG("start init search db");
2063     ExecSqls(executeSqlStrs, store);
2064 }
2065 
UpdateInsertPhotoUpdateAlbumTrigger(RdbStore & store)2066 static void UpdateInsertPhotoUpdateAlbumTrigger(RdbStore &store)
2067 {
2068     static const vector<string> executeSqlStrs = {
2069         INSERT_PHOTO_UPDATE_ALBUM_BUNDLENAME,
2070     };
2071     MEDIA_INFO_LOG("start update insert photo update album");
2072     ExecSqls(executeSqlStrs, store);
2073 }
2074 
ResetSearchTables()2075 bool MediaLibraryRdbStore::ResetSearchTables()
2076 {
2077     if (!MediaLibraryRdbStore::CheckRdbStore()) {
2078         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
2079         return false;
2080     }
2081     static const vector<string> executeSqlStrs = {
2082         "DROP TABLE IF EXISTS " + SEARCH_TOTAL_TABLE,
2083         "DROP TRIGGER IF EXISTS " + INSERT_SEARCH_TRIGGER,
2084         "DROP TRIGGER IF EXISTS " + UPDATE_SEARCH_TRIGGER,
2085         "DROP TRIGGER IF EXISTS " + UPDATE_SEARCH_STATUS_TRIGGER,
2086         "DROP TRIGGER IF EXISTS " + DELETE_SEARCH_TRIGGER,
2087         "DROP TRIGGER IF EXISTS " + ALBUM_MAP_INSERT_SEARCH_TRIGGER,
2088         "DROP TRIGGER IF EXISTS " + ALBUM_MAP_DELETE_SEARCH_TRIGGER,
2089         "DROP TRIGGER IF EXISTS " + ALBUM_UPDATE_SEARCH_TRIGGER,
2090         "DROP TRIGGER IF EXISTS " + ANALYSIS_UPDATE_SEARCH_TRIGGER,
2091     };
2092     MEDIA_INFO_LOG("start update search db");
2093     ExecSqls(executeSqlStrs, *rdbStore_);
2094     AddSearchTable(*rdbStore_);
2095     return true;
2096 }
2097 
ResetAnalysisTables()2098 bool MediaLibraryRdbStore::ResetAnalysisTables()
2099 {
2100     if (!MediaLibraryRdbStore::CheckRdbStore()) {
2101         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
2102         return false;
2103     }
2104     static const vector<string> executeSqlStrs = {
2105         "DROP TRIGGER IF EXISTS delete_vision_trigger",
2106         "DROP TRIGGER IF EXISTS insert_vision_trigger",
2107         "DROP TRIGGER IF EXISTS update_vision_trigger",
2108         "DROP TABLE IF EXISTS tab_analysis_ocr",
2109         "DROP TABLE IF EXISTS tab_analysis_label",
2110         "DROP TABLE IF EXISTS tab_analysis_saliency_detect",
2111         "DROP TABLE IF EXISTS tab_analysis_aesthetics_score",
2112         "DROP TABLE IF EXISTS tab_analysis_object",
2113         "DROP TABLE IF EXISTS tab_analysis_recommendation",
2114         "DROP TABLE IF EXISTS tab_analysis_segmentation",
2115         "DROP TABLE IF EXISTS tab_analysis_composition",
2116         "DROP TABLE IF EXISTS tab_analysis_total",
2117         "DROP TABLE IF EXISTS tab_analysis_image_face",
2118         "DROP TABLE IF EXISTS tab_analysis_face_tag",
2119         "DROP TABLE IF EXISTS tab_analysis_head",
2120         "DROP TABLE IF EXISTS tab_analysis_pose",
2121     };
2122     MEDIA_INFO_LOG("start update analysis table");
2123     ExecSqls(executeSqlStrs, *rdbStore_);
2124     AddAnalysisTables(*rdbStore_);
2125     AddFaceTables(*rdbStore_);
2126     AddAestheticCompositionTables(*rdbStore_);
2127     AddSaliencyTables(*rdbStore_);
2128     UpdateSpecForAddScreenshot(*rdbStore_);
2129     AddHeadAndPoseTables(*rdbStore_);
2130     AddSegmentationColumns(*rdbStore_);
2131     AddVideoLabelTable(*rdbStore_);
2132     AddFaceOcclusionAndPoseTypeColumn(*rdbStore_);
2133     return true;
2134 }
2135 
AddPackageNameColumnOnTables(RdbStore & store)2136 static void AddPackageNameColumnOnTables(RdbStore &store)
2137 {
2138     static const string ADD_PACKAGE_NAME_ON_PHOTOS = "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE +
2139         " ADD COLUMN " + PhotoColumn::MEDIA_PACKAGE_NAME + " TEXT";
2140     static const string ADD_PACKAGE_NAME_ON_AUDIOS = "ALTER TABLE " + AudioColumn::AUDIOS_TABLE +
2141         " ADD COLUMN " + AudioColumn::MEDIA_PACKAGE_NAME + " TEXT";
2142     static const string ADD_PACKAGE_NAME_ON_FILES = "ALTER TABLE " + MEDIALIBRARY_TABLE +
2143         " ADD COLUMN " + MEDIA_DATA_DB_PACKAGE_NAME + " TEXT";
2144 
2145     int32_t result = ExecSqlWithRetry([&]() { return store.ExecuteSql(ADD_PACKAGE_NAME_ON_PHOTOS); });
2146     if (result != NativeRdb::E_OK) {
2147         UpdateFail(__FILE__, __LINE__);
2148         MEDIA_ERR_LOG("Failed to update PHOTOS");
2149     }
2150     result = ExecSqlWithRetry([&]() { return store.ExecuteSql(ADD_PACKAGE_NAME_ON_AUDIOS); });
2151     if (result != NativeRdb::E_OK) {
2152         UpdateFail(__FILE__, __LINE__);
2153         MEDIA_ERR_LOG("Failed to update AUDIOS");
2154     }
2155     result = ExecSqlWithRetry([&]() { return store.ExecuteSql(ADD_PACKAGE_NAME_ON_FILES); });
2156     if (result != NativeRdb::E_OK) {
2157         UpdateFail(__FILE__, __LINE__);
2158         MEDIA_ERR_LOG("Failed to update FILES");
2159     }
2160 }
2161 
UpdateCloudAlbum(RdbStore & store)2162 void UpdateCloudAlbum(RdbStore &store)
2163 {
2164     /* album - add columns */
2165     const std::string addAlbumDirty = "ALTER TABLE " + PhotoAlbumColumns::TABLE +
2166         " ADD COLUMN " + PhotoAlbumColumns::ALBUM_DIRTY + " INT DEFAULT " +
2167         to_string(static_cast<int32_t>(DirtyTypes::TYPE_NEW)) + ";";
2168     int32_t ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(addAlbumDirty); });
2169     if (ret != NativeRdb::E_OK) {
2170         MEDIA_ERR_LOG("upgrade fail %{public}d: add ablum dirty", ret);
2171         UpdateFail(__FILE__, __LINE__);
2172     }
2173     const std::string addAlbumCloudId = "ALTER TABLE " + PhotoAlbumColumns::TABLE +
2174         " ADD COLUMN " + PhotoAlbumColumns::ALBUM_CLOUD_ID + " TEXT;";
2175     ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(addAlbumCloudId); });
2176     if (ret != NativeRdb::E_OK) {
2177         MEDIA_ERR_LOG("upgrade fail %{public}d: add ablum cloud id", ret);
2178         UpdateFail(__FILE__, __LINE__);
2179     }
2180     /* album - add triggers */
2181     ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(PhotoAlbumColumns::CREATE_ALBUM_INSERT_TRIGGER); });
2182     if (ret != NativeRdb::E_OK) {
2183         MEDIA_ERR_LOG("upgrade fail %{public}d: create album insert trigger", ret);
2184         UpdateFail(__FILE__, __LINE__);
2185     }
2186     ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(PhotoAlbumColumns::CREATE_ALBUM_MDIRTY_TRIGGER); });
2187     if (ret != NativeRdb::E_OK) {
2188         MEDIA_ERR_LOG("upgrade fail %{public}d: create album modify trigger", ret);
2189         UpdateFail(__FILE__, __LINE__);
2190     }
2191     ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(PhotoAlbumColumns::CREATE_ALBUM_DELETE_TRIGGER); });
2192     if (ret != NativeRdb::E_OK) {
2193         MEDIA_ERR_LOG("upgrade fail %{public}d: create album delete trigger", ret);
2194         UpdateFail(__FILE__, __LINE__);
2195     }
2196     /* album map - add columns */
2197     const std::string addAlbumMapColumns = "ALTER TABLE " + PhotoMap::TABLE +
2198         " ADD COLUMN " + PhotoMap::DIRTY +" INT DEFAULT " +
2199         to_string(static_cast<int32_t>(DirtyTypes::TYPE_NEW)) + ";";
2200     ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(addAlbumMapColumns); });
2201     if (ret != NativeRdb::E_OK) {
2202         MEDIA_ERR_LOG("upgrade fail %{public}d: add ablum columns", ret);
2203         UpdateFail(__FILE__, __LINE__);
2204     }
2205     /* album map - add triggers */
2206     ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(PhotoMap::CREATE_NEW_TRIGGER); });
2207     if (ret != NativeRdb::E_OK) {
2208         MEDIA_ERR_LOG("upgrade fail %{public}d: create album map insert trigger", ret);
2209         UpdateFail(__FILE__, __LINE__);
2210     }
2211     ret = ExecSqlWithRetry([&]() { return store.ExecuteSql(PhotoMap::CREATE_DELETE_TRIGGER); });
2212     if (ret != NativeRdb::E_OK) {
2213         MEDIA_ERR_LOG("upgrade fail %{public}d: create album map delete trigger", ret);
2214         UpdateFail(__FILE__, __LINE__);
2215     }
2216 }
2217 
AddCameraShotKey(RdbStore & store)2218 static void AddCameraShotKey(RdbStore &store)
2219 {
2220     static const string ADD_CAMERA_SHOT_KEY_ON_PHOTOS = "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE +
2221         " ADD COLUMN " + PhotoColumn::CAMERA_SHOT_KEY + " TEXT";
2222     int32_t result = ExecSqlWithRetry([&]() { return store.ExecuteSql(ADD_CAMERA_SHOT_KEY_ON_PHOTOS); });
2223     if (result != NativeRdb::E_OK) {
2224         UpdateFail(__FILE__, __LINE__);
2225         MEDIA_ERR_LOG("Failed to update PHOTOS");
2226     }
2227     result = ExecSqlWithRetry([&]() { return store.ExecuteSql(PhotoColumn::INDEX_CAMERA_SHOT_KEY); });
2228     if (result != NativeRdb::E_OK) {
2229         UpdateFail(__FILE__, __LINE__);
2230         MEDIA_ERR_LOG("Failed to create CAMERA_SHOT_KEY index");
2231     }
2232 }
2233 
RemoveAlbumCountTrigger(RdbStore & store)2234 void RemoveAlbumCountTrigger(RdbStore &store)
2235 {
2236     const vector<string> removeAlbumCountTriggers = {
2237         BaseColumn::DropTrigger() + "update_user_album_count",
2238         BaseColumn::DropTrigger() + "photo_album_insert_asset",
2239         BaseColumn::DropTrigger() + "photo_album_delete_asset",
2240     };
2241     ExecSqls(removeAlbumCountTriggers, store);
2242 }
2243 
AddExifAndUserComment(RdbStore & store)2244 void AddExifAndUserComment(RdbStore &store)
2245 {
2246     const string addUserCommentOnPhotos = "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE +
2247         " ADD COLUMN " + PhotoColumn::PHOTO_USER_COMMENT + " TEXT";
2248 
2249     const string addAllExifOnPhotos = "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE +
2250         " ADD COLUMN " + PhotoColumn::PHOTO_ALL_EXIF + " TEXT";
2251 
2252     const vector<string> addExifColumns = { addUserCommentOnPhotos, addAllExifOnPhotos };
2253     ExecSqls(addExifColumns, store);
2254 }
2255 
AddUpdateCloudSyncTrigger(RdbStore & store)2256 void AddUpdateCloudSyncTrigger(RdbStore &store)
2257 {
2258     const vector<string> addUpdateCloudSyncTrigger = { PhotoColumn::CREATE_PHOTOS_UPDATE_CLOUD_SYNC };
2259     ExecSqls(addUpdateCloudSyncTrigger, store);
2260 }
2261 
UpdateYearMonthDayData(RdbStore & store)2262 void UpdateYearMonthDayData(RdbStore &store)
2263 {
2264     MEDIA_DEBUG_LOG("UpdateYearMonthDayData start");
2265     const vector<string> updateSql = {
2266         "DROP TRIGGER IF EXISTS naturalbase_rdb_Audios_ON_DELETE",
2267         "DROP TRIGGER IF EXISTS naturalbase_rdb_Audios_ON_INSERT",
2268         "DROP TRIGGER IF EXISTS naturalbase_rdb_Audios_ON_UPDATE",
2269         "DROP TRIGGER IF EXISTS naturalbase_rdb_Files_ON_DELETE",
2270         "DROP TRIGGER IF EXISTS naturalbase_rdb_Files_ON_INSERT",
2271         "DROP TRIGGER IF EXISTS naturalbase_rdb_Files_ON_UPDATE",
2272         "DROP TRIGGER IF EXISTS naturalbase_rdb_Photos_ON_DELETE",
2273         "DROP TRIGGER IF EXISTS naturalbase_rdb_Photos_ON_INSERT",
2274         "DROP TRIGGER IF EXISTS naturalbase_rdb_Photos_ON_UPDATE",
2275         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_DATE_YEAR_INDEX,
2276         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_DATE_MONTH_INDEX,
2277         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_DATE_DAY_INDEX,
2278         "UPDATE " + PhotoColumn::PHOTOS_TABLE + " SET " +
2279             PhotoColumn::PHOTO_DATE_YEAR + " = strftime('%Y', datetime(date_added, 'unixepoch', 'localtime')), " +
2280             PhotoColumn::PHOTO_DATE_MONTH + " = strftime('%Y%m', datetime(date_added, 'unixepoch', 'localtime')), " +
2281             PhotoColumn::PHOTO_DATE_DAY + " = strftime('%Y%m%d', datetime(date_added, 'unixepoch', 'localtime'))",
2282         PhotoColumn::CREATE_YEAR_INDEX,
2283         PhotoColumn::CREATE_MONTH_INDEX,
2284         PhotoColumn::CREATE_DAY_INDEX,
2285         PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_INDEX,
2286     };
2287     ExecSqls(updateSql, store);
2288     MEDIA_DEBUG_LOG("UpdateYearMonthDayData end");
2289 }
2290 
FixIndexOrder(RdbStore & store)2291 void FixIndexOrder(RdbStore &store)
2292 {
2293     const vector<string> updateSql = {
2294         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_DATE_YEAR_INDEX,
2295         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_DATE_MONTH_INDEX,
2296         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_DATE_DAY_INDEX,
2297         "DROP INDEX IF EXISTS idx_media_type",
2298         "DROP INDEX IF EXISTS idx_sthp_dateadded",
2299         PhotoColumn::CREATE_YEAR_INDEX,
2300         PhotoColumn::CREATE_MONTH_INDEX,
2301         PhotoColumn::CREATE_DAY_INDEX,
2302         PhotoColumn::INDEX_SCTHP_ADDTIME,
2303         PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_INDEX,
2304         PhotoColumn::CREATE_SCHPT_DAY_INDEX,
2305     };
2306     ExecSqls(updateSql, store);
2307 }
2308 
AddYearMonthDayColumn(RdbStore & store)2309 void AddYearMonthDayColumn(RdbStore &store)
2310 {
2311     const vector<string> sqls = {
2312         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_DATE_YEAR + " TEXT",
2313         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_DATE_MONTH + " TEXT",
2314         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_DATE_DAY + " TEXT",
2315     };
2316     ExecSqls(sqls, store);
2317 }
2318 
AddCleanFlagAndThumbStatus(RdbStore & store)2319 void AddCleanFlagAndThumbStatus(RdbStore &store)
2320 {
2321     const vector<string> addSyncStatus = {
2322         "DROP INDEX IF EXISTS idx_shpt_date_added",
2323         "DROP INDEX IF EXISTS idx_shpt_media_type",
2324         "DROP INDEX IF EXISTS idx_shpt_date_day",
2325         BaseColumn::AlterTableAddIntColumn(PhotoColumn::PHOTOS_TABLE, PhotoColumn::PHOTO_CLEAN_FLAG),
2326         BaseColumn::AlterTableAddIntColumn(PhotoColumn::PHOTOS_TABLE, PhotoColumn::PHOTO_THUMB_STATUS),
2327         PhotoColumn::INDEX_SCTHP_ADDTIME,
2328         PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_INDEX,
2329         PhotoColumn::CREATE_SCHPT_DAY_INDEX,
2330     };
2331     int32_t result = ExecSqls(addSyncStatus, store);
2332     if (result != NativeRdb::E_OK) {
2333         MEDIA_ERR_LOG("Upgrade rdb need clean and thumb status error %{private}d", result);
2334     }
2335 }
2336 
AddCloudIndex(RdbStore & store)2337 void AddCloudIndex(RdbStore &store)
2338 {
2339     const vector<string> sqls = {
2340         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_CLOUD_ID_INDEX,
2341         PhotoColumn::CREATE_CLOUD_ID_INDEX,
2342     };
2343     ExecSqls(sqls, store);
2344 }
2345 
AddPhotoEditTimeColumn(RdbStore & store)2346 static void AddPhotoEditTimeColumn(RdbStore &store)
2347 {
2348     const string addEditTimeOnPhotos = "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE +
2349         " ADD COLUMN " + PhotoColumn::PHOTO_EDIT_TIME + " BIGINT DEFAULT 0";
2350     const vector<string> addEditTime = { addEditTimeOnPhotos };
2351     ExecSqls(addEditTime, store);
2352 }
2353 
AddShootingModeColumn(RdbStore & store)2354 void AddShootingModeColumn(RdbStore &store)
2355 {
2356     const std::string addShootringMode =
2357         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
2358         PhotoColumn::PHOTO_SHOOTING_MODE + " TEXT";
2359     const vector<string> addShootingModeColumn = { addShootringMode };
2360     int32_t result = ExecSqls(addShootingModeColumn, store);
2361     if (result != NativeRdb::E_OK) {
2362         MEDIA_ERR_LOG("Upgrade rdb shooting_mode error %{private}d", result);
2363     }
2364 }
2365 
AddShootingModeTagColumn(RdbStore & store)2366 void AddShootingModeTagColumn(RdbStore &store)
2367 {
2368     const std::string addShootringModeTag =
2369         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
2370         PhotoColumn::PHOTO_SHOOTING_MODE_TAG + " TEXT";
2371     const std::string dropExpiredClearMapTrigger =
2372         "DROP TRIGGER IF EXISTS delete_photo_clear_map";
2373     const vector<string> addShootingModeTagColumn = {addShootringModeTag,
2374         dropExpiredClearMapTrigger, TriggerDeletePhotoClearMap()};
2375     int32_t result = ExecSqls(addShootingModeTagColumn, store);
2376     if (result != NativeRdb::E_OK) {
2377         MEDIA_ERR_LOG("Upgrade rdb shooting_mode error %{private}d", result);
2378     }
2379 }
2380 
AddHiddenViewColumn(RdbStore & store)2381 static void AddHiddenViewColumn(RdbStore &store)
2382 {
2383     vector<string> upgradeSqls = {
2384         BaseColumn::AlterTableAddIntColumn(PhotoAlbumColumns::TABLE, PhotoAlbumColumns::CONTAINS_HIDDEN),
2385         BaseColumn::AlterTableAddIntColumn(PhotoAlbumColumns::TABLE, PhotoAlbumColumns::HIDDEN_COUNT),
2386         BaseColumn::AlterTableAddTextColumn(PhotoAlbumColumns::TABLE, PhotoAlbumColumns::HIDDEN_COVER),
2387     };
2388     ExecSqls(upgradeSqls, store);
2389 }
2390 
ModifyMdirtyTriggers(RdbStore & store)2391 static void ModifyMdirtyTriggers(RdbStore &store)
2392 {
2393     /* drop old mdirty trigger */
2394     const vector<string> dropMdirtyTriggers = {
2395         "DROP TRIGGER IF EXISTS photos_mdirty_trigger",
2396         "DROP TRIGGER IF EXISTS mdirty_trigger",
2397     };
2398     if (ExecSqls(dropMdirtyTriggers, store) != NativeRdb::E_OK) {
2399         UpdateFail(__FILE__, __LINE__);
2400         MEDIA_ERR_LOG("upgrade fail: drop old mdirty trigger");
2401     }
2402 
2403     /* create new mdirty trigger */
2404     if (ExecSqlWithRetry([&]() { return store.ExecuteSql(PhotoColumn::CREATE_PHOTOS_MDIRTY_TRIGGER); }) !=
2405         NativeRdb::E_OK) {
2406         UpdateFail(__FILE__, __LINE__);
2407         MEDIA_ERR_LOG("upgrade fail: create new photos mdirty trigger");
2408     }
2409 
2410     if (ExecSqlWithRetry([&]() { return store.ExecuteSql(CREATE_FILES_MDIRTY_TRIGGER); }) != NativeRdb::E_OK) {
2411         UpdateFail(__FILE__, __LINE__);
2412         MEDIA_ERR_LOG("upgrade fail: create new mdirty trigger");
2413     }
2414 }
2415 
AddLastVisitTimeColumn(RdbStore & store)2416 static void AddLastVisitTimeColumn(RdbStore &store)
2417 {
2418     const vector<string> sqls = {
2419         "ALTER TABLE " + AudioColumn::AUDIOS_TABLE + " DROP time_visit ",
2420         "ALTER TABLE " + REMOTE_THUMBNAIL_TABLE + " DROP time_visit ",
2421         "ALTER TABLE " + MEDIALIBRARY_TABLE + " DROP time_visit ",
2422         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " DROP time_visit ",
2423         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
2424         PhotoColumn::PHOTO_LAST_VISIT_TIME + " BIGINT DEFAULT 0",
2425     };
2426     int32_t result = ExecSqls(sqls, store);
2427     if (result != NativeRdb::E_OK) {
2428         MEDIA_ERR_LOG("Upgrade rdb last_visit_time error %{private}d", result);
2429     }
2430 }
2431 
AddHiddenTimeColumn(RdbStore & store)2432 void AddHiddenTimeColumn(RdbStore &store)
2433 {
2434     const vector<string> sqls = {
2435         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE +
2436             " ADD COLUMN " + PhotoColumn::PHOTO_HIDDEN_TIME + " BIGINT DEFAULT 0",
2437         PhotoColumn::CREATE_HIDDEN_TIME_INDEX,
2438     };
2439     ExecSqls(sqls, store);
2440 }
2441 
AddAlbumOrderColumn(RdbStore & store)2442 void AddAlbumOrderColumn(RdbStore &store)
2443 {
2444     const std::string addAlbumOrderColumn =
2445         "ALTER TABLE " + PhotoAlbumColumns::TABLE + " ADD COLUMN " +
2446         PhotoAlbumColumns::ALBUM_ORDER + " INT";
2447     const std::string initOriginOrder =
2448         "UPDATE " + PhotoAlbumColumns::TABLE + " SET " +
2449         PhotoAlbumColumns::ALBUM_ORDER + " = rowid";
2450     const std::string albumDeleteTrigger =
2451         " CREATE TRIGGER IF NOT EXISTS update_order_trigger AFTER DELETE ON " + PhotoAlbumColumns::TABLE +
2452         " FOR EACH ROW " +
2453         " BEGIN " +
2454         " UPDATE " + PhotoAlbumColumns::TABLE + " SET album_order = album_order - 1" +
2455         " WHERE album_order > old.album_order; " +
2456         " END";
2457     const std::string albumInsertTrigger =
2458         " CREATE TRIGGER IF NOT EXISTS insert_order_trigger AFTER INSERT ON " + PhotoAlbumColumns::TABLE +
2459         " BEGIN " +
2460         " UPDATE " + PhotoAlbumColumns::TABLE + " SET album_order = (" +
2461         " SELECT COALESCE(MAX(album_order), 0) + 1 FROM " + PhotoAlbumColumns::TABLE +
2462         ") WHERE rowid = new.rowid;" +
2463         " END";
2464 
2465     const vector<string> addAlbumOrder = { addAlbumOrderColumn, initOriginOrder,
2466         albumDeleteTrigger, albumInsertTrigger};
2467     int32_t result = ExecSqls(addAlbumOrder, store);
2468     if (result != NativeRdb::E_OK) {
2469         MEDIA_ERR_LOG("Upgrade rdb album order error %{private}d", result);
2470     }
2471 }
2472 
FixDocsPath(RdbStore & store)2473 static void FixDocsPath(RdbStore &store)
2474 {
2475     vector<string> sqls = {
2476         "UPDATE Files SET "
2477             " data = REPLACE(data, '/storage/cloud/files/Documents', '/storage/cloud/files/Docs/Documents'),"
2478             " data = REPLACE(data, '/storage/cloud/files/Download', '/storage/cloud/files/Docs/Download'),"
2479             " relative_path = REPLACE(relative_path, 'Documents/', 'Docs/Documents/'),"
2480             " relative_path = REPLACE(relative_path, 'Download/', 'Docs/Download/')"
2481         " WHERE data LIKE '/storage/cloud/files/Documents%' OR "
2482             " data LIKE '/storage/cloud/files/Download%' OR"
2483             " relative_path LIKE 'Documents/%' OR"
2484             " relative_path LIKE 'Download/%';",
2485         "UPDATE MediaTypeDirectory SET directory = 'Docs/' WHERE directory_type = 4 OR directory_type = 5",
2486     };
2487 
2488     ExecSqls(sqls, store);
2489 }
2490 
AddFormMap(RdbStore & store)2491 static void AddFormMap(RdbStore &store)
2492 {
2493     int32_t result = ExecSqlWithRetry([&]() { return store.ExecuteSql(FormMap::CREATE_FORM_MAP_TABLE); });
2494     if (result != NativeRdb::E_OK) {
2495         UpdateFail(__FILE__, __LINE__);
2496         MEDIA_ERR_LOG("Failed to update PHOTOS");
2497     }
2498 }
2499 
AddImageVideoCount(RdbStore & store)2500 static void AddImageVideoCount(RdbStore &store)
2501 {
2502     const vector<string> sqls = {
2503         "ALTER TABLE " + PhotoAlbumColumns::TABLE +
2504                 " ADD COLUMN " + PhotoAlbumColumns::ALBUM_IMAGE_COUNT + " INT DEFAULT 0",
2505         "ALTER TABLE " + PhotoAlbumColumns::TABLE +
2506                 " ADD COLUMN " + PhotoAlbumColumns::ALBUM_VIDEO_COUNT + " INT DEFAULT 0",
2507     };
2508 
2509     ExecSqls(sqls, store);
2510 }
2511 
AddSCHPTHiddenTimeIndex(RdbStore & store)2512 static void AddSCHPTHiddenTimeIndex(RdbStore &store)
2513 {
2514     const vector<string> sqls = {
2515         PhotoColumn::CREATE_SCHPT_HIDDEN_TIME_INDEX,
2516     };
2517     ExecSqls(sqls, store);
2518 }
2519 
UpdateClassifyDirtyData(RdbStore & store)2520 static void UpdateClassifyDirtyData(RdbStore &store)
2521 {
2522     static const vector<string> executeSqlStrs = {
2523         DROP_TABLE_ANALYSISALBUM,
2524         DROP_TABLE_ANALYSISPHOTOMAP,
2525         ALTER_WIDTH_COLUMN,
2526         ALTER_HEIGHT_COLUMN,
2527         CREATE_ANALYSIS_ALBUM,
2528         CREATE_ANALYSIS_ALBUM_MAP,
2529         CREATE_TAB_IMAGE_FACE,
2530         CREATE_TAB_FACE_TAG,
2531         DROP_INSERT_VISION_TRIGGER,
2532         CREATE_INSERT_VISION_TRIGGER_FOR_ADD_FACE,
2533         ADD_FACE_STATUS_COLUMN,
2534         UPDATE_TOTAL_VALUE,
2535         UPDATE_NOT_SUPPORT_VALUE,
2536         CREATE_IMAGE_FACE_INDEX
2537     };
2538     MEDIA_INFO_LOG("start clear dirty data");
2539     ExecSqls(executeSqlStrs, store);
2540 }
2541 
UpdateGeoTables(RdbStore & store)2542 static void UpdateGeoTables(RdbStore &store)
2543 {
2544     const vector<string> sqls = {
2545         "ALTER TABLE tab_geo_dictionary RENAME TO " +  GEO_DICTIONARY_TABLE,
2546         "ALTER TABLE tab_geo_knowledge RENAME TO " +  GEO_KNOWLEDGE_TABLE,
2547         CREATE_DICTIONARY_INDEX,
2548         DROP_KNOWLEDGE_INDEX,
2549         CREATE_NEW_KNOWLEDGE_INDEX,
2550         CREATE_CITY_NAME_INDEX,
2551         CREATE_LOCATION_KEY_INDEX,
2552     };
2553     ExecSqls(sqls, store);
2554 }
2555 
UpdatePhotosMdirtyTrigger(RdbStore & store)2556 static void UpdatePhotosMdirtyTrigger(RdbStore& store)
2557 {
2558     string dropSql = "DROP TRIGGER IF EXISTS photos_mdirty_trigger";
2559     if (ExecSqlWithRetry([&]() { return store.ExecuteSql(dropSql); }) != NativeRdb::E_OK) {
2560         MEDIA_ERR_LOG("Failed to drop old photos_mdirty_trigger: %{private}s", dropSql.c_str());
2561         UpdateFail(__FILE__, __LINE__);
2562     }
2563 
2564     if (ExecSqlWithRetry([&]() { return store.ExecuteSql(PhotoColumn::CREATE_PHOTOS_MDIRTY_TRIGGER); }) !=
2565         NativeRdb::E_OK) {
2566         UpdateFail(__FILE__, __LINE__);
2567         MEDIA_ERR_LOG("Failed to upgrade new photos_mdirty_trigger, %{private}s",
2568             PhotoColumn::CREATE_PHOTOS_MDIRTY_TRIGGER.c_str());
2569     }
2570 }
2571 
FixPhotoSchptMediaTypeIndex(RdbStore & store)2572 static void FixPhotoSchptMediaTypeIndex(RdbStore &store)
2573 {
2574     static const vector<string> executeSqlStrs = {
2575         PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_INDEX,
2576     };
2577     MEDIA_INFO_LOG("Fix idx_schpt_media_type index");
2578     ExecSqls(executeSqlStrs, store);
2579     MEDIA_INFO_LOG("End fix idx_schpt_media_type index.");
2580 }
2581 
AddIndexForFileId(RdbStore & store)2582 static void AddIndexForFileId(RdbStore& store)
2583 {
2584     const vector<string> sqls = {
2585         CREATE_IDX_FILEID_FOR_SEARCH_INDEX,
2586         CREATE_IDX_FILEID_FOR_ANALYSIS_TOTAL,
2587         PhotoMap::CREATE_IDX_FILEID_FOR_PHOTO_MAP,
2588         CREATE_IDX_FILEID_FOR_ANALYSIS_PHOTO_MAP,
2589     };
2590     MEDIA_INFO_LOG("start AddIndexForFileId");
2591     ExecSqls(sqls, store);
2592 }
2593 
AddCloudEnhancementAlbum(RdbStore & store)2594 static void AddCloudEnhancementAlbum(RdbStore& store)
2595 {
2596     ValuesBucket values;
2597     int32_t err = E_FAIL;
2598     values.PutInt(PhotoAlbumColumns::ALBUM_TYPE, PhotoAlbumType::SYSTEM);
2599     values.PutInt(PhotoAlbumColumns::ALBUM_SUBTYPE, PhotoAlbumSubType::CLOUD_ENHANCEMENT);
2600     values.PutInt(PhotoAlbumColumns::ALBUM_ORDER,
2601         PhotoAlbumSubType::CLOUD_ENHANCEMENT - PhotoAlbumSubType::SYSTEM_START);
2602 
2603     AbsRdbPredicates predicates(PhotoAlbumColumns::TABLE);
2604     predicates.EqualTo(PhotoAlbumColumns::ALBUM_TYPE, to_string(PhotoAlbumType::SYSTEM));
2605     predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::CLOUD_ENHANCEMENT));
2606 
2607     string sql;
2608     vector<ValueObject> bindArgs;
2609     // Build insert sql
2610     sql.append("INSERT").append(" INTO ").append(PhotoAlbumColumns::TABLE).append(" ");
2611     MediaLibraryRdbStore::BuildValuesSql(values, bindArgs, sql);
2612     sql.append(" WHERE NOT EXISTS (");
2613     MediaLibraryRdbStore::BuildQuerySql(predicates, { PhotoAlbumColumns::ALBUM_ID }, bindArgs, sql);
2614     sql.append(");");
2615     err = store.ExecuteSql(sql, bindArgs);
2616     values.Clear();
2617     if (err != E_OK) {
2618         MEDIA_ERR_LOG("Add cloud enhancement album failed, err: %{public}d", err);
2619     }
2620 }
2621 
UpdateSearchIndexTriggerForCleanFlag(RdbStore & store)2622 static void UpdateSearchIndexTriggerForCleanFlag(RdbStore& store)
2623 {
2624     const vector<string> sqls = {
2625         "DROP TRIGGER IF EXISTS update_search_status_trigger",
2626         CREATE_SEARCH_UPDATE_STATUS_TRIGGER,
2627     };
2628     MEDIA_INFO_LOG("start update search index for clean flag");
2629     ExecSqls(sqls, store);
2630 }
2631 
UpdateAlbumRefreshTable(RdbStore & store)2632 static void UpdateAlbumRefreshTable(RdbStore &store)
2633 {
2634     const vector<string> sqls = {
2635         CREATE_ALBUM_REFRESH_TABLE,
2636     };
2637     ExecSqls(sqls, store);
2638 }
2639 
UpdateFavoriteIndex(RdbStore & store)2640 static void UpdateFavoriteIndex(RdbStore &store)
2641 {
2642     MEDIA_INFO_LOG("Upgrade rdb UpdateFavoriteIndex");
2643     const vector<string> sqls = {
2644         PhotoColumn::CREATE_PHOTO_FAVORITE_INDEX,
2645         PhotoColumn::DROP_SCHPT_MEDIA_TYPE_INDEX,
2646         PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_INDEX,
2647     };
2648     ExecSqls(sqls, store);
2649 }
2650 
AddMissingUpdates(RdbStore & store)2651 static void AddMissingUpdates(RdbStore &store)
2652 {
2653     MEDIA_INFO_LOG("start add missing updates");
2654     vector<string> sqls;
2655     bool hasShootingModeTag = MediaLibraryRdbStore::HasColumnInTable(store, PhotoColumn::PHOTO_SHOOTING_MODE_TAG,
2656         PhotoColumn::PHOTOS_TABLE);
2657     if (!hasShootingModeTag) {
2658         MEDIA_INFO_LOG("start add shooting mode tag");
2659         const vector<string> sqls = {
2660             "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_SHOOTING_MODE_TAG +
2661                 " TEXT",
2662         };
2663         ExecSqls(sqls, store);
2664     }
2665     bool hasBundleName = MediaLibraryRdbStore::HasColumnInTable(store, PhotoAlbumColumns::ALBUM_BUNDLE_NAME,
2666         PhotoAlbumColumns::TABLE);
2667     bool hasLocalLanguage = MediaLibraryRdbStore::HasColumnInTable(store, PhotoAlbumColumns::ALBUM_LOCAL_LANGUAGE,
2668         PhotoAlbumColumns::TABLE);
2669     if (!hasBundleName) {
2670         MoveSourceAlbumToPhotoAlbumAndAddColumns(store);
2671         ModifySourceAlbumTriggers(store);
2672     } else if (!hasLocalLanguage) {
2673         ModifySourceAlbumTriggers(store);
2674     } else {
2675         MEDIA_INFO_LOG("both columns exist, no need to start source album related updates");
2676     }
2677     MEDIA_INFO_LOG("start add cloud index");
2678     AddCloudIndex(store);
2679     MEDIA_INFO_LOG("start update photos mdirty trigger");
2680     UpdatePhotosMdirtyTrigger(store);
2681     MEDIA_INFO_LOG("end add missing updates");
2682 }
2683 
AddMultiStagesCaptureColumns(RdbStore & store)2684 void AddMultiStagesCaptureColumns(RdbStore &store)
2685 {
2686     const vector<string> sqls = {
2687         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_ID + " TEXT",
2688         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_QUALITY + " INT",
2689         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_FIRST_VISIT_TIME +
2690             " BIGINT DEFAULT 0",
2691         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_DEFERRED_PROC_TYPE +
2692             " INT DEFAULT 0",
2693     };
2694     ExecSqls(sqls, store);
2695 }
2696 
UpdateMillisecondDate(RdbStore & store)2697 void UpdateMillisecondDate(RdbStore &store)
2698 {
2699     MEDIA_DEBUG_LOG("UpdateMillisecondDate start");
2700     const vector<string> updateSql = {
2701         "UPDATE " + PhotoColumn::PHOTOS_TABLE + " SET " +
2702         MediaColumn::MEDIA_DATE_ADDED + " = " + MediaColumn::MEDIA_DATE_ADDED + "*1000," +
2703         MediaColumn::MEDIA_DATE_MODIFIED + " = " + MediaColumn::MEDIA_DATE_MODIFIED + "*1000," +
2704         MediaColumn::MEDIA_DATE_TRASHED + " = " + MediaColumn::MEDIA_DATE_TRASHED + "*1000;",
2705         "UPDATE " + AudioColumn::AUDIOS_TABLE + " SET " +
2706         MediaColumn::MEDIA_DATE_ADDED + " = " + MediaColumn::MEDIA_DATE_ADDED + "*1000," +
2707         MediaColumn::MEDIA_DATE_MODIFIED + " = " + MediaColumn::MEDIA_DATE_MODIFIED + "*1000," +
2708         MediaColumn::MEDIA_DATE_TRASHED + " = " + MediaColumn::MEDIA_DATE_TRASHED + "*1000;",
2709         "UPDATE " + PhotoAlbumColumns::TABLE + " SET " +
2710         MediaColumn::MEDIA_DATE_MODIFIED + " = " +  MediaColumn::MEDIA_DATE_MODIFIED + "*1000;",
2711         "UPDATE " + MEDIALIBRARY_TABLE + " SET " +
2712         MediaColumn::MEDIA_DATE_ADDED + " = " + MediaColumn::MEDIA_DATE_ADDED + "*1000," +
2713         MediaColumn::MEDIA_DATE_MODIFIED + " = " + MediaColumn::MEDIA_DATE_MODIFIED + "*1000;",
2714     };
2715     ExecSqls(updateSql, store);
2716     MEDIA_DEBUG_LOG("UpdateMillisecondDate end");
2717 }
2718 
AddAddressDescriptionColumns(RdbStore & store)2719 void AddAddressDescriptionColumns(RdbStore &store)
2720 {
2721     const vector<string> sqls = {
2722         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + CITY_NAME + " TEXT",
2723         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + ADDRESS_DESCRIPTION + " TEXT",
2724     };
2725     ExecSqls(sqls, store);
2726 }
2727 
AddHasAstcColumns(RdbStore & store)2728 void AddHasAstcColumns(RdbStore &store)
2729 {
2730     const vector<string> sqls = {
2731         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_HAS_ASTC + " INT DEFAULT 0 ",
2732     };
2733     ExecSqls(sqls, store);
2734 }
2735 
AddIsLocalAlbum(RdbStore & store)2736 void AddIsLocalAlbum(RdbStore &store)
2737 {
2738     const vector<string> sqls = {
2739         ADD_IS_LOCAL_COLUMN_FOR_ALBUM,
2740         ADD_PHOTO_ALBUM_IS_LOCAL,
2741     };
2742     MEDIA_INFO_LOG("start add islocal column");
2743     ExecSqls(sqls, store);
2744 }
2745 
UpdateAOI(RdbStore & store)2746 void UpdateAOI(RdbStore &store)
2747 {
2748     const vector<string> sqls = {
2749         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + AOI + " TEXT ",
2750         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + POI + " TEXT ",
2751         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + FIRST_AOI + " TEXT ",
2752         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + FIRST_POI + " TEXT ",
2753         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + LOCATION_VERSION + " TEXT ",
2754         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + FIRST_AOI_CATEGORY + " TEXT ",
2755         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + FIRST_POI_CATEGORY + " TEXT ",
2756         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + FILE_ID + " INT ",
2757         DROP_KNOWLEDGE_INDEX,
2758         CREATE_NEW_KNOWLEDGE_INDEX,
2759         "ALTER TABLE " + VISION_TOTAL_TABLE + " DROP COLUMN " + GEO,
2760         "ALTER TABLE " + VISION_TOTAL_TABLE + " ADD COLUMN " + GEO + " INT DEFAULT 0",
2761         "ALTER TABLE " + HIGHLIGHT_COVER_INFO_TABLE +
2762             " ADD COLUMN " + COVER_SERVICE_VERSION + " INT DEFAULT 0",
2763         "ALTER TABLE " + HIGHLIGHT_PLAY_INFO_TABLE +
2764             " ADD COLUMN " + PLAY_SERVICE_VERSION + " INT DEFAULT 0",
2765 
2766     };
2767     MEDIA_INFO_LOG("start init aoi info of geo db");
2768     ExecSqls(sqls, store);
2769 }
2770 
AddStoryTables(RdbStore & store)2771 void AddStoryTables(RdbStore &store)
2772 {
2773     const vector<string> executeSqlStrs = {
2774         CREATE_HIGHLIGHT_ALBUM_TABLE,
2775         CREATE_HIGHLIGHT_COVER_INFO_TABLE,
2776         CREATE_HIGHLIGHT_PLAY_INFO_TABLE,
2777         CREATE_USER_PHOTOGRAPHY_INFO_TABLE,
2778         "ALTER TABLE " + VISION_LABEL_TABLE + " ADD COLUMN " + SALIENCY_SUB_PROB + " TEXT",
2779         "ALTER TABLE " + GEO_KNOWLEDGE_TABLE + " ADD COLUMN " + LOCATION_TYPE + " TEXT",
2780     };
2781     MEDIA_INFO_LOG("start init story db");
2782     ExecSqls(executeSqlStrs, store);
2783 }
2784 
UpdateAnalysisTables(RdbStore & store)2785 void UpdateAnalysisTables(RdbStore &store)
2786 {
2787     const vector<string> executeSqlStrs = {
2788         "ALTER TABLE " + VISION_OCR_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2789         "ALTER TABLE " + VISION_LABEL_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2790         "ALTER TABLE " + VISION_VIDEO_LABEL_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2791         "ALTER TABLE " + VISION_AESTHETICS_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2792         "ALTER TABLE " + VISION_SALIENCY_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2793         "ALTER TABLE " + VISION_OBJECT_TABLE + " ADD COLUMN " + SCALE_X + " REAL DEFAULT 0 ",
2794         "ALTER TABLE " + VISION_OBJECT_TABLE + " ADD COLUMN " + SCALE_Y + " REAL DEFAULT 0 ",
2795         "ALTER TABLE " + VISION_OBJECT_TABLE + " ADD COLUMN " + SCALE_WIDTH + " REAL DEFAULT 0 ",
2796         "ALTER TABLE " + VISION_OBJECT_TABLE + " ADD COLUMN " + SCALE_HEIGHT + " REAL DEFAULT 0 ",
2797         "ALTER TABLE " + VISION_OBJECT_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2798         "ALTER TABLE " + VISION_RECOMMENDATION_TABLE + " ADD COLUMN " + SCALE_X + " REAL DEFAULT 0 ",
2799         "ALTER TABLE " + VISION_RECOMMENDATION_TABLE + " ADD COLUMN " + SCALE_Y + " REAL DEFAULT 0 ",
2800         "ALTER TABLE " + VISION_RECOMMENDATION_TABLE + " ADD COLUMN " + SCALE_WIDTH + " REAL DEFAULT 0 ",
2801         "ALTER TABLE " + VISION_RECOMMENDATION_TABLE + " ADD COLUMN " + SCALE_HEIGHT + " REAL DEFAULT 0 ",
2802         "ALTER TABLE " + VISION_RECOMMENDATION_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2803         "ALTER TABLE " + VISION_SEGMENTATION_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2804         "ALTER TABLE " + VISION_COMPOSITION_TABLE + " ADD COLUMN " + SCALE_X + " REAL DEFAULT 0 ",
2805         "ALTER TABLE " + VISION_COMPOSITION_TABLE + " ADD COLUMN " + SCALE_Y + " REAL DEFAULT 0 ",
2806         "ALTER TABLE " + VISION_COMPOSITION_TABLE + " ADD COLUMN " + SCALE_WIDTH + " REAL DEFAULT 0 ",
2807         "ALTER TABLE " + VISION_COMPOSITION_TABLE + " ADD COLUMN " + SCALE_HEIGHT + " REAL DEFAULT 0 ",
2808         "ALTER TABLE " + VISION_COMPOSITION_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2809         "ALTER TABLE " + VISION_HEAD_TABLE + " ADD COLUMN " + SCALE_X + " REAL DEFAULT 0 ",
2810         "ALTER TABLE " + VISION_HEAD_TABLE + " ADD COLUMN " + SCALE_Y + " REAL DEFAULT 0 ",
2811         "ALTER TABLE " + VISION_HEAD_TABLE + " ADD COLUMN " + SCALE_WIDTH + " REAL DEFAULT 0 ",
2812         "ALTER TABLE " + VISION_HEAD_TABLE + " ADD COLUMN " + SCALE_HEIGHT + " REAL DEFAULT 0 ",
2813         "ALTER TABLE " + VISION_HEAD_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2814         "ALTER TABLE " + VISION_POSE_TABLE + " ADD COLUMN " + SCALE_X + " REAL DEFAULT 0 ",
2815         "ALTER TABLE " + VISION_POSE_TABLE + " ADD COLUMN " + SCALE_Y + " REAL DEFAULT 0 ",
2816         "ALTER TABLE " + VISION_POSE_TABLE + " ADD COLUMN " + SCALE_WIDTH + " REAL DEFAULT 0 ",
2817         "ALTER TABLE " + VISION_POSE_TABLE + " ADD COLUMN " + SCALE_HEIGHT + " REAL DEFAULT 0 ",
2818         "ALTER TABLE " + VISION_POSE_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2819         "ALTER TABLE " + VISION_IMAGE_FACE_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2820         "ALTER TABLE " + VISION_FACE_TAG_TABLE + " ADD COLUMN " + ANALYSIS_VERSION + " TEXT ",
2821     };
2822     MEDIA_INFO_LOG("update analysis tables of db");
2823     ExecSqls(executeSqlStrs, store);
2824 }
2825 
UpdateHighlightTablePrimaryKey(RdbStore & store)2826 void UpdateHighlightTablePrimaryKey(RdbStore &store)
2827 {
2828     const vector<string> executeSqlStrs = {
2829         "DROP TABLE IF EXISTS tab_highlight_album",
2830         "DROP TABLE IF EXISTS tab_highlight_cover_info",
2831         CREATE_HIGHLIGHT_ALBUM_TABLE,
2832         CREATE_HIGHLIGHT_COVER_INFO_TABLE,
2833     };
2834     MEDIA_INFO_LOG("update primary key of highlight db");
2835     ExecSqls(executeSqlStrs, store);
2836 }
2837 
AddBussinessRecordAlbum(RdbStore & store)2838 void AddBussinessRecordAlbum(RdbStore &store)
2839 {
2840     string updateDirtyForShootingMode = "UPDATE Photos SET dirty = 2 WHERE cloud_id is not null AND " +
2841         PhotoColumn::PHOTO_SHOOTING_MODE + " is not null AND " +
2842         PhotoColumn::PHOTO_SHOOTING_MODE + " != ''";
2843     const vector<string> sqls = {
2844         MedialibraryBusinessRecordColumn::CREATE_TABLE,
2845         MedialibraryBusinessRecordColumn::CREATE_BUSINESS_KEY_INDEX,
2846         updateDirtyForShootingMode,
2847     };
2848 
2849     MEDIA_INFO_LOG("start add bussiness record album");
2850     ExecSqls(sqls, store);
2851     UpdatePhotosMdirtyTrigger(store);
2852 }
2853 
AddOwnerAppId(RdbStore & store)2854 void AddOwnerAppId(RdbStore &store)
2855 {
2856     const vector<string> sqls = {
2857         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + MediaColumn::MEDIA_OWNER_APPID + " TEXT",
2858         "ALTER TABLE " + AudioColumn::AUDIOS_TABLE + " ADD COLUMN " + MediaColumn::MEDIA_OWNER_APPID + " TEXT"
2859     };
2860     MEDIA_INFO_LOG("start add owner_appid column");
2861     ExecSqls(sqls, store);
2862 }
2863 
AddIsCoverSatisfiedColumn(RdbStore & store)2864 void AddIsCoverSatisfiedColumn(RdbStore &store)
2865 {
2866     const vector<string> sqls = {
2867         ADD_IS_COVER_SATISFIED_FOR_ALBUM,
2868     };
2869     MEDIA_INFO_LOG("start add is cover satisfied column");
2870     ExecSqls(sqls, store);
2871 }
2872 
UpdateThumbnailReadyColumn(RdbStore & store)2873 void UpdateThumbnailReadyColumn(RdbStore &store)
2874 {
2875     const vector<string> sqls = {
2876         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " RENAME COLUMN " + PhotoColumn::PHOTO_HAS_ASTC
2877             + " TO " + PhotoColumn::PHOTO_THUMBNAIL_READY,
2878     };
2879     MEDIA_INFO_LOG("update has_astc to thumbnail_ready begin");
2880     ExecSqls(sqls, store);
2881     MEDIA_INFO_LOG("update has_astc to thumbnail_ready finished");
2882 }
2883 
AddOwnerAppIdToFiles(RdbStore & store)2884 void AddOwnerAppIdToFiles(RdbStore &store)
2885 {
2886     const vector<string> sqls = {
2887         "ALTER TABLE " + MEDIALIBRARY_TABLE + " ADD COLUMN " + MediaColumn::MEDIA_OWNER_APPID + " TEXT"
2888     };
2889     MEDIA_INFO_LOG("start add owner_appid column to files table");
2890     ExecSqls(sqls, store);
2891     MEDIA_INFO_LOG("add owner_appid column to files table finished");
2892 }
2893 
AddDynamicRangeType(RdbStore & store)2894 void AddDynamicRangeType(RdbStore &store)
2895 {
2896     const vector<string> sqls = {
2897         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
2898             PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE + " INT DEFAULT 0"
2899     };
2900     MEDIA_INFO_LOG("start add dynamic_range_type column");
2901     ExecSqls(sqls, store);
2902 }
2903 
AddLcdAndThumbSizeColumns(RdbStore & store)2904 void AddLcdAndThumbSizeColumns(RdbStore &store)
2905 {
2906     const vector<string> sqls = {
2907         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_LCD_SIZE + " TEXT",
2908         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_THUMB_SIZE + " TEXT",
2909     };
2910     ExecSqls(sqls, store);
2911 }
2912 
UpdatePhotoAlbumTigger(RdbStore & store)2913 void UpdatePhotoAlbumTigger(RdbStore &store)
2914 {
2915     static const vector<string> executeSqlStrs = {
2916         "DROP TRIGGER IF EXISTS album_modify_trigger",
2917         PhotoAlbumColumns::CREATE_ALBUM_MDIRTY_TRIGGER,
2918     };
2919     MEDIA_INFO_LOG("Start update album modify trigger");
2920     ExecSqls(executeSqlStrs, store);
2921 }
2922 
AddCloudEnhancementColumns(RdbStore & store)2923 static void AddCloudEnhancementColumns(RdbStore &store)
2924 {
2925     const vector<string> sqls = {
2926         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
2927             PhotoColumn::PHOTO_CE_AVAILABLE + " INT DEFAULT 0",
2928         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
2929             PhotoColumn::PHOTO_CE_STATUS_CODE + " INT ",
2930         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
2931             PhotoColumn::PHOTO_STRONG_ASSOCIATION + " INT DEFAULT 0",
2932         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
2933             PhotoColumn::PHOTO_ASSOCIATE_FILE_ID + " INT DEFAULT 0",
2934         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
2935             PhotoColumn::PHOTO_HAS_CLOUD_WATERMARK + " INT DEFAULT 0",
2936     };
2937     MEDIA_INFO_LOG("start add cloud enhancement columns");
2938     ExecSqls(sqls, store);
2939 }
2940 
AddThumbnailReady(RdbStore & store)2941 static void AddThumbnailReady(RdbStore &store)
2942 {
2943     const vector<string> sqls = {
2944         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
2945             PhotoColumn::PHOTO_THUMBNAIL_READY + " INT DEFAULT 0",
2946     };
2947     MEDIA_INFO_LOG("start add thumbnail ready columns");
2948     ExecSqls(sqls, store);
2949 }
2950 
CheckMediaColumns(RdbStore & store,const std::string & columnName)2951 static bool CheckMediaColumns(RdbStore &store, const std::string& columnName)
2952 {
2953     std::string checkSql = "PRAGMA table_info(" + PhotoColumn::PHOTOS_TABLE + ")";
2954     std::vector<NativeRdb::ValueObject> args;
2955     auto resultSet = store.QuerySql(checkSql, args);
2956     if (resultSet == nullptr) {
2957         return false;
2958     }
2959 
2960     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
2961         std::string name;
2962         resultSet->GetString(1, name);
2963         if (name == columnName) {
2964             return true;
2965         }
2966     }
2967 
2968     return false;
2969 }
2970 
AddCloudEnhanceColumnsFix(RdbStore & store)2971 static void AddCloudEnhanceColumnsFix(RdbStore& store)
2972 {
2973     bool hasColumn = CheckMediaColumns(store, PhotoColumn::PHOTO_CE_AVAILABLE);
2974     if (!hasColumn) {
2975         AddCloudEnhancementColumns(store);
2976         MEDIA_INFO_LOG("Add Cloud Enhance Cols completed successfully");
2977     }
2978 }
2979 
AddThumbnailReadyColumnsFix(RdbStore & store)2980 static void AddThumbnailReadyColumnsFix(RdbStore& store)
2981 {
2982     bool hasColumn = CheckMediaColumns(store, PhotoColumn::PHOTO_THUMBNAIL_READY);
2983     if (!hasColumn) {
2984         AddThumbnailReady(store);
2985         MEDIA_INFO_LOG("Add ThumbnailReady Column");
2986     }
2987 }
2988 
UpdateSourcePhotoAlbumTrigger(RdbStore & store)2989 static void UpdateSourcePhotoAlbumTrigger(RdbStore &store)
2990 {
2991     MEDIA_INFO_LOG("start update source photo album trigger");
2992     const vector<string> sqls = {
2993         DROP_INSERT_SOURCE_PHOTO_CREATE_SOURCE_ALBUM_TRIGGER,
2994         CREATE_INSERT_SOURCE_PHOTO_CREATE_SOURCE_ALBUM_TRIGGER,
2995     };
2996     ExecSqls(sqls, store);
2997     MEDIA_INFO_LOG("end update source photo album trigger");
2998 }
2999 
AddDynamicRangeColumnsFix(RdbStore & store)3000 static void AddDynamicRangeColumnsFix(RdbStore& store)
3001 {
3002     bool hasColumn = CheckMediaColumns(store, PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE);
3003     if (!hasColumn) {
3004         AddDynamicRangeType(store);
3005         MEDIA_INFO_LOG("Add Dynamic Range Cols completed successfully");
3006     }
3007 }
3008 
UpdateVisionTriggerForVideoLabel(RdbStore & store)3009 static void UpdateVisionTriggerForVideoLabel(RdbStore &store)
3010 {
3011     static const vector<string> executeSqlStrs = {
3012         DROP_UPDATE_VISION_TRIGGER,
3013         CREATE_VISION_UPDATE_TRIGGER_FOR_ADD_VIDEO_LABEL,
3014     };
3015     MEDIA_INFO_LOG("start update vision trigger for video label");
3016     ExecSqls(executeSqlStrs, store);
3017 }
3018 
AddMovingPhotoEffectMode(RdbStore & store)3019 static void AddMovingPhotoEffectMode(RdbStore &store)
3020 {
3021     const vector<string> sqls = {
3022         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
3023             PhotoColumn::MOVING_PHOTO_EFFECT_MODE + " INT DEFAULT 0"
3024     };
3025     MEDIA_INFO_LOG("start add moving_photo_effect_mode column");
3026     ExecSqls(sqls, store);
3027 }
3028 
UpdateIndexForAlbumQuery(RdbStore & store)3029 static void UpdateIndexForAlbumQuery(RdbStore &store)
3030 {
3031     const vector<string> sqls = {
3032         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_SCHPT_ADDED_INDEX,
3033         PhotoColumn::INDEX_SCTHP_ADDTIME,
3034         PhotoColumn::DROP_SCHPT_MEDIA_TYPE_INDEX,
3035         PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_INDEX,
3036     };
3037     MEDIA_INFO_LOG("start updating photo index");
3038     ExecSqls(sqls, store);
3039 }
3040 
AddBurstCoverLevelAndBurstKey(RdbStore & store)3041 void AddBurstCoverLevelAndBurstKey(RdbStore &store)
3042 {
3043     const vector<string> sqls = {
3044         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_BURST_COVER_LEVEL +
3045              " INT DEFAULT 1",
3046         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_BURST_KEY + " TEXT ",
3047     };
3048     MEDIA_INFO_LOG("start add burst_cover_level and burst_key column");
3049     ExecSqls(sqls, store);
3050 }
3051 
UpdateDataAddedIndexWithFileId(RdbStore & store)3052 static void UpdateDataAddedIndexWithFileId(RdbStore &store)
3053 {
3054     const vector<string> sqls = {
3055         PhotoColumn::DROP_INDEX_SCTHP_ADDTIME,
3056         PhotoColumn::INDEX_SCTHP_ADDTIME,
3057     };
3058     MEDIA_INFO_LOG("start update index of date added with file desc");
3059     ExecSqls(sqls, store);
3060 }
3061 
UpdateMultiCropInfo(RdbStore & store)3062 static void UpdateMultiCropInfo(RdbStore &store)
3063 {
3064     static const vector<string> executeSqlStrs = {
3065         "ALTER TABLE " + VISION_RECOMMENDATION_TABLE + " ADD COLUMN " + MOVEMENT_CROP + " TEXT",
3066         "ALTER TABLE " + VISION_RECOMMENDATION_TABLE + " ADD COLUMN " + MOVEMENT_VERSION + " TEXT",
3067     };
3068     MEDIA_INFO_LOG("start update multi crop triggers");
3069     ExecSqls(executeSqlStrs, store);
3070 }
3071 
UpdateSearchIndexTrigger(RdbStore & store)3072 static void UpdateSearchIndexTrigger(RdbStore &store)
3073 {
3074     const vector<string> sqls = {
3075         "DROP TRIGGER IF EXISTS update_search_status_trigger",
3076         CREATE_SEARCH_UPDATE_STATUS_TRIGGER,
3077         "DROP TRIGGER IF EXISTS album_map_insert_search_trigger",
3078         CREATE_ALBUM_MAP_INSERT_SEARCH_TRIGGER,
3079         "DROP TRIGGER IF EXISTS album_map_delete_search_trigger",
3080         CREATE_ALBUM_MAP_DELETE_SEARCH_TRIGGER,
3081     };
3082     MEDIA_INFO_LOG("start update search index");
3083     ExecSqls(sqls, store);
3084 }
3085 
ReportFailInfoAsync(AsyncTaskData * data)3086 static void ReportFailInfoAsync(AsyncTaskData *data)
3087 {
3088     MEDIA_INFO_LOG("Start ReportFailInfoAsync");
3089     const int32_t sleepTimeMs = 1000;
3090     this_thread::sleep_for(chrono::milliseconds(sleepTimeMs));
3091     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
3092     if (rdbStore == nullptr) {
3093         MEDIA_ERR_LOG("MediaDataAbility insert functionality rebStore is null.");
3094         return;
3095     }
3096 
3097     string querySql = "SELECT data FROM Photos GROUP BY data HAVING COUNT(*) > 1";
3098     auto result = rdbStore->QuerySql(querySql);
3099     int32_t count = 0;
3100     if (result == nullptr) {
3101         MEDIA_ERR_LOG("result is null");
3102         return;
3103     }
3104     if (result->GetRowCount(count) != NativeRdb::E_OK) {
3105         MEDIA_ERR_LOG("GetRowCount fail");
3106     }
3107     result->Close();
3108     int64_t startTime = MediaFileUtils::UTCTimeMilliSeconds();
3109     DfxReporter::ReportStartResult(DfxType::ADD_DATA_UNIQUE_INDEX_FAIL, count, startTime);
3110     bool ret = system::SetParameter("persist.multimedia.medialibrary.data_unique", "1");
3111     if (!ret) {
3112         MEDIA_ERR_LOG("Failed to set parameter, ret:%{public}d", ret);
3113     }
3114     MEDIA_INFO_LOG("HasDirtyData count:%{public}d", count);
3115 }
3116 
ReportFailInfo()3117 static void ReportFailInfo()
3118 {
3119     MEDIA_INFO_LOG("Start ReportFailInfo");
3120     auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
3121     if (asyncWorker == nullptr) {
3122         MEDIA_ERR_LOG("Failed to get async worker instance!");
3123         return;
3124     }
3125     shared_ptr<MediaLibraryAsyncTask> reportTask =
3126         make_shared<MediaLibraryAsyncTask>(ReportFailInfoAsync, nullptr);
3127     if (reportTask != nullptr) {
3128         asyncWorker->AddTask(reportTask, false);
3129     } else {
3130         MEDIA_ERR_LOG("Failed to create async task for reportTask!");
3131     }
3132 }
3133 
UpdateDataUniqueIndex(RdbStore & store)3134 static void UpdateDataUniqueIndex(RdbStore &store)
3135 {
3136     MEDIA_INFO_LOG("Start UpdateDataUniqueIndex");
3137     string sql = PhotoColumn::UPDATA_PHOTOS_DATA_UNIQUE;
3138     auto err = ExecSqlWithRetry([&]() { return store.ExecuteSql(sql); });
3139     if (err != NativeRdb::E_OK) {
3140         MEDIA_ERR_LOG("Failed to exec: %{public}s", sql.c_str());
3141         ReportFailInfo();
3142     }
3143     MEDIA_INFO_LOG("End UpdateDataUniqueIndex");
3144 }
3145 
AddOriginalSubtype(RdbStore & store)3146 static void AddOriginalSubtype(RdbStore &store)
3147 {
3148     const vector<string> sqls = {
3149         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
3150             PhotoColumn::PHOTO_ORIGINAL_SUBTYPE + " INT"
3151     };
3152     MEDIA_INFO_LOG("start add original_subtype column");
3153     ExecSqls(sqls, store);
3154 }
3155 
CompatLivePhoto(RdbStore & store,int32_t oldVersion)3156 static void CompatLivePhoto(RdbStore &store, int32_t oldVersion)
3157 {
3158     MEDIA_INFO_LOG("Start configuring param for live photo compatibility");
3159     bool ret = false;
3160     // there is no need to ResetCursor() twice if album fusion is included
3161     if (oldVersion >= VERSION_ADD_OWNER_ALBUM_ID) {
3162         ret = system::SetParameter(REFRESH_CLOUD_LIVE_PHOTO_FLAG, CLOUD_LIVE_PHOTO_NOT_REFRESHED);
3163         MEDIA_INFO_LOG("Set parameter for refreshing cloud live photo, ret: %{public}d", ret);
3164     }
3165 
3166     ret = system::SetParameter(COMPAT_LIVE_PHOTO_FILE_ID, "1"); // start compating from file_id: 1
3167     MEDIA_INFO_LOG("Set parameter for compating local live photo, ret: %{public}d", ret);
3168 }
3169 
ResetCloudCursorAfterInitFinish()3170 static void ResetCloudCursorAfterInitFinish()
3171 {
3172     MEDIA_INFO_LOG("Try reset cloud cursor after storage reconstruct");
3173     static uint32_t baseUserRange = 200000; // uid base offset
3174     uid_t uid = getuid() / baseUserRange;
3175     const string paramKey = "multimedia.medialibrary.startup." + to_string(uid);
3176     int32_t maxTryTimes = 10;
3177     if (WaitParameter(paramKey.c_str(), "true", maxTryTimes) == E_OK) {
3178         MEDIA_INFO_LOG("medialibrary init finish start reset cloud cursor");
3179         FileManagement::CloudSync::CloudSyncManager::GetInstance().ResetCursor();
3180         MEDIA_INFO_LOG("End reset cloud cursor");
3181     } else {
3182         MEDIA_INFO_LOG("try max time start reset cloud cursor");
3183         FileManagement::CloudSync::CloudSyncManager::GetInstance().ResetCursor();
3184         MEDIA_INFO_LOG("End reset cloud cursor");
3185     }
3186     MEDIA_INFO_LOG("Reset cloud cursor after storage reconstruct end");
3187 }
3188 
MatchedDataFusion(CompensateAlbumIdData * compensateData)3189 static int32_t MatchedDataFusion(CompensateAlbumIdData* compensateData)
3190 {
3191     int32_t matchedDataHandleResult = MediaLibraryAlbumFusionUtils::HandleMatchedDataFusion(
3192         compensateData->upgradeStore_);
3193     if (matchedDataHandleResult != E_OK) {
3194         MEDIA_ERR_LOG("Fatal err, handle matched relationship fail by %{public}d", matchedDataHandleResult);
3195         // This should not happen, try again
3196         matchedDataHandleResult = MediaLibraryAlbumFusionUtils::HandleMatchedDataFusion(
3197             compensateData->upgradeStore_);
3198         if (matchedDataHandleResult != E_OK) {
3199             MEDIA_ERR_LOG("Fatal err, handle matched relationship again by %{public}d", matchedDataHandleResult);
3200         }
3201     }
3202     return matchedDataHandleResult;
3203 }
3204 
ReconstructMediaLibraryStorageFormatExecutor(AsyncTaskData * data)3205 static void ReconstructMediaLibraryStorageFormatExecutor(AsyncTaskData *data)
3206 {
3207     if (data == nullptr) {
3208         return;
3209     }
3210     MediaLibraryAlbumFusionUtils::SetParameterToStopSync();
3211     MediaLibraryAlbumFusionUtils::SetAlbumFuseUpgradeStatus(0); // 0: set upgrade status fail
3212     CompensateAlbumIdData* compensateData = static_cast<CompensateAlbumIdData*>(data);
3213     MEDIA_INFO_LOG("ALBUM_FUSE: Processing old data start");
3214     MEDIA_INFO_LOG("ALBUM_FUSE: Compensating album id for old asset start");
3215     int64_t beginTime = MediaFileUtils::UTCTimeMilliSeconds();
3216     CHECK_AND_PRINT_LOG(MediaLibraryAlbumFusionUtils::RemoveMisAddedHiddenData(compensateData->upgradeStore_) == E_OK,
3217         "Failed to remove misadded hidden data");
3218     int64_t cleanDataBeginTime = MediaFileUtils::UTCTimeMilliSeconds();
3219     MediaLibraryAlbumFusionUtils::ReportAlbumFusionData(cleanDataBeginTime, AlbumFusionState::START,
3220         compensateData->upgradeStore_);
3221     if (MatchedDataFusion(compensateData) != E_OK) {
3222         MediaLibraryAlbumFusionUtils::ReportAlbumFusionData(cleanDataBeginTime, AlbumFusionState::FAILED,
3223             compensateData->upgradeStore_);
3224         return;
3225     }
3226     int32_t notMatchedDataHandleResult = MediaLibraryAlbumFusionUtils::HandleNotMatchedDataFusion(
3227         compensateData->upgradeStore_);
3228     if (notMatchedDataHandleResult != E_OK) {
3229         MEDIA_ERR_LOG("Fatal err, handle not matched relationship fail by %{public}d", notMatchedDataHandleResult);
3230         // This should not happen, and if it does, avoid cleaning up more data.
3231         MediaLibraryAlbumFusionUtils::ReportAlbumFusionData(cleanDataBeginTime, AlbumFusionState::FAILED,
3232             compensateData->upgradeStore_);
3233         return;
3234     }
3235     MEDIA_INFO_LOG("ALBUM_FUSE: End compensate album id for old asset cost %{public}ld",
3236         (long)(MediaFileUtils::UTCTimeMilliSeconds() - cleanDataBeginTime));
3237     MEDIA_INFO_LOG("ALBUM_FUSE: Start rebuild album and update relationship");
3238     int64_t albumCleanBeginTime = MediaFileUtils::UTCTimeMilliSeconds();
3239     int32_t rebuildResult = MediaLibraryAlbumFusionUtils::RebuildAlbumAndFillCloudValue(compensateData->upgradeStore_);
3240     MEDIA_INFO_LOG("ALBUM_FUSE: End rebuild album and update relationship cost %{public}ld",
3241         (long)(MediaFileUtils::UTCTimeMilliSeconds() - albumCleanBeginTime));
3242     // Restore cloud sync
3243     MediaLibraryAlbumFusionUtils::SetParameterToStartSync();
3244     MediaLibraryAlbumFusionUtils::SetAlbumFuseUpgradeStatus(1); // 1: set upgrade status success
3245     ResetCloudCursorAfterInitFinish();
3246     MediaLibraryAlbumFusionUtils::RefreshAllAlbums();
3247     MediaLibraryAlbumFusionUtils::ReportAlbumFusionData(cleanDataBeginTime, AlbumFusionState::SUCCESS,
3248         compensateData->upgradeStore_);
3249     MEDIA_INFO_LOG("ALBUM_FUSE: Processing old data end, cost %{public}ld",
3250         (long)(MediaFileUtils::UTCTimeMilliSeconds() - beginTime));
3251 }
3252 
ReconstructMediaLibraryStorageFormatWithLock(AsyncTaskData * data)3253 static void ReconstructMediaLibraryStorageFormatWithLock(AsyncTaskData *data)
3254 {
3255     if (data == nullptr) {
3256         return;
3257     }
3258     CompensateAlbumIdData *compensateData = static_cast<CompensateAlbumIdData *>(data);
3259     if (compensateData == nullptr) {
3260         MEDIA_ERR_LOG("compensateData is nullptr");
3261         return;
3262     }
3263     std::unique_lock<std::mutex> reconstructLock(compensateData->lock_, std::defer_lock);
3264     if (reconstructLock.try_lock()) {
3265         ReconstructMediaLibraryStorageFormatExecutor(data);
3266     } else {
3267         MEDIA_WARN_LOG("Failed to acquire lock, skipping task Reconstruct.");
3268     }
3269 }
3270 
AddOwnerAlbumIdAndRefractorTrigger(RdbStore & store)3271 static void AddOwnerAlbumIdAndRefractorTrigger(RdbStore &store)
3272 {
3273     const vector<string> sqls = {
3274         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
3275             PhotoColumn::PHOTO_OWNER_ALBUM_ID + " INT DEFAULT 0",
3276         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
3277             PhotoColumn::PHOTO_ORIGINAL_ASSET_CLOUD_ID + " TEXT",
3278         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
3279             PhotoColumn::PHOTO_SOURCE_PATH + " TEXT",
3280         "DROP TABLE IF EXISTS album_plugin ",
3281         DROP_PHOTO_ALBUM_CLEAR_MAP_SQL,
3282         DROP_INSERT_PHOTO_INSERT_SOURCE_ALBUM_SQL,
3283         DROP_INSERT_PHOTO_UPDATE_SOURCE_ALBUM_SQL,
3284         DROP_INSERT_SOURCE_PHOTO_CREATE_SOURCE_ALBUM_TRIGGER,
3285         DROP_INSERT_SOURCE_PHOTO_UPDATE_ALBUM_ID_TRIGGER,
3286         "DROP TRIGGER IF EXISTS photos_mdirty_trigger",
3287         PhotoColumn::CREATE_PHOTOS_MDIRTY_TRIGGER,
3288         CREATE_INSERT_SOURCE_PHOTO_CREATE_SOURCE_ALBUM_TRIGGER,
3289         CREATE_INSERT_SOURCE_UPDATE_ALBUM_ID_TRIGGER,
3290 
3291     };
3292     MEDIA_INFO_LOG("Add owner_album_id column for Photos");
3293     ExecSqls(sqls, store);
3294 }
3295 
AddMergeInfoColumnForAlbum(RdbStore & store)3296 static void AddMergeInfoColumnForAlbum(RdbStore &store)
3297 {
3298     const vector<string> addMergeInfoSql = {
3299         "ALTER TABLE " + PhotoAlbumColumns::TABLE + " ADD COLUMN " +
3300         PhotoAlbumColumns::ALBUM_DATE_ADDED + " BIGINT DEFAULT 0",
3301         "ALTER TABLE " + PhotoAlbumColumns::TABLE + " ADD COLUMN " +
3302         PhotoAlbumColumns::ALBUM_PRIORITY + " INT",
3303         "ALTER TABLE " + PhotoAlbumColumns::TABLE + " ADD COLUMN " +
3304         PhotoAlbumColumns::ALBUM_LPATH + " TEXT",
3305         DROP_INDEX_SOURCE_ALBUM_INDEX,
3306         CREATE_SOURCE_ALBUM_INDEX,
3307         CREATE_DEFALUT_ALBUM_FOR_NO_RELATIONSHIP_ASSET,
3308     };
3309     MEDIA_INFO_LOG("Add merge info for PhotoAlbum");
3310     ExecSqls(addMergeInfoSql, store);
3311     const std::string queryHiddenAlbumId =
3312         "SELECT album_id FROM PhotoAlbum WHERE album_name = '.hiddenAlbum'";
3313     auto resultSet = store.QuerySql(queryHiddenAlbumId);
3314     if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
3315         int32_t err = ExecSqlWithRetry([&]() { return store.ExecuteSql(CREATE_HIDDEN_ALBUM_FOR_DUAL_ASSET); });
3316         if (err != NativeRdb::E_OK) {
3317             MEDIA_ERR_LOG("Failed to exec: %{private}s", CREATE_HIDDEN_ALBUM_FOR_DUAL_ASSET.c_str());
3318         }
3319     }
3320 }
3321 
ReconstructMediaLibraryStorageFormat(const std::shared_ptr<MediaLibraryRdbStore> store)3322 int32_t MediaLibraryRdbStore::ReconstructMediaLibraryStorageFormat(const std::shared_ptr<MediaLibraryRdbStore> store)
3323 {
3324     MEDIA_INFO_LOG("ALBUM_FUSE: Start reconstruct medialibrary storage format task!");
3325     auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
3326     if (asyncWorker ==  nullptr) {
3327         MEDIA_ERR_LOG("Failed to get aysnc worker instance!");
3328         return E_FAIL;
3329     }
3330     auto *taskData = new (std::nothrow) CompensateAlbumIdData(store, MediaLibraryRdbStore::reconstructLock_);
3331     if (taskData == nullptr) {
3332         MEDIA_ERR_LOG("Failed to alloc async data for compensate album id");
3333         return E_NO_MEMORY;
3334     }
3335     auto asyncTask = std::make_shared<MediaLibraryAsyncTask>(ReconstructMediaLibraryStorageFormatWithLock, taskData);
3336     asyncWorker->AddTask(asyncTask, false);
3337     return E_OK;
3338 }
3339 
AddHighlightMapTable(RdbStore & store)3340 void AddHighlightMapTable(RdbStore &store)
3341 {
3342     const vector<string> executeSqlStrs = {
3343         CREATE_ANALYSIS_ASSET_SD_MAP_TABLE,
3344         CREATE_ANALYSIS_ALBUM_ASET_MAP_TABLE,
3345         "ALTER TABLE " + HIGHLIGHT_PLAY_INFO_TABLE + " ADD COLUMN " + HIGHLIGHTING_ALGO_VERSION + " TEXT",
3346         "ALTER TABLE " + HIGHLIGHT_PLAY_INFO_TABLE + " ADD COLUMN " + CAMERA_MOVEMENT_ALGO_VERSION + " TEXT",
3347         "ALTER TABLE " + HIGHLIGHT_PLAY_INFO_TABLE + " ADD COLUMN " + TRANSITION_ALGO_VERSION + " TEXT",
3348     };
3349     MEDIA_INFO_LOG("add analysis map table of highlight db");
3350     ExecSqls(executeSqlStrs, store);
3351 }
3352 
UpgradeOtherTableExt(RdbStore & store,int32_t oldVersion)3353 static void UpgradeOtherTableExt(RdbStore &store, int32_t oldVersion)
3354 {
3355     if (oldVersion < VERSION_FIX_DOCS_PATH) {
3356         FixDocsPath(store);
3357     }
3358 
3359     if (oldVersion < VERSION_CLEAR_LABEL_DATA) {
3360         UpdateClassifyDirtyData(store);
3361     }
3362 
3363     if (oldVersion < VERSION_ADD_SHOOTING_MODE_TAG) {
3364         AddShootingModeTagColumn(store);
3365         PrepareShootingModeAlbum(store);
3366     }
3367 
3368     if (oldVersion < VERSION_ADD_PORTRAIT_IN_ALBUM) {
3369         AddPortraitInAnalysisAlbum(store);
3370     }
3371 
3372     if (oldVersion < VERSION_UPDATE_GEO_TABLE) {
3373         UpdateGeoTables(store);
3374     }
3375 
3376     if (oldVersion < VERSION_ADD_MULTISTAGES_CAPTURE) {
3377         AddMultiStagesCaptureColumns(store);
3378     }
3379 }
3380 
UpgradeOtherTable(RdbStore & store,int32_t oldVersion)3381 static void UpgradeOtherTable(RdbStore &store, int32_t oldVersion)
3382 {
3383     if (oldVersion < VERSION_ADD_PACKAGE_NAME) {
3384         AddPackageNameColumnOnTables(store);
3385     }
3386 
3387     if (oldVersion < VERSION_ADD_CLOUD_ALBUM) {
3388         UpdateCloudAlbum(store);
3389     }
3390 
3391     if (oldVersion < VERSION_ADD_CAMERA_SHOT_KEY) {
3392         AddCameraShotKey(store);
3393     }
3394 
3395     if (oldVersion < VERSION_REMOVE_ALBUM_COUNT_TRIGGER) {
3396         RemoveAlbumCountTrigger(store);
3397     }
3398 
3399     if (oldVersion < VERSION_ADD_ALL_EXIF) {
3400         AddExifAndUserComment(store);
3401     }
3402 
3403     if (oldVersion < VERSION_ADD_UPDATE_CLOUD_SYNC_TRIGGER) {
3404         AddUpdateCloudSyncTrigger(store);
3405     }
3406 
3407     if (oldVersion < VERSION_ADD_YEAR_MONTH_DAY) {
3408         AddYearMonthDayColumn(store);
3409     }
3410 
3411     if (oldVersion < VERSION_UPDATE_YEAR_MONTH_DAY) {
3412         UpdateYearMonthDayData(store);
3413     }
3414 
3415     if (oldVersion < VERSION_ADD_PHOTO_EDIT_TIME) {
3416         AddPhotoEditTimeColumn(store);
3417     }
3418 
3419     if (oldVersion < VERSION_FIX_INDEX_ORDER) {
3420         FixIndexOrder(store);
3421     }
3422 
3423     if (oldVersion < VERSION_ADD_SHOOTING_MODE) {
3424         AddShootingModeColumn(store);
3425     }
3426     UpgradeOtherTableExt(store, oldVersion);
3427     // !! Do not add upgrade code here !!
3428 }
3429 
UpgradeGalleryFeatureTable(RdbStore & store,int32_t oldVersion)3430 static void UpgradeGalleryFeatureTable(RdbStore &store, int32_t oldVersion)
3431 {
3432     if (oldVersion < VERSION_ADD_HIDDEN_VIEW_COLUMNS) {
3433         AddHiddenViewColumn(store);
3434     }
3435 
3436     if (oldVersion < VERSION_ADD_LAST_VISIT_TIME) {
3437         ModifyMdirtyTriggers(store);
3438         AddLastVisitTimeColumn(store);
3439     }
3440 
3441     if (oldVersion < VERSION_ADD_HIDDEN_TIME) {
3442         AddHiddenTimeColumn(store);
3443     }
3444 
3445     if (oldVersion < VERSION_ADD_LOCATION_TABLE) {
3446         // two version to maintain consistency
3447         AddLocationTables(store);
3448     }
3449 
3450     if (oldVersion < VERSION_ADD_ALBUM_ORDER) {
3451         AddAlbumOrderColumn(store);
3452     }
3453 
3454     if (oldVersion < VERSION_ADD_FORM_MAP) {
3455         AddFormMap(store);
3456     }
3457 
3458     if (oldVersion < VERSION_ADD_SOURCE_ALBUM_TRIGGER) {
3459         AddSourceAlbumTrigger(store);
3460     }
3461 
3462     if (oldVersion < VERSION_ADD_IMAGE_VIDEO_COUNT) {
3463         AddImageVideoCount(store);
3464     }
3465 
3466     if (oldVersion < VERSION_ADD_SCHPT_HIDDEN_TIME_INDEX) {
3467         AddSCHPTHiddenTimeIndex(store);
3468     }
3469 
3470     if (oldVersion < VERSION_UPDATE_PHOTOS_MDIRTY_TRIGGER) {
3471         UpdatePhotosMdirtyTrigger(store);
3472     }
3473 
3474     if (oldVersion < VERSION_ALBUM_REFRESH) {
3475         UpdateAlbumRefreshTable(store);
3476     }
3477 
3478     if (oldVersion < VERSION_ADD_FAVORITE_INDEX) {
3479         UpdateFavoriteIndex(store);
3480     }
3481 }
3482 
UpgradeVisionTable(RdbStore & store,int32_t oldVersion)3483 static void UpgradeVisionTable(RdbStore &store, int32_t oldVersion)
3484 {
3485     if (oldVersion < VERSION_ADD_VISION_TABLE) {
3486         AddAnalysisTables(store);
3487     }
3488 
3489     if (oldVersion < VERSION_ADD_FACE_TABLE) {
3490         AddFaceTables(store);
3491     }
3492 
3493     if (oldVersion < VERSION_ADD_VISION_ALBUM) {
3494         AddAnalysisAlbum(store);
3495     }
3496 
3497     if (oldVersion < VERSION_ADD_SEARCH_TABLE) {
3498         AddSearchTable(store);
3499     }
3500 
3501     if (oldVersion < VERSION_ADD_AESTHETIC_COMPOSITION_TABLE) {
3502         AddAestheticCompositionTables(store);
3503     }
3504 
3505     if (oldVersion < VERSION_ADD_SALIENCY_TABLE) {
3506         AddSaliencyTables(store);
3507     }
3508 
3509     if (oldVersion < VERSION_REOMOVE_SOURCE_ALBUM_TO_ANALYSIS) {
3510         RemoveSourceAlbumToAnalysis(store);
3511     }
3512 
3513     if (oldVersion < VERSION_UPDATE_DATE_TO_MILLISECOND) {
3514         UpdateMillisecondDate(store);
3515     }
3516 
3517     if (oldVersion < VERSION_ADD_ADDRESS_DESCRIPTION) {
3518         AddAddressDescriptionColumns(store);
3519     }
3520 
3521     if (oldVersion < VERSION_ADD_HAS_ASTC) {
3522         AddHasAstcColumns(store);
3523     }
3524 
3525     if (oldVersion < VERSION_UPDATE_SPEC_FOR_ADD_SCREENSHOT) {
3526         UpdateSpecForAddScreenshot(store);
3527     }
3528 
3529     if (oldVersion < VERSION_MOVE_SOURCE_ALBUM_TO_PHOTO_ALBUM_AND_ADD_COLUMNS) {
3530         MoveSourceAlbumToPhotoAlbumAndAddColumns(store);
3531     }
3532 
3533     if (oldVersion < VERSION_MODIFY_SOURCE_ALBUM_TRIGGERS) {
3534         ModifySourceAlbumTriggers(store);
3535     }
3536     // !! Do not add upgrade code here !!
3537 }
3538 
UpgradeExtendedVisionTable(RdbStore & store,int32_t oldVersion)3539 static void UpgradeExtendedVisionTable(RdbStore &store, int32_t oldVersion)
3540 {
3541     if (oldVersion < VERSION_ADD_HEAD_AND_POSE_TABLE) {
3542         AddHeadAndPoseTables(store);
3543     }
3544 
3545     if (oldVersion < VERSION_ADD_SEGMENTATION_COLUMNS) {
3546         AddSegmentationColumns(store);
3547     }
3548     // !! Do not add upgrade code here !!
3549 }
3550 
UpgradeHistory(RdbStore & store,int32_t oldVersion)3551 static void UpgradeHistory(RdbStore &store, int32_t oldVersion)
3552 {
3553     if (oldVersion < VERSION_ADD_MISSING_UPDATES) {
3554         AddMissingUpdates(store);
3555     }
3556 
3557     if (oldVersion < VERSION_UPDATE_MDIRTY_TRIGGER_FOR_SDIRTY) {
3558         UpdateMdirtyTriggerForSdirty(store);
3559     }
3560 }
3561 
UpdatePhotosSearchUpdateTrigger(RdbStore & store)3562 static void UpdatePhotosSearchUpdateTrigger(RdbStore &store)
3563 {
3564     static const vector<string> executeSqlStrs = {
3565         "DROP TRIGGER IF EXISTS update_search_status_trigger",
3566         CREATE_SEARCH_UPDATE_STATUS_TRIGGER,
3567     };
3568     MEDIA_INFO_LOG("Start update photos search trigger");
3569     ExecSqls(executeSqlStrs, store);
3570 }
3571 
AddIsTemp(RdbStore & store)3572 static void AddIsTemp(RdbStore &store)
3573 {
3574     static const vector<string> executeSqlStrs = {
3575         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_IS_TEMP + " INT DEFAULT 0"
3576     };
3577     MEDIA_INFO_LOG("Start add is_temp on Photos in upgrade");
3578     ExecSqls(executeSqlStrs, store);
3579 }
3580 
AddIsTempToTrigger(RdbStore & store)3581 static void AddIsTempToTrigger(RdbStore &store)
3582 {
3583     static const vector<string> executeSqlStrs = {
3584         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_SCHPT_DAY_INDEX,
3585         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_SCHPT_MEDIA_TYPE_INDEX,
3586         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_SCHPT_HIDDEN_TIME_INDEX,
3587         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_FAVORITE_INDEX,
3588         "DROP INDEX IF EXISTS " + PhotoColumn::PHOTO_SCHPT_ADDED_INDEX,
3589         PhotoColumn::CREATE_SCHPT_DAY_INDEX,
3590         PhotoColumn::CREATE_SCHPT_MEDIA_TYPE_INDEX,
3591         PhotoColumn::CREATE_SCHPT_HIDDEN_TIME_INDEX,
3592         PhotoColumn::CREATE_PHOTO_FAVORITE_INDEX,
3593         PhotoColumn::INDEX_SCTHP_ADDTIME,
3594     };
3595     MEDIA_INFO_LOG("Add is_temp to trigger in upgrade");
3596     ExecSqls(executeSqlStrs, store);
3597 }
3598 
AddDisplayNameIndex(RdbStore & store)3599 static void AddDisplayNameIndex(RdbStore &store)
3600 {
3601     static const vector<string> executeSqlStrs = {
3602         PhotoColumn::CREATE_PHOTO_DISPLAYNAME_INDEX,
3603     };
3604     MEDIA_INFO_LOG("Add displayname index");
3605     ExecSqls(executeSqlStrs, store);
3606 }
3607 
AddAppUriPermissionInfo(RdbStore & store)3608 static void AddAppUriPermissionInfo(RdbStore &store)
3609 {
3610     const std::string SYNC_DATA_FROM_PHOTOS_SQL =
3611         "insert into "+ AppUriPermissionColumn::APP_URI_PERMISSION_TABLE + "(" +
3612         AppUriPermissionColumn::APP_ID + ", " + AppUriPermissionColumn::FILE_ID + ", " +
3613         AppUriPermissionColumn::URI_TYPE + ", " + AppUriPermissionColumn::PERMISSION_TYPE + ", " +
3614         AppUriPermissionColumn::DATE_MODIFIED + ") " +
3615         "select " +
3616         MediaColumn::MEDIA_OWNER_APPID + ", " + MediaColumn::MEDIA_ID + ", " +
3617         std::to_string(AppUriPermissionColumn::URI_PHOTO) + ", " +
3618         std::to_string(AppUriPermissionColumn::PERMISSION_PERSIST_READ_WRITE) + ", " +
3619         MediaColumn::MEDIA_DATE_ADDED +
3620         " from " + PhotoColumn::PHOTOS_TABLE +
3621         " where " + MediaColumn::MEDIA_OWNER_APPID + " is not null";
3622 
3623     const std::string SYNC_DATA_FROM_AUDIOS_SQL =
3624         "insert into "+ AppUriPermissionColumn::APP_URI_PERMISSION_TABLE + "(" +
3625         AppUriPermissionColumn::APP_ID + ", " + AppUriPermissionColumn::FILE_ID + ", " +
3626         AppUriPermissionColumn::URI_TYPE + ", " + AppUriPermissionColumn::PERMISSION_TYPE + ", " +
3627         AppUriPermissionColumn::DATE_MODIFIED + ") " +
3628         "select " +
3629         MediaColumn::MEDIA_OWNER_APPID + ", " + MediaColumn::MEDIA_ID + ", " +
3630         std::to_string(AppUriPermissionColumn::URI_AUDIO) + ", " +
3631         std::to_string(AppUriPermissionColumn::PERMISSION_PERSIST_READ_WRITE) + ", " +
3632         MediaColumn::MEDIA_DATE_ADDED +
3633         " from " + AudioColumn::AUDIOS_TABLE +
3634         " where " + MediaColumn::MEDIA_OWNER_APPID + " is not null";
3635     const vector<string> sqls = {
3636         AppUriPermissionColumn::CREATE_APP_URI_PERMISSION_TABLE,
3637         AppUriPermissionColumn::CREATE_URI_URITYPE_APPID_INDEX,
3638         SYNC_DATA_FROM_PHOTOS_SQL,
3639         SYNC_DATA_FROM_AUDIOS_SQL,
3640         TriggerDeletePhotoClearAppUriPermission(),
3641         TriggerDeleteAudioClearAppUriPermission(),
3642     };
3643     MEDIA_INFO_LOG("add uriPermission table info when upgrade phone");
3644     ExecSqls(sqls, store);
3645 }
3646 
AddCoverPosition(RdbStore & store)3647 static void AddCoverPosition(RdbStore &store)
3648 {
3649     const vector<string> sqls = {
3650         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_COVER_POSITION +
3651             " BIGINT DEFAULT 0",
3652     };
3653     MEDIA_INFO_LOG("start add cover_position column");
3654     ExecSqls(sqls, store);
3655 }
3656 
AddSchptReadyIndex(RdbStore & store)3657 static void AddSchptReadyIndex(RdbStore &store)
3658 {
3659     static const vector<string> executeSqlStrs = {
3660         PhotoColumn::INDEX_SCHPT_READY,
3661     };
3662     MEDIA_INFO_LOG("Add schpt ready index");
3663     ExecSqls(executeSqlStrs, store);
3664 }
3665 
UpdateSourceAlbumAndAlbumBundlenameTriggers(RdbStore & store)3666 static void UpdateSourceAlbumAndAlbumBundlenameTriggers(RdbStore &store)
3667 {
3668     static const vector<string> executeSqlStrs = {
3669         DROP_INSERT_PHOTO_INSERT_SOURCE_ALBUM,
3670         DROP_INSERT_PHOTO_UPDATE_SOURCE_ALBUM,
3671         DROP_INSERT_PHOTO_UPDATE_ALBUM_BUNDLENAME,
3672         INSERT_PHOTO_INSERT_SOURCE_ALBUM,
3673         INSERT_PHOTO_UPDATE_SOURCE_ALBUM,
3674         INSERT_PHOTO_UPDATE_ALBUM_BUNDLENAME,
3675     };
3676     MEDIA_INFO_LOG("start update source album and album bundlename triggers");
3677     ExecSqls(executeSqlStrs, store);
3678 }
3679 
AddFrontCameraType(RdbStore & store)3680 static void AddFrontCameraType(RdbStore &store)
3681 {
3682     const vector<string> sqls = {
3683         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_FRONT_CAMERA + " TEXT"
3684     };
3685     MEDIA_INFO_LOG("Start add front column");
3686     ExecSqls(sqls, store);
3687 }
3688 
AddPortraitCoverSelectionColumn(RdbStore & store)3689 static void AddPortraitCoverSelectionColumn(RdbStore &store)
3690 {
3691     MEDIA_INFO_LOG("Start add portrait cover selection column");
3692 
3693     const vector<string> sqls = {
3694         "ALTER TABLE " + VISION_IMAGE_FACE_TABLE + " ADD COLUMN " + BEAUTY_BOUNDER_X + " REAL",
3695         "ALTER TABLE " + VISION_IMAGE_FACE_TABLE + " ADD COLUMN " + BEAUTY_BOUNDER_Y + " REAL",
3696         "ALTER TABLE " + VISION_IMAGE_FACE_TABLE + " ADD COLUMN " + BEAUTY_BOUNDER_WIDTH + " REAL",
3697         "ALTER TABLE " + VISION_IMAGE_FACE_TABLE + " ADD COLUMN " + BEAUTY_BOUNDER_HEIGHT + " REAL",
3698         "ALTER TABLE " + VISION_IMAGE_FACE_TABLE + " ADD COLUMN " + FACE_AESTHETICS_SCORE + " REAL",
3699         "ALTER TABLE " + VISION_IMAGE_FACE_TABLE + " ADD COLUMN " + BEAUTY_BOUNDER_VERSION + " TEXT default '' ",
3700         "ALTER TABLE " + VISION_IMAGE_FACE_TABLE + " ADD COLUMN " + IS_EXCLUDED + " INT default 0 ",
3701     };
3702     ExecSqls(sqls, store);
3703 }
3704 
AddDetailTimeToPhotos(RdbStore & store)3705 static void AddDetailTimeToPhotos(RdbStore &store)
3706 {
3707     const vector<string> sqls = {
3708         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_DETAIL_TIME + " TEXT"
3709     };
3710     MEDIA_INFO_LOG("Add detail_time column start");
3711     ExecSqls(sqls, store);
3712 }
3713 
AddThumbnailVisible(RdbStore & store)3714 static void AddThumbnailVisible(RdbStore& store)
3715 {
3716     const vector<string> sqls = {
3717         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_THUMBNAIL_VISIBLE +
3718         " INT DEFAULT 0",
3719         "UPDATE " + PhotoColumn::PHOTOS_TABLE +
3720         " SET thumbnail_visible = "
3721         " CASE "
3722             " WHEN thumbnail_ready > 0 THEN 1 "
3723             " ELSE 0 "
3724         " END ",
3725         PhotoColumn::DROP_INDEX_SCHPT_READY,
3726         PhotoColumn::INDEX_SCHPT_READY,
3727     };
3728     MEDIA_INFO_LOG("Add thumbnail visible column and index");
3729     ExecSqls(sqls, store);
3730 }
3731 
AddVideoFaceTable(RdbStore & store)3732 static void AddVideoFaceTable(RdbStore &store)
3733 {
3734     const vector<string> sqls = {
3735         CREATE_TAB_VIDEO_FACE,
3736         CREATE_VIDEO_FACE_INDEX,
3737         "ALTER TABLE " + VISION_TOTAL_TABLE + " ADD COLUMN " + GEO + " INT"
3738     };
3739     MEDIA_INFO_LOG("Add video face table start");
3740     ExecSqls(sqls, store);
3741 }
3742 
AddSupportedWatermarkType(RdbStore & store)3743 static void AddSupportedWatermarkType(RdbStore &store)
3744 {
3745     const vector<string> sqls = {
3746         "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " +
3747             PhotoColumn::SUPPORTED_WATERMARK_TYPE + " INT "
3748     };
3749     MEDIA_INFO_LOG("start add supported_watermark_type column");
3750     ExecSqls(sqls, store);
3751 }
3752 
UpgradeExtensionPart3(RdbStore & store,int32_t oldVersion)3753 static void UpgradeExtensionPart3(RdbStore &store, int32_t oldVersion)
3754 {
3755     if (oldVersion < VERSION_ADD_HIGHLIGHT_MAP_TABLES) {
3756         AddHighlightMapTable(store);
3757         AddVideoFaceTable(store);
3758     }
3759 
3760     if (oldVersion < VERSION_UPDATE_SEARCH_INDEX_TRIGGER_FOR_CLEAN_FLAG) {
3761         UpdateSearchIndexTriggerForCleanFlag(store);
3762     }
3763 
3764     if (oldVersion < VERSION_CREATE_TAB_OLD_PHOTOS) {
3765         TabOldPhotosTableEventHandler().OnCreate(store);
3766     }
3767 
3768     if (oldVersion < VERSION_HDR_AND_CLOUD_ENAHCNEMENT_FIX) {
3769         AddDynamicRangeColumnsFix(store);
3770         AddCloudEnhanceColumnsFix(store);
3771     }
3772 
3773     if (oldVersion < VERSION_THUMBNAIL_READY_FIX) {
3774         AddThumbnailReadyColumnsFix(store);
3775     }
3776 
3777     if (oldVersion < VERSION_UPDATE_AOI) {
3778         UpdateAOI(store);
3779     }
3780 
3781     if (oldVersion < VERSION_UPDATE_SOURCE_PHOTO_ALBUM_TRIGGER) {
3782         UpdateSourcePhotoAlbumTrigger(store);
3783     }
3784 
3785     if (oldVersion < VERSION_ADD_SUPPORTED_WATERMARK_TYPE) {
3786         AddSupportedWatermarkType(store);
3787     }
3788 }
3789 
UpgradeExtensionPart2(RdbStore & store,int32_t oldVersion)3790 static void UpgradeExtensionPart2(RdbStore &store, int32_t oldVersion)
3791 {
3792     // VERSION_UPGRADE_THUMBNAIL move to HandleUpgradeRdbAsync()
3793 
3794     if (oldVersion < VERSION_UPDATE_SEARCH_INDEX_TRIGGER) {
3795         UpdateSearchIndexTrigger(store);
3796     }
3797 
3798     if (oldVersion < VERSION_UPDATE_MULTI_CROP_INFO) {
3799         UpdateMultiCropInfo(store);
3800     }
3801 
3802     if (oldVersion < VERSION_UDAPTE_DATA_UNIQUE) {
3803         UpdateDataUniqueIndex(store);
3804     }
3805 
3806     if (oldVersion < VERSION_ADD_ORIGINAL_SUBTYPE) {
3807         AddOriginalSubtype(store);
3808     }
3809 
3810     if (oldVersion < VERSION_CLOUD_ENAHCNEMENT) {
3811         AddCloudEnhancementColumns(store);
3812     }
3813     // VERSION_UPDATE_BURST_DIRTY = 101 move to UpgradeRdbStoreAsync(), avoid to cost for long time.
3814 
3815     if (oldVersion < VERSION_UPDATE_MDIRTY_TRIGGER_FOR_UPLOADING_MOVING_PHOTO) {
3816         UpdatePhotosMdirtyTrigger(store);
3817     }
3818 
3819     if (oldVersion < VERSION_ADD_INDEX_FOR_FILEID) {
3820         AddIndexForFileId(store);
3821     }
3822 
3823     if (oldVersion < VERSION_FIX_PHOTO_SCHPT_MEDIA_TYPE_INDEX) {
3824         FixPhotoSchptMediaTypeIndex(store);
3825     }
3826 
3827     if (oldVersion < VERSION_ADD_DETAIL_TIME) {
3828         AddDetailTimeToPhotos(store);
3829     }
3830 
3831     if (oldVersion < VERSION_ADD_OWNER_ALBUM_ID) {
3832         AddOwnerAlbumIdAndRefractorTrigger(store);
3833         AlbumPluginTableEventHandler albumPluginTableEventHandler;
3834         albumPluginTableEventHandler.OnUpgrade(store, oldVersion, oldVersion);
3835         AddMergeInfoColumnForAlbum(store);
3836         MEDIA_INFO_LOG("ALBUM_FUSE:SetAlbumFuseUpgradeStatus");
3837         MediaLibraryAlbumFusionUtils::SetAlbumFuseUpgradeStatus(0);
3838     }
3839 
3840     if (oldVersion < VERSION_COMPAT_LIVE_PHOTO) {
3841         CompatLivePhoto(store, oldVersion);
3842     }
3843 
3844     if (oldVersion < VERSION_ADD_CLOUD_ENHANCEMENT_ALBUM) {
3845         AddCloudEnhancementAlbum(store);
3846     }
3847 
3848     if (oldVersion < VERSION_ADD_THUMBNAIL_VISIBLE_FIX) {
3849         AddThumbnailVisible(store);
3850     }
3851 
3852     UpgradeExtensionPart3(store, oldVersion);
3853     // !! Do not add upgrade code here !!
3854 }
3855 
UpgradeExtensionPart1(RdbStore & store,int32_t oldVersion)3856 static void UpgradeExtensionPart1(RdbStore &store, int32_t oldVersion)
3857 {
3858     if (oldVersion < VERSION_ADD_OWNER_APPID_TO_FILES_TABLE) {
3859         AddOwnerAppIdToFiles(store);
3860     }
3861 
3862     if (oldVersion < VERSION_ADD_IS_TEMP_TO_TRIGGER) {
3863         AddIsTempToTrigger(store);
3864     }
3865 
3866     if (oldVersion < VERSION_UPDATE_PHOTO_THUMBNAIL_READY) {
3867         UpdateThumbnailReadyColumn(store);
3868     }
3869 
3870     if (oldVersion < PHOTOS_CREATE_DISPLAYNAME_INDEX) {
3871         AddDisplayNameIndex(store);
3872     }
3873 
3874     if (oldVersion < VERSION_UPDATE_ANALYSIS_TABLES) {
3875         UpdateAnalysisTables(store);
3876     }
3877 
3878     if (oldVersion < VERSION_ADD_COVER_POSITION) {
3879         AddCoverPosition(store);
3880     }
3881 
3882     if (oldVersion < VERSION_ADD_SCHPT_READY_INEDX) {
3883         AddSchptReadyIndex(store);
3884     }
3885 
3886     if (oldVersion < VERSION_UPDATE_SOURCE_ALBUM_AND_ALBUM_BUNDLENAME_TRIGGERS) {
3887         UpdateSourceAlbumAndAlbumBundlenameTriggers(store);
3888     }
3889 
3890     if (oldVersion < VERSION_ADD_FRONT_CAMERA_TYPE) {
3891         AddFrontCameraType(store);
3892     }
3893 
3894     if (oldVersion < VERSION_UPDATE_PHOTO_INDEX_FOR_ALBUM_COUNT_COVER) {
3895         UpdateIndexForAlbumQuery(store);
3896     }
3897 
3898     if (oldVersion < VERSION_ADD_BURST_COVER_LEVEL_AND_BURST_KEY) {
3899         AddBurstCoverLevelAndBurstKey(store);
3900     }
3901 
3902     // VERSION_CREATE_BURSTKEY_INDEX = 93 move to UpgradeRdbStoreAsync(), avoid to cost for long time.
3903 
3904     if (oldVersion < VERSION_PORTRAIT_COVER_SELECTION_ADD_COLUMNS) {
3905         AddPortraitCoverSelectionColumn(store);
3906     }
3907 
3908     if (oldVersion < VERSION_UPDATE_DATA_ADDED_INDEX) {
3909         UpdateDataAddedIndexWithFileId(store);
3910     }
3911 
3912     if (oldVersion < VERSION_ADD_APP_URI_PERMISSION_INFO) {
3913         AddAppUriPermissionInfo(store);
3914     }
3915 
3916     UpgradeExtensionPart2(store, oldVersion);
3917     // !! Do not add upgrade code here !!
3918 }
3919 
CreatePhotosExtTable(RdbStore & store)3920 static void CreatePhotosExtTable(RdbStore &store)
3921 {
3922     static const vector<string> executeSqlStrs = {
3923         PhotoExtColumn::CREATE_PHOTO_EXT_TABLE
3924     };
3925     MEDIA_INFO_LOG("Start create photo ext table in update");
3926     ExecSqls(executeSqlStrs, store);
3927 }
3928 
UpgradeExtensionExt(RdbStore & store,int32_t oldVersion)3929 static void UpgradeExtensionExt(RdbStore &store, int32_t oldVersion)
3930 {
3931     if (oldVersion < VERSION_UPDATE_PHOTO_ALBUM_BUNDLENAME) {
3932         UpdateInsertPhotoUpdateAlbumTrigger(store);
3933     }
3934 
3935     if (oldVersion < VERSION_UPDATE_PHOTO_ALBUM_TIGGER) {
3936         UpdatePhotoAlbumTigger(store);
3937     }
3938 
3939     if (oldVersion < VERSION_ADD_THUMB_LCD_SIZE_COLUMN) {
3940         AddLcdAndThumbSizeColumns(store);
3941     }
3942 
3943     if (oldVersion < VERSION_UPDATE_HIGHLIGHT_TABLE_PRIMARY_KEY) {
3944         UpdateHighlightTablePrimaryKey(store);
3945     }
3946 
3947     if (oldVersion < VERSION_UPDATE_VISION_TRIGGER_FOR_VIDEO_LABEL) {
3948         UpdateVisionTriggerForVideoLabel(store);
3949     }
3950 
3951     if (oldVersion < VERSION_ADD_FACE_OCCLUSION_AND_POSE_TYPE_COLUMN) {
3952         AddFaceOcclusionAndPoseTypeColumn(store);
3953     }
3954 
3955     if (oldVersion < VERSION_ADD_MOVING_PHOTO_EFFECT_MODE) {
3956         AddMovingPhotoEffectMode(store);
3957     }
3958 
3959     if (oldVersion < VERSION_ADD_IS_TEMP) {
3960         AddIsTemp(store);
3961     }
3962 }
3963 
UpgradeExtension(RdbStore & store,int32_t oldVersion)3964 static void UpgradeExtension(RdbStore &store, int32_t oldVersion)
3965 {
3966     if (oldVersion < VERSION_UPDATE_SEARCH_INDEX) {
3967         UpdatePhotosSearchUpdateTrigger(store);
3968     }
3969 
3970     if (oldVersion < VERSION_ADD_STOYR_TABLE) {
3971         AddStoryTables(store);
3972     }
3973 
3974     if (oldVersion < VERSION_SHOOTING_MODE_CLOUD) {
3975         AddBussinessRecordAlbum(store);
3976     }
3977 
3978     if (oldVersion < VERSION_ADD_OWNER_APPID) {
3979         AddOwnerAppId(store);
3980     }
3981 
3982     if (oldVersion < VERSION_ADD_VIDEO_LABEL_TABEL) {
3983         AddVideoLabelTable(store);
3984     }
3985 
3986     if (oldVersion < VERSION_CREATE_PHOTOS_EXT_TABLE) {
3987         CreatePhotosExtTable(store);
3988     }
3989 
3990     if (oldVersion < VERSION_UPDATE_VIDEO_LABEL_TABEL) {
3991         UpdateVideoLabelTable(store);
3992     }
3993 
3994     if (oldVersion < VERSION_ADD_DYNAMIC_RANGE_TYPE) {
3995         AddDynamicRangeType(store);
3996     }
3997 
3998     UpgradeExtensionExt(store, oldVersion);
3999     UpgradeExtensionPart1(store, oldVersion);
4000     // !! Do not add upgrade code here !!
4001 }
4002 
UpgradeAlbumTable(RdbStore & store,int32_t oldVersion)4003 static void UpgradeAlbumTable(RdbStore &store, int32_t oldVersion)
4004 {
4005     if (oldVersion < VERSION_ADD_IS_LOCAL_ALBUM) {
4006         AddIsLocalAlbum(store);
4007     }
4008 }
4009 
UpgradeAnalysisAlbumTable(RdbStore & store,int32_t oldVersion)4010 static void UpgradeAnalysisAlbumTable(RdbStore &store, int32_t oldVersion)
4011 {
4012     if (oldVersion < VERSION_ADD_IS_COVER_SATISFIED_COLUMN) {
4013         AddIsCoverSatisfiedColumn(store);
4014     }
4015 }
4016 
OnUpgrade(RdbStore & store,int32_t oldVersion,int32_t newVersion)4017 int32_t MediaLibraryDataCallBack::OnUpgrade(RdbStore &store, int32_t oldVersion, int32_t newVersion)
4018 {
4019     MediaLibraryTracer tracer;
4020     tracer.Start("MediaLibraryDataCallBack::OnUpgrade");
4021     if (MediaLibraryRdbStore::GetOldVersion() == -1) {
4022         MediaLibraryRdbStore::SetOldVersion(oldVersion);
4023     }
4024     MEDIA_INFO_LOG("OnUpgrade old:%{public}d, new:%{public}d", oldVersion, newVersion);
4025     g_upgradeErr = false;
4026     if (oldVersion < VERSION_ADD_CLOUD) {
4027         VersionAddCloud(store);
4028     }
4029 
4030     if (oldVersion < VERSION_ADD_META_MODIFED) {
4031         AddMetaModifiedColumn(store);
4032     }
4033 
4034     if (oldVersion < VERSION_MODIFY_SYNC_STATUS) {
4035         ModifySyncStatus(store);
4036     }
4037 
4038     if (oldVersion < VERSION_ADD_API10_TABLE) {
4039         API10TableCreate(store);
4040     }
4041 
4042     if (oldVersion < VERSION_MODIFY_DELETE_TRIGGER) {
4043         ModifyDeleteTrigger(store);
4044     }
4045 
4046     if (oldVersion < VERSION_ADD_CLOUD_VERSION) {
4047         AddCloudVersion(store);
4048     }
4049 
4050     if (oldVersion < VERSION_UPDATE_CLOUD_PATH) {
4051         UpdateCloudPath(store);
4052     }
4053 
4054     if (oldVersion < VERSION_UPDATE_API10_TABLE) {
4055         UpdateAPI10Table(store);
4056     }
4057 
4058     if (oldVersion < VERSION_ADD_TABLE_TYPE) {
4059         AddTableType(store);
4060     }
4061 
4062     if (oldVersion < VERSION_ADD_PHOTO_CLEAN_FLAG_AND_THUMB_STATUS) {
4063         AddCleanFlagAndThumbStatus(store);
4064     }
4065 
4066     if (oldVersion < VERSION_ADD_CLOUD_ID_INDEX) {
4067         AddCloudIndex(store);
4068     }
4069 
4070     UpgradeOtherTable(store, oldVersion);
4071     UpgradeGalleryFeatureTable(store, oldVersion);
4072 
4073     if (!g_upgradeErr) {
4074         VariantMap map = {{KEY_PRE_VERSION, oldVersion}, {KEY_AFTER_VERSION, newVersion}};
4075         PostEventUtils::GetInstance().PostStatProcess(StatType::DB_UPGRADE_STAT, map);
4076     }
4077 
4078     UpgradeVisionTable(store, oldVersion);
4079     UpgradeExtendedVisionTable(store, oldVersion);
4080     UpgradeHistory(store, oldVersion);
4081     UpgradeAlbumTable(store, oldVersion);
4082     UpgradeExtension(store, oldVersion);
4083     UpgradeAnalysisAlbumTable(store, oldVersion);
4084     return NativeRdb::E_OK;
4085 }
4086 
SetOldVersion(int32_t oldVersion)4087 void MediaLibraryRdbStore::SetOldVersion(int32_t oldVersion)
4088 {
4089     int32_t errCode;
4090     shared_ptr<NativePreferences::Preferences> prefs =
4091         NativePreferences::PreferencesHelper::GetPreferences(RDB_CONFIG, errCode);
4092     if (!prefs) {
4093         MEDIA_ERR_LOG("get preferences error: %{public}d", errCode);
4094         return;
4095     }
4096     prefs->PutInt(RDB_OLD_VERSION, oldVersion);
4097     prefs->FlushSync();
4098 }
4099 
GetOldVersion()4100 int32_t MediaLibraryRdbStore::GetOldVersion()
4101 {
4102     int32_t errCode;
4103     shared_ptr<NativePreferences::Preferences> prefs =
4104         NativePreferences::PreferencesHelper::GetPreferences(RDB_CONFIG, errCode);
4105     if (!prefs) {
4106         MEDIA_ERR_LOG("get preferences error: %{public}d", errCode);
4107         return oldVersion_;
4108     }
4109     return prefs->GetInt(RDB_OLD_VERSION, oldVersion_);
4110 }
4111 
HasColumnInTable(RdbStore & store,const string & columnName,const string & tableName)4112 bool MediaLibraryRdbStore::HasColumnInTable(RdbStore &store, const string &columnName, const string &tableName)
4113 {
4114     string querySql = "SELECT " + MEDIA_COLUMN_COUNT_1 + " FROM pragma_table_info('" + tableName + "') WHERE name = '" +
4115         columnName + "'";
4116     auto resultSet = store.QuerySql(querySql);
4117     if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
4118         MEDIA_ERR_LOG("Get column count failed");
4119         return false;
4120     }
4121     int32_t count = GetInt32Val(MEDIA_COLUMN_COUNT_1, resultSet);
4122     MEDIA_DEBUG_LOG("%{private}s in %{private}s: %{public}d", columnName.c_str(), tableName.c_str(), count);
4123     return count > 0;
4124 }
4125 
AddColumnIfNotExists(RdbStore & store,const string & columnName,const string & columnType,const string & tableName)4126 void MediaLibraryRdbStore::AddColumnIfNotExists(
4127     RdbStore &store, const string &columnName, const string &columnType, const string &tableName)
4128 {
4129     if (!HasColumnInTable(store, columnName, tableName)) {
4130         string sql = "ALTER TABLE " + tableName + " ADD COLUMN " + columnName + " " + columnType;
4131         ExecSqlWithRetry([&]() { return store.ExecuteSql(sql); });
4132     }
4133 }
4134 
Update(int & changedRows,const std::string & table,const ValuesBucket & row,const std::string & whereClause,const std::vector<std::string> & args)4135 int MediaLibraryRdbStore::Update(int &changedRows, const std::string &table, const ValuesBucket &row,
4136     const std::string &whereClause, const std::vector<std::string> &args)
4137 {
4138     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4139         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4140         return E_HAS_DB_ERROR;
4141     }
4142     return ExecSqlWithRetry(
4143         [&]() { return MediaLibraryRdbStore::GetRaw()->Update(changedRows, table, row, whereClause, args); });
4144 }
4145 
ObtainDistributedTableName(const std::string & device,const std::string & table,int & errCode)4146 std::string MediaLibraryRdbStore::ObtainDistributedTableName(const std::string &device, const std::string &table,
4147     int &errCode)
4148 {
4149     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4150         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4151         return "";
4152     }
4153     return MediaLibraryRdbStore::GetRaw()->ObtainDistributedTableName(device, table, errCode);
4154 }
4155 
Backup(const std::string & databasePath,const std::vector<uint8_t> & encryptKey)4156 int MediaLibraryRdbStore::Backup(const std::string &databasePath, const std::vector<uint8_t> &encryptKey)
4157 {
4158     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4159         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4160         return E_HAS_DB_ERROR;
4161     }
4162     return ExecSqlWithRetry([&]() { return MediaLibraryRdbStore::GetRaw()->Backup(databasePath, encryptKey); });
4163 }
4164 
Sync(const DistributedRdb::SyncOption & option,const AbsRdbPredicates & predicate,const DistributedRdb::AsyncBrief & async)4165 int MediaLibraryRdbStore::Sync(const DistributedRdb::SyncOption &option, const AbsRdbPredicates &predicate,
4166     const DistributedRdb::AsyncBrief &async)
4167 {
4168     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4169         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4170         return E_HAS_DB_ERROR;
4171     }
4172     return ExecSqlWithRetry([&]() { return MediaLibraryRdbStore::GetRaw()->Sync(option, predicate, async); });
4173 }
4174 
QueryByStep(const std::string & sql,const std::vector<ValueObject> & args)4175 std::shared_ptr<NativeRdb::ResultSet> MediaLibraryRdbStore::QueryByStep(const std::string &sql,
4176     const std::vector<ValueObject> &args)
4177 {
4178     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4179         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4180         return nullptr;
4181     }
4182     return MediaLibraryRdbStore::GetRaw()->QueryByStep(sql, args);
4183 }
4184 
QueryByStep(const AbsRdbPredicates & predicates,const std::vector<std::string> & columns)4185 std::shared_ptr<NativeRdb::ResultSet> MediaLibraryRdbStore::QueryByStep(const AbsRdbPredicates &predicates,
4186     const std::vector<std::string> &columns)
4187 {
4188     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4189         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4190         return nullptr;
4191     }
4192     return MediaLibraryRdbStore::GetRaw()->QueryByStep(predicates, columns);
4193 }
4194 
Update(int & changedRows,const ValuesBucket & row,const AbsRdbPredicates & predicates)4195 int MediaLibraryRdbStore::Update(int &changedRows, const ValuesBucket &row, const AbsRdbPredicates &predicates)
4196 {
4197     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4198         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4199         return E_HAS_DB_ERROR;
4200     }
4201     return ExecSqlWithRetry([&]() { return MediaLibraryRdbStore::GetRaw()->Update(changedRows, row, predicates); });
4202 }
4203 
Insert(int64_t & outRowId,const std::string & table,const ValuesBucket & row)4204 int MediaLibraryRdbStore::Insert(int64_t &outRowId, const std::string &table, const ValuesBucket &row)
4205 {
4206     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4207         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4208         return E_HAS_DB_ERROR;
4209     }
4210     return ExecSqlWithRetry([&]() { return MediaLibraryRdbStore::GetRaw()->Insert(outRowId, table, row); });
4211 }
4212 
Delete(int & deletedRows,const std::string & table,const std::string & whereClause,const std::vector<std::string> & args)4213 int MediaLibraryRdbStore::Delete(int &deletedRows, const std::string &table, const std::string &whereClause,
4214     const std::vector<std::string> &args)
4215 {
4216     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4217         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4218         return E_HAS_DB_ERROR;
4219     }
4220     return ExecSqlWithRetry(
4221         [&]() { return MediaLibraryRdbStore::GetRaw()->Delete(deletedRows, table, whereClause, args); });
4222 }
4223 
Delete(int & deletedRows,const AbsRdbPredicates & predicates)4224 int MediaLibraryRdbStore::Delete(int &deletedRows, const AbsRdbPredicates &predicates)
4225 {
4226     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4227         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4228         return E_HAS_DB_ERROR;
4229     }
4230     return ExecSqlWithRetry([&]() { return MediaLibraryRdbStore::GetRaw()->Delete(deletedRows, predicates); });
4231 }
4232 
Query(const NativeRdb::AbsRdbPredicates & predicates,const std::vector<std::string> & columns)4233 std::shared_ptr<NativeRdb::ResultSet> MediaLibraryRdbStore::Query(const NativeRdb::AbsRdbPredicates &predicates,
4234     const std::vector<std::string> &columns)
4235 {
4236     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4237         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4238         return nullptr;
4239     }
4240     return MediaLibraryRdbStore::GetRaw()->Query(predicates, columns);
4241 }
4242 
QuerySql(const std::string & sql,const std::vector<ValueObject> & args)4243 std::shared_ptr<AbsSharedResultSet> MediaLibraryRdbStore::QuerySql(const std::string &sql,
4244     const std::vector<ValueObject> &args)
4245 {
4246     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4247         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4248         return nullptr;
4249     }
4250     return MediaLibraryRdbStore::GetRaw()->QuerySql(sql, args);
4251 }
4252 
InterruptBackup()4253 int MediaLibraryRdbStore::InterruptBackup()
4254 {
4255     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4256         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4257         return E_HAS_DB_ERROR;
4258     }
4259     return ExecSqlWithRetry([&]() { return MediaLibraryRdbStore::GetRaw()->InterruptBackup(); });
4260 }
4261 
IsSlaveDiffFromMaster() const4262 bool MediaLibraryRdbStore::IsSlaveDiffFromMaster() const
4263 {
4264     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4265         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4266         return false;
4267     }
4268     return MediaLibraryRdbStore::GetRaw()->IsSlaveDiffFromMaster();
4269 }
4270 
Restore(const std::string & backupPath,const std::vector<uint8_t> & newKey)4271 int MediaLibraryRdbStore::Restore(const std::string &backupPath, const std::vector<uint8_t> &newKey)
4272 {
4273     if (!MediaLibraryRdbStore::CheckRdbStore()) {
4274         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4275         return E_HAS_DB_ERROR;
4276     }
4277     return ExecSqlWithRetry([&]() { return MediaLibraryRdbStore::GetRaw()->Restore(backupPath, newKey); });
4278 }
4279 
DataCallBackOnCreate()4280 int32_t MediaLibraryRdbStore::DataCallBackOnCreate()
4281 {
4282     MediaLibraryDataCallBack callback;
4283     int32_t ret = callback.OnCreate(*GetRaw());
4284     if (ret != NativeRdb::E_OK) {
4285         MEDIA_ERR_LOG("MediaLibraryDataCallBack OnCreate error, ret: %{public}d", ret);
4286     }
4287     return ret;
4288 }
4289 
WalCheckPoint()4290 void MediaLibraryRdbStore::WalCheckPoint()
4291 {
4292     std::unique_lock<std::mutex> lock(walCheckPointMutex_, std::defer_lock);
4293     if (!lock.try_lock()) {
4294         MEDIA_WARN_LOG("wal_checkpoint in progress, skip this operation");
4295         return;
4296     }
4297 
4298     struct stat fileStat;
4299     const std::string walFile = MEDIA_DB_DIR + "/rdb/media_library.db-wal";
4300     if (stat(walFile.c_str(), &fileStat) < 0) {
4301         if (errno != ENOENT) {
4302             MEDIA_ERR_LOG("wal_checkpoint stat failed, errno: %{public}d", errno);
4303         }
4304         return;
4305     }
4306     ssize_t size = fileStat.st_size;
4307     if (size < 0) {
4308         MEDIA_ERR_LOG("Invalid size for wal_checkpoint, size: %{public}zd", size);
4309         return;
4310     }
4311     if (size <= RDB_CHECK_WAL_SIZE) {
4312         return;
4313     }
4314 
4315     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
4316     if (rdbStore == nullptr) {
4317         MEDIA_ERR_LOG("wal_checkpoint rdbStore is nullptr!");
4318         return;
4319     }
4320     auto errCode = rdbStore->ExecuteSql("PRAGMA wal_checkpoint(TRUNCATE)");
4321     if (errCode != NativeRdb::E_OK) {
4322         MEDIA_ERR_LOG("wal_checkpoint ExecuteSql failed, errCode: %{public}d", errCode);
4323     }
4324 }
4325 
ExecuteForChangedRowCount(int64_t & outValue,const std::string & sql,const std::vector<NativeRdb::ValueObject> & args)4326 int MediaLibraryRdbStore::ExecuteForChangedRowCount(int64_t &outValue, const std::string &sql,
4327     const std::vector<NativeRdb::ValueObject> &args)
4328 {
4329     if (!CheckRdbStore()) {
4330         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
4331         return E_HAS_DB_ERROR;
4332     }
4333     return ExecSqlWithRetry([&]() { return GetRaw()->ExecuteForChangedRowCount(outValue, sql, args); });
4334 }
4335 
4336 #ifdef DISTRIBUTED
MediaLibraryRdbStoreObserver(const string & bundleName)4337 MediaLibraryRdbStoreObserver::MediaLibraryRdbStoreObserver(const string &bundleName)
4338 {
4339     bundleName_ = bundleName;
4340     isNotifyDeviceChange_ = false;
4341 
4342     if (timer_ == nullptr) {
4343         timer_ = make_unique<OHOS::Utils::Timer>(bundleName_);
4344         timerId_ = timer_->Register(bind(&MediaLibraryRdbStoreObserver::NotifyDeviceChange, this),
4345             NOTIFY_TIME_INTERVAL);
4346         timer_->Setup();
4347     }
4348 }
4349 
~MediaLibraryRdbStoreObserver()4350 MediaLibraryRdbStoreObserver::~MediaLibraryRdbStoreObserver()
4351 {
4352     if (timer_ != nullptr) {
4353         timer_->Shutdown();
4354         timer_->Unregister(timerId_);
4355         timer_ = nullptr;
4356     }
4357 }
4358 
OnChange(const vector<string> & devices)4359 void MediaLibraryRdbStoreObserver::OnChange(const vector<string> &devices)
4360 {
4361     MEDIA_INFO_LOG("MediaLibraryRdbStoreObserver OnChange call");
4362     if (devices.empty() || bundleName_.empty()) {
4363         return;
4364     }
4365     MediaLibraryDevice::GetInstance()->NotifyRemoteFileChange();
4366 }
4367 
NotifyDeviceChange()4368 void MediaLibraryRdbStoreObserver::NotifyDeviceChange()
4369 {
4370     if (isNotifyDeviceChange_) {
4371         MediaLibraryDevice::GetInstance()->NotifyDeviceChange();
4372         isNotifyDeviceChange_ = false;
4373     }
4374 }
4375 #endif
4376 } // namespace OHOS::Media
4377