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