diff --git a/frameworks/libs/distributeddb/common/include/db_common.h b/frameworks/libs/distributeddb/common/include/db_common.h index 2775893abecef39db12a01aa13839e8a072ac1db..be85e6fb30fa6f6ca8b345dd726523b9edc4ef05 100644 --- a/frameworks/libs/distributeddb/common/include/db_common.h +++ b/frameworks/libs/distributeddb/common/include/db_common.h @@ -112,6 +112,10 @@ public: static std::string GenerateHashLabel(const DBInfo &dbInfo); static uint64_t EraseBit(uint64_t origin, uint64_t eraseBit); + + static void LoadGrdLib(void); + + static bool IsGrdLibLoaded(void); private: static void InsertNodesByScore(const std::map> &graph, const std::vector &generateNodes, const std::map &scoreGraph, diff --git a/frameworks/libs/distributeddb/common/src/db_common.cpp b/frameworks/libs/distributeddb/common/src/db_common.cpp index f7950a032c7277ccdd6be834d2deb759169dfe40..e6536641776842013063ea960a15287c81ee919e 100644 --- a/frameworks/libs/distributeddb/common/src/db_common.cpp +++ b/frameworks/libs/distributeddb/common/src/db_common.cpp @@ -15,8 +15,11 @@ #include "db_common.h" +#include #include #include +#include +#include #include #include "cloud/cloud_db_constant.h" @@ -59,6 +62,9 @@ namespace { const std::string CAP_HEX_CHAR_MAP = "0123456789ABCDEF"; } +static std::atomic_bool g_isGRDLoaded = false; +static std::mutex g_mutex; + int DBCommon::CreateDirectory(const std::string &directory) { bool isExisted = OS::CheckPathExistence(directory); @@ -633,4 +639,19 @@ uint64_t DBCommon::EraseBit(uint64_t origin, uint64_t eraseBit) { return origin & (~eraseBit); } + +void DBCommon::LoadGrdLib(void) +{ + if (!g_isGRDLoaded) { + std::lock_guard lock(g_mutex); + if (dlopen("libgaussdb_rd.z.so", RTLD_LAZY) != NULL) { + g_isGRDLoaded = true; + } + } +} + +bool DBCommon::IsGrdLibLoaded(void) +{ + return g_isGRDLoaded; +} } // namespace DistributedDB diff --git a/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h b/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h index 2b4c38e0d6145e564286742051c107099e6fac22..bd9e44eab3c4af7787ebb940765d2155c2ec8fcb 100755 --- a/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h +++ b/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h @@ -88,5 +88,7 @@ struct GRD_APIInfo { KVBatchDestory KVBatchDestoryApi = nullptr; }; GRD_APIInfo GetApiInfoInstance(); +void LoadGRDLib(void); +bool IsGRDLibInvalid(void); } // namespace DocumentDB #endif // __cplusplus diff --git a/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp b/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp index 9b2233f5dcfa517b178777deb56ad48ad805845b..0f619b9757fe53456a34cd0c3bf4bf0298310d39 100644 --- a/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp +++ b/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp @@ -306,15 +306,22 @@ void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStor if (!GetKvStoreParamCheck(storeId, option, callback)) { return; } + auto tmpOption = option; + if (tmpOption.storageEngineType == std::string(GAUSSDB_RD)) { + DBCommon::LoadGrdLib(); + if (!DBCommon::IsGrdLibLoaded()) { + tmpOption.storageEngineType = std::string(SQLITE); + } + } // check if schema is supported and valid SchemaObject schema; - DBStatus retCode = CheckAndGetSchema(option.isMemoryDb, option.schema, schema); + DBStatus retCode = CheckAndGetSchema(tmpOption.isMemoryDb, tmpOption.schema, schema); if (retCode != OK) { callback(retCode, nullptr); return; } KvDBProperties properties; - InitPropWithNbOption(properties, GetKvStorePath(), schema, option); + InitPropWithNbOption(properties, GetKvStorePath(), schema, tmpOption); DBCommon::SetDatabaseIds(properties, appId_, userId_, storeId, instanceId_); int errCode; @@ -336,7 +343,7 @@ void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStor return; } - status = SetObserverNotifier(kvStore, option); + status = SetObserverNotifier(kvStore, tmpOption); if (status != OK) { CloseKvStore(kvStore); callback(status, nullptr); @@ -346,7 +353,7 @@ void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStor bool enAutoSync = false; (void)conn->Pragma(PRAGMA_AUTO_SYNC, static_cast(&enAutoSync)); - SecurityOption secOption = option.secOption; + SecurityOption secOption = tmpOption.secOption; (void)conn->Pragma(PRAGMA_TRIGGER_TO_MIGRATE_DATA, &secOption); callback(OK, kvStore); 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 b127cf91c5bc622d046681f1056e39d9b5ec8c11..10a96b94a680125da24114660edccaf253902dde 100755 --- 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 @@ -361,6 +361,114 @@ HWTEST_F(DistributedDBInterfacesNBDelegateTest, CombineTest001, TestSize.Level1) g_kvNbDelegatePtr = nullptr; } +/** + * @tc.name: CombineTest002 + * @tc.desc: Test the NbDelegate for combined operation, try to use GAUSSDB_RD. + * @tc.type: FUNC + * @tc.require: AR000CCPOM + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBInterfacesNBDelegateTest, CombineTest002, TestSize.Level1) +{ + /** + * @tc.steps:step1. Get the nb delegate. + * @tc.expected: step1. Get results OK and non-null delegate. + */ + KvStoreNbDelegate::Option option = {true, false, false}; + option.storageEngineType = GAUSSDB_RD; + g_mgr.GetKvStore("distributed_nb_delegate_test", option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); + EXPECT_TRUE(g_kvDelegateStatus == OK); + Key key; + key = {'A', 'C', 'Q'}; + Value value; + value = {'G', 'D', 'O'}; + Value valueRead; + KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest; + ASSERT_TRUE(observer != nullptr); + /** + * @tc.steps:step2. Register the non-null observer for the special key. + * @tc.expected: step2. Register results OK. + */ + EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_LOCAL_ONLY, observer), OK); + /** + * @tc.steps:step3. Put the local data. + * @tc.expected: step3. Put returns OK. + */ + EXPECT_EQ(g_kvNbDelegatePtr->PutLocal(key, value), OK); + std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME)); + /** + * @tc.steps:step4. Check the local data. + * @tc.expected: step4. The get data is equal to the put data. + */ + EXPECT_EQ(g_kvNbDelegatePtr->GetLocal(key, valueRead), OK); + /** + * @tc.steps:step5. Delete the local data. + * @tc.expected: step5. Delete returns OK. + */ + EXPECT_EQ(g_kvNbDelegatePtr->DeleteLocal(key), OK); + std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME)); + /** + * @tc.steps:step6. Check the local data. + * @tc.expected: step6. Couldn't find the deleted data. + */ + EXPECT_EQ(g_kvNbDelegatePtr->GetLocal(key, valueRead), NOT_FOUND); + /** + * @tc.steps:step7. UnRegister the observer. + * @tc.expected: step7. Returns OK. + */ + EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(observer), OK); + delete observer; + observer = nullptr; + Key key1; + key1 = {'D', 'B', 'N'}; + Value value1; + value1 = {'P', 'D', 'G'}; + + Key key2 = key1; + Value value2; + key2.push_back('U'); + value2 = {'C'}; + /** + * @tc.steps:step8. Put the data. + * @tc.expected: step8. Put returns OK. + */ + EXPECT_EQ(g_kvNbDelegatePtr->Put(key1, value1), OK); + Value valueRead2; + /** + * @tc.steps:step9. Check the data. + * @tc.expected: step9. Getting the put data returns OK. + */ + EXPECT_EQ(g_kvNbDelegatePtr->Get(key1, valueRead2), OK); + /** + * @tc.steps:step10. Put another data. + * @tc.expected: step10. Returns OK. + */ + EXPECT_EQ(g_kvNbDelegatePtr->Put(key2, value2), OK); + std::vector vect; + /** + * @tc.steps:step10. Get the batch data using the prefix key. + * @tc.expected: step10. Results OK and the batch data size is equal to the put data size. + */ + EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(key1, vect), OK); + EXPECT_EQ(vect.size(), 2UL); + /** + * @tc.steps:step11. Delete one data. + * @tc.expected: step11. Results OK and couldn't get the deleted data. + */ + EXPECT_EQ(g_kvNbDelegatePtr->Delete(key1), OK); + EXPECT_EQ(g_kvNbDelegatePtr->Get(key1, valueRead2), NOT_FOUND); + + LOGD("Close store"); + /** + * @tc.steps:step12. Close the kv store. + * @tc.expected: step12. Results OK and delete successfully. + */ + EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); + EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_delegate_test"), OK); + g_kvNbDelegatePtr = nullptr; +} + /** * @tc.name: CreateMemoryDb001 * @tc.desc: Create memory database after.