diff --git a/services/distributeddataservice/service/data_share/common/db_delegate.cpp b/services/distributeddataservice/service/data_share/common/db_delegate.cpp index 765d69b5cef356952e244a4b542018c6da61b5fc..2a3e970799a90cbe3b7e1ee9d8162d7500db0eaf 100644 --- a/services/distributeddataservice/service/data_share/common/db_delegate.cpp +++ b/services/distributeddataservice/service/data_share/common/db_delegate.cpp @@ -46,12 +46,7 @@ std::shared_ptr DBDelegate::Create(DistributedData::StoreMetaData &m it->second->time_ = std::chrono::steady_clock::now() + std::chrono::seconds(INTERVAL); return !stores.empty(); } - store = std::make_shared(metaData, NO_CHANGE_VERSION, true, extUri, backup); - if (store->IsInvalid()) { - store = nullptr; - ZLOGE("creator failed, storeName: %{public}s", metaData.GetStoreAlias().c_str()); - return false; - } + store = std::make_shared(); auto entity = std::make_shared(store, metaData); stores.emplace(metaData.storeId, entity); StartTimer(metaData.isEncrypt); @@ -62,7 +57,24 @@ std::shared_ptr DBDelegate::Create(DistributedData::StoreMetaData &m } else { stores_.Compute(metaData.tokenId, storeFunc); } - return store; + + // rdbStore is initialized outside the ConcurrentMap, because this maybe a time-consuming operation. + bool success = store->Init(metaData, NO_CHANGE_VERSION, true, extUri, backup); + if (success) { + return store; + } + ZLOGE("creator failed, storeName: %{public}s", metaData.GetStoreAlias().c_str()); + auto eraseFunc = [&metaData] + (auto &, std::map> &stores) -> bool { + stores.erase(metaData.storeId); + return !stores.empty(); + }; + if (metaData.isEncrypt) { + storesEncrypt_.Compute(metaData.tokenId, eraseFunc); + } else { + stores_.Compute(metaData.tokenId, eraseFunc); + } + return nullptr; } void DBDelegate::SetExecutorPool(std::shared_ptr executor) diff --git a/services/distributeddataservice/service/data_share/common/db_delegate.h b/services/distributeddataservice/service/data_share/common/db_delegate.h index 0cb36808d507731ba5dcdcff61549766c7fad631..b5b51aec15ce942adba43bc2177d96470414be06 100644 --- a/services/distributeddataservice/service/data_share/common/db_delegate.h +++ b/services/distributeddataservice/service/data_share/common/db_delegate.h @@ -37,6 +37,8 @@ public: using Filter = std::function; static std::shared_ptr Create(DistributedData::StoreMetaData &metaData, const std::string &extUri = "", const std::string &backup = ""); + virtual bool Init(const DistributedData::StoreMetaData &meta, int version, + bool registerFunction, const std::string &extUri, const std::string &backup) = 0; static void Close(const Filter &filter); virtual std::pair> Query(const std::string &tableName, const DataSharePredicates &predicates, const std::vector &columns, @@ -128,8 +130,8 @@ public: static std::shared_ptr GetInstance( bool reInit = false, const std::string &dir = "", const std::shared_ptr &executors = nullptr); virtual ~KvDBDelegate() = default; - virtual std::pair Upsert(const std::string &collectionName, const KvData &value) = 0; - virtual std::pair Delete(const std::string &collectionName, const std::string &filter) = 0; + virtual std::pair Upsert(const std::string &collectionName, const KvData &value) = 0; + virtual std::pair Delete(const std::string &collectionName, const std::string &filter) = 0; virtual int32_t Get(const std::string &collectionName, const Id &id, std::string &value) = 0; virtual int32_t Get(const std::string &collectionName, const std::string &filter, const std::string &projection, std::string &result) = 0; diff --git a/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp b/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp index de1036ff2b24476a28b4730fe59b0adbbbd37c79..b673271be18e48615843a10fa1780b686ed2588d 100644 --- a/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp +++ b/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp @@ -97,16 +97,32 @@ std::pair RdbDelegate::GetConfig(const DistributedData::Sto return std::make_pair(E_OK, config); } -RdbDelegate::RdbDelegate(const DistributedData::StoreMetaData &meta, int version, +RdbDelegate::RdbDelegate() +{ +} + +bool RdbDelegate::Init(const DistributedData::StoreMetaData &meta, int version, bool registerFunction, const std::string &extUri, const std::string &backup) - : tokenId_(meta.tokenId), bundleName_(meta.bundleName), storeName_(meta.storeId), - haMode_(meta.haMode), extUri_(extUri), backup_(backup), user_(meta.user) { + if (isInited_) { + return true; + } + std::lock_guard lock(initMutex_); + if (isInited_) { + return true; + } + tokenId_ = meta.tokenId; + bundleName_ = meta.bundleName; + storeName_ = meta.storeId; + haMode_ = meta.haMode; + extUri_ = extUri; + backup_ = backup; + user_ = meta.user; auto [err, config] = GetConfig(meta, registerFunction); if (err != E_OK) { ZLOGW("Get rdbConfig failed, errCode is %{public}d, dir is %{public}s", err, DistributedData::Anonymous::Change(meta.dataDir).c_str()); - return; + return false; } DefaultOpenCallback callback; TimeoutReport timeoutReport({meta.bundleName, "", meta.storeId, __FUNCTION__, 0}); @@ -117,8 +133,12 @@ RdbDelegate::RdbDelegate(const DistributedData::StoreMetaData &meta, int version ZLOGW("GetRdbStore failed, errCode is %{public}d, dir is %{public}s", errCode_, DistributedData::Anonymous::Change(meta.dataDir).c_str()); RdbDelegate::TryAndSend(errCode_); + return false; } + isInited_ = true; + return true; } + RdbDelegate::~RdbDelegate() { ZLOGI("Destruct. BundleName: %{public}s. StoreName: %{public}s. user: %{public}s", bundleName_.c_str(), diff --git a/services/distributeddataservice/service/data_share/common/rdb_delegate.h b/services/distributeddataservice/service/data_share/common/rdb_delegate.h index d7c3eedaf8d018549a28a9d2bd6097f29318fc1f..3fe8b3dce8395ce402089c3db4bf1a72477e0c13 100644 --- a/services/distributeddataservice/service/data_share/common/rdb_delegate.h +++ b/services/distributeddataservice/service/data_share/common/rdb_delegate.h @@ -31,9 +31,10 @@ namespace OHOS::DataShare { using namespace OHOS::NativeRdb; class RdbDelegate final : public DBDelegate { public: - explicit RdbDelegate(const DistributedData::StoreMetaData &meta, int version, - bool registerFunction, const std::string &extUri, const std::string &backup); + explicit RdbDelegate(); ~RdbDelegate(); + bool Init(const DistributedData::StoreMetaData &meta, int version, + bool registerFunction, const std::string &extUri, const std::string &backup) override; std::pair> Query(const std::string &tableName, const DataSharePredicates &predicates, const std::vector &columns, int32_t callingPid, uint32_t callingTokenId) override; @@ -59,13 +60,15 @@ private: static constexpr int RETRY = 3; static constexpr const char *DUAL_WRITE = "dualWrite"; static constexpr const char *PERIODIC = "periodic"; - uint32_t tokenId_; - std::string bundleName_; - std::string storeName_; - int32_t haMode_; - std::string extUri_; - std::string backup_; - std::string user_; + uint32_t tokenId_ = 0; + std::string bundleName_ = ""; + std::string storeName_ = ""; + int32_t haMode_ = 0; + std::string extUri_ = ""; + std::string backup_ = ""; + std::string user_ = ""; + std::mutex initMutex_; + bool isInited_ = false; }; class DefaultOpenCallback : public RdbOpenCallback { public: diff --git a/services/distributeddataservice/service/test/data_share_common_test.cpp b/services/distributeddataservice/service/test/data_share_common_test.cpp index 9f9f92555c39c0580ed76f8ff3286fc19f0f4588..a6db0130b3801335238fccf95b37ad8a60df3dc4 100644 --- a/services/distributeddataservice/service/test/data_share_common_test.cpp +++ b/services/distributeddataservice/service/test/data_share_common_test.cpp @@ -163,7 +163,8 @@ HWTEST_F(DataShareCommonTest, InsertEx001, TestSize.Level1) bool registerFunction = false; std::string extUri = "uri"; std::string backup = "backup"; - RdbDelegate rdbDelegate(metaData, version, registerFunction, extUri, backup); + RdbDelegate rdbDelegate; + rdbDelegate.Init(metaData, version, registerFunction, extUri, backup); rdbDelegate.store_ = nullptr; std::string tableName = ""; DataShare::DataShareValuesBucket valuesBucket; @@ -196,7 +197,8 @@ HWTEST_F(DataShareCommonTest, UpdateEx001, TestSize.Level1) bool registerFunction = false; std::string extUri = "uri"; std::string backup = "backup"; - RdbDelegate rdbDelegate(metaData, version, registerFunction, extUri, backup); + RdbDelegate rdbDelegate; + rdbDelegate.Init(metaData, version, registerFunction, extUri, backup); rdbDelegate.store_ = nullptr; std::string tableName = ""; DataShare::DataShareValuesBucket valuesBucket; @@ -230,7 +232,8 @@ HWTEST_F(DataShareCommonTest, DeleteEx001, TestSize.Level1) bool registerFunction = false; std::string extUri = "uri"; std::string backup = "backup"; - RdbDelegate rdbDelegate(metaData, version, registerFunction, extUri, backup); + RdbDelegate rdbDelegate; + rdbDelegate.Init(metaData, version, registerFunction, extUri, backup); rdbDelegate.store_ = nullptr; std::string tableName = ""; DataSharePredicates predicate; @@ -261,7 +264,8 @@ HWTEST_F(DataShareCommonTest, Query001, TestSize.Level1) bool registerFunction = false; std::string extUri = "uri"; std::string backup = "backup"; - RdbDelegate rdbDelegate(metaData, version, registerFunction, extUri, backup); + RdbDelegate rdbDelegate; + rdbDelegate.Init(metaData, version, registerFunction, extUri, backup); rdbDelegate.store_ = nullptr; std::string tableName = ""; DataSharePredicates predicate; @@ -295,7 +299,8 @@ HWTEST_F(DataShareCommonTest, Query002, TestSize.Level1) bool registerFunction = false; std::string extUri = "uri"; std::string backup = "backup"; - RdbDelegate rdbDelegate(metaData, version, registerFunction, extUri, backup); + RdbDelegate rdbDelegate; + rdbDelegate.Init(metaData, version, registerFunction, extUri, backup); rdbDelegate.store_ = nullptr; std::string sql = "testsql"; std::vector selectionArgs; @@ -326,7 +331,8 @@ HWTEST_F(DataShareCommonTest, QuerySql001, TestSize.Level1) bool registerFunction = false; std::string extUri = "uri"; std::string backup = "backup"; - RdbDelegate rdbDelegate(metaData, version, registerFunction, extUri, backup); + RdbDelegate rdbDelegate; + rdbDelegate.Init(metaData, version, registerFunction, extUri, backup); rdbDelegate.store_ = nullptr; std::string sql = "testsql"; auto result = rdbDelegate.QuerySql(sql); @@ -356,7 +362,8 @@ HWTEST_F(DataShareCommonTest, UpdateSql001, TestSize.Level1) bool registerFunction = false; std::string extUri = "uri"; std::string backup = "backup"; - RdbDelegate rdbDelegate(metaData, version, registerFunction, extUri, backup); + RdbDelegate rdbDelegate; + rdbDelegate.Init(metaData, version, registerFunction, extUri, backup); rdbDelegate.store_ = nullptr; std::string sql = "testsql"; auto result = rdbDelegate.UpdateSql(sql); @@ -564,4 +571,42 @@ HWTEST_F(DataShareCommonTest, ClearTimer003, TestSize.Level1) EXPECT_TRUE(manager.timerCache_.empty()); ZLOGI("ClearTimer003 end"); } + +/** + * @tc.name: DBDelegateTest001 + * @tc.desc: do nothing when delegate already inited + * @tc.type: FUNC + */ +HWTEST_F(DataShareCommonTest, DBDelegateTest001, TestSize.Level0) { + RdbDelegate delegate; + DistributedData::StoreMetaData meta; + meta.tokenId = 1; + + delegate.isInited_ = true; + delegate.Init({}, 0, false, "extUri", "backup"); + + EXPECT_TRUE(delegate.isInited_); + EXPECT_EQ(delegate.tokenId_, 0); + EXPECT_EQ(delegate.extUri_, ""); + EXPECT_EQ(delegate.backup_, ""); +} + +/** + * @tc.name : DBDelegateTest002 + * @tc.number: init members in delegate init + * @tc.type: FUNC + */ +HWTEST_F(DataShareCommonTest, DBDelegateTest002, TestSize.Level0) { + RdbDelegate delegate; + DistributedData::StoreMetaData meta; + meta.tokenId = 1; + + delegate.isInited_ = false; + delegate.Init(meta, 0, false, "extUri", "backup"); + + EXPECT_FALSE(delegate.isInited_); + EXPECT_EQ(delegate.tokenId_, meta.tokenId); + EXPECT_EQ(delegate.extUri_, "extUri"); + EXPECT_EQ(delegate.backup_, "backup"); +} } // namespace OHOS::Test \ No newline at end of file