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