diff --git a/frameworks/libs/distributeddb/common/include/db_common.h b/frameworks/libs/distributeddb/common/include/db_common.h index c43981059ebe737f0813b855f8228775b63971c8..242f23a2fd2177a43379c5c671b740e44f3aaa48 100644 --- a/frameworks/libs/distributeddb/common/include/db_common.h +++ b/frameworks/libs/distributeddb/common/include/db_common.h @@ -58,7 +58,8 @@ public: static std::string StringMasking(const std::string &oriStr, size_t remain = 3); // remain 3 unmask - static std::string GetDistributedTableName(const std::string &device, const std::string &tableName); + static std::string GetDistributedTableName(const std::string &device, const std::string &tableName, + const std::string &appId = "", bool useOriDev = false); static void GetDeviceFromName(const std::string &deviceTableName, std::string &deviceHash, std::string &tableName); diff --git a/frameworks/libs/distributeddb/common/include/db_constant.h b/frameworks/libs/distributeddb/common/include/db_constant.h index 928a08655105c6315c9eea4c8cce428fb7881f42..e593bd3feab17e0d9a923e55c2ebf5e36b9f326d 100644 --- a/frameworks/libs/distributeddb/common/include/db_constant.h +++ b/frameworks/libs/distributeddb/common/include/db_constant.h @@ -159,6 +159,8 @@ public: static constexpr uint32_t MAX_CONDITION_COUNT = 32; static constexpr uint32_t REMOTE_QUERY_MAX_SQL_LEN = 1000000U; + + static constexpr int HASH_KEY_SIZE = 32; // size of SHA256_DIGEST_LENGTH }; } // namespace DistributedDB #endif // DISTRIBUTEDDB_CONSTANT_H diff --git a/frameworks/libs/distributeddb/common/include/runtime_context.h b/frameworks/libs/distributeddb/common/include/runtime_context.h index 856c5b31d8a09a284f806dc1356d8dbf79adb08d..e3218ef2855ccde54bb794803fd6255864d1f677 100644 --- a/frameworks/libs/distributeddb/common/include/runtime_context.h +++ b/frameworks/libs/distributeddb/common/include/runtime_context.h @@ -141,6 +141,13 @@ public: virtual void StopTaskPool() = 0; virtual void StopTimeTickMonitorIfNeed() = 0; + + virtual void SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback) = 0; + + virtual int TranslateDeviceId(const std::string &deviceId, + const std::string &appId, std::string &newDeviceId) = 0; + + virtual bool ExistTranslateDevIdCallback() const = 0; protected: RuntimeContext() = default; virtual ~RuntimeContext() {} diff --git a/frameworks/libs/distributeddb/common/src/db_common.cpp b/frameworks/libs/distributeddb/common/src/db_common.cpp index 74bf012ffaf9064336b1b15c1bf5cd472689ffbf..42b6a0269a6dabd546ea5c46059857945710b54c 100644 --- a/frameworks/libs/distributeddb/common/src/db_common.cpp +++ b/frameworks/libs/distributeddb/common/src/db_common.cpp @@ -21,6 +21,7 @@ #include "db_errno.h" #include "platform_specific.h" #include "hash.h" +#include "runtime_context.h" #include "value_hash_calc.h" namespace DistributedDB { @@ -320,9 +321,18 @@ std::string DBCommon::StringMasking(const std::string &oriStr, size_t remain) return oriStr; } -std::string DBCommon::GetDistributedTableName(const std::string &device, const std::string &tableName) +std::string DBCommon::GetDistributedTableName(const std::string &device, const std::string &tableName, + const std::string &appId, bool useOriDev) { - std::string deviceHashHex = DBCommon::TransferStringToHex(DBCommon::TransferHashString(device)); + std::string deviceHashHex; + std::string newDeviceId; + if (useOriDev && RuntimeContext::GetInstance()->ExistTranslateDevIdCallback()) { + deviceHashHex = device; + } else if (appId.empty() || RuntimeContext::GetInstance()->TranslateDeviceId(device, appId, newDeviceId) != E_OK) { + deviceHashHex = DBCommon::TransferStringToHex(DBCommon::TransferHashString(device)); + } else { + deviceHashHex = newDeviceId; + } return DBConstant::RELATIONAL_PREFIX + tableName + "_" + deviceHashHex; } diff --git a/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp b/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp index 9fe505aa41dd5af6ae16ea68e7ec21f56e917241..c256dff999d64a88ab7349e1ed5e8c12a83a8cf0 100644 --- a/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp +++ b/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp @@ -746,4 +746,32 @@ void RuntimeContextImpl::StopTimeTickMonitorIfNeed() timeTickMonitor_ = nullptr; } } + +void RuntimeContextImpl::SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback) +{ + std::lock_guard autoLock(translateToDeviceIdLock_); + translateToDeviceIdCallback_ = callback; + deviceIdCache_.clear(); +} + +int RuntimeContextImpl::TranslateDeviceId(const std::string &deviceId, + const std::string &appId, std::string &newDeviceId) +{ + std::lock_guard autoLock(translateToDeviceIdLock_); + if (translateToDeviceIdCallback_ == nullptr) { + return -E_NOT_SUPPORT; + } + if (deviceIdCache_.find(deviceId) == deviceIdCache_.end() || + deviceIdCache_[deviceId].find(appId) == deviceIdCache_[deviceId].end()) { + deviceIdCache_[deviceId][appId] = translateToDeviceIdCallback_(deviceId, appId); + } + newDeviceId = deviceIdCache_[deviceId][appId]; + return E_OK; +} + +bool RuntimeContextImpl::ExistTranslateDevIdCallback() const +{ + std::lock_guard autoLock(translateToDeviceIdLock_); + return translateToDeviceIdCallback_ != nullptr; +} } // namespace DistributedDB diff --git a/frameworks/libs/distributeddb/common/src/runtime_context_impl.h b/frameworks/libs/distributeddb/common/src/runtime_context_impl.h index 62b9ce623c790f949af7c6b026006c2e9b50c8c1..bd350aad944a301ad4bb19d1e9887e98f3f46911 100644 --- a/frameworks/libs/distributeddb/common/src/runtime_context_impl.h +++ b/frameworks/libs/distributeddb/common/src/runtime_context_impl.h @@ -130,6 +130,12 @@ public: void StopTimeTickMonitorIfNeed() override; + void SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback) override; + + int TranslateDeviceId(const std::string &deviceId, + const std::string &appId, std::string &newDeviceId) override; + + bool ExistTranslateDevIdCallback() const override; private: static constexpr int MAX_TP_THREADS = 10; // max threads of the task pool. static constexpr int MIN_TP_THREADS = 1; // min threads of the task pool. @@ -192,6 +198,10 @@ private: // Get map from this callback, use for run permission check in remote device mutable std::shared_mutex permissionConditionLock_; PermissionConditionCallback permissionConditionCallback_; + + mutable std::mutex translateToDeviceIdLock_; + TranslateToDeviceIdCallback translateToDeviceIdCallback_; + std::map> deviceIdCache_; // cache > }; } // namespace DistributedDB diff --git a/frameworks/libs/distributeddb/include/types_export.h b/frameworks/libs/distributeddb/include/types_export.h index 95adef5e899bf4cd490bb5625d14b6aaee63837d..ed691127db80e80106743da5b1c0783c5df29971 100644 --- a/frameworks/libs/distributeddb/include/types_export.h +++ b/frameworks/libs/distributeddb/include/types_export.h @@ -206,5 +206,7 @@ enum class CompressAlgorithm : uint8_t { NONE = 0, ZLIB = 1 }; + +using TranslateToDeviceIdCallback = std::function; } // namespace DistributedDB #endif // DISTRIBUTEDDB_TYPES_EXPORT_H diff --git a/frameworks/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h b/frameworks/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h index 21a112187afa4849d6db44b17519a3964384cdab..453aea705e8d1ad7343b1e2f7091a03e2f1af7ba 100644 --- a/frameworks/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h +++ b/frameworks/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h @@ -227,6 +227,9 @@ public: // calculate full sync sync data size after Serialize; // return 1M while sync data size is larger than 1M, otherwise return actualy size DB_API virtual size_t GetSyncDataSize(const std::string &device) const = 0; + + // update all key in sync_data which is not deleted data + DB_API virtual DBStatus UpdateKey(const UpdateKeyCallback &callback) = 0; }; } // namespace DistributedDB diff --git a/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h b/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h index 9bb6f38e5adc133f04e81e764f1dc2ea91911226..3405f055bf5096516f454fcfb0b29be32a295406 100644 --- a/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h +++ b/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h @@ -50,6 +50,9 @@ public: // timeout is in ms. DB_API virtual DBStatus RemoteQuery(const std::string &device, const RemoteCondition &condition, uint64_t timeout, std::shared_ptr &result) = 0; + + // remove all device data + DB_API virtual DBStatus RemoveDeviceData() = 0; }; } // namespace DistributedDB #endif // RELATIONAL_STORE_DELEGATE_H \ No newline at end of file diff --git a/frameworks/libs/distributeddb/interfaces/include/runtime_config.h b/frameworks/libs/distributeddb/interfaces/include/runtime_config.h index 1386e47410a2c220dd423ac0530e390acbc01b23..5bbd98fb13c1b825931285357e0f219f6230f8a4 100644 --- a/frameworks/libs/distributeddb/interfaces/include/runtime_config.h +++ b/frameworks/libs/distributeddb/interfaces/include/runtime_config.h @@ -50,6 +50,7 @@ public: DB_API static bool IsProcessSystemApiAdapterValid(); + DB_API static void SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback); private: static std::mutex communicatorMutex_; static std::mutex multiUserMutex_; diff --git a/frameworks/libs/distributeddb/interfaces/include/store_types.h b/frameworks/libs/distributeddb/interfaces/include/store_types.h index 6a73e36c06a5d2e45c741dabe3810c7b21810792..a021d77dbb5ebb5dd06d4588dde39892a3ececba 100644 --- a/frameworks/libs/distributeddb/interfaces/include/store_types.h +++ b/frameworks/libs/distributeddb/interfaces/include/store_types.h @@ -129,5 +129,7 @@ struct RemoteCondition { std::string sql; // The sql statement; std::vector bindArgs; // The bind args. }; + +using UpdateKeyCallback = std::function; } // namespace DistributedDB #endif // KV_STORE_TYPE_H diff --git a/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp b/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp index 4f45317896c7ecaebd90eb8436f11ea3c94c3c02..054e16b66c61b2567a836fb57a6d683c6996bde1 100644 --- a/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp +++ b/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp @@ -974,4 +974,21 @@ size_t KvStoreNbDelegateImpl::GetSyncDataSize(const std::string &device) const } return size; } + +DBStatus KvStoreNbDelegateImpl::UpdateKey(const UpdateKeyCallback &callback) +{ + if (conn_ == nullptr) { + LOGE("%s", INVALID_CONNECTION); + return DB_ERROR; + } + if (callback == nullptr) { + return INVALID_ARGS; + } + int errCode = conn_->UpdateKey(callback); + if (errCode == E_OK) { + return OK; + } + LOGW("[KvStoreNbDelegate] update keys failed:%d", errCode); + return TransferDBErrno(errCode); +} } // namespace DistributedDB diff --git a/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.h b/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.h index 7ca51a31e59980327498285ae4c00f0306cb3011..24d7c5d8923dc4cd1e30a20ed3203e0986f1e812 100644 --- a/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.h +++ b/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.h @@ -156,6 +156,8 @@ public: size_t GetSyncDataSize(const std::string &device) const override; + // update all key in sync_data which is not deleted data + DBStatus UpdateKey(const UpdateKeyCallback &callback) override; private: DBStatus GetInner(const IOption &option, const Key &key, Value &value) const; DBStatus PutInner(const IOption &option, const Key &key, const Value &value); diff --git a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp index 714364dac3e3f551f568e7307647659cf5fd27fa..02a18d3daa43e5827ea4150019b5bb7f2db54d54 100644 --- a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp +++ b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp @@ -160,5 +160,20 @@ DBStatus RelationalStoreDelegateImpl::RemoteQuery(const std::string &device, con } return OK; } + +DBStatus RelationalStoreDelegateImpl::RemoveDeviceData() +{ + if (conn_ == nullptr) { + LOGE("Invalid connection for operation!"); + return DB_ERROR; + } + + int errCode = conn_->RemoveDeviceData(); + if (errCode != E_OK) { + LOGW("[RelationalStore Delegate] remove device data failed:%d", errCode); + return TransferDBErrno(errCode); + } + return OK; +} } // namespace DistributedDB #endif \ No newline at end of file diff --git a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h index 508bd94540bd3cc612a51d610f389da3e6d83e60..a5a2a7373fcbf3ceecbf51859a753fbb4072e566 100644 --- a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h +++ b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h @@ -46,6 +46,8 @@ public: DBStatus RemoteQuery(const std::string &device, const RemoteCondition &condition, uint64_t timeout, std::shared_ptr &result) override; + DBStatus RemoveDeviceData() override; + private: static void OnSyncComplete(const std::map> &devicesStatus, const SyncStatusCallback &onComplete); diff --git a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp index 84ca3ba52802bd3c2105709ddab5e5f3296c397d..63e91ffeb31e56db1d8286565e010b0bdfedd969 100644 --- a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp +++ b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp @@ -136,7 +136,7 @@ std::string RelationalStoreManager::GetDistributedTableName(const std::string &d if (device.empty() || tableName.empty()) { return {}; } - return DBCommon::GetDistributedTableName(device, tableName); + return DBCommon::GetDistributedTableName(device, tableName, "", true); } void RelationalStoreManager::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback) diff --git a/frameworks/libs/distributeddb/interfaces/src/runtime_config.cpp b/frameworks/libs/distributeddb/interfaces/src/runtime_config.cpp index 1dbabc517ce0724c432cb55d1798f5bf1ef2a2bd..d55b996e4551b80903079a302f19c64c956c5c66 100644 --- a/frameworks/libs/distributeddb/interfaces/src/runtime_config.cpp +++ b/frameworks/libs/distributeddb/interfaces/src/runtime_config.cpp @@ -128,5 +128,10 @@ DBStatus RuntimeConfig::SetPermissionConditionCallback(const PermissionCondition int errCode = RuntimeContext::GetInstance()->SetPermissionConditionCallback(callback); return TransferDBErrno(errCode); } + +void RuntimeConfig::SetTranslateToDeviceIdCallback(const DistributedDB::TranslateToDeviceIdCallback &callback) +{ + RuntimeContext::GetInstance()->SetTranslateToDeviceIdCallback(callback); +} } // namespace DistributedDB #endif \ No newline at end of file diff --git a/frameworks/libs/distributeddb/storage/include/ikvdb_connection.h b/frameworks/libs/distributeddb/storage/include/ikvdb_connection.h index 8cfebe8f0402977c7f02edb0a5536968de4350d0..eec37ba70d14b129cb7644af9931d64db2f23eaf 100644 --- a/frameworks/libs/distributeddb/storage/include/ikvdb_connection.h +++ b/frameworks/libs/distributeddb/storage/include/ikvdb_connection.h @@ -131,6 +131,8 @@ public: virtual int GetKeys(const IOption &option, const Key &keyPrefix, std::vector &keys) const = 0; virtual int GetSyncDataSize(const std::string &device, size_t &size) const = 0; + + virtual int UpdateKey(const UpdateKeyCallback &callback) = 0; }; } // namespace DistributedDB diff --git a/frameworks/libs/distributeddb/storage/include/relational_store_connection.h b/frameworks/libs/distributeddb/storage/include/relational_store_connection.h index 202b5f52debdf637f1a2be9b1207bff4cdf7f913..bd48de49e6761947474bb4a99d75ef0390997ad6 100644 --- a/frameworks/libs/distributeddb/storage/include/relational_store_connection.h +++ b/frameworks/libs/distributeddb/storage/include/relational_store_connection.h @@ -53,6 +53,7 @@ public: virtual int CreateDistributedTable(const std::string &tableName) = 0; virtual int RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier ¬ifier) = 0; + virtual int RemoveDeviceData() = 0; virtual int RemoveDeviceData(const std::string &device) = 0; virtual int RemoveDeviceData(const std::string &device, const std::string &tableName) = 0; virtual void RegisterObserverAction(const RelationalObserverAction &action) = 0; diff --git a/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.cpp b/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.cpp index 7e6047d1a3363da37f5c7ee9eb769cf2c36db1f8..9bd0b60c3c11573350d6cf6baa2f244ace65e02b 100644 --- a/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.cpp +++ b/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.cpp @@ -356,4 +356,9 @@ int GenericKvDBConnection::GetSyncDataSize(const std::string &device, size_t &si { return -E_NOT_SUPPORT; } + +int GenericKvDBConnection::UpdateKey(const UpdateKeyCallback &callback) +{ + return -E_NOT_SUPPORT; +} } \ No newline at end of file diff --git a/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.h b/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.h index d99aa4d6d42bd741dd246bc3a7a639fc90ac38e4..09c1088bf01cc292dbd629c35a767a6017c0713e 100644 --- a/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.h +++ b/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.h @@ -78,6 +78,8 @@ public: int GetKeys(const IOption &option, const Key &keyPrefix, std::vector &keys) const override; int GetSyncDataSize(const std::string &device, size_t &size) const override; + + int UpdateKey(const UpdateKeyCallback &callback) override; protected: // Get the stashed 'KvDB_ pointer' without ref. template diff --git a/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp b/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp index 7b6be36816a16d80695449dce5b9e72571abe361..88f93cbfa6750e97627a7224dd48699cf9dbe02a 100644 --- a/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp +++ b/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp @@ -478,8 +478,10 @@ int RelationalSyncAbleStorage::SaveSyncDataItems(const QueryObject &object, std: return errCode; } + const auto &appId = storageEngine_->GetProperties().GetStringProp(DBProperties::APP_ID, ""); auto inserter = RelationalSyncDataInserter::CreateInserter(deviceName, query, storageEngine_->GetSchema(), - remoteSchema.GetTable(query.GetTableName()).GetFieldInfos(), dataItems); + remoteSchema.GetTable(query.GetTableName()).GetFieldInfos(), appId); + inserter.SetEntries(dataItems); auto *handle = GetHandle(true, errCode, OperatePerm::NORMAL_PERM); if (handle == nullptr) { @@ -604,12 +606,13 @@ int RelationalSyncAbleStorage::CreateDistributedDeviceTable(const std::string &d return errCode; } + auto appId = storageEngine_->GetProperties().GetStringProp(DBProperties::APP_ID, ""); for (const auto &[table, strategy] : syncStrategy) { if (!strategy.permitSync) { continue; } - errCode = handle->CreateDistributedDeviceTable(device, storageEngine_->GetSchema().GetTable(table)); + errCode = handle->CreateDistributedDeviceTable(device, storageEngine_->GetSchema().GetTable(table), appId); if (errCode != E_OK) { LOGE("Create distributed device table failed. %d", errCode); break; diff --git a/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp b/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp index aeebb9fe3a3bd65e3fa4438d19adeff4e8f03db2..d732ee3c466112ccd771fd8bf5bb5e44b0ba8ada 100644 --- a/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp +++ b/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp @@ -50,11 +50,10 @@ RelationalSyncDataInserter::~RelationalSyncDataInserter() RelationalSyncDataInserter RelationalSyncDataInserter::CreateInserter(const std::string &deviceName, const QueryObject &query, const RelationalSchemaObject &localSchema, const std::vector &remoteFields, - const std::vector &entries) + const std::string &appId) { RelationalSyncDataInserter inserter; inserter.SetDeviceId(deviceName); - inserter.SetEntries(entries); inserter.SetRemoteFields(remoteFields); inserter.SetQuery(query); TableInfo localTable = localSchema.GetTable(query.GetTableName()); @@ -63,7 +62,7 @@ RelationalSyncDataInserter RelationalSyncDataInserter::CreateInserter(const std: if (localSchema.GetTableMode() == DistributedTableMode::COLLABORATION) { inserter.SetInsertTableName(localTable.GetTableName()); } else { - inserter.SetInsertTableName(DBCommon::GetDistributedTableName(deviceName, localTable.GetTableName())); + inserter.SetInsertTableName(DBCommon::GetDistributedTableName(deviceName, localTable.GetTableName(), appId)); } return inserter; } @@ -208,14 +207,15 @@ int RelationalSyncDataInserter::GetDeleteSyncDataStmt(sqlite3 *db, sqlite3_stmt int RelationalSyncDataInserter::GetSaveLogStatement(sqlite3 *db, sqlite3_stmt *&logStmt, sqlite3_stmt *&queryStmt) { - std::string devName = DBCommon::TransferHashString(deviceId_); + std::string devName = DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceId_)); const std::string tableName = DBConstant::RELATIONAL_PREFIX + query_.GetTableName() + "_log"; - std::string dataFormat = "?, '" + deviceId_ + "', ?, ?, ?, ?, ?"; + std::string dataFormat = "?, '" + devName + "', ?, ?, ?, ?, ?"; std::string columnList = "data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key"; std::string sql = "INSERT OR REPLACE INTO " + tableName + " (" + columnList + ") VALUES (" + dataFormat + ");"; int errCode = SQLiteUtils::GetStatement(db, sql, logStmt); if (errCode != E_OK) { + LOGD("sql is %s", sql.c_str()); LOGE("[info statement] Get log statement fail! errCode:%d", errCode); return errCode; } @@ -250,8 +250,9 @@ int RelationalSyncDataInserter::PrepareStatement(sqlite3 *db, SaveSyncDataStmt & int RelationalSyncDataInserter::Iterate(const std::function &saveSyncDataItem) { int errCode = E_OK; + std::string devName = DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceId_)); for (auto &it : entries_) { - it.dev = deviceId_; + it.dev = devName; errCode = saveSyncDataItem(it); if (errCode != E_OK) { LOGE("Save sync data item failed. err=%d", errCode); diff --git a/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.h b/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.h index 0a9bb827492c030c7bcf694c91574e7222575600..b45151f85f2aabbc01f4ae3a68e09c221246a20f 100644 --- a/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.h +++ b/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.h @@ -45,7 +45,7 @@ public: static RelationalSyncDataInserter CreateInserter(const std::string &deviceName, const QueryObject &query, const RelationalSchemaObject &localSchema, const std::vector &remoteFields, - const std::vector &entries); + const std::string &appId); void SetDeviceId(std::string deviceId); // Set remote fields in cid order diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp index 288d5443677c366de9a702d17f1e4315be0b6e00..b61611186e017776a4f8f1c2556f0f1f4c79ef22 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp @@ -431,6 +431,60 @@ int SQLiteRelationalStore::CreateDistributedTable(const std::string &tableName) return errCode; } +int SQLiteRelationalStore::RemoveDeviceData() +{ + auto mode = static_cast(sqliteStorageEngine_->GetProperties().GetIntProp( + RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE)); + if (mode == DistributedTableMode::COLLABORATION) { + LOGE("Not support remove device data in collaboration mode."); + return -E_NOT_SUPPORT; + } + + TableInfoMap tables = sqliteStorageEngine_->GetSchema().GetTables(); // TableInfoMap + if (tables.empty()) { + return E_OK; + } + + int errCode = E_OK; + auto *handle = GetHandle(true, errCode); + if (handle == nullptr) { + return errCode; + } + + errCode = handle->StartTransaction(TransactType::IMMEDIATE); + if (errCode != E_OK) { + ReleaseHandle(handle); + return errCode; + } + + std::vector tableNameList; + for (const auto &table: tables) { + errCode = handle->DeleteDistributedDeviceTable("", table.second.GetTableName()); + if (errCode != E_OK) { + LOGE("delete device data failed. %d", errCode); + break; + } + + errCode = handle->DeleteDistributedAllDeviceTableLog(table.second.GetTableName()); + if (errCode != E_OK) { + LOGE("delete device data failed. %d", errCode); + break; + } + tableNameList.push_back(table.second.GetTableName()); + } + + if (errCode != E_OK) { + (void)handle->Rollback(); + ReleaseHandle(handle); + return errCode; + } + + errCode = handle->Commit(); + ReleaseHandle(handle); + storageEngine_->NotifySchemaChanged(); + return EraseAllDeviceWatermark(tableNameList); +} + int SQLiteRelationalStore::RemoveDeviceData(const std::string &device, const std::string &tableName) { auto mode = static_cast(sqliteStorageEngine_->GetProperties().GetIntProp( @@ -458,7 +512,13 @@ int SQLiteRelationalStore::RemoveDeviceData(const std::string &device, const std return errCode; } - errCode = handle->DeleteDistributedDeviceTable(device, tableName); + const auto &appId = sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::APP_ID, ""); + std::string devTableName; + std::string hashDev = DBCommon::TransferStringToHex(DBCommon::TransferHashString(device)); + if (RuntimeContext::GetInstance()->TranslateDeviceId(device, appId, devTableName) != E_OK) { + devTableName = hashDev; + } + errCode = handle->DeleteDistributedDeviceTable(devTableName, tableName); if (errCode != E_OK) { LOGE("delete device data failed. %d", errCode); goto END; @@ -466,7 +526,7 @@ int SQLiteRelationalStore::RemoveDeviceData(const std::string &device, const std for (const auto &it : tables) { if (tableName.empty() || it.second.GetTableName() == tableName) { - errCode = handle->DeleteDistributedDeviceTableLog(device, it.second.GetTableName()); + errCode = handle->DeleteDistributedDeviceTableLog(hashDev, it.second.GetTableName()); if (errCode != E_OK) { LOGE("delete device data failed. %d", errCode); break; @@ -673,5 +733,30 @@ int SQLiteRelationalStore::RemoteQuery(const std::string &device, const RemoteCo return syncAbleEngine_->RemoteQuery(device, condition, timeout, connectionId, result); } + +int SQLiteRelationalStore::EraseAllDeviceWatermark(const std::vector &tableNameList) +{ + int errCode = E_OK; + auto *handle = GetHandle(true, errCode); + if (handle == nullptr) { + LOGE("[SingleVerRDBStore] GetExistsDeviceList get handle failed:%d", errCode); + return errCode; + } + std::set devices; + errCode = handle->GetExistsDeviceList(devices); + if (errCode != E_OK) { + LOGE("[SingleVerRDBStore] Get remove device list from meta failed. err=%d", errCode); + } + ReleaseHandle(handle); + for (const auto &tableName: tableNameList) { + for (const auto &device: devices) { + errCode = syncAbleEngine_->EraseDeviceWaterMark(device, false, tableName); + if (errCode != E_OK) { + return errCode; + } + } + } + return errCode; +} } #endif \ No newline at end of file diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h index 216b0ad26edc82ea08330c3ddd11054c27d078e7..4f9994eac1ca370052994e9d4941bc2b273d87b6 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h @@ -58,6 +58,7 @@ public: int CreateDistributedTable(const std::string &tableName); + int RemoveDeviceData(); int RemoveDeviceData(const std::string &device, const std::string &tableName); void RegisterObserverAction(const RelationalObserverAction &action); @@ -98,6 +99,8 @@ private: void IncreaseConnectionCounter(); int InitStorageEngine(const RelationalDBProperties &kvDBProp); + int EraseAllDeviceWatermark(const std::vector &tableNameList); + // use for sync Interactive std::unique_ptr syncAbleEngine_ = nullptr; // For storage operate sync function // use ref obj same as kv diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp index 86e72eed861431787f77a251443ed14c90c9dcbd..57fb3c36ea20d1ef70e12971af946424e93119c3 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp @@ -156,6 +156,21 @@ int SQLiteRelationalStoreConnection::CreateDistributedTable(const std::string &t return errCode; } +int SQLiteRelationalStoreConnection::RemoveDeviceData() +{ + auto *store = GetDB(); + if (store == nullptr) { + LOGE("[RelationalConnection] store is null, get DB failed!"); + return -E_INVALID_CONNECTION; + } + + int errCode = store->RemoveDeviceData(); + if (errCode != E_OK) { + LOGE("[RelationalConnection] remove device data failed. %d", errCode); + } + return errCode; +} + int SQLiteRelationalStoreConnection::RemoveDeviceData(const std::string &device) { return RemoveDeviceData(device, {}); diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h index 3c51d21de0b4b2eb3edd81cc23922c9514c67181..0c85ca89c4ba3ef5b8636cd22d4f097afe0a48ad 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h @@ -39,6 +39,7 @@ public: int CreateDistributedTable(const std::string &tableName) override; int RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier ¬ifier) override; + int RemoveDeviceData() override; int RemoveDeviceData(const std::string &device) override; int RemoveDeviceData(const std::string &device, const std::string &tableName) override; void RegisterObserverAction(const RelationalObserverAction &action) override; diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_meta_executor.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_meta_executor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4fb98686cb020a41be42c9776514575819cd7896 --- /dev/null +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_meta_executor.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sqlite_meta_executor.h" + +#include "db_common.h" +#include "db_constant.h" +namespace DistributedDB { +int SqliteMetaExecutor::GetMetaKeysByKeyPrefix(const std::string &keyPre, sqlite3 *dbHandle, MetaMode metaMode, + bool isMemDb, std::set &outKeys) +{ + sqlite3_stmt *statement = nullptr; + std::string sqlStr; + switch (metaMode) { + case MetaMode::KV: + sqlStr = SELECT_META_KEYS_BY_PREFIX; + break; + case MetaMode::KV_ATTACH: + sqlStr = SELECT_ATTACH_META_KEYS_BY_PREFIX; + break; + case MetaMode::RDB: + sqlStr = SELECT_RDB_META_KEYS_BY_PREFIX; + break; + default: + return -E_INVALID_ARGS; + } + int errCode = SQLiteUtils::GetStatement(dbHandle, sqlStr, statement); + if (errCode != E_OK) { + LOGE("[SqliteMetaExecutor] Get statement failed:%d", errCode); + return errCode; + } + + Key keyPrefix; + DBCommon::StringToVector(keyPre + '%', keyPrefix); + errCode = SQLiteUtils::BindBlobToStatement(statement, 1, keyPrefix); // 1: bind index for prefix key + if (errCode != E_OK) { + LOGE("[SqliteMetaExecutor] Bind statement failed:%d", errCode); + SQLiteUtils::ResetStatement(statement, true, errCode); + return errCode; + } + + std::vector keys; + errCode = GetAllKeys(statement, dbHandle, isMemDb, keys); + SQLiteUtils::ResetStatement(statement, true, errCode); + for (const auto &it : keys) { + if (it.size() >= keyPre.size() + DBConstant::HASH_KEY_SIZE) { + outKeys.insert({it.begin() + keyPre.size(), it.begin() + keyPre.size() + DBConstant::HASH_KEY_SIZE}); + } else { + LOGW("[SqliteMetaExecutor] Get invalid key, size=%zu", it.size()); + } + } + return errCode; +} + +int SqliteMetaExecutor::GetAllKeys(sqlite3_stmt *statement, sqlite3 *dbHandle, bool isMemDb, std::vector &keys) +{ + if (statement == nullptr) { + return -E_INVALID_DB; + } + int errCode; + do { + errCode = SQLiteUtils::StepWithRetry(statement, isMemDb); + if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { + Key key; + errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, key); + if (errCode != E_OK) { + break; + } + + keys.push_back(std::move(key)); + } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { + errCode = E_OK; + break; + } else { + LOGE("SQLite step for getting all keys failed:%d", errCode); + break; + } + } while (true); + return errCode; +} + +int SqliteMetaExecutor::GetExistsDevicesFromMeta(sqlite3 *dbHandle, MetaMode metaMode, + bool isMemDb, std::set &devices) +{ + int errCode = GetMetaKeysByKeyPrefix(DBConstant::DEVICEID_PREFIX_KEY, dbHandle, metaMode, isMemDb, devices); + if (errCode != E_OK) { + LOGE("Get meta data key failed. err=%d", errCode); + return errCode; + } + errCode = GetMetaKeysByKeyPrefix(DBConstant::QUERY_SYNC_PREFIX_KEY, dbHandle, metaMode, isMemDb, devices); + if (errCode != E_OK) { + LOGE("Get meta data key failed. err=%d", errCode); + return errCode; + } + errCode = GetMetaKeysByKeyPrefix(DBConstant::DELETE_SYNC_PREFIX_KEY, dbHandle, metaMode, isMemDb, devices); + if (errCode != E_OK) { + LOGE("Get meta data key failed. err=%d", errCode); + } + return errCode; +} +} \ No newline at end of file diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_meta_executor.h b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_meta_executor.h new file mode 100644 index 0000000000000000000000000000000000000000..b8c1bacd453ef25aceef14cc7099dc467c997841 --- /dev/null +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_meta_executor.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SQLITE_META_EXECUTOR_H +#define SQLITE_META_EXECUTOR_H + +#include "sqlite_utils.h" + +namespace DistributedDB { +class SqliteMetaExecutor { +public: + enum class MetaMode { + KV = 0, + KV_ATTACH = 1, + RDB = 2 + }; + static int GetMetaKeysByKeyPrefix(const std::string &keyPre, sqlite3 *dbHandle, MetaMode metaMode, bool isMemDb, + std::set &outKeys); + + static int GetAllKeys(sqlite3_stmt *statement, sqlite3 *dbHandle, bool isMemDb, std::vector &keys); + + static int GetExistsDevicesFromMeta(sqlite3 *dbHandle, MetaMode metaMode, + bool isMemDb, std::set &devices); + + static constexpr const char *SELECT_ATTACH_META_KEYS_BY_PREFIX = + "SELECT key FROM meta.meta_data where key like ?;"; + + static constexpr const char *SELECT_META_KEYS_BY_PREFIX = + "SELECT key FROM meta_data where key like ?;"; + + static constexpr const char *SELECT_RDB_META_KEYS_BY_PREFIX = + "SELECT key FROM naturalbase_rdb_aux_metadata where key like ?;"; +}; +} // DistributedDB +#endif // SQLITE_META_EXECUTOR_H diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp index ca6de67dfc1ccf5f3dc4ce52b71e9c8cbf0dd059..942debdbf32ecbed895e40bf4da45eda649230b6 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp @@ -1833,5 +1833,33 @@ int SQLiteSingleVerNaturalStoreConnection::GetEntriesInner(bool isGetValue, cons return errCode; } +int SQLiteSingleVerNaturalStoreConnection::UpdateKey(const DistributedDB::UpdateKeyCallback &callback) +{ + if (IsExtendedCacheDBMode()) { + LOGE("[Connection] Not support update key in cache mode"); + return -E_NOT_SUPPORT; + } + SingleVerDataType type = SingleVerDataType::SYNC_TYPE; + int errCode = E_OK; + { + std::lock_guard lock(transactionMutex_); + if (writeHandle_ != nullptr) { + LOGD("[Connection] Transaction started already."); + errCode = writeHandle_->UpdateKey(callback); + return errCode; + } + } + + + SQLiteSingleVerStorageExecutor *handle = GetExecutor(true, errCode); + if (handle == nullptr) { + LOGE("[Connection]::[UpdateKey] Get executor failed, errCode = [%d]", errCode); + return errCode; + } + + errCode = handle->UpdateKey(callback); + ReleaseExecutor(handle); + return errCode; +} DEFINE_OBJECT_TAG_FACILITIES(SQLiteSingleVerNaturalStoreConnection) } \ No newline at end of file diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.h b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.h index 84381bfcb90f8669fc9e4a1314c445b8d20fb85f..330876c6a9d706a6e678a516b0858c31da9a7a85 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.h +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.h @@ -107,6 +107,7 @@ public: int GetKeys(const IOption &option, const Key &keyPrefix, std::vector &keys) const override; + int UpdateKey(const UpdateKeyCallback &callback) override; private: int CheckMonoStatus(OperatePerm perm); diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp index 02c5c7a6f1892811624dbaf4a9ce7825b8b62bd2..f7757c17fd6aebd970bdd7c05793385583a3def1 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp @@ -23,6 +23,7 @@ #include "log_table_manager_factory.h" #include "relational_row_data_impl.h" #include "res_finalizer.h" +#include "sqlite_meta_executor.h" #include "sqlite_relational_utils.h" namespace DistributedDB { @@ -210,8 +211,7 @@ int GetDeviceTableName(sqlite3 *handle, const std::string &tableName, const std: if (device.empty() && tableName.empty()) { // device and table name should not both be empty return -E_INVALID_ARGS; } - std::string deviceHash = DBCommon::TransferStringToHex(DBCommon::TransferHashString(device)); - std::string devicePattern = device.empty() ? "%" : deviceHash; + std::string devicePattern = device.empty() ? "%" : device; std::string tablePattern = tableName.empty() ? "%" : tableName; std::string deviceTableName = DBConstant::RELATIONAL_PREFIX + tablePattern + "_" + devicePattern; @@ -1091,6 +1091,12 @@ int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedDeviceTable(const return errCode; } +int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedAllDeviceTableLog(const std::string &tableName) +{ + std::string deleteLogSql = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_log WHERE flag&0x02=0"; + return SQLiteUtils::ExecuteRawSQL(dbHandle_, deleteLogSql); +} + int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedDeviceTableLog(const std::string &device, const std::string &tableName) { @@ -1179,7 +1185,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CheckAndCleanDistributedTable(cons } int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedDeviceTable(const std::string &device, - const TableInfo &baseTbl) + const TableInfo &baseTbl, const std::string &appId) { if (dbHandle_ == nullptr) { return -E_INVALID_DB; @@ -1189,7 +1195,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedDeviceTable(const return -E_INVALID_ARGS; } - std::string deviceTableName = DBCommon::GetDistributedTableName(device, baseTbl.GetTableName()); + std::string deviceTableName = DBCommon::GetDistributedTableName(device, baseTbl.GetTableName(), appId); int errCode = SQLiteUtils::CreateSameStuTable(dbHandle_, baseTbl, deviceTableName); if (errCode != E_OK) { LOGE("Create device table failed. %d", errCode); @@ -1370,5 +1376,11 @@ int SQLiteSingleVerRelationalStorageExecutor::CheckEncryptedOrCorrupted() const } return errCode; } + +int SQLiteSingleVerRelationalStorageExecutor::GetExistsDeviceList(std::set &devices) const +{ + return SqliteMetaExecutor::GetExistsDevicesFromMeta(dbHandle_, SqliteMetaExecutor::MetaMode::RDB, + isMemDb_, devices); +} } // namespace DistributedDB #endif diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h index ecbda6642f94fd71111181e9e566953a3ddf9c42..385ec0f0f89fbb5d986eed711a26ff5e192a081a 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h @@ -64,6 +64,8 @@ public: int DeleteDistributedDeviceTable(const std::string &device, const std::string &tableName); + int DeleteDistributedAllDeviceTableLog(const std::string &tableName); + int DeleteDistributedDeviceTableLog(const std::string &device, const std::string &tableName); int DeleteDistributedLogTable(const std::string &tableName); @@ -71,7 +73,7 @@ public: int CheckAndCleanDistributedTable(const std::vector &tableNames, std::vector &missingTables); - int CreateDistributedDeviceTable(const std::string &device, const TableInfo &baseTbl); + int CreateDistributedDeviceTable(const std::string &device, const TableInfo &baseTbl, const std::string &appId); int CheckQueryObjectLegal(const TableInfo &table, QueryObject &query, const std::string &schemaVersion); @@ -84,6 +86,8 @@ public: int CheckEncryptedOrCorrupted() const; + int GetExistsDeviceList(std::set &devices) const; + private: int GetDataItemForSync(sqlite3_stmt *statement, DataItem &dataItem, bool isGettingDeletedData) const; diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.cpp index d7b1304654a3011cba5294b63607bd3fb42e0af7..26af5942c00b022fbd9fec0de881ab1e6818aaef 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.cpp @@ -24,11 +24,11 @@ #include "parcel.h" #include "platform_specific.h" #include "runtime_context.h" +#include "sqlite_meta_executor.h" #include "sqlite_single_ver_storage_executor_sql.h" namespace DistributedDB { namespace { -const int HASH_KEY_SIZE = 32; // size of SHA256_DIGEST_LENGTH void InitCommitNotifyDataKeyStatus(SingleVerNaturalStoreCommitNotifyData *committedData, const Key &hashKey, const DataOperStatus &dataStatus) @@ -1405,44 +1405,11 @@ int SQLiteSingleVerStorageExecutor::GetAllMetaKeys(std::vector &keys) const return errCode; } - errCode = GetAllKeys(statement, keys); + errCode = SqliteMetaExecutor::GetAllKeys(statement, dbHandle_, isMemDb_, keys); SQLiteUtils::ResetStatement(statement, true, errCode); return errCode; } -int SQLiteSingleVerStorageExecutor::GetMetaKeysByKeyPrefix(const std::string &keyPre, - std::set &outKeys) const -{ - sqlite3_stmt *statement = nullptr; - const std::string &sqlStr = (attachMetaMode_ ? SELECT_ATTACH_META_KEYS_BY_PREFIX : SELECT_META_KEYS_BY_PREFIX); - int errCode = SQLiteUtils::GetStatement(dbHandle_, sqlStr, statement); - if (errCode != E_OK) { - LOGE("[SingleVerExe][GetAllKey] Get statement failed:%d", errCode); - return errCode; - } - - Key keyPrefix; - DBCommon::StringToVector(keyPre + '%', keyPrefix); - errCode = SQLiteUtils::BindBlobToStatement(statement, 1, keyPrefix); // 1: bind index for prefix key - if (errCode != E_OK) { - LOGE("[SingleVerExe][GetAllKey] Bind statement failed:%d", errCode); - SQLiteUtils::ResetStatement(statement, true, errCode); - return errCode; - } - - std::vector keys; - errCode = GetAllKeys(statement, keys); - SQLiteUtils::ResetStatement(statement, true, errCode); - for (const auto &it : keys) { - if (it.size() >= keyPre.size() + HASH_KEY_SIZE) { - outKeys.insert({it.begin() + keyPre.size(), it.begin() + keyPre.size() + HASH_KEY_SIZE}); - } else { - LOGW("[SingleVerExe][GetAllKey] Get invalid key, size=%zu", it.size()); - } - } - return errCode; -} - int SQLiteSingleVerStorageExecutor::GetAllSyncedEntries(const std::string &deviceName, std::vector &entries) const { @@ -1514,34 +1481,6 @@ int SQLiteSingleVerStorageExecutor::GetAllEntries(sqlite3_stmt *statement, std:: return errCode; } -int SQLiteSingleVerStorageExecutor::GetAllKeys(sqlite3_stmt *statement, std::vector &keys) const -{ - if (statement == nullptr) { - return -E_INVALID_DB; - } - int errCode; - do { - errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_); - if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { - Key key; - errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, key); - if (errCode != E_OK) { - break; - } - - keys.push_back(std::move(key)); - } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { - errCode = E_OK; - break; - } else { - LOGE("SQLite step for getting all keys failed:%d", errCode); - break; - } - } while (true); - - return errCode; -} - int SQLiteSingleVerStorageExecutor::BindSavedSyncData(sqlite3_stmt *statement, const DataItem &dataItem, const Key &hashKey, const SyncDataDevices &devices, bool isUpdate) { @@ -2236,20 +2175,90 @@ uint64_t SQLiteSingleVerStorageExecutor::GetLogFileSize() const int SQLiteSingleVerStorageExecutor::GetExistsDevicesFromMeta(std::set &devices) { - int errCode = GetMetaKeysByKeyPrefix(DBConstant::DEVICEID_PREFIX_KEY, devices); + return SqliteMetaExecutor::GetExistsDevicesFromMeta(dbHandle_, + attachMetaMode_ ? SqliteMetaExecutor::MetaMode::KV_ATTACH : SqliteMetaExecutor::MetaMode::KV, + isMemDb_, devices); +} + +int SQLiteSingleVerStorageExecutor::UpdateKey(const UpdateKeyCallback &callback) +{ + if (dbHandle_ == nullptr) { + return -E_INVALID_DB; + } + UpdateContext context; + context.callback = callback; + int errCode = CreateFuncUpdateKey(context, &Translate, &CalHashKey); if (errCode != E_OK) { - LOGE("Get meta data key failed. err=%d", errCode); return errCode; } - errCode = GetMetaKeysByKeyPrefix(DBConstant::QUERY_SYNC_PREFIX_KEY, devices); + int executeErrCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, UPDATE_SYNC_DATA_KEY_SQL); + context.callback = nullptr; + errCode = CreateFuncUpdateKey(context, nullptr, nullptr); + if (executeErrCode != E_OK) { + return executeErrCode; + } if (errCode != E_OK) { - LOGE("Get meta data key failed. err=%d", errCode); return errCode; } - errCode = GetMetaKeysByKeyPrefix(DBConstant::DELETE_SYNC_PREFIX_KEY, devices); - if (errCode != E_OK) { - LOGE("Get meta data key failed. err=%d", errCode); + if (context.errCode != E_OK) { + return context.errCode; } - return errCode; + return E_OK; +} + +int SQLiteSingleVerStorageExecutor::CreateFuncUpdateKey(UpdateContext &context, + void(*translateFunc)(sqlite3_context *ctx, int argc, sqlite3_value **argv), + void(*calHashFunc)(sqlite3_context *ctx, int argc, sqlite3_value **argv)) +{ + int errCode = sqlite3_create_function_v2(dbHandle_, FUNC_NAME_TRANSLATE_KEY, 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, + &context, translateFunc, nullptr, nullptr, nullptr); + if (errCode != SQLITE_OK) { + LOGE("[SqlSinExe][UpdateKey] Create func=translate_key failed=%d", errCode); + return SQLiteUtils::MapSQLiteErrno(errCode); + } + errCode = sqlite3_create_function_v2(dbHandle_, FUNC_NAME_CAL_HASH_KEY, 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, + &context, calHashFunc, nullptr, nullptr, nullptr); + if (errCode != SQLITE_OK) { + LOGE("[SqlSinExe][UpdateKey] Create func=translate_key failed=%d", errCode); + return SQLiteUtils::MapSQLiteErrno(errCode); + } + return E_OK; +} + +void SQLiteSingleVerStorageExecutor::Translate(sqlite3_context *ctx, int argc, sqlite3_value **argv) +{ + if (ctx == nullptr || argc != 1 || argv == nullptr) { // i parameters, which are key + LOGW("[SqlSinExe][Translate] invalid param=%d", argc); + return; + } + auto context = static_cast(sqlite3_user_data(ctx)); + auto keyBlob = static_cast(sqlite3_value_blob(argv[0])); + int keyBlobLen = sqlite3_value_bytes(argv[0]); + Key oldKey; + if (keyBlob != nullptr && keyBlobLen > 0) { + oldKey = Key(keyBlob, keyBlob + keyBlobLen); + } + Key newKey; + context->callback(oldKey, newKey); + if (newKey.size() >= DBConstant::MAX_KEY_SIZE || newKey.empty()) { + LOGE("[SqlSinExe][Translate] invalid key len=%zu", newKey.size()); + context->errCode = -E_INVALID_ARGS; + sqlite3_result_error(ctx, "Update key is invalid", -1); + return; + } + context->newKey = newKey; + sqlite3_result_blob(ctx, newKey.data(), static_cast(newKey.size()), SQLITE_TRANSIENT); +} + +void SQLiteSingleVerStorageExecutor::CalHashKey(sqlite3_context *ctx, int argc, sqlite3_value **argv) +{ + if (ctx == nullptr || argc != 1 || argv == nullptr) { + LOGW("[SqlSinExe][Translate] invalid param=%d", argc); + return; + } + auto context = static_cast(sqlite3_user_data(ctx)); + Key hashKey; + DBCommon::CalcValueHash(context->newKey, hashKey); + sqlite3_result_blob(ctx, hashKey.data(), static_cast(hashKey.size()), SQLITE_TRANSIENT); } } // namespace DistributedDB diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.h b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.h index 255792ccb48051f3c7775b39f74de686c2216298..50eb398bb8be7d1c35c6bf8cc0355fe425dc71c2 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.h +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.h @@ -121,7 +121,6 @@ public: // Get all the meta keys. int GetAllMetaKeys(std::vector &keys) const; - int GetMetaKeysByKeyPrefix(const std::string &keyPre, std::set &outKeys) const; int GetAllSyncedEntries(const std::string &deviceName, std::vector &entries) const; @@ -251,6 +250,8 @@ public: int GetExistsDevicesFromMeta(std::set &devices); + int UpdateKey(const UpdateKeyCallback &callback); + private: struct SaveRecordStatements { sqlite3_stmt *queryStatement = nullptr; @@ -265,6 +266,12 @@ private: } }; + struct UpdateContext { + int errCode = E_OK; + Key newKey; + UpdateKeyCallback callback; + }; + void PutIntoCommittedData(const DataItem &itemPut, const DataItem &itemGet, const DataOperStatus &status, SingleVerNaturalStoreCommitNotifyData *committedData); @@ -301,8 +308,6 @@ private: int InitResultSet(QueryObject &queryObj, sqlite3_stmt *&countStmt); - int GetAllKeys(sqlite3_stmt *statement, std::vector &keys) const; - int GetAllEntries(sqlite3_stmt *statement, std::vector &entries) const; int BindPutKvData(sqlite3_stmt *statement, const Key &key, const Value &value, Timestamp timestamp, @@ -396,6 +401,14 @@ private: int CheckMissQueryDataItem(sqlite3_stmt *stmt, const std::string &deviceName, DataItem &item); + int CreateFuncUpdateKey(UpdateContext &context, + void(*translateFunc)(sqlite3_context *ctx, int argc, sqlite3_value **argv), + void(*calHashFunc)(sqlite3_context *ctx, int argc, sqlite3_value **argv)); + + static void Translate(sqlite3_context *ctx, int argc, sqlite3_value **argv); + + static void CalHashKey(sqlite3_context *ctx, int argc, sqlite3_value **argv); + sqlite3_stmt *getSyncStatement_; sqlite3_stmt *getResultRowIdStatement_; sqlite3_stmt *getResultEntryStatement_; diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_sql.h b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_sql.h index 5fceeaebb415b255acb25d90ebc0c97dd261b5da..17ad51839d86f031a4685599c0d77de19e4a5289 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_sql.h +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_sql.h @@ -230,6 +230,13 @@ namespace DistributedDB { const std::string GET_SYNC_DATA_TIRGGER_SQL = "SELECT name FROM SQLITE_MASTER WHERE TYPE = 'trigger' AND TBL_NAME = 'sync_data' AND name like ?;"; + constexpr const char *UPDATE_SYNC_DATA_KEY_SQL = + "UPDATE sync_data SET key=translate_key(key), hash_key=cal_hash_key(key) WHERE flag&0x01=0"; + + constexpr const char *FUNC_NAME_TRANSLATE_KEY = "translate_key"; + + constexpr const char *FUNC_NAME_CAL_HASH_KEY = "cal_hash_key"; + const int BIND_KV_KEY_INDEX = 1; const int BIND_KV_VAL_INDEX = 2; const int BIND_LOCAL_TIMESTAMP_INDEX = 3; diff --git a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp index 7e4d6646d9bb0a229f6b6b86816e8ba8b7e1367b..35a34d23597455b761007aecb285491ce6639187 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp @@ -2515,4 +2515,113 @@ HWTEST_F(DistributedDBInterfacesNBDelegateTest, PutSync001, TestSize.Level3) EXPECT_EQ(mgr.CloseKvStore(g_kvNbDelegatePtr), OK); g_kvNbDelegatePtr = nullptr; EXPECT_EQ(mgr.DeleteKvStore(STORE_ID_1), OK); +} + +/** + * @tc.name: UpdateKey001 + * @tc.desc: Test update key + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBInterfacesNBDelegateTest, UpdateKey001, TestSize.Level0) +{ + /** + * @tc.steps:step1. Create database. + * @tc.expected: step1. Returns a non-null kvstore. + */ + KvStoreNbDelegate::Option option; + g_mgr.GetKvStore("UpdateKey001", option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); + EXPECT_TRUE(g_kvDelegateStatus == OK); + /** + * @tc.steps:step2. Put (k1, v1) into the database. + * @tc.expected: step2. Returns OK. + */ + Key k1 = {'k', '1'}; + EXPECT_EQ(g_kvNbDelegatePtr->Put(k1, VALUE_1), OK); + /** + * @tc.steps:step3. Update (k1, v1) to (k10, v1). + * @tc.expected: step3. Returns OK and get k1 return not found. + */ + g_kvNbDelegatePtr->UpdateKey([](const Key &originKey, Key &newKey) { + newKey = originKey; + newKey.push_back('0'); + }); + Value actualValue; + EXPECT_EQ(g_kvNbDelegatePtr->Get(k1, actualValue), NOT_FOUND); + k1.push_back('0'); + EXPECT_EQ(g_kvNbDelegatePtr->Get(k1, actualValue), OK); + EXPECT_EQ(actualValue, VALUE_1); + /** + * @tc.steps:step4. Close store. + * @tc.expected: step4. Returns OK. + */ + EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); + EXPECT_EQ(g_mgr.DeleteKvStore("UpdateKey001"), OK); + g_kvNbDelegatePtr = nullptr; +} + +/** + * @tc.name: UpdateKey002 + * @tc.desc: Test update key with transaction + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBInterfacesNBDelegateTest, UpdateKey002, TestSize.Level0) +{ + /** + * @tc.steps:step1. Create database. + * @tc.expected: step1. Returns a non-null kvstore. + */ + KvStoreNbDelegate::Option option; + g_mgr.GetKvStore("UpdateKey001", option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); + EXPECT_TRUE(g_kvDelegateStatus == OK); + /** + * @tc.steps:step2. Put (k1, v1) into the database . + * @tc.expected: step2. Returns OK. + */ + Key k1 = {'k', '1'}; + EXPECT_EQ(g_kvNbDelegatePtr->Put(k1, VALUE_1), OK); + g_kvNbDelegatePtr->StartTransaction(); + /** + * @tc.steps:step3. Update (k1, v1) to (k10, v1). + * @tc.expected: step3. Returns OK and get k1 return not found. + */ + g_kvNbDelegatePtr->UpdateKey([](const Key &originKey, Key &newKey) { + newKey = originKey; + newKey.push_back('0'); + }); + Value actualValue; + EXPECT_EQ(g_kvNbDelegatePtr->Get(k1, actualValue), NOT_FOUND); + Key k10 = {'k', '1', '0'}; + EXPECT_EQ(g_kvNbDelegatePtr->Get(k10, actualValue), OK); + EXPECT_EQ(actualValue, VALUE_1); + /** + * @tc.steps:step5. Rollback Transaction. + * @tc.expected: step5. k10 not exist in db. + */ + g_kvNbDelegatePtr->Rollback(); + EXPECT_EQ(g_kvNbDelegatePtr->Get(k10, actualValue), NOT_FOUND); + EXPECT_EQ(g_kvNbDelegatePtr->Get(k1, actualValue), OK); + /** + * @tc.steps:step5. Commit transaction. + * @tc.expected: step5. data exist in db. + */ + g_kvNbDelegatePtr->StartTransaction(); + g_kvNbDelegatePtr->UpdateKey([](const Key &originKey, Key &newKey) { + newKey = originKey; + newKey.push_back('0'); + }); + g_kvNbDelegatePtr->Commit(); + EXPECT_EQ(g_kvNbDelegatePtr->Get(k10, actualValue), OK); + /** + * @tc.steps:step6. Close store. + * @tc.expected: step6. Returns OK. + */ + EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); + EXPECT_EQ(g_mgr.DeleteKvStore("UpdateKey001"), OK); + g_kvNbDelegatePtr = nullptr; } \ No newline at end of file diff --git a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp index 30ac553382052cc5698ae1799861850ceda0b003..cefa24176097e625a064e84514822262cd2064ad 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp @@ -836,7 +836,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest00 EXPECT_EQ(delegate->RemoveDeviceData(DEVICE_B), OK); int logCnt = -1; - std::string checkLogSql = "SELECT count(*) FROM naturalbase_rdb_aux_t1_log WHERE device = '" + DEVICE_B + "'"; + std::string checkLogSql = "SELECT count(*) FROM naturalbase_rdb_aux_t1_log"; RelationalTestUtils::ExecSql(db, checkLogSql, nullptr, [&logCnt](sqlite3_stmt *stmt) { logCnt = sqlite3_column_int(stmt, 0); return E_OK; @@ -845,7 +845,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest00 int dataCnt = -1; std::string deviceTable = g_mgr.GetDistributedTableName(DEVICE_B, "t1"); - std::string checkDataSql = "SELECT count(*) FROM " + deviceTable + " WHERE device = '" + DEVICE_B + "'"; + std::string checkDataSql = "SELECT count(*) FROM " + deviceTable; RelationalTestUtils::ExecSql(db, checkDataSql, nullptr, [&dataCnt](sqlite3_stmt *stmt) { dataCnt = sqlite3_column_int(stmt, 0); return E_OK; @@ -857,6 +857,69 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest00 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); } +/** + * @tc.name: RelationalRemoveDeviceDataTest003 + * @tc.desc: Test remove all device data and sync again + * @tc.type: FUNC + * @tc.require: AR000GK58F + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest003, TestSize.Level1) +{ + /** + * @tc.steps:step1. Prepare db and data + * @tc.expected: step1. Return OK. + */ + RuntimeConfig::SetTranslateToDeviceIdCallback([](const std::string &oriDevId, const std::string &appId) { + return oriDevId + "_" + appId; + }); + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + ASSERT_NE(db, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, SIMPLE_CREATE_TABLE_SQL), SQLITE_OK); + AddDeviceSchema(g_deviceB, db, "t1"); + RelationalStoreDelegate *delegate = nullptr; + DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate); + EXPECT_EQ(status, OK); + ASSERT_NE(delegate, nullptr); + EXPECT_EQ(delegate->CreateDistributedTable("t1"), OK); + g_deviceB->PutDeviceData("t1", std::vector { + {1, "111", 1, 0, 1} // test data + }); + std::vector devices = {DEVICE_B}; + Query query = Query::Select("t1").EqualTo("a", 1); + status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, + [&devices](const std::map> &devicesMap) { + ASSERT_EQ(devicesMap.size(), devices.size()); + EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK); + }, true); + EXPECT_EQ(status, OK); + /** + * @tc.steps:step2. remove device data and check table + * @tc.expected: step2. dev table not exist and log not exist device b. + */ + std::this_thread::sleep_for(std::chrono::seconds(1)); + EXPECT_EQ(delegate->RemoveDeviceData(), OK); + int logCnt = -1; + std::string checkLogSql = "SELECT count(*) FROM naturalbase_rdb_aux_t1_log"; + RelationalTestUtils::ExecSql(db, checkLogSql, nullptr, [&logCnt](sqlite3_stmt *stmt) { + logCnt = sqlite3_column_int(stmt, 0); + return E_OK; + }); + EXPECT_EQ(logCnt, 0); + std::string deviceTable = RelationalStoreManager::GetDistributedTableName(DEVICE_B, "t1"); + std::string checkDataSql = "SELECT count(*) FROM " + deviceTable; + EXPECT_NE(RelationalTestUtils::ExecSql(db, checkDataSql, nullptr, nullptr), SQLITE_OK); + /** + * @tc.steps:step3. close db + * @tc.expected: step3. Return OK. + */ + status = g_mgr.CloseStore(delegate); + EXPECT_EQ(status, OK); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + RuntimeConfig::SetTranslateToDeviceIdCallback(nullptr); +} + /** * @tc.name: RelationalOpenStorePathCheckTest001 * @tc.desc: Test open store with same label but different path. @@ -1073,4 +1136,28 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, SqliteKeyWordTest001, TestSize.L EXPECT_EQ(status, OK); delegate = nullptr; EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); +} + +/** + * @tc.name: GetDistributedTableName001 + * @tc.desc: Test get distributed table name + * @tc.type: FUNC + * @tc.require: AR000GK58F + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBInterfacesRelationalTest, GetDistributedTableName001, TestSize.Level1) +{ + const std::string deviceName = "DEVICES_A"; + const std::string tableName = "TABLE"; + const std::string hashDev = DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceName)); + + std::string devTableName = RelationalStoreManager::GetDistributedTableName(deviceName, tableName); + EXPECT_EQ(devTableName, DBConstant::RELATIONAL_PREFIX + tableName + "_" + hashDev); + RuntimeConfig::SetTranslateToDeviceIdCallback([](const std::string &oriDevId, const std::string &appId) { + EXPECT_EQ(appId, ""); + return oriDevId; + }); + devTableName = RelationalStoreManager::GetDistributedTableName(deviceName, tableName); + EXPECT_EQ(devTableName, DBConstant::RELATIONAL_PREFIX + tableName + "_" + deviceName); + RuntimeConfig::SetTranslateToDeviceIdCallback(nullptr); } \ No newline at end of file diff --git a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp index 2e84627135081078db315b350405e235de1b0c92..124f4dce912d569c73df6a2ca76aaf56778f4252 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp @@ -978,8 +978,8 @@ HWTEST_F(DistributedDBMockSyncModuleTest, SyncLifeTest004, TestSize.Level3) syncer->EnableAutoSync(true); incRefCount = 0; syncer->RemoteDataChanged(""); - EXPECT_EQ(incRefCount, 1); // refCount is 1 std::this_thread::sleep_for(std::chrono::seconds(1)); + EXPECT_EQ(incRefCount, 2); // refCount is 2 syncer = nullptr; RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); delete syncDBInterface; diff --git a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp index 0edb53235a52fa709acff4e3c6a125efaca750fd..7710f414f76f137f83874428354a55bdfe59ed75 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp @@ -1918,4 +1918,54 @@ HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, InterceptDataFail001, TestSiz } VirtualDataItem item; EXPECT_EQ(g_deviceB->GetData(key, item), -E_NOT_FOUND); +} + +/** + * @tc.name: UpdateKey001 + * @tc.desc: test update key can effect local data and sync data, without delete data + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, UpdateKey001, TestSize.Level1) +{ + /** + * @tc.steps: step1. device A set sync data (k1, v1) local data (k2, v2) (k3, v3) and delete (k4, v4) + * @tc.expected: step1. put data return ok + */ + Key k1 = {'k', '1'}; + Value v1 = {'v', '1'}; + g_deviceB->PutData(k1, v1, 1, 0); + ASSERT_EQ(g_deviceB->Sync(SyncMode::SYNC_MODE_PUSH_ONLY, true), E_OK); + Value actualValue; + EXPECT_EQ(g_kvDelegatePtr->Get(k1, actualValue), OK); + EXPECT_EQ(v1, actualValue); + Key k2 = {'k', '2'}; + Value v2 = {'v', '2'}; + Key k3 = {'k', '3'}; + Value v3 = {'v', '3'}; + Key k4 = {'k', '4'}; + Value v4 = {'v', '4'}; + EXPECT_EQ(g_kvDelegatePtr->Put(k2, v2), OK); + EXPECT_EQ(g_kvDelegatePtr->Put(k3, v3), OK); + EXPECT_EQ(g_kvDelegatePtr->Put(k4, v4), OK); + EXPECT_EQ(g_kvDelegatePtr->Delete(k4), OK); + /** + * @tc.steps: step2. device A update key and set + * @tc.expected: step2. put data return ok + */ + DBStatus status = g_kvDelegatePtr->UpdateKey([](const Key &originKey, Key &newKey) { + newKey = originKey; + newKey.push_back('0'); + }); + EXPECT_EQ(status, OK); + k1.push_back('0'); + k2.push_back('0'); + k3.push_back('0'); + EXPECT_EQ(g_kvDelegatePtr->Get(k1, actualValue), OK); + EXPECT_EQ(v1, actualValue); + EXPECT_EQ(g_kvDelegatePtr->Get(k2, actualValue), OK); + EXPECT_EQ(v2, actualValue); + EXPECT_EQ(g_kvDelegatePtr->Get(k3, actualValue), OK); + EXPECT_EQ(v3, actualValue); } \ No newline at end of file