diff --git a/frameworks/innerkitsimpl/media_library_helper/src/media_column.cpp b/frameworks/innerkitsimpl/media_library_helper/src/media_column.cpp index 7ae0c43ddfe49fd29f79d1272833aea01744cb20..d8c25e8141337b086806082df902902aa0a19c4e 100644 --- a/frameworks/innerkitsimpl/media_library_helper/src/media_column.cpp +++ b/frameworks/innerkitsimpl/media_library_helper/src/media_column.cpp @@ -102,6 +102,37 @@ const std::string PhotoColumn::CREATE_PHOTO_TABLE = "CREATE TABLE IF NOT EXISTS PHOTO_LCD_VISIT_TIME + " BIGINT DEFAULT 0, " + PHOTO_POSITION + " INT DEFAULT 1)"; +const std::string PhotoColumn::CREATE_PHOTOS_DELETE_TRIGGER = + "CREATE TRIGGER photos_delete_trigger AFTER UPDATE ON " + + PhotoColumn::PHOTOS_TABLE + " FOR EACH ROW WHEN new.dirty = " + + std::to_string(static_cast(DirtyTypes::TYPE_DELETED)) + + " and OLD.cloud_id is NULL " + + " BEGIN " + + " DELETE FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE file_id = old.file_id;" + + " END;"; + +const std::string PhotoColumn::CREATE_PHOTOS_FDIRTY_TRIGGER = + "CREATE TRIGGER photos_fdirty_trigger AFTER UPDATE ON " + + PhotoColumn::PHOTOS_TABLE + " FOR EACH ROW WHEN OLD.cloud_id IS NOT NULL AND" + + " new.date_modified <> old.date_modified " + + " BEGIN " + + " UPDATE " + PhotoColumn::PHOTOS_TABLE + " SET dirty = " + + std::to_string(static_cast(DirtyTypes::TYPE_FDIRTY)) + + " WHERE file_id = old.file_id;" + + " END;"; + +const std::string PhotoColumn::CREATE_PHOTOS_MDIRTY_TRIGGER = + "CREATE TRIGGER photos_mdirty_trigger AFTER UPDATE ON " + + PhotoColumn::PHOTOS_TABLE + " FOR EACH ROW WHEN OLD.cloud_id IS NOT NULL" + + " AND new.date_modified = old.date_modified AND old.dirty = " + + std::to_string(static_cast(DirtyTypes::TYPE_SYNCED)) + + " AND new.dirty = old.dirty" + + " BEGIN " + + " UPDATE " + PhotoColumn::PHOTOS_TABLE + " SET dirty = " + + std::to_string(static_cast(DirtyTypes::TYPE_MDIRTY)) + + " WHERE file_id = old.file_id;" + + " END;"; + const std::set PhotoColumn::PHOTO_COLUMNS = { PhotoColumn::PHOTO_ORIENTATION, PhotoColumn::PHOTO_LATITUDE, PhotoColumn::PHOTO_LONGITUDE, PhotoColumn::PHOTO_LCD, PhotoColumn::PHOTO_HEIGHT, PhotoColumn::PHOTO_WIDTH, PhotoColumn::PHOTO_LCD_VISIT_TIME, PhotoColumn::PHOTO_POSITION, diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn b/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn index a35e047ba23d6b430c57f4894259eecf0680807f..bf31dd2f22d47802a986af172fb9638837039064 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn @@ -149,6 +149,7 @@ ohos_shared_library("medialibrary_data_extension") { public_configs = [ ":media_data_extension_public_config" ] deps = [ + "${MEDIALIB_CLOUD_SYNC_PATH}:cloud_sync", "${MEDIALIB_INNERKITS_PATH}/media_library_helper:media_library", "${MEDIALIB_SERVICES_PATH}/media_async_worker:medialibrary_async_worker", "${MEDIALIB_SERVICES_PATH}/media_thumbnail:medialibrary_thumbnail", @@ -156,6 +157,8 @@ ohos_shared_library("medialibrary_data_extension") { "${MEDIALIB_UTILS_PATH}:permission_utils", ] + include_dirs = [ "${MEDIALIB_CLOUD_SYNC_PATH}/include" ] + external_deps = [ "ability_base:want", "ability_base:zuri", @@ -171,6 +174,7 @@ ohos_shared_library("medialibrary_data_extension") { "device_auth:deviceauth_sdk", "device_manager:devicemanagersdk", "device_security_level:dslm_sdk", + "dfs_service:cloudsync_kit_inner", "eventhandler:libeventhandler", "hitrace_native:hitrace_meter", "hiviewdfx_hilog_native:libhilog", diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_rdbstore.cpp b/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_rdbstore.cpp index b606fef5b688971b858a30c00b309f4ec7543206..13d52244d8163ea68e07137287967fa481eebdf9 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_rdbstore.cpp +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_rdbstore.cpp @@ -26,6 +26,7 @@ #include "sqlite_database_utils.h" #include "sqlite_sql_builder.h" #include "sqlite_utils.h" +#include "cloud_sync_helper.h" using namespace std; using namespace OHOS::NativeRdb; @@ -173,9 +174,17 @@ int32_t MediaLibraryRdbStore::Delete(MediaLibraryCommand &cmd, int32_t &deletedR MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully."); return E_HAS_DB_ERROR; } - - int32_t ret = rdbStore_->Delete(deletedRows, cmd.GetTableName(), cmd.GetAbsRdbPredicates()->GetWhereClause(), - cmd.GetAbsRdbPredicates()->GetWhereArgs()); + int32_t ret = NativeRdb::E_ERROR; + if (cmd.GetTableName() == MEDIALIBRARY_TABLE || cmd.GetTableName() == PhotoColumn::PHOTOS_TABLE) { + ValuesBucket valuesBucket; + valuesBucket.PutInt(MEDIA_DATA_DB_DIRTY, static_cast(DirtyType::TYPE_DELETED)); + ret = rdbStore_->Update(deletedRows, cmd.GetTableName(), valuesBucket, + cmd.GetAbsRdbPredicates()->GetWhereClause(), cmd.GetAbsRdbPredicates()->GetWhereArgs()); + CloudSyncHelper::GetInstance()->StartSync(); + } else { + ret = rdbStore_->Delete(deletedRows, cmd.GetTableName(), cmd.GetAbsRdbPredicates()->GetWhereClause(), + cmd.GetAbsRdbPredicates()->GetWhereArgs()); + } if (ret != NativeRdb::E_OK) { MEDIA_ERR_LOG("rdbStore_->Delete failed, ret = %{public}d", ret); return E_HAS_DB_ERROR; @@ -205,7 +214,7 @@ int32_t MediaLibraryRdbStore::Update(MediaLibraryCommand &cmd, int32_t &changedR vector devices = vector(); GetAllNetworkId(devices); SyncPushTable(bundleName_, cmd.GetTableName(), changedRows, devices); - + CloudSyncHelper::GetInstance()->StartSync(); return ret; } @@ -216,7 +225,17 @@ shared_ptr MediaLibraryRdbStore::Query(MediaLibraryCommand MEDIA_ERR_LOG("rdbStore_ is nullptr"); return nullptr; } - + if (cmd.GetTableName() == MEDIALIBRARY_TABLE || cmd.GetTableName() == PhotoColumn::PHOTOS_TABLE) { + string strQueryCondition = cmd.GetAbsRdbPredicates()->GetWhereClause(); + string dirtyFilterCondition = "dirty <> " + std::to_string(static_cast(DirtyType::TYPE_DELETED)); + if (!strQueryCondition.empty()) { + dirtyFilterCondition += " AND "; + strQueryCondition = dirtyFilterCondition + strQueryCondition; + } else { + strQueryCondition = dirtyFilterCondition; + } + cmd.GetAbsRdbPredicates()->SetWhereClause(strQueryCondition); + } auto *predicates = cmd.GetAbsRdbPredicates(); #ifdef ML_DEBUG MEDIA_DEBUG_LOG("tablename = %s", cmd.GetTableName().c_str()); @@ -312,9 +331,17 @@ int32_t MediaLibraryRdbStore::Delete(const AbsRdbPredicates &predicates) MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully."); return E_HAS_DB_ERROR; } - + int err = E_ERR; int32_t deletedRows = 0; - int err = rdbStore_->Delete(deletedRows, predicates); + if (predicates.GetTableName() == MEDIALIBRARY_TABLE || predicates.GetTableName() == PhotoColumn::PHOTOS_TABLE) { + ValuesBucket valuesBucket; + valuesBucket.PutInt(MEDIA_DATA_DB_DIRTY, static_cast(DirtyType::TYPE_DELETED)); + err = rdbStore_->Update(deletedRows, valuesBucket, predicates); + CloudSyncHelper::GetInstance()->StartSync(); + } else { + err = rdbStore_->Delete(deletedRows, predicates); + } + if (err != E_OK) { MEDIA_ERR_LOG("Failed to execute delete, err: %{public}d", err); return E_HAS_DB_ERROR; @@ -338,6 +365,7 @@ int32_t MediaLibraryRdbStore::Update(int32_t &changedRows, const ValuesBucket &v MEDIA_ERR_LOG("Failed to execute update, err: %{public}d", err); return E_HAS_DB_ERROR; } + CloudSyncHelper::GetInstance()->StartSync(); return changedRows; } @@ -669,6 +697,9 @@ int32_t MediaLibraryDataCallBack::OnCreate(RdbStore &store) vector executeSqlStrs = { CREATE_MEDIA_TABLE, PhotoColumn::CREATE_PHOTO_TABLE, + PhotoColumn::CREATE_PHOTOS_DELETE_TRIGGER, + PhotoColumn::CREATE_PHOTOS_FDIRTY_TRIGGER, + PhotoColumn::CREATE_PHOTOS_MDIRTY_TRIGGER, AudioColumn::CREATE_AUDIO_TABLE, DocumentColumn::CREATE_DOCUMENT_TABLE, CREATE_SMARTALBUM_TABLE, @@ -686,6 +717,9 @@ int32_t MediaLibraryDataCallBack::OnCreate(RdbStore &store) CREATE_BUNDLE_PREMISSION_TABLE, CREATE_MEDIALIBRARY_ERROR_TABLE, CREATE_REMOTE_THUMBNAIL_TABLE, + CREATE_FILES_DELETE_TRIGGER, + CREATE_FILES_MDIRTY_TRIGGER, + CREATE_FILES_FDIRTY_TRIGGER, PhotoAlbumColumns::CREATE_TABLE, PhotoAlbumColumns::INDEX_ALBUM_TYPES, PhotoMap::CREATE_TABLE, diff --git a/interfaces/inner_api/media_library_helper/include/media_column.h b/interfaces/inner_api/media_library_helper/include/media_column.h index 37a9c622f7d0a42ac025947e43bda628cc08e993..e61297516dd3c3437ba3f7ed77312a6ce6c39be1 100644 --- a/interfaces/inner_api/media_library_helper/include/media_column.h +++ b/interfaces/inner_api/media_library_helper/include/media_column.h @@ -21,6 +21,15 @@ namespace OHOS::Media { +enum class DirtyTypes : int32_t { + TYPE_SYNCED, + TYPE_NEW, + TYPE_MDIRTY, + TYPE_FDIRTY, + TYPE_DELETED, + TYPE_RETRY +}; + class MediaColumn { public: // Asset Base Parameter @@ -77,6 +86,11 @@ public: // create PhotoTable sql static const std::string CREATE_PHOTO_TABLE; + // create Photo cloud sync trigger + static const std::string CREATE_PHOTOS_DELETE_TRIGGER; + static const std::string CREATE_PHOTOS_FDIRTY_TRIGGER; + static const std::string CREATE_PHOTOS_MDIRTY_TRIGGER; + // photo uri static const std::string PHOTO_URI_PREFIX; static const std::string PHOTO_TYPE_URI; diff --git a/interfaces/inner_api/media_library_helper/include/medialibrary_db_const.h b/interfaces/inner_api/media_library_helper/include/medialibrary_db_const.h index 92031a9be2370e30f3ad530dcf754327fa363eed..88823937a8421e3566ab3d0374b713ba9fbe466e 100644 --- a/interfaces/inner_api/media_library_helper/include/medialibrary_db_const.h +++ b/interfaces/inner_api/media_library_helper/include/medialibrary_db_const.h @@ -449,6 +449,34 @@ const std::string QUERY_MEDIA_VOLUME = "SELECT sum(" + MEDIA_DATA_DB_SIZE + ") A MEDIA_DATA_DB_MEDIA_TYPE + " = " + std::to_string(MEDIA_TYPE_AUDIO) + " GROUP BY " + MEDIA_DATA_DB_MEDIA_TYPE; +const std::string CREATE_FILES_DELETE_TRIGGER = "CREATE TRIGGER delete_trigger AFTER UPDATE ON " + + MEDIALIBRARY_TABLE + " FOR EACH ROW WHEN new.dirty = " + + std::to_string(static_cast(DirtyType::TYPE_DELETED)) + + " and OLD.cloud_id is NULL " + + " BEGIN " + + " DELETE FROM " + MEDIALIBRARY_TABLE + " WHERE file_id = old.file_id;" + + " END;"; + +const std::string CREATE_FILES_FDIRTY_TRIGGER = "CREATE TRIGGER fdirty_trigger AFTER UPDATE ON " + + MEDIALIBRARY_TABLE + " FOR EACH ROW WHEN OLD.cloud_id IS NOT NULL AND" + + " new.date_modified <> old.date_modified " + + " BEGIN " + + " UPDATE " + MEDIALIBRARY_TABLE + " SET dirty = " + + std::to_string(static_cast(DirtyType::TYPE_FDIRTY)) + + " WHERE file_id = old.file_id;" + + " END;"; + +const std::string CREATE_FILES_MDIRTY_TRIGGER = "CREATE TRIGGER mdirty_trigger AFTER UPDATE ON " + + MEDIALIBRARY_TABLE + " FOR EACH ROW WHEN OLD.cloud_id IS NOT NULL" + + " AND new.date_modified = old.date_modified AND old.dirty = " + + std::to_string(static_cast(DirtyType::TYPE_SYNCED)) + + " AND new.dirty = old.dirty" + + " BEGIN " + + " UPDATE " + MEDIALIBRARY_TABLE + " SET dirty = " + + std::to_string(static_cast(DirtyType::TYPE_MDIRTY)) + + " WHERE file_id = old.file_id;" + + " END;"; + /* * Error Table */